Revert "Import React DevTools v4"
This reverts commit b438699d3620bff236282b049204e1221b3689e9.
Brian Vaughn committed
Aug 28, 2019 at 07:39 UTC
b8390310b14cce89fd26df83f969505b5f129f10
383 files changed
+223
-63526
.circleci/config.yml
-13
@@ -158,16 +158,6 @@ jobs:
158
- *run_yarn
159
- run: yarn test-build --maxWorkers=2
160
161
- test_build_devtools:
162
- docker: *docker
163
- environment: *environment
164
- steps:
165
- - checkout
166
- - attach_workspace: *attach_workspace
167
- - *restore_yarn_cache
168
- - *run_yarn
169
- - run: yarn test-build-devtools --maxWorkers=2
170
-
161
test_dom_fixtures:
162
docker: *docker
163
environment: *environment
@@ -241,9 +231,6 @@ workflows:
231
- test_build_prod:
232
requires:
233
- build
244
- - test_build_devtools:
245
- requires:
246
- - build
234
- test_dom_fixtures:
235
requires:
236
- build
.eslintignore
-7
@@ -12,10 +12,3 @@ scripts/bench/benchmarks/**/*.js
12
13
# React repository clone
14
scripts/bench/remote-repo/
15
-
16
-packages/react-devtools-core/dist
17
-packages/react-devtools-extensions/chrome/build
18
-packages/react-devtools-extensions/firefox/build
19
-packages/react-devtools-extensions/shared/build
20
-packages/react-devtools-inline/dist
21
-packages/react-devtools-shell/dist
\ No newline at end of file
.gitignore
-11
@@ -22,14 +22,3 @@ chrome-user-data
22
.vscode
23
*.swp
24
*.swo
25
-
26
-packages/react-devtools-core/dist
27
-packages/react-devtools-extensions/chrome/build
28
-packages/react-devtools-extensions/chrome/*.crx
29
-packages/react-devtools-extensions/chrome/*.pem
30
-packages/react-devtools-extensions/firefox/build
31
-packages/react-devtools-extensions/firefox/*.xpi
32
-packages/react-devtools-extensions/firefox/*.pem
33
-packages/react-devtools-extensions/shared/build
34
-packages/react-devtools-inline/dist
35
-packages/react-devtools-shell/dist
\ No newline at end of file
.prettierignore
deleted
-6
@@ -1,6 +0,0 @@
1
-packages/react-devtools-core/dist
2
-packages/react-devtools-extensions/chrome/build
3
-packages/react-devtools-extensions/firefox/build
4
-packages/react-devtools-extensions/shared/build
5
-packages/react-devtools-inline/dist
6
-packages/react-devtools-shell/dist
\ No newline at end of file
fixtures/devtools/regression/14.9.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 14.9</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@0.14.9/dist/react.js"></script>
15
- <script src="https://unpkg.com/react-dom@0.14.9/dist/react-dom.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/14.9.html">http://localhost:3000/14.9.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/15.0.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 15.0</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@15.0/dist/react.js"></script>
15
- <script src="https://unpkg.com/react-dom@15.0/dist/react-dom.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/15.0.html">http://localhost:3000/15.0.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/15.1.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 15.1</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@15.1/dist/react.js"></script>
15
- <script src="https://unpkg.com/react-dom@15.1/dist/react-dom.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/15.1.html">http://localhost:3000/15.1.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/15.2.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 15.2</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@15.2/dist/react.js"></script>
15
- <script src="https://unpkg.com/react-dom@15.2/dist/react-dom.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/15.2.html">http://localhost:3000/15.2.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/15.3.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 15.3</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@15.3/dist/react.js"></script>
15
- <script src="https://unpkg.com/react-dom@15.3/dist/react-dom.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/15.3.html">http://localhost:3000/15.3.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/15.4.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 15.4</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@15.4/dist/react.js"></script>
15
- <script src="https://unpkg.com/react-dom@15.4/dist/react-dom.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/15.4.html">http://localhost:3000/15.4.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/15.5.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 15.5</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@15.5/dist/react.js"></script>
15
- <script src="https://unpkg.com/react-dom@15.5/dist/react-dom.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/15.5.html">http://localhost:3000/15.5.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/15.6.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 15.6</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@15.6/dist/react.js"></script>
15
- <script src="https://unpkg.com/react-dom@15.6/dist/react-dom.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/15.6.html">http://localhost:3000/15.6.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/16.0.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 16.0</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@16.0/umd/react.development.js"></script>
15
- <script src="https://unpkg.com/react-dom@16.0/umd/react-dom.development.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/16.0.html">http://localhost:3000/16.0.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/16.1.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 16.1</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@16.1/umd/react.development.js"></script>
15
- <script src="https://unpkg.com/react-dom@16.1/umd/react-dom.development.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/16.1.html">http://localhost:3000/16.1.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/16.2.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 16.2</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@16.2/umd/react.development.js"></script>
15
- <script src="https://unpkg.com/react-dom@16.2/umd/react-dom.development.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/16.2.html">http://localhost:3000/16.2.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/16.3.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 16.3</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@16.3/umd/react.development.js"></script>
15
- <script src="https://unpkg.com/react-dom@16.3/umd/react-dom.development.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/16.3.html">http://localhost:3000/16.3.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/16.4.html
deleted
-38
@@ -1,38 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 16.4</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/react@16.4/umd/react.development.js"></script>
15
- <script src="https://unpkg.com/react-dom@16.4/umd/react-dom.development.js"></script>
16
-
17
- <!-- Don't use this in production: -->
18
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
19
- </head>
20
- <body>
21
- <div id="root">
22
- 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.
23
- <br/><br/>
24
- Use the <code>server</code> script instead:
25
- <br/><br/>
26
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
27
- <code>open <a href="http://localhost:3000/16.4.html">http://localhost:3000/16.4.html</a></code>
28
- </div>
29
-
30
- <script src="shared.js" type="text/babel"></script>
31
-
32
- <!--
33
- This is a great way to try React but it's not suitable for production.
34
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
35
- Learn more at https://reactjs.org/docs/getting-started.html
36
- -->
37
- </body>
38
-</html>
\ No newline at end of file
fixtures/devtools/regression/16.5.html
deleted
-40
@@ -1,40 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 16.5</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/schedule@0.5.0/umd/schedule.development.js"></script>
15
- <script src="https://unpkg.com/schedule@0.5.0/umd/schedule-tracing.development.js"></script>
16
- <script src="https://unpkg.com/react@16.5/umd/react.development.js"></script>
17
- <script src="https://unpkg.com/react-dom@16.5/umd/react-dom.development.js"></script>
18
-
19
- <!-- Don't use this in production: -->
20
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
21
- </head>
22
- <body>
23
- <div id="root">
24
- 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.
25
- <br/><br/>
26
- Use the <code>server</code> script instead:
27
- <br/><br/>
28
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
29
- <code>open <a href="http://localhost:3000/16.5.html">http://localhost:3000/16.5.html</a></code>
30
- </div>
31
-
32
- <script src="shared.js" type="text/babel"></script>
33
-
34
- <!--
35
- This is a great way to try React but it's not suitable for production.
36
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
37
- Learn more at https://reactjs.org/docs/getting-started.html
38
- -->
39
- </body>
40
-</html>
\ No newline at end of file
fixtures/devtools/regression/16.6.html
deleted
-41
@@ -1,41 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 16.6</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/scheduler@0.10.0/umd/scheduler.development.js"></script>
15
- <script src="https://unpkg.com/scheduler@0.10.0/umd/scheduler-tracing.development.js"></script>
16
- <script src="https://unpkg.com/react@16.6/umd/react.development.js"></script>
17
- <script src="https://unpkg.com/react-dom@16.6/umd/react-dom.development.js"></script>
18
- <script src="https://unpkg.com/react-cache@2.0.0-alpha.1/umd/react-cache.development.js"></script>
19
-
20
- <!-- Don't use this in production: -->
21
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
22
- </head>
23
- <body>
24
- <div id="root">
25
- 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.
26
- <br/><br/>
27
- Use the <code>server</code> script instead:
28
- <br/><br/>
29
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
30
- <code>open <a href="http://localhost:3000/16.6.html">http://localhost:3000/16.6.html</a></code>
31
- </div>
32
-
33
- <script src="shared.js" type="text/babel"></script>
34
-
35
- <!--
36
- This is a great way to try React but it's not suitable for production.
37
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
38
- Learn more at https://reactjs.org/docs/getting-started.html
39
- -->
40
- </body>
41
-</html>
\ No newline at end of file
fixtures/devtools/regression/16.7.html
deleted
-41
@@ -1,41 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React 16.7</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/scheduler@0.12.0/umd/scheduler.development.js"></script>
15
- <script src="https://unpkg.com/scheduler@0.12.0/umd/scheduler-tracing.development.js"></script>
16
- <script src="https://unpkg.com/react@16.7/umd/react.development.js"></script>
17
- <script src="https://unpkg.com/react-dom@16.7/umd/react-dom.development.js"></script>
18
- <script src="https://unpkg.com/react-cache@2.0.0-alpha.1/umd/react-cache.development.js"></script>
19
-
20
- <!-- Don't use this in production: -->
21
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
22
- </head>
23
- <body>
24
- <div id="root">
25
- 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.
26
- <br/><br/>
27
- Use the <code>server</code> script instead:
28
- <br/><br/>
29
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
30
- <code>open <a href="http://localhost:3000/16.7.html">http://localhost:3000/16.7.html</a></code>
31
- </div>
32
-
33
- <script src="shared.js" type="text/babel"></script>
34
-
35
- <!--
36
- This is a great way to try React but it's not suitable for production.
37
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
38
- Learn more at https://reactjs.org/docs/getting-started.html
39
- -->
40
- </body>
41
-</html>
\ No newline at end of file
fixtures/devtools/regression/canary.html
deleted
-41
@@ -1,41 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React canary</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/scheduler@canary/umd/scheduler.development.js"></script>
15
- <script src="https://unpkg.com/scheduler@canary/umd/scheduler-tracing.development.js"></script>
16
- <script src="https://unpkg.com/react@canary/umd/react.development.js"></script>
17
- <script src="https://unpkg.com/react-dom@canary/umd/react-dom.development.js"></script>
18
- <script src="https://unpkg.com/react-cache@next/umd/react-cache.development.js"></script>
19
-
20
- <!-- Don't use this in production: -->
21
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
22
- </head>
23
- <body>
24
- <div id="root">
25
- 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.
26
- <br/><br/>
27
- Use the <code>server</code> script instead:
28
- <br/><br/>
29
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
30
- <code>open <a href="http://localhost:3000/canary.html">http://localhost:3000/canary.html</a></code>
31
- </div>
32
-
33
- <script src="shared.js" type="text/babel"></script>
34
-
35
- <!--
36
- This is a great way to try React but it's not suitable for production.
37
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
38
- Learn more at https://reactjs.org/docs/getting-started.html
39
- -->
40
- </body>
41
-</html>
\ No newline at end of file
fixtures/devtools/regression/index.html
deleted
-28
@@ -1,28 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React DevTools regression test</title>
6
- <link rel="stylesheet" href="styles.css" />
7
- </head>
8
- <body>
9
- <iframe src="canary.html"></iframe>
10
- <iframe src="next.html"></iframe>
11
- <iframe src="16.7.html"></iframe>
12
- <iframe src="16.6.html"></iframe>
13
- <iframe src="16.5.html"></iframe>
14
- <iframe src="16.4.html"></iframe>
15
- <iframe src="16.3.html"></iframe>
16
- <iframe src="16.2.html"></iframe>
17
- <iframe src="16.1.html"></iframe>
18
- <iframe src="16.0.html"></iframe>
19
- <iframe src="15.6.html"></iframe>
20
- <iframe src="15.5.html"></iframe>
21
- <iframe src="15.4.html"></iframe>
22
- <iframe src="15.3.html"></iframe>
23
- <iframe src="15.2.html"></iframe>
24
- <iframe src="15.1.html"></iframe>
25
- <iframe src="15.0.html"></iframe>
26
- <iframe src="14.9.html"></iframe>
27
- </body>
28
-</html>
\ No newline at end of file
fixtures/devtools/regression/next.html
deleted
-41
@@ -1,41 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>React next</title>
6
- <link rel="stylesheet" href="styles.css" />
7
-
8
- <script type="text/javascript">
9
- // Enable DevTools to inspect React inside of an <iframe>
10
- // This must run before React is loaded
11
- __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
12
- </script>
13
-
14
- <script src="https://unpkg.com/scheduler@next/umd/scheduler.development.js"></script>
15
- <script src="https://unpkg.com/scheduler@next/umd/scheduler-tracing.development.js"></script>
16
- <script src="https://unpkg.com/react@next/umd/react.development.js"></script>
17
- <script src="https://unpkg.com/react-dom@next/umd/react-dom.development.js"></script>
18
- <script src="https://unpkg.com/react-cache@next/umd/react-cache.development.js"></script>
19
-
20
- <!-- Don't use this in production: -->
21
- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
22
- </head>
23
- <body>
24
- <div id="root">
25
- 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.
26
- <br/><br/>
27
- Use the <code>server</code> script instead:
28
- <br/><br/>
29
- <code>node ./fixtures/devtools/regression/server.js</code><br/>
30
- <code>open <a href="http://localhost:3000/next.html">http://localhost:3000/next.html</a></code>
31
- </div>
32
-
33
- <script src="shared.js" type="text/babel"></script>
34
-
35
- <!--
36
- This is a great way to try React but it's not suitable for production.
37
- It slowly compiles JSX with Babel in the browser and uses a large development build of React.
38
- Learn more at https://reactjs.org/docs/getting-started.html
39
- -->
40
- </body>
41
-</html>
\ No newline at end of file
fixtures/devtools/regression/server.js
deleted
-16
@@ -1,16 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-const finalhandler = require('finalhandler');
4
-const http = require('http');
5
-const serveStatic = require('serve-static');
6
-
7
-// Serve fixtures folder
8
-const serve = serveStatic(__dirname, {index: 'index.html'});
9
-
10
-// Create server
11
-const server = http.createServer(function onRequest(req, res) {
12
- serve(req, res, finalhandler(req, res));
13
-});
14
-
15
-// Listen
16
-server.listen(3000);
fixtures/devtools/regression/shared.js
deleted
-328
@@ -1,328 +0,0 @@
1
-/* eslint-disable no-fallthrough, react/react-in-jsx-scope, react/jsx-no-undef */
2
-/* global React ReactCache ReactDOM SchedulerTracing ScheduleTracing */
3
-
4
-const apps = [];
5
-
6
-const pieces = React.version.split('.');
7
-const major =
8
- pieces[0] === '0' ? parseInt(pieces[1], 10) : parseInt(pieces[0], 10);
9
-const minor =
10
- pieces[0] === '0' ? parseInt(pieces[2], 10) : parseInt(pieces[1], 10);
11
-
12
-// Convenience wrapper to organize API features in DevTools.
13
-function Feature({children, label, version}) {
14
- return (
15
- <div className="Feature">
16
- <div className="FeatureHeader">
17
- <code className="FeatureCode">{label}</code>
18
- <small>{version}</small>
19
- </div>
20
- {children}
21
- </div>
22
- );
23
-}
24
-
25
-// Simplify interaction tracing for tests below.
26
-let trace = null;
27
-if (typeof SchedulerTracing !== 'undefined') {
28
- trace = SchedulerTracing.unstable_trace;
29
-} else if (typeof ScheduleTracing !== 'undefined') {
30
- trace = ScheduleTracing.unstable_trace;
31
-} else {
32
- trace = (_, __, callback) => callback();
33
-}
34
-
35
-// https://github.com/facebook/react/blob/master/CHANGELOG.md
36
-switch (major) {
37
- case 16:
38
- switch (minor) {
39
- case 7:
40
- if (typeof React.useState === 'function') {
41
- // Hooks
42
- function Hooks() {
43
- const [count, setCount] = React.useState(0);
44
- const incrementCount = React.useCallback(
45
- () => setCount(count + 1),
46
- [count]
47
- );
48
- return (
49
- <div>
50
- count: {count}{' '}
51
- <button onClick={incrementCount}>increment</button>
52
- </div>
53
- );
54
- }
55
- apps.push(
56
- <Feature key="Hooks" label="Hooks" version="16.7+">
57
- <Hooks />
58
- </Feature>
59
- );
60
- }
61
- case 6:
62
- // memo
63
- function LabelComponent({label}) {
64
- return <label>{label}</label>;
65
- }
66
- const AnonymousMemoized = React.memo(({label}) => (
67
- <label>{label}</label>
68
- ));
69
- const Memoized = React.memo(LabelComponent);
70
- const CustomMemoized = React.memo(LabelComponent);
71
- CustomMemoized.displayName = 'MemoizedLabelFunction';
72
- apps.push(
73
- <Feature key="memo" label="memo" version="16.6+">
74
- <AnonymousMemoized label="AnonymousMemoized" />
75
- <Memoized label="Memoized" />
76
- <CustomMemoized label="CustomMemoized" />
77
- </Feature>
78
- );
79
-
80
- // Suspense
81
- const loadResource = ([text, ms]) => {
82
- return new Promise((resolve, reject) => {
83
- setTimeout(() => {
84
- resolve(text);
85
- }, ms);
86
- });
87
- };
88
- const getResourceKey = ([text, ms]) => text;
89
- const Resource = ReactCache.unstable_createResource(
90
- loadResource,
91
- getResourceKey
92
- );
93
- class Suspending extends React.Component {
94
- state = {useSuspense: false};
95
- useSuspense = () => this.setState({useSuspense: true});
96
- render() {
97
- if (this.state.useSuspense) {
98
- const text = Resource.read(['loaded', 2000]);
99
- return text;
100
- } else {
101
- return <button onClick={this.useSuspense}>load data</button>;
102
- }
103
- }
104
- }
105
- apps.push(
106
- <Feature key="Suspense" label="Suspense" version="16.6+">
107
- <React.Suspense fallback={<div>loading...</div>}>
108
- <Suspending />
109
- </React.Suspense>
110
- </Feature>
111
- );
112
-
113
- // lazy
114
- const LazyWithDefaultProps = React.lazy(
115
- () =>
116
- new Promise(resolve => {
117
- function FooWithDefaultProps(props) {
118
- return (
119
- <h1>
120
- {props.greeting}, {props.name}
121
- </h1>
122
- );
123
- }
124
- FooWithDefaultProps.defaultProps = {
125
- name: 'World',
126
- greeting: 'Bonjour',
127
- };
128
- resolve({
129
- default: FooWithDefaultProps,
130
- });
131
- })
132
- );
133
- apps.push(
134
- <Feature key="lazy" label="lazy" version="16.6+">
135
- <React.Suspense fallback={<div>loading...</div>}>
136
- <LazyWithDefaultProps greeting="Hello" />
137
- </React.Suspense>
138
- </Feature>
139
- );
140
- case 5:
141
- case 4:
142
- // unstable_Profiler
143
- class ProfilerChild extends React.Component {
144
- state = {count: 0};
145
- incrementCount = () =>
146
- this.setState(prevState => ({count: prevState.count + 1}));
147
- render() {
148
- return (
149
- <div>
150
- count: {this.state.count}{' '}
151
- <button onClick={this.incrementCount}>increment</button>
152
- </div>
153
- );
154
- }
155
- }
156
- const onRender = (...args) => {};
157
- const Profiler = React.unstable_Profiler || React.Profiler;
158
- apps.push(
159
- <Feature
160
- key="unstable_Profiler"
161
- label="unstable_Profiler"
162
- version="16.4+">
163
- <Profiler id="count" onRender={onRender}>
164
- <div>
165
- <ProfilerChild />
166
- </div>
167
- </Profiler>
168
- </Feature>
169
- );
170
- case 3:
171
- // createContext()
172
- const LocaleContext = React.createContext();
173
- LocaleContext.displayName = 'LocaleContext';
174
- const ThemeContext = React.createContext();
175
- apps.push(
176
- <Feature key="createContext" label="createContext" version="16.3+">
177
- <ThemeContext.Provider value="blue">
178
- <ThemeContext.Consumer>
179
- {theme => <div>theme: {theme}</div>}
180
- </ThemeContext.Consumer>
181
- </ThemeContext.Provider>
182
- <LocaleContext.Provider value="en-US">
183
- <LocaleContext.Consumer>
184
- {locale => <div>locale: {locale}</div>}
185
- </LocaleContext.Consumer>
186
- </LocaleContext.Provider>
187
- </Feature>
188
- );
189
-
190
- // forwardRef()
191
- const AnonymousFunction = React.forwardRef((props, ref) => (
192
- <div ref={ref}>{props.children}</div>
193
- ));
194
- const NamedFunction = React.forwardRef(function named(props, ref) {
195
- return <div ref={ref}>{props.children}</div>;
196
- });
197
- const CustomName = React.forwardRef((props, ref) => (
198
- <div ref={ref}>{props.children}</div>
199
- ));
200
- CustomName.displayName = 'CustomNameForwardRef';
201
- apps.push(
202
- <Feature key="forwardRef" label="forwardRef" version="16.3+">
203
- <AnonymousFunction>AnonymousFunction</AnonymousFunction>
204
- <NamedFunction>NamedFunction</NamedFunction>
205
- <CustomName>CustomName</CustomName>
206
- </Feature>
207
- );
208
-
209
- // StrictMode
210
- class StrictModeChild extends React.Component {
211
- render() {
212
- return 'StrictModeChild';
213
- }
214
- }
215
- apps.push(
216
- <Feature key="StrictMode" label="StrictMode" version="16.3+">
217
- <React.StrictMode>
218
- <StrictModeChild />
219
- </React.StrictMode>
220
- </Feature>
221
- );
222
-
223
- // unstable_AsyncMode (later renamed to unstable_ConcurrentMode, then ConcurrentMode)
224
- const ConcurrentMode =
225
- React.ConcurrentMode ||
226
- React.unstable_ConcurrentMode ||
227
- React.unstable_AsyncMode;
228
- apps.push(
229
- <Feature
230
- key="AsyncMode/ConcurrentMode"
231
- label="AsyncMode/ConcurrentMode"
232
- version="16.3+">
233
- <ConcurrentMode>
234
- <div>
235
- unstable_AsyncMode was added in 16.3, renamed to
236
- unstable_ConcurrentMode in 16.5, and then renamed to
237
- ConcurrentMode in 16.7
238
- </div>
239
- </ConcurrentMode>
240
- </Feature>
241
- );
242
- case 2:
243
- // Fragment
244
- apps.push(
245
- <Feature key="Fragment" label="Fragment" version="16.4+">
246
- <React.Fragment>
247
- <div>one</div>
248
- <div>two</div>
249
- </React.Fragment>
250
- </Feature>
251
- );
252
- case 1:
253
- case 0:
254
- default:
255
- break;
256
- }
257
- break;
258
- case 15:
259
- break;
260
- case 14:
261
- break;
262
- default:
263
- break;
264
-}
265
-
266
-function Even() {
267
- return <small>(even)</small>;
268
-}
269
-
270
-// Simple stateful app shared by all React versions
271
-class SimpleApp extends React.Component {
272
- state = {count: 0};
273
- incrementCount = () => {
274
- const updaterFn = prevState => ({count: prevState.count + 1});
275
- trace('Updating count', performance.now(), () => this.setState(updaterFn));
276
- };
277
- render() {
278
- const {count} = this.state;
279
- return (
280
- <div>
281
- {count % 2 === 0 ? (
282
- <span>
283
- count: {count} <Even />
284
- </span>
285
- ) : (
286
- <span>count: {count}</span>
287
- )}{' '}
288
- <button onClick={this.incrementCount}>increment</button>
289
- </div>
290
- );
291
- }
292
-}
293
-apps.push(
294
- <Feature key="Simple stateful app" label="Simple stateful app" version="any">
295
- <SimpleApp />
296
- </Feature>
297
-);
298
-
299
-// This component, with the version prop, helps organize DevTools at a glance.
300
-function TopLevelWrapperForDevTools({version}) {
301
- let header = <h1>React {version}</h1>;
302
- if (version.includes('canary')) {
303
- const commitSha = version.match(/.+canary-(.+)/)[1];
304
- header = (
305
- <h1>
306
- React canary{' '}
307
- <a href={`https://github.com/facebook/react/commit/${commitSha}`}>
308
- {commitSha}
309
- </a>
310
- </h1>
311
- );
312
- } else if (version.includes('alpha')) {
313
- header = <h1>React next</h1>;
314
- }
315
-
316
- return (
317
- <div>
318
- {header}
319
- {apps}
320
- </div>
321
- );
322
-}
323
-TopLevelWrapperForDevTools.displayName = 'React';
324
-
325
-ReactDOM.render(
326
- <TopLevelWrapperForDevTools version={React.version} />,
327
- document.getElementById('root')
328
-);
fixtures/devtools/regression/styles.css
deleted
-37
@@ -1,37 +0,0 @@
1
-body {
2
- font-family: sans-serif;
3
- font-size: 12px;
4
-}
5
-
6
-h1 {
7
- margin: 0;
8
- font-size: 20px;
9
-}
10
-
11
-h2 {
12
- margin: 1rem 0 0;
13
-}
14
-
15
-iframe {
16
- border: 1px solid #ddd;
17
- border-radius: 0.5rem;
18
-}
19
-
20
-code {
21
- white-space: nowrap;
22
-}
23
-
24
-.Feature {
25
- margin: 1rem 0;
26
- border-bottom: 1px solid #eee;
27
- padding-bottom: 1rem;
28
-}
29
-.FeatureHeader {
30
- font-size: 16px;
31
- margin-bottom: 0.5rem;
32
-}
33
-.FeatureCode {
34
- background-color: #eee;
35
- padding: 0.25rem;
36
- border-radius: 0.25rem;
37
-}
fixtures/devtools/standalone/index.html
deleted
-313
@@ -1,313 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>TODO List</title>
6
-
7
- <!-- DevTools -->
8
- <script src="http://localhost:8097"></script>
9
-
10
- <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
11
- <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
12
- <script src="https://unpkg.com/immutable@4.0.0-rc.12/dist/immutable.js"></script>
13
-
14
- <!-- Don't use this in production: -->
15
- <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
16
-
17
- <style type="text/css">
18
- .Input {
19
- font-size: 1rem;
20
- padding: 0.25rem;
21
- }
22
-
23
- .IconButton {
24
- padding: 0.25rem;
25
- border: none;
26
- background: none;
27
- cursor: pointer;
28
- }
29
-
30
- .List {
31
- margin: 0.5rem 0 0;
32
- padding: 0;
33
- }
34
-
35
- .ListItem {
36
- list-style-type: none;
37
- }
38
-
39
- .Label {
40
- cursor: pointer;
41
- padding: 0.25rem;
42
- color: #555;
43
- }
44
- .Label:hover {
45
- color: #000;
46
- }
47
-
48
- .IconButton {
49
- padding: 0.25rem;
50
- border: none;
51
- background: none;
52
- cursor: pointer;
53
- }
54
- </style>
55
- </head>
56
- <body>
57
- <div id="root"></div>
58
- <script type="text/babel">
59
- const { Fragment, useCallback, useState } = React;
60
-
61
- function List(props) {
62
- const [newItemText, setNewItemText] = useState("");
63
- const [items, setItems] = useState([
64
- { id: 1, isComplete: true, text: "First" },
65
- { id: 2, isComplete: true, text: "Second" },
66
- { id: 3, isComplete: false, text: "Third" }
67
- ]);
68
- const [uid, setUID] = useState(4);
69
-
70
- const handleClick = useCallback(() => {
71
- if (newItemText !== "") {
72
- setItems([
73
- ...items,
74
- {
75
- id: uid,
76
- isComplete: false,
77
- text: newItemText
78
- }
79
- ]);
80
- setUID(uid + 1);
81
- setNewItemText("");
82
- }
83
- }, [newItemText, items, uid]);
84
-
85
- const handleKeyPress = useCallback(
86
- event => {
87
- if (event.key === "Enter") {
88
- handleClick();
89
- }
90
- },
91
- [handleClick]
92
- );
93
-
94
- const handleChange = useCallback(
95
- event => {
96
- setNewItemText(event.currentTarget.value);
97
- },
98
- [setNewItemText]
99
- );
100
-
101
- const removeItem = useCallback(
102
- itemToRemove => setItems(items.filter(item => item !== itemToRemove)),
103
- [items]
104
- );
105
-
106
- const toggleItem = useCallback(
107
- itemToToggle => {
108
- const index = items.indexOf(itemToToggle);
109
-
110
- setItems(
111
- items
112
- .slice(0, index)
113
- .concat({
114
- ...itemToToggle,
115
- isComplete: !itemToToggle.isComplete
116
- })
117
- .concat(items.slice(index + 1))
118
- );
119
- },
120
- [items]
121
- );
122
-
123
- return (
124
- <Fragment>
125
- <h1>List</h1>
126
- <input
127
- type="text"
128
- placeholder="New list item..."
129
- className="Input"
130
- value={newItemText}
131
- onChange={handleChange}
132
- onKeyPress={handleKeyPress}
133
- />
134
- <button
135
- className="IconButton"
136
- disabled={newItemText === ""}
137
- onClick={handleClick}
138
- >
139
- <span role="img" aria-label="Add item">
140
- ➕
141
- </span>
142
- </button>
143
- <ul className="List">
144
- {items.map(item => (
145
- <ListItem
146
- key={item.id}
147
- item={item}
148
- removeItem={removeItem}
149
- toggleItem={toggleItem}
150
- />
151
- ))}
152
- </ul>
153
- </Fragment>
154
- );
155
- }
156
-
157
- function ListItem({ item, removeItem, toggleItem }) {
158
- const handleDelete = useCallback(() => {
159
- removeItem(item);
160
- }, [item, removeItem]);
161
-
162
- const handleToggle = useCallback(() => {
163
- toggleItem(item);
164
- }, [item, toggleItem]);
165
-
166
- return (
167
- <li className="ListItem">
168
- <button className="IconButton" onClick={handleDelete}>
169
- 🗑
170
- </button>
171
- <label className="Label">
172
- <input
173
- className="Input"
174
- checked={item.isComplete}
175
- onChange={handleToggle}
176
- type="checkbox"
177
- />{" "}
178
- {item.text}
179
- </label>
180
- </li>
181
- );
182
- }
183
-
184
- function SimpleValues() {
185
- return (
186
- <ChildComponent
187
- string="abc"
188
- emptyString=""
189
- number={123}
190
- undefined={undefined}
191
- null={null}
192
- nan={NaN}
193
- infinity={Infinity}
194
- true={true}
195
- false={false}
196
- />
197
- );
198
- }
199
-
200
- class Custom {
201
- _number = 42;
202
- get number() {
203
- return this._number;
204
- }
205
- }
206
-
207
- function CustomObject() {
208
- return <ChildComponent customObject={new Custom()} />;
209
- }
210
-
211
- const object = {
212
- string: "abc",
213
- longString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKJLMNOPQRSTUVWXYZ1234567890",
214
- emptyString: "",
215
- number: 123,
216
- boolean: true,
217
- undefined: undefined,
218
- null: null
219
- };
220
-
221
- function ObjectProps() {
222
- return (
223
- <ChildComponent
224
- object={{
225
- outer: {
226
- inner: object
227
- }
228
- }}
229
- array={["first", "second", "third"]}
230
- objectInArray={[object]}
231
- arrayInObject={{ array: ["first", "second", "third"] }}
232
- deepObject={{
233
- // Known limitation: we won't go deeper than several levels.
234
- // In the future, we might offer a way to request deeper access on demand.
235
- a: {
236
- b: {
237
- c: {
238
- d: {
239
- e: {
240
- f: {
241
- g: {
242
- h: {
243
- i: {
244
- j: 10
245
- }
246
- }
247
- }
248
- }
249
- }
250
- }
251
- }
252
- }
253
- }
254
- }}
255
- />
256
- );
257
- }
258
-
259
- const set = new Set(['abc', 123]);
260
- const map = new Map([['name', 'Brian'], ['food', 'sushi']]);
261
- const setOfSets = new Set([new Set(['a', 'b', 'c']), new Set([1, 2, 3])]);
262
- const mapOfMaps = new Map([['first', map], ['second', map]]);
263
- const typedArray = Int8Array.from([100, -100, 0]);
264
- const immutable = Immutable.fromJS({
265
- a: [{ hello: 'there' }, 'fixed', true],
266
- b: 123,
267
- c: {
268
- '1': 'xyz',
269
- xyz: 1,
270
- },
271
- });
272
-
273
- function UnserializableProps() {
274
- return (
275
- <ChildComponent
276
- map={map}
277
- set={set}
278
- mapOfMaps={mapOfMaps}
279
- setOfSets={setOfSets}
280
- typedArray={typedArray}
281
- immutable={immutable}
282
- />
283
- );
284
- }
285
-
286
- function ChildComponent(props: any) {
287
- return null;
288
- }
289
-
290
- function InspectableElements() {
291
- return (
292
- <Fragment>
293
- <SimpleValues />
294
- <ObjectProps />
295
- <UnserializableProps />
296
- <CustomObject />
297
- </Fragment>
298
- );
299
- }
300
-
301
- function App() {
302
- return (
303
- <Fragment>
304
- <List />
305
- <InspectableElements />
306
- </Fragment>
307
- );
308
- }
309
-
310
- ReactDOM.render(<App />, document.getElementById("root"));
311
- </script>
312
- </body>
313
-</html>
package.json
+3
-5
@@ -48,10 +48,10 @@
48
"error-stack-parser": "^2.0.2",
49
"eslint": "^6.1.0",
50
"eslint-config-fbjs": "^1.1.1",
51
- "eslint-plugin-babel": "^5.3.0",
51
"eslint-plugin-flowtype": "^2.25.0",
52
"eslint-plugin-jest": "^22.15.0",
53
"eslint-plugin-no-for-of-loops": "^1.0.0",
54
+ "eslint-plugin-babel": "^5.3.0",
55
"eslint-plugin-react": "^6.7.1",
56
"eslint-plugin-react-internal": "link:./scripts/eslint-rules",
57
"fbjs-scripts": "^0.8.3",
@@ -62,8 +62,8 @@
62
"google-closure-compiler": "20190301.0.0",
63
"gzip-size": "^3.0.0",
64
"jasmine-check": "^1.0.0-rc.0",
65
- "jest": "^23",
66
- "jest-diff": "^23",
65
+ "jest": "^23.1.0",
66
+ "jest-diff": "^23.0.1",
67
"jest-snapshot-serializer-raw": "^1.1.0",
68
"minimatch": "^3.0.4",
69
"minimist": "^1.2.0",
@@ -109,8 +109,6 @@
109
"test-prod-build": "yarn test-build-prod",
110
"test-build": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.build.js",
111
"test-build-prod": "cross-env NODE_ENV=production jest --config ./scripts/jest/config.build.js",
112
- "test-build-devtools": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.build-devtools.js",
113
- "debug-test-build-devtools": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.build-devtools.js",
112
"test-dom-fixture": "cd fixtures/dom && yarn && yarn prestart && yarn test",
113
"flow": "node ./scripts/tasks/flow.js",
114
"flow-ci": "node ./scripts/tasks/flow-ci.js",
packages/react-debug-tools/src/ReactDebugHooks.js
+2
-2
@@ -253,14 +253,14 @@ const Dispatcher: DispatcherType = {
253
254
// Inspect
255
256
-export type HooksNode = {
256
+type HooksNode = {
257
id: number | null,
258
isStateEditable: boolean,
259
name: string,
260
value: mixed,
261
subHooks: Array<HooksNode>,
262
};
263
-export type HooksTree = Array<HooksNode>;
263
+type HooksTree = Array<HooksNode>;
264
265
// Don't assume
266
//
packages/react-devtools-core/README.md
+7
-16
@@ -12,17 +12,20 @@ This is similar requiring the `react-devtools` package, but provides several con
12
13
```js
14
const { connectToDevTools } = require("react-devtools-core");
15
-connectToDevTools(config);
15
+connectToDevTools({
16
+ // Config options
17
+});
18
+
19
```
20
21
Run `connectToDevTools()` in the same context as React to set up a connection to DevTools.
22
Be sure to run this function *before* importing e.g. `react`, `react-dom`, `react-native`.
23
21
-The `config` object may contain:
24
+The `options` object may contain:
25
* `host: string` (defaults to "localhost") - Websocket will connect to this host.
26
* `port: number` (defaults to `8097`) - Websocket will connect to this port.
27
* `websocket: Websocket` - Custom websocked to use. Overrides `host` and `port` settings if provided.
25
-* `resolveRNStyle: (style: number) => ?Object` - Used by the React Native style plug-in.
28
+* `resolveNativeStyle: (style: number) => ?Object` - Used by the React Native style plug-in.
29
* `isAppActive: () => boolean` - If provided, DevTools will poll this method and wait until it returns true before connecting to React.
30
31
## `react-devtools-core/standalone`
@@ -38,16 +41,4 @@ require("react-devtools-core/standalone")
41
.startServer(port);
42
```
43
41
-Reference the `react-devtools` package for a complete integration example.
42
-
43
-## Development
44
-
45
-Watch for changes made to the backend entry point and rebuild:
46
-```sh
47
-yarn start:backend
48
-```
49
-
50
-Watch for changes made to the standalone UI entry point and rebuild:
51
-```sh
52
-yarn start:standalone
53
-```
\ No newline at end of file
44
+Reference the `react-devtools` package for a complete integration example.
\ No newline at end of file
packages/react-devtools-core/backend.js
deleted
-1
@@ -1 +0,0 @@
1
-module.exports = require('./dist/backend');
packages/react-devtools-core/package.json
+2
-31
@@ -1,34 +1,5 @@
1
{
2
+ "private": true,
3
"name": "react-devtools-core",
3
- "version": "4.0.6",
4
- "description": "Use react-devtools outside of the browser",
5
- "license": "MIT",
6
- "main": "./dist/backend.js",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/facebook/react.git",
10
- "directory": "packages/react-devtools-core"
11
- },
12
- "files": [
13
- "dist",
14
- "backend.js",
15
- "build-info.json",
16
- "standalone.js"
17
- ],
18
- "scripts": {
19
- "build": "yarn build:backend && yarn build:standalone",
20
- "build:backend": "cross-env NODE_ENV=production webpack --config webpack.backend.js",
21
- "build:standalone": "cross-env NODE_ENV=production webpack --config webpack.standalone.js",
22
- "prepublish": "yarn run build",
23
- "start:backend": "cross-env NODE_ENV=development webpack --config webpack.backend.js --watch",
24
- "start:standalone": "cross-env NODE_ENV=development webpack --config webpack.standalone.js --watch"
25
- },
26
- "dependencies": {
27
- "es6-symbol": "^3",
28
- "shell-quote": "^1.6.1",
29
- "ws": "^7"
30
- },
31
- "devDependencies": {
32
- "cross-env": "^3.1.4"
33
- }
4
+ "version": "0.0.0"
5
}
packages/react-devtools-core/src/backend.js
deleted
-284
@@ -1,284 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import Agent from 'react-devtools-shared/src/backend/agent';
11
-import Bridge from 'react-devtools-shared/src/bridge';
12
-import {installHook} from 'react-devtools-shared/src/hook';
13
-import {initBackend} from 'react-devtools-shared/src/backend';
14
-import {__DEBUG__} from 'react-devtools-shared/src/constants';
15
-import setupNativeStyleEditor from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
16
-import {getDefaultComponentFilters} from 'react-devtools-shared/src/utils';
17
-
18
-import type {BackendBridge} from 'react-devtools-shared/src/bridge';
19
-import type {ComponentFilter} from 'react-devtools-shared/src/types';
20
-import type {DevToolsHook} from 'react-devtools-shared/src/backend/types';
21
-import type {ResolveNativeStyle} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
22
-
23
-type ConnectOptions = {
24
- host?: string,
25
- nativeStyleEditorValidAttributes?: $ReadOnlyArray<string>,
26
- port?: number,
27
- resolveRNStyle?: ResolveNativeStyle,
28
- isAppActive?: () => boolean,
29
- websocket?: ?WebSocket,
30
-};
31
-
32
-installHook(window);
33
-
34
-const hook: DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
35
-
36
-let savedComponentFilters: Array<
37
- ComponentFilter,
38
-> = getDefaultComponentFilters();
39
-
40
-function debug(methodName: string, ...args) {
41
- if (__DEBUG__) {
42
- console.log(
43
- `%c[core/backend] %c${methodName}`,
44
- 'color: teal; font-weight: bold;',
45
- 'font-weight: bold;',
46
- ...args,
47
- );
48
- }
49
-}
50
-
51
-export function connectToDevTools(options: ?ConnectOptions) {
52
- const {
53
- host = 'localhost',
54
- nativeStyleEditorValidAttributes,
55
- port = 8097,
56
- websocket,
57
- resolveRNStyle = null,
58
- isAppActive = () => true,
59
- } =
60
- options || {};
61
-
62
- let retryTimeoutID: TimeoutID | null = null;
63
-
64
- function scheduleRetry() {
65
- if (retryTimeoutID === null) {
66
- // Two seconds because RN had issues with quick retries.
67
- retryTimeoutID = setTimeout(() => connectToDevTools(options), 2000);
68
- }
69
- }
70
-
71
- if (!isAppActive()) {
72
- // If the app is in background, maybe retry later.
73
- // Don't actually attempt to connect until we're in foreground.
74
- scheduleRetry();
75
- return;
76
- }
77
-
78
- let bridge: BackendBridge | null = null;
79
-
80
- const messageListeners = [];
81
- const uri = 'ws://' + host + ':' + port;
82
-
83
- // If existing websocket is passed, use it.
84
- // This is necessary to support our custom integrations.
85
- // See D6251744.
86
- const ws = websocket ? websocket : new window.WebSocket(uri);
87
- ws.onclose = handleClose;
88
- ws.onerror = handleFailed;
89
- ws.onmessage = handleMessage;
90
- ws.onopen = function() {
91
- bridge = new Bridge({
92
- listen(fn) {
93
- messageListeners.push(fn);
94
- return () => {
95
- const index = messageListeners.indexOf(fn);
96
- if (index >= 0) {
97
- messageListeners.splice(index, 1);
98
- }
99
- };
100
- },
101
- send(event: string, payload: any, transferable?: Array<any>) {
102
- if (ws.readyState === ws.OPEN) {
103
- if (__DEBUG__) {
104
- debug('wall.send()', event, payload);
105
- }
106
-
107
- ws.send(JSON.stringify({event, payload}));
108
- } else {
109
- if (__DEBUG__) {
110
- debug(
111
- 'wall.send()',
112
- 'Shutting down bridge because of closed WebSocket connection',
113
- );
114
- }
115
-
116
- if (bridge !== null) {
117
- bridge.emit('shutdown');
118
- }
119
-
120
- scheduleRetry();
121
- }
122
- },
123
- });
124
- bridge.addListener(
125
- 'inspectElement',
126
- ({id, rendererID}: {id: number, rendererID: number}) => {
127
- const renderer = agent.rendererInterfaces[rendererID];
128
- if (renderer != null) {
129
- // Send event for RN to highlight.
130
- const nodes: ?Array<HTMLElement> = renderer.findNativeNodesForFiberID(
131
- id,
132
- );
133
- if (nodes != null && nodes[0] != null) {
134
- agent.emit('showNativeHighlight', nodes[0]);
135
- }
136
- }
137
- },
138
- );
139
- bridge.addListener(
140
- 'updateComponentFilters',
141
- (componentFilters: Array<ComponentFilter>) => {
142
- // Save filter changes in memory, in case DevTools is reloaded.
143
- // In that case, the renderer will already be using the updated values.
144
- // We'll lose these in between backend reloads but that can't be helped.
145
- savedComponentFilters = componentFilters;
146
- },
147
- );
148
-
149
- // The renderer interface doesn't read saved component filters directly,
150
- // because they are generally stored in localStorage within the context of the extension.
151
- // Because of this it relies on the extension to pass filters.
152
- // In the case of the standalone DevTools being used with a website,
153
- // saved filters are injected along with the backend script tag so we shouldn't override them here.
154
- // This injection strategy doesn't work for React Native though.
155
- // Ideally the backend would save the filters itself, but RN doesn't provide a sync storage solution.
156
- // So for now we just fall back to using the default filters...
157
- if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ == null) {
158
- bridge.send('overrideComponentFilters', savedComponentFilters);
159
- }
160
-
161
- // TODO (npm-packages) Warn if "isBackendStorageAPISupported"
162
- const agent = new Agent(bridge);
163
- agent.addListener('shutdown', () => {
164
- // If we received 'shutdown' from `agent`, we assume the `bridge` is already shutting down,
165
- // and that caused the 'shutdown' event on the `agent`, so we don't need to call `bridge.shutdown()` here.
166
- hook.emit('shutdown');
167
- });
168
-
169
- initBackend(hook, agent, window);
170
-
171
- // Setup React Native style editor if the environment supports it.
172
- if (resolveRNStyle != null || hook.resolveRNStyle != null) {
173
- setupNativeStyleEditor(
174
- bridge,
175
- agent,
176
- ((resolveRNStyle || hook.resolveRNStyle: any): ResolveNativeStyle),
177
- nativeStyleEditorValidAttributes ||
178
- hook.nativeStyleEditorValidAttributes ||
179
- null,
180
- );
181
- } else {
182
- // Otherwise listen to detect if the environment later supports it.
183
- // For example, Flipper does not eagerly inject these values.
184
- // Instead it relies on the React Native Inspector to lazily inject them.
185
- let lazyResolveRNStyle;
186
- let lazyNativeStyleEditorValidAttributes;
187
-
188
- const initAfterTick = () => {
189
- if (bridge !== null) {
190
- setupNativeStyleEditor(
191
- bridge,
192
- agent,
193
- lazyResolveRNStyle,
194
- lazyNativeStyleEditorValidAttributes,
195
- );
196
- }
197
- };
198
-
199
- if (!hook.hasOwnProperty('resolveRNStyle')) {
200
- Object.defineProperty(
201
- hook,
202
- 'resolveRNStyle',
203
- ({
204
- enumerable: false,
205
- get() {
206
- return lazyResolveRNStyle;
207
- },
208
- set(value) {
209
- lazyResolveRNStyle = value;
210
- initAfterTick();
211
- },
212
- }: Object),
213
- );
214
- }
215
- if (!hook.hasOwnProperty('nativeStyleEditorValidAttributes')) {
216
- Object.defineProperty(
217
- hook,
218
- 'nativeStyleEditorValidAttributes',
219
- ({
220
- enumerable: false,
221
- get() {
222
- return lazyNativeStyleEditorValidAttributes;
223
- },
224
- set(value) {
225
- lazyNativeStyleEditorValidAttributes = value;
226
- initAfterTick();
227
- },
228
- }: Object),
229
- );
230
- }
231
- }
232
- };
233
-
234
- function handleClose() {
235
- if (__DEBUG__) {
236
- debug('WebSocket.onclose');
237
- }
238
-
239
- if (bridge !== null) {
240
- bridge.emit('shutdown');
241
- }
242
-
243
- scheduleRetry();
244
- }
245
-
246
- function handleFailed() {
247
- if (__DEBUG__) {
248
- debug('WebSocket.onerror');
249
- }
250
-
251
- scheduleRetry();
252
- }
253
-
254
- function handleMessage(event) {
255
- let data;
256
- try {
257
- if (typeof event.data === 'string') {
258
- data = JSON.parse(event.data);
259
- if (__DEBUG__) {
260
- debug('WebSocket.onmessage', data);
261
- }
262
- } else {
263
- throw Error();
264
- }
265
- } catch (e) {
266
- console.error(
267
- '[React DevTools] Failed to parse JSON: ' + (event.data: any),
268
- );
269
- return;
270
- }
271
- messageListeners.forEach(fn => {
272
- try {
273
- fn(data);
274
- } catch (error) {
275
- // jsc doesn't play so well with tracebacks that go into eval'd code,
276
- // so the stack trace here will stop at the `eval()` call. Getting the
277
- // message that caused the error is the best we can do for now.
278
- console.log('[React DevTools] Error calling listener', data);
279
- console.log('error:', error);
280
- throw error;
281
- }
282
- });
283
- }
284
-}
packages/react-devtools-core/src/editor.js
deleted
-190
@@ -1,190 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {existsSync} from 'fs';
11
-import {basename, join, isAbsolute} from 'path';
12
-import {execSync, spawn} from 'child_process';
13
-import {parse} from 'shell-quote';
14
-
15
-function isTerminalEditor(editor: string): boolean {
16
- switch (editor) {
17
- case 'vim':
18
- case 'emacs':
19
- case 'nano':
20
- return true;
21
- default:
22
- return false;
23
- }
24
-}
25
-
26
-// Map from full process name to binary that starts the process
27
-// We can't just re-use full process name, because it will spawn a new instance
28
-// of the app every time
29
-const COMMON_EDITORS = {
30
- '/Applications/Atom.app/Contents/MacOS/Atom': 'atom',
31
- '/Applications/Atom Beta.app/Contents/MacOS/Atom Beta':
32
- '/Applications/Atom Beta.app/Contents/MacOS/Atom Beta',
33
- '/Applications/Sublime Text.app/Contents/MacOS/Sublime Text':
34
- '/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl',
35
- '/Applications/Sublime Text 2.app/Contents/MacOS/Sublime Text 2':
36
- '/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl',
37
- '/Applications/Visual Studio Code.app/Contents/MacOS/Electron': 'code',
38
-};
39
-
40
-function getArgumentsForLineNumber(
41
- editor: string,
42
- filePath: string,
43
- lineNumber: number,
44
-): Array<string> {
45
- switch (basename(editor)) {
46
- case 'vim':
47
- case 'mvim':
48
- return [filePath, '+' + lineNumber];
49
- case 'atom':
50
- case 'Atom':
51
- case 'Atom Beta':
52
- case 'subl':
53
- case 'sublime':
54
- case 'wstorm':
55
- case 'appcode':
56
- case 'charm':
57
- case 'idea':
58
- return [filePath + ':' + lineNumber];
59
- case 'joe':
60
- case 'emacs':
61
- case 'emacsclient':
62
- return ['+' + lineNumber, filePath];
63
- case 'rmate':
64
- case 'mate':
65
- case 'mine':
66
- return ['--line', lineNumber + '', filePath];
67
- case 'code':
68
- return ['-g', filePath + ':' + lineNumber];
69
- default:
70
- // For all others, drop the lineNumber until we have
71
- // a mapping above, since providing the lineNumber incorrectly
72
- // can result in errors or confusing behavior.
73
- return [filePath];
74
- }
75
-}
76
-
77
-function guessEditor(): Array<string> {
78
- // Explicit config always wins
79
- if (process.env.REACT_EDITOR) {
80
- return parse(process.env.REACT_EDITOR);
81
- }
82
-
83
- // Using `ps x` on OSX we can find out which editor is currently running.
84
- // Potentially we could use similar technique for Windows and Linux
85
- if (process.platform === 'darwin') {
86
- try {
87
- const output = execSync('ps x').toString();
88
- const processNames = Object.keys(COMMON_EDITORS);
89
- for (let i = 0; i < processNames.length; i++) {
90
- const processName = processNames[i];
91
- if (output.indexOf(processName) !== -1) {
92
- return [COMMON_EDITORS[processName]];
93
- }
94
- }
95
- } catch (error) {
96
- // Ignore...
97
- }
98
- }
99
-
100
- // Last resort, use old skool env vars
101
- if (process.env.VISUAL) {
102
- return [process.env.VISUAL];
103
- } else if (process.env.EDITOR) {
104
- return [process.env.EDITOR];
105
- }
106
-
107
- return [];
108
-}
109
-
110
-let childProcess = null;
111
-
112
-export function getValidFilePath(
113
- maybeRelativePath: string,
114
- absoluteProjectRoots: Array<string>,
115
-): string | null {
116
- // We use relative paths at Facebook with deterministic builds.
117
- // This is why our internal tooling calls React DevTools with absoluteProjectRoots.
118
- // If the filename is absolute then we don't need to care about this.
119
- if (isAbsolute(maybeRelativePath)) {
120
- if (existsSync(maybeRelativePath)) {
121
- return maybeRelativePath;
122
- }
123
- } else {
124
- for (let i = 0; i < absoluteProjectRoots.length; i++) {
125
- const projectRoot = absoluteProjectRoots[i];
126
- const joinedPath = join(projectRoot, maybeRelativePath);
127
- if (existsSync(joinedPath)) {
128
- return joinedPath;
129
- }
130
- }
131
- }
132
-
133
- return null;
134
-}
135
-
136
-export function doesFilePathExist(
137
- maybeRelativePath: string,
138
- absoluteProjectRoots: Array<string>,
139
-): boolean {
140
- return getValidFilePath(maybeRelativePath, absoluteProjectRoots) !== null;
141
-}
142
-
143
-export function launchEditor(
144
- maybeRelativePath: string,
145
- lineNumber: number,
146
- absoluteProjectRoots: Array<string>,
147
-) {
148
- const filePath = getValidFilePath(maybeRelativePath, absoluteProjectRoots);
149
- if (filePath === null) {
150
- return;
151
- }
152
-
153
- // Sanitize lineNumber to prevent malicious use on win32
154
- // via: https://github.com/nodejs/node/blob/c3bb4b1aa5e907d489619fb43d233c3336bfc03d/lib/child_process.js#L333
155
- if (lineNumber && isNaN(lineNumber)) {
156
- return;
157
- }
158
-
159
- let [editor, ...args] = guessEditor();
160
- if (!editor) {
161
- return;
162
- }
163
-
164
- if (lineNumber) {
165
- args = args.concat(getArgumentsForLineNumber(editor, filePath, lineNumber));
166
- } else {
167
- args.push(filePath);
168
- }
169
-
170
- if (childProcess && isTerminalEditor(editor)) {
171
- // There's an existing editor process already and it's attached
172
- // to the terminal, so go kill it. Otherwise two separate editor
173
- // instances attach to the stdin/stdout which gets confusing.
174
- childProcess.kill('SIGKILL');
175
- }
176
-
177
- if (process.platform === 'win32') {
178
- // On Windows, launch the editor in a shell because spawn can only
179
- // launch .exe files.
180
- childProcess = spawn('cmd.exe', ['/C', editor].concat(args), {
181
- stdio: 'inherit',
182
- });
183
- } else {
184
- childProcess = spawn(editor, args, {stdio: 'inherit'});
185
- }
186
- childProcess.on('error', function() {});
187
- childProcess.on('exit', function(errorCode) {
188
- childProcess = null;
189
- });
190
-}
packages/react-devtools-core/src/standalone.js
deleted
-326
@@ -1,326 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {createElement} from 'react';
11
-import {
12
- // $FlowFixMe Flow does not yet know about flushSync()
13
- flushSync,
14
- // $FlowFixMe Flow does not yet know about createRoot()
15
- unstable_createRoot as createRoot,
16
-} from 'react-dom';
17
-import Bridge from 'react-devtools-shared/src/bridge';
18
-import Store from 'react-devtools-shared/src/devtools/store';
19
-import {
20
- getSavedComponentFilters,
21
- getAppendComponentStack,
22
-} from 'react-devtools-shared/src/utils';
23
-import {Server} from 'ws';
24
-import {join} from 'path';
25
-import {readFileSync} from 'fs';
26
-import {installHook} from 'react-devtools-shared/src/hook';
27
-import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
28
-import {doesFilePathExist, launchEditor} from './editor';
29
-import {__DEBUG__} from 'react-devtools-shared/src/constants';
30
-
31
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
32
-import type {InspectedElement} from 'react-devtools-shared/src/devtools/views/Components/types';
33
-
34
-installHook(window);
35
-
36
-export type StatusListener = (message: string) => void;
37
-
38
-let node: HTMLElement = ((null: any): HTMLElement);
39
-let nodeWaitingToConnectHTML: string = '';
40
-let projectRoots: Array<string> = [];
41
-let statusListener: StatusListener = (message: string) => {};
42
-
43
-// Unlike browser extension users, people using the standalone have actively installed version 4,
44
-// So we probably don't need to show them a changelog notice.
45
-// We should give embedded users (e.g. Nuclide, Sonar) a way of showing this dialog though.
46
-let showWelcomeToTheNewDevToolsDialog: boolean = false;
47
-
48
-function setContentDOMNode(value: HTMLElement) {
49
- node = value;
50
-
51
- // Save so we can restore the exact waiting message between sessions.
52
- nodeWaitingToConnectHTML = node.innerHTML;
53
-
54
- return DevtoolsUI;
55
-}
56
-
57
-function setProjectRoots(value: Array<string>) {
58
- projectRoots = value;
59
-}
60
-
61
-function setStatusListener(value: StatusListener) {
62
- statusListener = value;
63
- return DevtoolsUI;
64
-}
65
-
66
-function setShowWelcomeToTheNewDevToolsDialog(value: boolean) {
67
- showWelcomeToTheNewDevToolsDialog = value;
68
- return DevtoolsUI;
69
-}
70
-
71
-let bridge: FrontendBridge | null = null;
72
-let store: Store | null = null;
73
-let root = null;
74
-
75
-const log = (...args) => console.log('[React DevTools]', ...args);
76
-log.warn = (...args) => console.warn('[React DevTools]', ...args);
77
-log.error = (...args) => console.error('[React DevTools]', ...args);
78
-
79
-function debug(methodName: string, ...args) {
80
- if (__DEBUG__) {
81
- console.log(
82
- `%c[core/standalone] %c${methodName}`,
83
- 'color: teal; font-weight: bold;',
84
- 'font-weight: bold;',
85
- ...args,
86
- );
87
- }
88
-}
89
-
90
-function safeUnmount() {
91
- flushSync(() => {
92
- if (root !== null) {
93
- root.unmount();
94
- }
95
- });
96
- root = null;
97
-}
98
-
99
-function reload() {
100
- safeUnmount();
101
-
102
- node.innerHTML = '';
103
-
104
- setTimeout(() => {
105
- root = createRoot(node);
106
- root.render(
107
- createElement(DevTools, {
108
- bridge: ((bridge: any): FrontendBridge),
109
- canViewElementSourceFunction,
110
- showTabBar: true,
111
- showWelcomeToTheNewDevToolsDialog,
112
- store: ((store: any): Store),
113
- warnIfLegacyBackendDetected: true,
114
- viewElementSourceFunction,
115
- }),
116
- );
117
- }, 100);
118
-}
119
-
120
-function canViewElementSourceFunction(
121
- inspectedElement: InspectedElement,
122
-): boolean {
123
- if (
124
- inspectedElement.canViewSource === false ||
125
- inspectedElement.source === null
126
- ) {
127
- return false;
128
- }
129
-
130
- const {source} = inspectedElement;
131
-
132
- return doesFilePathExist(source.fileName, projectRoots);
133
-}
134
-
135
-function viewElementSourceFunction(
136
- id: number,
137
- inspectedElement: InspectedElement,
138
-): void {
139
- const {source} = inspectedElement;
140
- if (source !== null) {
141
- launchEditor(source.fileName, source.lineNumber, projectRoots);
142
- } else {
143
- log.error('Cannot inspect element', id);
144
- }
145
-}
146
-
147
-function onDisconnected() {
148
- safeUnmount();
149
-
150
- node.innerHTML = nodeWaitingToConnectHTML;
151
-}
152
-
153
-function onError({code, message}) {
154
- safeUnmount();
155
-
156
- if (code === 'EADDRINUSE') {
157
- node.innerHTML = `<div id="waiting"><h2>Another instance of DevTools is running</h2></div>`;
158
- } else {
159
- node.innerHTML = `<div id="waiting"><h2>Unknown error (${message})</h2></div>`;
160
- }
161
-}
162
-
163
-function initialize(socket: WebSocket) {
164
- const listeners = [];
165
- socket.onmessage = event => {
166
- let data;
167
- try {
168
- if (typeof event.data === 'string') {
169
- data = JSON.parse(event.data);
170
-
171
- if (__DEBUG__) {
172
- debug('WebSocket.onmessage', data);
173
- }
174
- } else {
175
- throw Error();
176
- }
177
- } catch (e) {
178
- log.error('Failed to parse JSON', event.data);
179
- return;
180
- }
181
- listeners.forEach(fn => {
182
- try {
183
- fn(data);
184
- } catch (error) {
185
- log.error('Error calling listener', data);
186
- throw error;
187
- }
188
- });
189
- };
190
-
191
- bridge = new Bridge({
192
- listen(fn) {
193
- listeners.push(fn);
194
- return () => {
195
- const index = listeners.indexOf(fn);
196
- if (index >= 0) {
197
- listeners.splice(index, 1);
198
- }
199
- };
200
- },
201
- send(event: string, payload: any, transferable?: Array<any>) {
202
- if (socket.readyState === socket.OPEN) {
203
- socket.send(JSON.stringify({event, payload}));
204
- }
205
- },
206
- });
207
- ((bridge: any): FrontendBridge).addListener('shutdown', () => {
208
- socket.close();
209
- });
210
-
211
- store = new Store(bridge, {supportsNativeInspection: false});
212
-
213
- log('Connected');
214
- reload();
215
-}
216
-
217
-let startServerTimeoutID: TimeoutID | null = null;
218
-
219
-function connectToSocket(socket: WebSocket) {
220
- socket.onerror = err => {
221
- onDisconnected();
222
- log.error('Error with websocket connection', err);
223
- };
224
- socket.onclose = () => {
225
- onDisconnected();
226
- log('Connection to RN closed');
227
- };
228
- initialize(socket);
229
-
230
- return {
231
- close: function() {
232
- onDisconnected();
233
- },
234
- };
235
-}
236
-
237
-function startServer(port?: number = 8097) {
238
- const httpServer = require('http').createServer();
239
- const server = new Server({server: httpServer});
240
- let connected: WebSocket | null = null;
241
- server.on('connection', (socket: WebSocket) => {
242
- if (connected !== null) {
243
- connected.close();
244
- log.warn(
245
- 'Only one connection allowed at a time.',
246
- 'Closing the previous connection',
247
- );
248
- }
249
- connected = socket;
250
- socket.onerror = error => {
251
- connected = null;
252
- onDisconnected();
253
- log.error('Error with websocket connection', error);
254
- };
255
- socket.onclose = () => {
256
- connected = null;
257
- onDisconnected();
258
- log('Connection to RN closed');
259
- };
260
- initialize(socket);
261
- });
262
-
263
- server.on('error', event => {
264
- onError(event);
265
- log.error('Failed to start the DevTools server', event);
266
- startServerTimeoutID = setTimeout(() => startServer(port), 1000);
267
- });
268
-
269
- httpServer.on('request', (request, response) => {
270
- // Serve a file that immediately sets up the connection.
271
- const backendFile = readFileSync(join(__dirname, 'backend.js'));
272
-
273
- // The renderer interface doesn't read saved component filters directly,
274
- // because they are generally stored in localStorage within the context of the extension.
275
- // Because of this it relies on the extension to pass filters, so include them wth the response here.
276
- // This will ensure that saved filters are shared across different web pages.
277
- const savedPreferencesString = `
278
- window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = ${JSON.stringify(
279
- getSavedComponentFilters(),
280
- )};
281
- window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = ${JSON.stringify(
282
- getAppendComponentStack(),
283
- )};`;
284
-
285
- response.end(
286
- savedPreferencesString +
287
- '\n;' +
288
- backendFile.toString() +
289
- '\n;' +
290
- 'ReactDevToolsBackend.connectToDevTools();',
291
- );
292
- });
293
-
294
- httpServer.on('error', event => {
295
- onError(event);
296
- statusListener('Failed to start the server.');
297
- startServerTimeoutID = setTimeout(() => startServer(port), 1000);
298
- });
299
-
300
- httpServer.listen(port, () => {
301
- statusListener('The server is listening on the port ' + port + '.');
302
- });
303
-
304
- return {
305
- close: function() {
306
- connected = null;
307
- onDisconnected();
308
- if (startServerTimeoutID !== null) {
309
- clearTimeout(startServerTimeoutID);
310
- }
311
- server.close();
312
- httpServer.close();
313
- },
314
- };
315
-}
316
-
317
-const DevtoolsUI = {
318
- connectToSocket,
319
- setContentDOMNode,
320
- setProjectRoots,
321
- setShowWelcomeToTheNewDevToolsDialog,
322
- setStatusListener,
323
- startServer,
324
-};
325
-
326
-export default DevtoolsUI;
packages/react-devtools-core/standalone.js
deleted
-1
@@ -1 +0,0 @@
1
-module.exports = require('./dist/standalone');
packages/react-devtools-core/webpack.backend.js
deleted
-67
@@ -1,67 +0,0 @@
1
-const {resolve} = require('path');
2
-const {DefinePlugin} = require('webpack');
3
-const {
4
- getGitHubURL,
5
- getVersionString,
6
-} = require('react-devtools-extensions/utils');
7
-
8
-const NODE_ENV = process.env.NODE_ENV;
9
-if (!NODE_ENV) {
10
- console.error('NODE_ENV not set');
11
- process.exit(1);
12
-}
13
-
14
-const builtModulesDir = resolve(__dirname, '..', '..', 'build', 'node_modules');
15
-
16
-const __DEV__ = NODE_ENV === 'development';
17
-
18
-const GITHUB_URL = getGitHubURL();
19
-const DEVTOOLS_VERSION = getVersionString();
20
-
21
-module.exports = {
22
- mode: __DEV__ ? 'development' : 'production',
23
- devtool: __DEV__ ? 'cheap-module-eval-source-map' : false,
24
- entry: {
25
- backend: './src/backend.js',
26
- },
27
- output: {
28
- path: __dirname + '/dist',
29
- filename: '[name].js',
30
-
31
- // This name is important; standalone references it in order to connect.
32
- library: 'ReactDevToolsBackend',
33
- libraryTarget: 'umd',
34
- },
35
- resolve: {
36
- alias: {
37
- react: resolve(builtModulesDir, 'react'),
38
- 'react-dom': resolve(builtModulesDir, 'react-dom'),
39
- 'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
40
- 'react-is': resolve(builtModulesDir, 'react-is'),
41
- scheduler: resolve(builtModulesDir, 'scheduler'),
42
- },
43
- },
44
- plugins: [
45
- new DefinePlugin({
46
- __DEV__: true,
47
- 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
48
- 'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
49
- }),
50
- ],
51
- module: {
52
- rules: [
53
- {
54
- test: /\.js$/,
55
- loader: 'babel-loader',
56
- options: {
57
- configFile: resolve(
58
- __dirname,
59
- '..',
60
- 'react-devtools-shared',
61
- 'babel.config.js',
62
- ),
63
- },
64
- },
65
- ],
66
- },
67
-};
packages/react-devtools-core/webpack.standalone.js
deleted
-93
@@ -1,93 +0,0 @@
1
-const {resolve} = require('path');
2
-const {DefinePlugin} = require('webpack');
3
-const {
4
- getGitHubURL,
5
- getVersionString,
6
-} = require('react-devtools-extensions/utils');
7
-
8
-const NODE_ENV = process.env.NODE_ENV;
9
-if (!NODE_ENV) {
10
- console.error('NODE_ENV not set');
11
- process.exit(1);
12
-}
13
-
14
-const builtModulesDir = resolve(__dirname, '..', '..', 'build', 'node_modules');
15
-
16
-const __DEV__ = NODE_ENV === 'development';
17
-
18
-const GITHUB_URL = getGitHubURL();
19
-const DEVTOOLS_VERSION = getVersionString();
20
-
21
-module.exports = {
22
- mode: __DEV__ ? 'development' : 'production',
23
- devtool: __DEV__ ? 'cheap-module-eval-source-map' : false,
24
- target: 'electron-main',
25
- entry: {
26
- standalone: './src/standalone.js',
27
- },
28
- output: {
29
- path: __dirname + '/dist',
30
- filename: '[name].js',
31
- library: '[name]',
32
- libraryTarget: 'commonjs2',
33
- },
34
- resolve: {
35
- alias: {
36
- react: resolve(builtModulesDir, 'react'),
37
- 'react-dom': resolve(builtModulesDir, 'react-dom'),
38
- 'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
39
- 'react-is': resolve(builtModulesDir, 'react-is'),
40
- scheduler: resolve(builtModulesDir, 'scheduler'),
41
- },
42
- },
43
- node: {
44
- // Don't replace __dirname!
45
- // This would break the standalone DevTools ability to load the backend.
46
- // see https://github.com/facebook/react-devtools/issues/1269
47
- __dirname: false,
48
- },
49
- plugins: [
50
- new DefinePlugin({
51
- __DEV__: false,
52
- 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
53
- 'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
54
- 'process.env.NODE_ENV': `"${NODE_ENV}"`,
55
- }),
56
- ],
57
- module: {
58
- rules: [
59
- {
60
- test: /\.js$/,
61
- loader: 'babel-loader',
62
- options: {
63
- configFile: resolve(
64
- __dirname,
65
- '..',
66
- 'react-devtools-shared',
67
- 'babel.config.js',
68
- ),
69
- },
70
- },
71
- {
72
- test: /\.css$/,
73
- use: [
74
- {
75
- loader: 'style-loader',
76
- },
77
- {
78
- loader: 'css-loader',
79
- options: {
80
- // WARNING It's important that we disable CSS source maps for production builds.
81
- // This causes style-loader to insert styles via a <style> tag rather than URL.createObjectURL,
82
- // which in turn avoids a nasty Electron/Chromium bug that breaks DevTools in Nuclide.
83
- // (Calls to URL.createObjectURL seem to crash the webview process.)
84
- sourceMap: __DEV__,
85
- modules: true,
86
- localIdentName: '[local]___[hash:base64:5]',
87
- },
88
- },
89
- ],
90
- },
91
- ],
92
- },
93
-};
packages/react-devtools-extensions/.circleci/config.yml
deleted
-58
@@ -1,58 +0,0 @@
1
-# Javascript Node CircleCI 2.0 configuration file
2
-#
3
-# Check https://circleci.com/docs/2.0/language-javascript/ for more details
4
-#
5
-version: 2
6
-jobs:
7
- build:
8
- docker:
9
- # specify the version you desire here
10
- - image: circleci/node:10.12.0
11
-
12
- # Specify service dependencies here if necessary
13
- # CircleCI maintains a library of pre-built images
14
- # documented at https://circleci.com/docs/2.0/circleci-images/
15
- # - image: circleci/mongo:3.4.4
16
-
17
- working_directory: ~/repo
18
-
19
- steps:
20
- - checkout
21
-
22
- # Download and cache dependencies
23
- - restore_cache:
24
- name: Restore node_modules cache
25
- keys:
26
- - v1-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}
27
- - v1-node-{{ arch }}-{{ .Branch }}-
28
- - v1-node-{{ arch }}-
29
-
30
- - run:
31
- name: Nodejs Version
32
- command: node --version
33
-
34
- - run:
35
- name: Install Packages
36
- command: yarn install --frozen-lockfile
37
-
38
- - save_cache:
39
- name: Save node_modules cache
40
- key: v1-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}
41
- paths:
42
- - node_modules
43
-
44
- - run:
45
- name: Check formatting
46
- command: yarn prettier:ci
47
-
48
- - run:
49
- name: Check lint
50
- command: yarn lint:ci
51
-
52
- - run:
53
- name: Check Flow
54
- command: yarn flow
55
-
56
- - run:
57
- name: Test Packages
58
- command: yarn test
\ No newline at end of file
packages/react-devtools-extensions/README.md
deleted
-22
@@ -1,22 +0,0 @@
1
-This is the source code for the React DevTools browser extension.
2
-
3
-## Installation
4
-
5
-The easiest way to install this extension is as a browser add-on:
6
-* [Chrome web store](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en)
7
-* [Firefox Add-ons](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/)
8
-
9
-## Development
10
-
11
-You can also build and install from source:
12
-```sh
13
-yarn install
14
-
15
-cd packages/react-devtools-extensions/
16
-
17
-yarn build:chrome # => packages/react-devtools-extensions/chrome/build
18
-yarn run test:chrome # Test Chrome extension
19
-
20
-yarn build:firefox # => packages/react-devtools-extensions/firefox/build
21
-yarn run test:firefox # Test Firefox extension
22
-```
packages/react-devtools-extensions/build.js
deleted
-120
@@ -1,120 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-'use strict';
4
-
5
-const archiver = require('archiver');
6
-const {execSync} = require('child_process');
7
-const {readFileSync, writeFileSync, createWriteStream} = require('fs');
8
-const {copy, ensureDir, move, remove} = require('fs-extra');
9
-const {join} = require('path');
10
-const {getGitCommit} = require('./utils');
11
-
12
-// These files are copied along with Webpack-bundled files
13
-// to produce the final web extension
14
-const STATIC_FILES = ['icons', 'popups', 'main.html', 'panel.html'];
15
-
16
-const preProcess = async (destinationPath, tempPath) => {
17
- await remove(destinationPath); // Clean up from previously completed builds
18
- await remove(tempPath); // Clean up from any previously failed builds
19
- await ensureDir(tempPath); // Create temp dir for this new build
20
-};
21
-
22
-const build = async (tempPath, manifestPath) => {
23
- const binPath = join(tempPath, 'bin');
24
- const zipPath = join(tempPath, 'zip');
25
-
26
- const webpackPath = join(
27
- __dirname,
28
- '..',
29
- '..',
30
- 'node_modules',
31
- '.bin',
32
- 'webpack',
33
- );
34
- execSync(
35
- `${webpackPath} --config webpack.config.js --output-path ${binPath}`,
36
- {
37
- cwd: __dirname,
38
- env: process.env,
39
- stdio: 'inherit',
40
- },
41
- );
42
- execSync(
43
- `${webpackPath} --config webpack.backend.js --output-path ${binPath}`,
44
- {
45
- cwd: __dirname,
46
- env: process.env,
47
- stdio: 'inherit',
48
- },
49
- );
50
-
51
- // Make temp dir
52
- await ensureDir(zipPath);
53
-
54
- const copiedManifestPath = join(zipPath, 'manifest.json');
55
-
56
- // Copy unbuilt source files to zip dir to be packaged:
57
- await copy(binPath, join(zipPath, 'build'));
58
- await copy(manifestPath, copiedManifestPath);
59
- await Promise.all(
60
- STATIC_FILES.map(file => copy(join(__dirname, file), join(zipPath, file))),
61
- );
62
-
63
- const commit = getGitCommit();
64
- const dateString = new Date().toLocaleDateString();
65
- const manifest = JSON.parse(readFileSync(copiedManifestPath).toString());
66
- const versionDateString = `${manifest.version} (${dateString})`;
67
- if (manifest.version_name) {
68
- manifest.version_name = versionDateString;
69
- }
70
- manifest.description += `\n\nCreated from revision ${commit} on ${dateString}.`;
71
-
72
- writeFileSync(copiedManifestPath, JSON.stringify(manifest, null, 2));
73
-
74
- // Pack the extension
75
- const archive = archiver('zip', {zlib: {level: 9}});
76
- const zipStream = createWriteStream(join(tempPath, 'ReactDevTools.zip'));
77
- await new Promise((resolve, reject) => {
78
- archive
79
- .directory(zipPath, false)
80
- .on('error', err => reject(err))
81
- .pipe(zipStream);
82
- archive.finalize();
83
- zipStream.on('close', () => resolve());
84
- });
85
-};
86
-
87
-const postProcess = async (tempPath, destinationPath) => {
88
- const unpackedSourcePath = join(tempPath, 'zip');
89
- const packedSourcePath = join(tempPath, 'ReactDevTools.zip');
90
- const packedDestPath = join(destinationPath, 'ReactDevTools.zip');
91
- const unpackedDestPath = join(destinationPath, 'unpacked');
92
-
93
- await move(unpackedSourcePath, unpackedDestPath); // Copy built files to destination
94
- await move(packedSourcePath, packedDestPath); // Copy built files to destination
95
- await remove(tempPath); // Clean up temp directory and files
96
-};
97
-
98
-const main = async buildId => {
99
- const root = join(__dirname, buildId);
100
- const manifestPath = join(root, 'manifest.json');
101
- const destinationPath = join(root, 'build');
102
-
103
- try {
104
- const tempPath = join(__dirname, 'build', buildId);
105
- await preProcess(destinationPath, tempPath);
106
- await build(tempPath, manifestPath);
107
-
108
- const builtUnpackedPath = join(destinationPath, 'unpacked');
109
- await postProcess(tempPath, destinationPath);
110
-
111
- return builtUnpackedPath;
112
- } catch (error) {
113
- console.error(error);
114
- process.exit(1);
115
- }
116
-
117
- return null;
118
-};
119
-
120
-module.exports = main;
packages/react-devtools-extensions/chrome/README.md
deleted
-12
@@ -1,12 +0,0 @@
1
-# The Chrome extension
2
-
3
-The source code for this extension has moved to `shells/webextension`.
4
-
5
-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.
6
-
7
-## Testing in Chrome
8
-
9
-You can test a local build of the web extension like so:
10
-
11
- 1. Build the extension: `node build`
12
- 1. Follow the on-screen instructions.
packages/react-devtools-extensions/chrome/build.js
deleted
-43
@@ -1,43 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-'use strict';
4
-
5
-const chalk = require('chalk');
6
-const {execSync} = require('child_process');
7
-const {existsSync} = require('fs');
8
-const {isAbsolute, join, relative} = require('path');
9
-const {argv} = require('yargs');
10
-const build = require('../build');
11
-
12
-const main = async () => {
13
- const {crx, keyPath} = argv;
14
-
15
- if (crx) {
16
- if (!keyPath || !existsSync(keyPath)) {
17
- console.error('Must specify a key file (.pem) to build CRX');
18
- process.exit(1);
19
- }
20
- }
21
-
22
- await build('chrome');
23
-
24
- if (crx) {
25
- const cwd = join(__dirname, 'build');
26
-
27
- let safeKeyPath = keyPath;
28
- if (!isAbsolute(keyPath)) {
29
- safeKeyPath = join(relative(cwd, process.cwd()), keyPath);
30
- }
31
-
32
- execSync(`crx pack ./unpacked -o ReactDevTools.crx -p ${safeKeyPath}`, {
33
- cwd,
34
- });
35
- }
36
-
37
- console.log(chalk.green('\nThe Chrome extension has been built!'));
38
- console.log(chalk.green('You can test this build by running:'));
39
- console.log(chalk.gray('\n# From the react-devtools root directory:'));
40
- console.log('yarn run test:chrome');
41
-};
42
-
43
-main();
packages/react-devtools-extensions/chrome/deploy.js
deleted
-9
@@ -1,9 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-'use strict';
4
-
5
-const deploy = require('../deploy');
6
-
7
-const main = async () => await deploy('chrome');
8
-
9
-main();
packages/react-devtools-extensions/chrome/manifest.json
deleted
-52
@@ -1,52 +0,0 @@
1
-{
2
- "manifest_version": 2,
3
- "name": "React Developer Tools",
4
- "description": "Adds React debugging tools to the Chrome Developer Tools.",
5
- "version": "4.0.6",
6
- "version_name": "4.0.6",
7
-
8
- "minimum_chrome_version": "49",
9
-
10
- "icons": {
11
- "16": "icons/16-production.png",
12
- "32": "icons/32-production.png",
13
- "48": "icons/48-production.png",
14
- "128": "icons/128-production.png"
15
- },
16
-
17
- "browser_action": {
18
- "default_icon": {
19
- "16": "icons/16-disabled.png",
20
- "32": "icons/32-disabled.png",
21
- "48": "icons/48-disabled.png",
22
- "128": "icons/128-disabled.png"
23
- },
24
-
25
- "default_popup": "popups/disabled.html"
26
- },
27
-
28
- "devtools_page": "main.html",
29
-
30
- "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
31
- "web_accessible_resources": [
32
- "main.html",
33
- "panel.html",
34
- "build/backend.js",
35
- "build/renderer.js"
36
- ],
37
-
38
- "background": {
39
- "scripts": ["build/background.js"],
40
- "persistent": false
41
- },
42
-
43
- "permissions": ["file:///*", "http://*/*", "https://*/*"],
44
-
45
- "content_scripts": [
46
- {
47
- "matches": ["<all_urls>"],
48
- "js": ["build/injectGlobalHook.js"],
49
- "run_at": "document_start"
50
- }
51
- ]
52
-}
packages/react-devtools-extensions/chrome/now.json
deleted
-5
@@ -1,5 +0,0 @@
1
-{
2
- "name": "react-devtools-experimental-chrome",
3
- "alias": ["react-devtools-experimental-chrome"],
4
- "files": ["index.html", "ReactDevTools.zip"]
5
-}
packages/react-devtools-extensions/chrome/test.js
deleted
-13
@@ -1,13 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-'use strict';
4
-
5
-const chromeLaunch = require('chrome-launch');
6
-const {resolve} = require('path');
7
-
8
-const EXTENSION_PATH = resolve('./chrome/build/unpacked');
9
-const START_URL = 'https://facebook.github.io/react/';
10
-
11
-chromeLaunch(START_URL, {
12
- args: [`--load-extension=${EXTENSION_PATH}`],
13
-});
packages/react-devtools-extensions/deploy.chrome.html
deleted
-8
@@ -1,8 +0,0 @@
1
-<ol>
2
- <li><a href="ReactDevTools.zip">download extension</a></li>
3
- <li>Double-click to extract</li>
4
- <li>Navigate to <code>chrome://extensions/</code></li>
5
- <li>Enable "Developer mode"</li>
6
- <li>Click "LOAD UNPACKED"</li>
7
- <li>Select extracted extension folder (<code>ReactDevTools</code>)</li>
8
-</ol>
\ No newline at end of file
packages/react-devtools-extensions/deploy.firefox.html
deleted
-7
@@ -1,7 +0,0 @@
1
-<ol>
2
- <li><a href="ReactDevTools.zip">download extension</a></li>
3
- <li>Extract/unzip</li>
4
- <li>Visit <code>about:debugging</code></li>
5
- <li>Click "Load Temporary Add-on"</li>
6
- <li>Select the <code>manifest.json</code> file inside of the extracted extension folder (<code>ReactDevTools</code>)</li>
7
-</ol>
\ No newline at end of file
packages/react-devtools-extensions/deploy.html
deleted
-40
@@ -1,40 +0,0 @@
1
-<html>
2
-<head>
3
- <meta charset="utf8">
4
- <title>React DevTools pre-release</title>
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <style>
7
- body {
8
- font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
9
- sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
10
- font-size: 14px;
11
- }
12
- </style>
13
-</head>
14
-<body>
15
- <h1>
16
- React DevTools pre-release
17
- </h1>
18
-
19
- <h3>
20
- Created on <strong>%date%</strong> from
21
- <a href="http://github.com/facebook/react/commit/%commit%"><code>%commit%</code></a>
22
- </h3>
23
-
24
- <p>
25
- This is a preview build of the <a href="https://github.com/facebook/react">React DevTools extension</a>.
26
- </p>
27
-
28
- <h2>Installation instructions</h2>
29
- %installation%
30
- <p>
31
- 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.
32
- </p>
33
-
34
- <h2>Bug reports</h2>
35
- <p>
36
- Please report bugs as <a href="https://github.com/facebook/react/issues/new?labels=Component:%20Developer%20Tools">GitHub issues</a>.
37
- Please include all of the info required to reproduce the bug (e.g. links, code, instructions).
38
- </p>
39
-</body>
40
-</html>
packages/react-devtools-extensions/deploy.js
deleted
-58
@@ -1,58 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-'use strict';
4
-
5
-const {exec, execSync} = require('child_process');
6
-const {readFileSync, writeFileSync} = require('fs');
7
-const {join} = require('path');
8
-
9
-const main = async buildId => {
10
- const root = join(__dirname, buildId);
11
- const buildPath = join(root, 'build');
12
-
13
- execSync(`node ${join(root, './build')}`, {
14
- cwd: __dirname,
15
- env: {
16
- ...process.env,
17
- NODE_ENV: 'production',
18
- },
19
- stdio: 'inherit',
20
- });
21
-
22
- await exec(`cp ${join(root, 'now.json')} ${join(buildPath, 'now.json')}`, {
23
- cwd: root,
24
- });
25
-
26
- const file = readFileSync(join(root, 'now.json'));
27
- const json = JSON.parse(file);
28
- const alias = json.alias[0];
29
-
30
- const commit = execSync('git rev-parse HEAD')
31
- .toString()
32
- .trim()
33
- .substr(0, 7);
34
-
35
- let date = new Date();
36
- date = `${date.toLocaleDateString()} – ${date.toLocaleTimeString()}`;
37
-
38
- const installationInstructions =
39
- buildId === 'chrome'
40
- ? readFileSync(join(__dirname, 'deploy.chrome.html'))
41
- : readFileSync(join(__dirname, 'deploy.firefox.html'));
42
-
43
- let html = readFileSync(join(__dirname, 'deploy.html')).toString();
44
- html = html.replace(/%commit%/g, commit);
45
- html = html.replace(/%date%/g, date);
46
- html = html.replace(/%installation%/, installationInstructions);
47
-
48
- writeFileSync(join(buildPath, 'index.html'), html);
49
-
50
- await exec(`now deploy && now alias ${alias}`, {
51
- cwd: buildPath,
52
- stdio: 'inherit',
53
- });
54
-
55
- console.log(`Deployed to https://${alias}.now.sh`);
56
-};
57
-
58
-module.exports = main;
packages/react-devtools-extensions/firefox/README.md
deleted
-12
@@ -1,12 +0,0 @@
1
-# The Firefox extension
2
-
3
-The source code for this extension has moved to `shells/webextension`.
4
-
5
-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.
6
-
7
-## Testing in Firefox
8
-
9
- 1. Build the extension: `node build`
10
- 1. Follow the on-screen instructions.
11
-
12
-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.
packages/react-devtools-extensions/firefox/build.js
deleted
-37
@@ -1,37 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-'use strict';
4
-
5
-const chalk = require('chalk');
6
-const build = require('../build');
7
-
8
-const main = async () => {
9
- await build('firefox');
10
-
11
- console.log(chalk.green('\nThe Firefox extension has been built!'));
12
- console.log(chalk.green('You can test this build by running:'));
13
- console.log(chalk.gray('\n# From the react-devtools root directory:'));
14
- console.log('yarn run test:firefox');
15
- console.log(
16
- chalk.gray('\n# You can also test against upcoming Firefox releases.')
17
- );
18
- console.log(
19
- chalk.gray(
20
- '# First download a release from https://www.mozilla.org/en-US/firefox/channel/desktop/'
21
- )
22
- );
23
- console.log(
24
- chalk.gray(
25
- '# And then tell web-ext which release to use (eg firefoxdeveloperedition, nightly, beta):'
26
- )
27
- );
28
- console.log('WEB_EXT_FIREFOX=nightly yarn run test:firefox');
29
- console.log(chalk.gray('\n# You can test against older versions too:'));
30
- console.log(
31
- 'WEB_EXT_FIREFOX=/Applications/Firefox52.app/Contents/MacOS/firefox-bin yarn run test:firefox'
32
- );
33
-};
34
-
35
-main();
36
-
37
-module.exports = {main};
packages/react-devtools-extensions/firefox/deploy.js
deleted
-9
@@ -1,9 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-'use strict';
4
-
5
-const deploy = require('../deploy');
6
-
7
-const main = async () => await deploy('firefox');
8
-
9
-main();
packages/react-devtools-extensions/firefox/manifest.json
deleted
-56
@@ -1,56 +0,0 @@
1
-{
2
- "manifest_version": 2,
3
- "name": "React Developer Tools",
4
- "description": "Adds React debugging tools to the Firefox Developer Tools.",
5
- "version": "4.0.6",
6
-
7
- "applications": {
8
- "gecko": {
9
- "id": "@react-devtools",
10
- "strict_min_version": "54.0"
11
- }
12
- },
13
-
14
- "icons": {
15
- "16": "icons/16-production.png",
16
- "32": "icons/32-production.png",
17
- "48": "icons/48-production.png",
18
- "128": "icons/128-production.png"
19
- },
20
-
21
- "browser_action": {
22
- "default_icon": {
23
- "16": "icons/16-disabled.png",
24
- "32": "icons/32-disabled.png",
25
- "48": "icons/48-disabled.png",
26
- "128": "icons/128-disabled.png"
27
- },
28
-
29
- "default_popup": "popups/disabled.html",
30
- "browser_style": true
31
- },
32
-
33
- "devtools_page": "main.html",
34
-
35
- "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
36
- "web_accessible_resources": [
37
- "main.html",
38
- "panel.html",
39
- "build/backend.js",
40
- "build/renderer.js"
41
- ],
42
-
43
- "background": {
44
- "scripts": ["build/background.js"]
45
- },
46
-
47
- "permissions": ["file:///*", "http://*/*", "https://*/*"],
48
-
49
- "content_scripts": [
50
- {
51
- "matches": ["<all_urls>"],
52
- "js": ["build/injectGlobalHook.js"],
53
- "run_at": "document_start"
54
- }
55
- ]
56
-}
packages/react-devtools-extensions/firefox/now.json
deleted
-5
@@ -1,5 +0,0 @@
1
-{
2
- "name": "react-devtools-experimental-firefox",
3
- "alias": ["react-devtools-experimental-firefox"],
4
- "files": ["index.html", "ReactDevTools.zip"]
5
-}
packages/react-devtools-extensions/firefox/test.js
deleted
-48
@@ -1,48 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-'use strict';
4
-
5
-const {exec} = require('child-process-promise');
6
-const {Finder} = require('firefox-profile');
7
-const {resolve} = require('path');
8
-
9
-const EXTENSION_PATH = resolve('./firefox/build/unpacked');
10
-const START_URL = 'https://facebook.github.io/react/';
11
-
12
-const main = async () => {
13
- const finder = new Finder();
14
-
15
- // Use default Firefox profile for testing purposes.
16
- // This prevents users from having to re-login-to sites before testing.
17
- const findPathPromise = new Promise((resolvePromise, rejectPromise) => {
18
- finder.getPath('default', (error, profile) => {
19
- if (error) {
20
- rejectPromise(error);
21
- } else {
22
- resolvePromise(profile);
23
- }
24
- });
25
- });
26
-
27
- const options = [
28
- `--source-dir=${EXTENSION_PATH}`,
29
- `--start-url=${START_URL}`,
30
- '--browser-console',
31
- ];
32
-
33
- try {
34
- const path = await findPathPromise;
35
- const trimmedPath = path.replace(' ', '\\ ');
36
- options.push(`--firefox-profile=${trimmedPath}`);
37
- } catch (err) {
38
- console.warn('Could not find default profile, using temporary profile.');
39
- }
40
-
41
- try {
42
- await exec(`web-ext run ${options.join(' ')}`);
43
- } catch (err) {
44
- console.error('`web-ext run` failed', err.stdout, err.stderr);
45
- }
46
-};
47
-
48
-main();
packages/react-devtools-extensions/flow-typed/jest.js
deleted
-1190
@@ -1,1190 +0,0 @@
1
-'use strict';
2
-
3
-type JestMockFn<TArguments: $ReadOnlyArray<*>, TReturn> = {
4
- (...args: TArguments): TReturn,
5
- /**
6
- * An object for introspecting mock calls
7
- */
8
- mock: {
9
- /**
10
- * An array that represents all calls that have been made into this mock
11
- * function. Each call is represented by an array of arguments that were
12
- * passed during the call.
13
- */
14
- calls: Array<TArguments>,
15
- /**
16
- * An array that contains all the object instances that have been
17
- * instantiated from this mock function.
18
- */
19
- instances: Array<TReturn>,
20
- /**
21
- * An array that contains all the object results that have been
22
- * returned by this mock function call
23
- */
24
- results: Array<{isThrow: boolean, value: TReturn}>,
25
- },
26
- /**
27
- * Resets all information stored in the mockFn.mock.calls and
28
- * mockFn.mock.instances arrays. Often this is useful when you want to clean
29
- * up a mock's usage data between two assertions.
30
- */
31
- mockClear(): void,
32
- /**
33
- * Resets all information stored in the mock. This is useful when you want to
34
- * completely restore a mock back to its initial state.
35
- */
36
- mockReset(): void,
37
- /**
38
- * Removes the mock and restores the initial implementation. This is useful
39
- * when you want to mock functions in certain test cases and restore the
40
- * original implementation in others. Beware that mockFn.mockRestore only
41
- * works when mock was created with jest.spyOn. Thus you have to take care of
42
- * restoration yourself when manually assigning jest.fn().
43
- */
44
- mockRestore(): void,
45
- /**
46
- * Accepts a function that should be used as the implementation of the mock.
47
- * The mock itself will still record all calls that go into and instances
48
- * that come from itself -- the only difference is that the implementation
49
- * will also be executed when the mock is called.
50
- */
51
- mockImplementation(
52
- fn: (...args: TArguments) => TReturn
53
- ): JestMockFn<TArguments, TReturn>,
54
- /**
55
- * Accepts a function that will be used as an implementation of the mock for
56
- * one call to the mocked function. Can be chained so that multiple function
57
- * calls produce different results.
58
- */
59
- mockImplementationOnce(
60
- fn: (...args: TArguments) => TReturn
61
- ): JestMockFn<TArguments, TReturn>,
62
- /**
63
- * Accepts a string to use in test result output in place of "jest.fn()" to
64
- * indicate which mock function is being referenced.
65
- */
66
- mockName(name: string): JestMockFn<TArguments, TReturn>,
67
- /**
68
- * Just a simple sugar function for returning `this`
69
- */
70
- mockReturnThis(): void,
71
- /**
72
- * Accepts a value that will be returned whenever the mock function is called.
73
- */
74
- mockReturnValue(value: TReturn): JestMockFn<TArguments, TReturn>,
75
- /**
76
- * Sugar for only returning a value once inside your mock
77
- */
78
- mockReturnValueOnce(value: TReturn): JestMockFn<TArguments, TReturn>,
79
- /**
80
- * Sugar for jest.fn().mockImplementation(() => Promise.resolve(value))
81
- */
82
- mockResolvedValue(value: TReturn): JestMockFn<TArguments, Promise<TReturn>>,
83
- /**
84
- * Sugar for jest.fn().mockImplementationOnce(() => Promise.resolve(value))
85
- */
86
- mockResolvedValueOnce(
87
- value: TReturn
88
- ): JestMockFn<TArguments, Promise<TReturn>>,
89
- /**
90
- * Sugar for jest.fn().mockImplementation(() => Promise.reject(value))
91
- */
92
- mockRejectedValue(value: TReturn): JestMockFn<TArguments, Promise<any>>,
93
- /**
94
- * Sugar for jest.fn().mockImplementationOnce(() => Promise.reject(value))
95
- */
96
- mockRejectedValueOnce(value: TReturn): JestMockFn<TArguments, Promise<any>>,
97
-};
98
-
99
-type JestAsymmetricEqualityType = {
100
- /**
101
- * A custom Jasmine equality tester
102
- */
103
- asymmetricMatch(value: mixed): boolean,
104
-};
105
-
106
-type JestCallsType = {
107
- allArgs(): mixed,
108
- all(): mixed,
109
- any(): boolean,
110
- count(): number,
111
- first(): mixed,
112
- mostRecent(): mixed,
113
- reset(): void,
114
-};
115
-
116
-type JestClockType = {
117
- install(): void,
118
- mockDate(date: Date): void,
119
- tick(milliseconds?: number): void,
120
- uninstall(): void,
121
-};
122
-
123
-type JestMatcherResult = {
124
- message?: string | (() => string),
125
- pass: boolean,
126
-};
127
-
128
-type JestMatcher = (
129
- actual: any,
130
- expected: any
131
-) => JestMatcherResult | Promise<JestMatcherResult>;
132
-
133
-type JestPromiseType = {
134
- /**
135
- * Use rejects to unwrap the reason of a rejected promise so any other
136
- * matcher can be chained. If the promise is fulfilled the assertion fails.
137
- */
138
- // eslint-disable-next-line no-use-before-define
139
- rejects: JestExpectType,
140
- /**
141
- * Use resolves to unwrap the value of a fulfilled promise so any other
142
- * matcher can be chained. If the promise is rejected the assertion fails.
143
- */
144
- // eslint-disable-next-line no-use-before-define
145
- resolves: JestExpectType,
146
-};
147
-
148
-/**
149
- * Jest allows functions and classes to be used as test names in test() and
150
- * describe()
151
- */
152
-type JestTestName = string | Function;
153
-
154
-/**
155
- * Plugin: jest-styled-components
156
- */
157
-
158
-type JestStyledComponentsMatcherValue =
159
- | string
160
- | JestAsymmetricEqualityType
161
- | RegExp
162
- | typeof undefined;
163
-
164
-type JestStyledComponentsMatcherOptions = {
165
- media?: string,
166
- modifier?: string,
167
- supports?: string,
168
-};
169
-
170
-type JestStyledComponentsMatchersType = {
171
- toHaveStyleRule(
172
- property: string,
173
- value: JestStyledComponentsMatcherValue,
174
- options?: JestStyledComponentsMatcherOptions
175
- ): void,
176
-};
177
-
178
-/**
179
- * Plugin: jest-enzyme
180
- */
181
-type EnzymeMatchersType = {
182
- // 5.x
183
- toBeEmpty(): void,
184
- toBePresent(): void,
185
- // 6.x
186
- toBeChecked(): void,
187
- toBeDisabled(): void,
188
- toBeEmptyRender(): void,
189
- toContainMatchingElement(selector: string): void,
190
- toContainMatchingElements(n: number, selector: string): void,
191
- toContainExactlyOneMatchingElement(selector: string): void,
192
- toContainReact(element: React$Element<any>): void,
193
- toExist(): void,
194
- toHaveClassName(className: string): void,
195
- toHaveHTML(html: string): void,
196
- toHaveProp: ((propKey: string, propValue?: any) => void) &
197
- ((props: {}) => void),
198
- toHaveRef(refName: string): void,
199
- toHaveState: ((stateKey: string, stateValue?: any) => void) &
200
- ((state: {}) => void),
201
- toHaveStyle: ((styleKey: string, styleValue?: any) => void) &
202
- ((style: {}) => void),
203
- toHaveTagName(tagName: string): void,
204
- toHaveText(text: string): void,
205
- toHaveValue(value: any): void,
206
- toIncludeText(text: string): void,
207
- toMatchElement(
208
- element: React$Element<any>,
209
- options?: {|ignoreProps?: boolean, verbose?: boolean|}
210
- ): void,
211
- toMatchSelector(selector: string): void,
212
- // 7.x
213
- toHaveDisplayName(name: string): void,
214
-};
215
-
216
-// DOM testing library extensions https://github.com/kentcdodds/dom-testing-library#custom-jest-matchers
217
-type DomTestingLibraryType = {
218
- toBeDisabled(): void,
219
- toBeEmpty(): void,
220
- toBeInTheDocument(): void,
221
- toBeVisible(): void,
222
- toContainElement(element: HTMLElement | null): void,
223
- toContainHTML(htmlText: string): void,
224
- toHaveAttribute(name: string, expectedValue?: string): void,
225
- toHaveClass(...classNames: string[]): void,
226
- toHaveFocus(): void,
227
- toHaveFormValues(expectedValues: {[name: string]: any}): void,
228
- toHaveStyle(css: string): void,
229
- toHaveTextContent(
230
- content: string | RegExp,
231
- options?: {normalizeWhitespace: boolean}
232
- ): void,
233
- toBeInTheDOM(): void,
234
-};
235
-
236
-// Jest JQuery Matchers: https://github.com/unindented/custom-jquery-matchers
237
-type JestJQueryMatchersType = {
238
- toExist(): void,
239
- toHaveLength(len: number): void,
240
- toHaveId(id: string): void,
241
- toHaveClass(className: string): void,
242
- toHaveTag(tag: string): void,
243
- toHaveAttr(key: string, val?: any): void,
244
- toHaveProp(key: string, val?: any): void,
245
- toHaveText(text: string | RegExp): void,
246
- toHaveData(key: string, val?: any): void,
247
- toHaveValue(val: any): void,
248
- toHaveCss(css: {[key: string]: any}): void,
249
- toBeChecked(): void,
250
- toBeDisabled(): void,
251
- toBeEmpty(): void,
252
- toBeHidden(): void,
253
- toBeSelected(): void,
254
- toBeVisible(): void,
255
- toBeFocused(): void,
256
- toBeInDom(): void,
257
- toBeMatchedBy(sel: string): void,
258
- toHaveDescendant(sel: string): void,
259
- toHaveDescendantWithText(sel: string, text: string | RegExp): void,
260
-};
261
-
262
-// Jest Extended Matchers: https://github.com/jest-community/jest-extended
263
-type JestExtendedMatchersType = {
264
- /**
265
- * Note: Currently unimplemented
266
- * Passing assertion
267
- *
268
- * @param {String} message
269
- */
270
- // pass(message: string): void;
271
-
272
- /**
273
- * Note: Currently unimplemented
274
- * Failing assertion
275
- *
276
- * @param {String} message
277
- */
278
- // fail(message: string): void;
279
-
280
- /**
281
- * Use .toBeEmpty when checking if a String '', Array [] or Object {} is empty.
282
- */
283
- toBeEmpty(): void,
284
-
285
- /**
286
- * Use .toBeOneOf when checking if a value is a member of a given Array.
287
- * @param {Array.<*>} members
288
- */
289
- toBeOneOf(members: any[]): void,
290
-
291
- /**
292
- * Use `.toBeNil` when checking a value is `null` or `undefined`.
293
- */
294
- toBeNil(): void,
295
-
296
- /**
297
- * Use `.toSatisfy` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean`.
298
- * @param {Function} predicate
299
- */
300
- toSatisfy(predicate: (n: any) => boolean): void,
301
-
302
- /**
303
- * Use `.toBeArray` when checking if a value is an `Array`.
304
- */
305
- toBeArray(): void,
306
-
307
- /**
308
- * Use `.toBeArrayOfSize` when checking if a value is an `Array` of size x.
309
- * @param {Number} x
310
- */
311
- toBeArrayOfSize(x: number): void,
312
-
313
- /**
314
- * Use `.toIncludeAllMembers` when checking if an `Array` contains all of the same members of a given set.
315
- * @param {Array.<*>} members
316
- */
317
- toIncludeAllMembers(members: any[]): void,
318
-
319
- /**
320
- * Use `.toIncludeAnyMembers` when checking if an `Array` contains any of the members of a given set.
321
- * @param {Array.<*>} members
322
- */
323
- toIncludeAnyMembers(members: any[]): void,
324
-
325
- /**
326
- * Use `.toSatisfyAll` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean` for all values in an array.
327
- * @param {Function} predicate
328
- */
329
- toSatisfyAll(predicate: (n: any) => boolean): void,
330
-
331
- /**
332
- * Use `.toBeBoolean` when checking if a value is a `Boolean`.
333
- */
334
- toBeBoolean(): void,
335
-
336
- /**
337
- * Use `.toBeTrue` when checking a value is equal (===) to `true`.
338
- */
339
- toBeTrue(): void,
340
-
341
- /**
342
- * Use `.toBeFalse` when checking a value is equal (===) to `false`.
343
- */
344
- toBeFalse(): void,
345
-
346
- /**
347
- * Use .toBeDate when checking if a value is a Date.
348
- */
349
- toBeDate(): void,
350
-
351
- /**
352
- * Use `.toBeFunction` when checking if a value is a `Function`.
353
- */
354
- toBeFunction(): void,
355
-
356
- /**
357
- * Use `.toHaveBeenCalledBefore` when checking if a `Mock` was called before another `Mock`.
358
- *
359
- * Note: Required Jest version >22
360
- * Note: Your mock functions will have to be asynchronous to cause the timestamps inside of Jest to occur in a differentJS event loop, otherwise the mock timestamps will all be the same
361
- *
362
- * @param {Mock} mock
363
- */
364
- toHaveBeenCalledBefore(mock: JestMockFn<any, any>): void,
365
-
366
- /**
367
- * Use `.toBeNumber` when checking if a value is a `Number`.
368
- */
369
- toBeNumber(): void,
370
-
371
- /**
372
- * Use `.toBeNaN` when checking a value is `NaN`.
373
- */
374
- toBeNaN(): void,
375
-
376
- /**
377
- * Use `.toBeFinite` when checking if a value is a `Number`, not `NaN` or `Infinity`.
378
- */
379
- toBeFinite(): void,
380
-
381
- /**
382
- * Use `.toBePositive` when checking if a value is a positive `Number`.
383
- */
384
- toBePositive(): void,
385
-
386
- /**
387
- * Use `.toBeNegative` when checking if a value is a negative `Number`.
388
- */
389
- toBeNegative(): void,
390
-
391
- /**
392
- * Use `.toBeEven` when checking if a value is an even `Number`.
393
- */
394
- toBeEven(): void,
395
-
396
- /**
397
- * Use `.toBeOdd` when checking if a value is an odd `Number`.
398
- */
399
- toBeOdd(): void,
400
-
401
- /**
402
- * Use `.toBeWithin` when checking if a number is in between the given bounds of: start (inclusive) and end (exclusive).
403
- *
404
- * @param {Number} start
405
- * @param {Number} end
406
- */
407
- toBeWithin(start: number, end: number): void,
408
-
409
- /**
410
- * Use `.toBeObject` when checking if a value is an `Object`.
411
- */
412
- toBeObject(): void,
413
-
414
- /**
415
- * Use `.toContainKey` when checking if an object contains the provided key.
416
- *
417
- * @param {String} key
418
- */
419
- toContainKey(key: string): void,
420
-
421
- /**
422
- * Use `.toContainKeys` when checking if an object has all of the provided keys.
423
- *
424
- * @param {Array.<String>} keys
425
- */
426
- toContainKeys(keys: string[]): void,
427
-
428
- /**
429
- * Use `.toContainAllKeys` when checking if an object only contains all of the provided keys.
430
- *
431
- * @param {Array.<String>} keys
432
- */
433
- toContainAllKeys(keys: string[]): void,
434
-
435
- /**
436
- * Use `.toContainAnyKeys` when checking if an object contains at least one of the provided keys.
437
- *
438
- * @param {Array.<String>} keys
439
- */
440
- toContainAnyKeys(keys: string[]): void,
441
-
442
- /**
443
- * Use `.toContainValue` when checking if an object contains the provided value.
444
- *
445
- * @param {*} value
446
- */
447
- toContainValue(value: any): void,
448
-
449
- /**
450
- * Use `.toContainValues` when checking if an object contains all of the provided values.
451
- *
452
- * @param {Array.<*>} values
453
- */
454
- toContainValues(values: any[]): void,
455
-
456
- /**
457
- * Use `.toContainAllValues` when checking if an object only contains all of the provided values.
458
- *
459
- * @param {Array.<*>} values
460
- */
461
- toContainAllValues(values: any[]): void,
462
-
463
- /**
464
- * Use `.toContainAnyValues` when checking if an object contains at least one of the provided values.
465
- *
466
- * @param {Array.<*>} values
467
- */
468
- toContainAnyValues(values: any[]): void,
469
-
470
- /**
471
- * Use `.toContainEntry` when checking if an object contains the provided entry.
472
- *
473
- * @param {Array.<String, String>} entry
474
- */
475
- toContainEntry(entry: [string, string]): void,
476
-
477
- /**
478
- * Use `.toContainEntries` when checking if an object contains all of the provided entries.
479
- *
480
- * @param {Array.<Array.<String, String>>} entries
481
- */
482
- toContainEntries(entries: [string, string][]): void,
483
-
484
- /**
485
- * Use `.toContainAllEntries` when checking if an object only contains all of the provided entries.
486
- *
487
- * @param {Array.<Array.<String, String>>} entries
488
- */
489
- toContainAllEntries(entries: [string, string][]): void,
490
-
491
- /**
492
- * Use `.toContainAnyEntries` when checking if an object contains at least one of the provided entries.
493
- *
494
- * @param {Array.<Array.<String, String>>} entries
495
- */
496
- toContainAnyEntries(entries: [string, string][]): void,
497
-
498
- /**
499
- * Use `.toBeExtensible` when checking if an object is extensible.
500
- */
501
- toBeExtensible(): void,
502
-
503
- /**
504
- * Use `.toBeFrozen` when checking if an object is frozen.
505
- */
506
- toBeFrozen(): void,
507
-
508
- /**
509
- * Use `.toBeSealed` when checking if an object is sealed.
510
- */
511
- toBeSealed(): void,
512
-
513
- /**
514
- * Use `.toBeString` when checking if a value is a `String`.
515
- */
516
- toBeString(): void,
517
-
518
- /**
519
- * Use `.toEqualCaseInsensitive` when checking if a string is equal (===) to another ignoring the casing of both strings.
520
- *
521
- * @param {String} string
522
- */
523
- toEqualCaseInsensitive(string: string): void,
524
-
525
- /**
526
- * Use `.toStartWith` when checking if a `String` starts with a given `String` prefix.
527
- *
528
- * @param {String} prefix
529
- */
530
- toStartWith(prefix: string): void,
531
-
532
- /**
533
- * Use `.toEndWith` when checking if a `String` ends with a given `String` suffix.
534
- *
535
- * @param {String} suffix
536
- */
537
- toEndWith(suffix: string): void,
538
-
539
- /**
540
- * Use `.toInclude` when checking if a `String` includes the given `String` substring.
541
- *
542
- * @param {String} substring
543
- */
544
- toInclude(substring: string): void,
545
-
546
- /**
547
- * Use `.toIncludeRepeated` when checking if a `String` includes the given `String` substring the correct number of times.
548
- *
549
- * @param {String} substring
550
- * @param {Number} times
551
- */
552
- toIncludeRepeated(substring: string, times: number): void,
553
-
554
- /**
555
- * Use `.toIncludeMultiple` when checking if a `String` includes all of the given substrings.
556
- *
557
- * @param {Array.<String>} substring
558
- */
559
- toIncludeMultiple(substring: string[]): void,
560
-};
561
-
562
-interface JestExpectType {
563
- not: JestExpectType &
564
- EnzymeMatchersType &
565
- DomTestingLibraryType &
566
- JestJQueryMatchersType &
567
- JestStyledComponentsMatchersType &
568
- JestExtendedMatchersType;
569
- /**
570
- * If you have a mock function, you can use .lastCalledWith to test what
571
- * arguments it was last called with.
572
- */
573
- lastCalledWith(...args: Array<any>): void;
574
- /**
575
- * toBe just checks that a value is what you expect. It uses === to check
576
- * strict equality.
577
- */
578
- toBe(value: any): void;
579
- /**
580
- * Use .toBeCalledWith to ensure that a mock function was called with
581
- * specific arguments.
582
- */
583
- toBeCalledWith(...args: Array<any>): void;
584
- /**
585
- * Using exact equality with floating point numbers is a bad idea. Rounding
586
- * means that intuitive things fail.
587
- */
588
- toBeCloseTo(num: number, delta: any): void;
589
- /**
590
- * Use .toBeDefined to check that a variable is not undefined.
591
- */
592
- toBeDefined(): void;
593
- /**
594
- * Use .toBeFalsy when you don't care what a value is, you just want to
595
- * ensure a value is false in a boolean context.
596
- */
597
- toBeFalsy(): void;
598
- /**
599
- * To compare floating point numbers, you can use toBeGreaterThan.
600
- */
601
- toBeGreaterThan(number: number): void;
602
- /**
603
- * To compare floating point numbers, you can use toBeGreaterThanOrEqual.
604
- */
605
- toBeGreaterThanOrEqual(number: number): void;
606
- /**
607
- * To compare floating point numbers, you can use toBeLessThan.
608
- */
609
- toBeLessThan(number: number): void;
610
- /**
611
- * To compare floating point numbers, you can use toBeLessThanOrEqual.
612
- */
613
- toBeLessThanOrEqual(number: number): void;
614
- /**
615
- * Use .toBeInstanceOf(Class) to check that an object is an instance of a
616
- * class.
617
- */
618
- toBeInstanceOf(cls: Class<*>): void;
619
- /**
620
- * .toBeNull() is the same as .toBe(null) but the error messages are a bit
621
- * nicer.
622
- */
623
- toBeNull(): void;
624
- /**
625
- * Use .toBeTruthy when you don't care what a value is, you just want to
626
- * ensure a value is true in a boolean context.
627
- */
628
- toBeTruthy(): void;
629
- /**
630
- * Use .toBeUndefined to check that a variable is undefined.
631
- */
632
- toBeUndefined(): void;
633
- /**
634
- * Use .toContain when you want to check that an item is in a list. For
635
- * testing the items in the list, this uses ===, a strict equality check.
636
- */
637
- toContain(item: any): void;
638
- /**
639
- * Use .toContainEqual when you want to check that an item is in a list. For
640
- * testing the items in the list, this matcher recursively checks the
641
- * equality of all fields, rather than checking for object identity.
642
- */
643
- toContainEqual(item: any): void;
644
- /**
645
- * Use .toEqual when you want to check that two objects have the same value.
646
- * This matcher recursively checks the equality of all fields, rather than
647
- * checking for object identity.
648
- */
649
- toEqual(value: any): void;
650
- /**
651
- * Use .toHaveBeenCalled to ensure that a mock function got called.
652
- */
653
- toHaveBeenCalled(): void;
654
- toBeCalled(): void;
655
- /**
656
- * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact
657
- * number of times.
658
- */
659
- toHaveBeenCalledTimes(number: number): void;
660
- toBeCalledTimes(number: number): void;
661
- /**
662
- *
663
- */
664
- toHaveBeenNthCalledWith(nthCall: number, ...args: Array<any>): void;
665
- nthCalledWith(nthCall: number, ...args: Array<any>): void;
666
- /**
667
- *
668
- */
669
- toHaveReturned(): void;
670
- toReturn(): void;
671
- /**
672
- *
673
- */
674
- toHaveReturnedTimes(number: number): void;
675
- toReturnTimes(number: number): void;
676
- /**
677
- *
678
- */
679
- toHaveReturnedWith(value: any): void;
680
- toReturnWith(value: any): void;
681
- /**
682
- *
683
- */
684
- toHaveLastReturnedWith(value: any): void;
685
- lastReturnedWith(value: any): void;
686
- /**
687
- *
688
- */
689
- toHaveNthReturnedWith(nthCall: number, value: any): void;
690
- nthReturnedWith(nthCall: number, value: any): void;
691
- /**
692
- * Use .toHaveBeenCalledWith to ensure that a mock function was called with
693
- * specific arguments.
694
- */
695
- toHaveBeenCalledWith(...args: Array<any>): void;
696
- toBeCalledWith(...args: Array<any>): void;
697
- /**
698
- * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called
699
- * with specific arguments.
700
- */
701
- toHaveBeenLastCalledWith(...args: Array<any>): void;
702
- lastCalledWith(...args: Array<any>): void;
703
- /**
704
- * Check that an object has a .length property and it is set to a certain
705
- * numeric value.
706
- */
707
- toHaveLength(number: number): void;
708
- /**
709
- *
710
- */
711
- toHaveProperty(propPath: string, value?: any): void;
712
- /**
713
- * Use .toMatch to check that a string matches a regular expression or string.
714
- */
715
- toMatch(regexpOrString: RegExp | string): void;
716
- /**
717
- * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object.
718
- */
719
- toMatchObject(object: Object | Array<Object>): void;
720
- /**
721
- * Use .toStrictEqual to check that a javascript object matches a subset of the properties of an object.
722
- */
723
- toStrictEqual(value: any): void;
724
- /**
725
- * This ensures that an Object matches the most recent snapshot.
726
- */
727
- toMatchSnapshot(propertyMatchers?: any, name?: string): void;
728
- /**
729
- * This ensures that an Object matches the most recent snapshot.
730
- */
731
- toMatchSnapshot(name: string): void;
732
-
733
- toMatchInlineSnapshot(snapshot?: string): void;
734
- toMatchInlineSnapshot(propertyMatchers?: any, snapshot?: string): void;
735
- /**
736
- * Use .toThrow to test that a function throws when it is called.
737
- * If you want to test that a specific error gets thrown, you can provide an
738
- * argument to toThrow. The argument can be a string for the error message,
739
- * a class for the error, or a regex that should match the error.
740
- *
741
- * Alias: .toThrowError
742
- */
743
- toThrow(message?: string | Error | Class<Error> | RegExp): void;
744
- toThrowError(message?: string | Error | Class<Error> | RegExp): void;
745
- /**
746
- * Use .toThrowErrorMatchingSnapshot to test that a function throws a error
747
- * matching the most recent snapshot when it is called.
748
- */
749
- toThrowErrorMatchingSnapshot(): void;
750
- toThrowErrorMatchingInlineSnapshot(snapshot?: string): void;
751
-}
752
-
753
-type JestObjectType = {
754
- /**
755
- * Disables automatic mocking in the module loader.
756
- *
757
- * After this method is called, all `require()`s will return the real
758
- * versions of each module (rather than a mocked version).
759
- */
760
- disableAutomock(): JestObjectType,
761
- /**
762
- * An un-hoisted version of disableAutomock
763
- */
764
- autoMockOff(): JestObjectType,
765
- /**
766
- * Enables automatic mocking in the module loader.
767
- */
768
- enableAutomock(): JestObjectType,
769
- /**
770
- * An un-hoisted version of enableAutomock
771
- */
772
- autoMockOn(): JestObjectType,
773
- /**
774
- * Clears the mock.calls and mock.instances properties of all mocks.
775
- * Equivalent to calling .mockClear() on every mocked function.
776
- */
777
- clearAllMocks(): JestObjectType,
778
- /**
779
- * Resets the state of all mocks. Equivalent to calling .mockReset() on every
780
- * mocked function.
781
- */
782
- resetAllMocks(): JestObjectType,
783
- /**
784
- * Restores all mocks back to their original value.
785
- */
786
- restoreAllMocks(): JestObjectType,
787
- /**
788
- * Removes any pending timers from the timer system.
789
- */
790
- clearAllTimers(): void,
791
- /**
792
- * Returns the number of fake timers still left to run.
793
- */
794
- getTimerCount(): number,
795
- /**
796
- * The same as `mock` but not moved to the top of the expectation by
797
- * babel-jest.
798
- */
799
- doMock(moduleName: string, moduleFactory?: any): JestObjectType,
800
- /**
801
- * The same as `unmock` but not moved to the top of the expectation by
802
- * babel-jest.
803
- */
804
- dontMock(moduleName: string): JestObjectType,
805
- /**
806
- * Returns a new, unused mock function. Optionally takes a mock
807
- * implementation.
808
- */
809
- fn<TArguments: $ReadOnlyArray<*>, TReturn>(
810
- implementation?: (...args: TArguments) => TReturn
811
- ): JestMockFn<TArguments, TReturn>,
812
- /**
813
- * Determines if the given function is a mocked function.
814
- */
815
- isMockFunction(fn: Function): boolean,
816
- /**
817
- * Given the name of a module, use the automatic mocking system to generate a
818
- * mocked version of the module for you.
819
- */
820
- genMockFromModule(moduleName: string): any,
821
- /**
822
- * Mocks a module with an auto-mocked version when it is being required.
823
- *
824
- * The second argument can be used to specify an explicit module factory that
825
- * is being run instead of using Jest's automocking feature.
826
- *
827
- * The third argument can be used to create virtual mocks -- mocks of modules
828
- * that don't exist anywhere in the system.
829
- */
830
- mock(
831
- moduleName: string,
832
- moduleFactory?: any,
833
- options?: Object
834
- ): JestObjectType,
835
- /**
836
- * Returns the actual module instead of a mock, bypassing all checks on
837
- * whether the module should receive a mock implementation or not.
838
- */
839
- requireActual(moduleName: string): any,
840
- /**
841
- * Returns a mock module instead of the actual module, bypassing all checks
842
- * on whether the module should be required normally or not.
843
- */
844
- requireMock(moduleName: string): any,
845
- /**
846
- * Resets the module registry - the cache of all required modules. This is
847
- * useful to isolate modules where local state might conflict between tests.
848
- */
849
- resetModules(): JestObjectType,
850
-
851
- /**
852
- * Creates a sandbox registry for the modules that are loaded inside the
853
- * callback function. This is useful to isolate specific modules for every
854
- * test so that local module state doesn't conflict between tests.
855
- */
856
- isolateModules(fn: () => void): JestObjectType,
857
-
858
- /**
859
- * Exhausts the micro-task queue (usually interfaced in node via
860
- * process.nextTick).
861
- */
862
- runAllTicks(): void,
863
- /**
864
- * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(),
865
- * setInterval(), and setImmediate()).
866
- */
867
- runAllTimers(): void,
868
- /**
869
- * Exhausts all tasks queued by setImmediate().
870
- */
871
- runAllImmediates(): void,
872
- /**
873
- * Executes only the macro task queue (i.e. all tasks queued by setTimeout()
874
- * or setInterval() and setImmediate()).
875
- */
876
- advanceTimersByTime(msToRun: number): void,
877
- /**
878
- * Executes only the macro task queue (i.e. all tasks queued by setTimeout()
879
- * or setInterval() and setImmediate()).
880
- *
881
- * Renamed to `advanceTimersByTime`.
882
- */
883
- runTimersToTime(msToRun: number): void,
884
- /**
885
- * Executes only the macro-tasks that are currently pending (i.e., only the
886
- * tasks that have been queued by setTimeout() or setInterval() up to this
887
- * point)
888
- */
889
- runOnlyPendingTimers(): void,
890
- /**
891
- * Explicitly supplies the mock object that the module system should return
892
- * for the specified module. Note: It is recommended to use jest.mock()
893
- * instead.
894
- */
895
- setMock(moduleName: string, moduleExports: any): JestObjectType,
896
- /**
897
- * Indicates that the module system should never return a mocked version of
898
- * the specified module from require() (e.g. that it should always return the
899
- * real module).
900
- */
901
- unmock(moduleName: string): JestObjectType,
902
- /**
903
- * Instructs Jest to use fake versions of the standard timer functions
904
- * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick,
905
- * setImmediate and clearImmediate).
906
- */
907
- useFakeTimers(): JestObjectType,
908
- /**
909
- * Instructs Jest to use the real versions of the standard timer functions.
910
- */
911
- useRealTimers(): JestObjectType,
912
- /**
913
- * Creates a mock function similar to jest.fn but also tracks calls to
914
- * object[methodName].
915
- */
916
- spyOn(
917
- object: Object,
918
- methodName: string,
919
- accessType?: 'get' | 'set'
920
- ): JestMockFn<any, any>,
921
- /**
922
- * Set the default timeout interval for tests and before/after hooks in milliseconds.
923
- * Note: The default timeout interval is 5 seconds if this method is not called.
924
- */
925
- setTimeout(timeout: number): JestObjectType,
926
-};
927
-
928
-type JestSpyType = {
929
- calls: JestCallsType,
930
-};
931
-
932
-/** Runs this function after every test inside this context */
933
-declare function afterEach(
934
- fn: (done: () => void) => ?Promise<mixed>,
935
- timeout?: number
936
-): void;
937
-/** Runs this function before every test inside this context */
938
-declare function beforeEach(
939
- fn: (done: () => void) => ?Promise<mixed>,
940
- timeout?: number
941
-): void;
942
-/** Runs this function after all tests have finished inside this context */
943
-declare function afterAll(
944
- fn: (done: () => void) => ?Promise<mixed>,
945
- timeout?: number
946
-): void;
947
-/** Runs this function before any tests have started inside this context */
948
-declare function beforeAll(
949
- fn: (done: () => void) => ?Promise<mixed>,
950
- timeout?: number
951
-): void;
952
-
953
-/** A context for grouping tests together */
954
-declare var describe: {
955
- /**
956
- * Creates a block that groups together several related tests in one "test suite"
957
- */
958
- (name: JestTestName, fn: () => void): void,
959
-
960
- /**
961
- * Only run this describe block
962
- */
963
- only(name: JestTestName, fn: () => void): void,
964
-
965
- /**
966
- * Skip running this describe block
967
- */
968
- skip(name: JestTestName, fn: () => void): void,
969
-
970
- /**
971
- * each runs this test against array of argument arrays per each run
972
- *
973
- * @param {table} table of Test
974
- */
975
- each(
976
- ...table: Array<Array<mixed> | mixed> | [Array<string>, string]
977
- ): (
978
- name: JestTestName,
979
- fn?: (...args: Array<any>) => ?Promise<mixed>,
980
- timeout?: number
981
- ) => void,
982
-};
983
-
984
-/** An individual test unit */
985
-declare var it: {
986
- /**
987
- * An individual test unit
988
- *
989
- * @param {JestTestName} Name of Test
990
- * @param {Function} Test
991
- * @param {number} Timeout for the test, in milliseconds.
992
- */
993
- (
994
- name: JestTestName,
995
- fn?: (done: () => void) => ?Promise<mixed>,
996
- timeout?: number
997
- ): void,
998
-
999
- /**
1000
- * Only run this test
1001
- *
1002
- * @param {JestTestName} Name of Test
1003
- * @param {Function} Test
1004
- * @param {number} Timeout for the test, in milliseconds.
1005
- */
1006
- only(
1007
- name: JestTestName,
1008
- fn?: (done: () => void) => ?Promise<mixed>,
1009
- timeout?: number
1010
- ): {
1011
- each(
1012
- ...table: Array<Array<mixed> | mixed> | [Array<string>, string]
1013
- ): (
1014
- name: JestTestName,
1015
- fn?: (...args: Array<any>) => ?Promise<mixed>,
1016
- timeout?: number
1017
- ) => void,
1018
- },
1019
-
1020
- /**
1021
- * Skip running this test
1022
- *
1023
- * @param {JestTestName} Name of Test
1024
- * @param {Function} Test
1025
- * @param {number} Timeout for the test, in milliseconds.
1026
- */
1027
- skip(
1028
- name: JestTestName,
1029
- fn?: (done: () => void) => ?Promise<mixed>,
1030
- timeout?: number
1031
- ): void,
1032
-
1033
- /**
1034
- * Highlight planned tests in the summary output
1035
- *
1036
- * @param {String} Name of Test to do
1037
- */
1038
- todo(name: string): void,
1039
-
1040
- /**
1041
- * Run the test concurrently
1042
- *
1043
- * @param {JestTestName} Name of Test
1044
- * @param {Function} Test
1045
- * @param {number} Timeout for the test, in milliseconds.
1046
- */
1047
- concurrent(
1048
- name: JestTestName,
1049
- fn?: (done: () => void) => ?Promise<mixed>,
1050
- timeout?: number
1051
- ): void,
1052
-
1053
- /**
1054
- * each runs this test against array of argument arrays per each run
1055
- *
1056
- * @param {table} table of Test
1057
- */
1058
- each(
1059
- ...table: Array<Array<mixed> | mixed> | [Array<string>, string]
1060
- ): (
1061
- name: JestTestName,
1062
- fn?: (...args: Array<any>) => ?Promise<mixed>,
1063
- timeout?: number
1064
- ) => void,
1065
-};
1066
-
1067
-declare function fit(
1068
- name: JestTestName,
1069
- fn: (done: () => void) => ?Promise<mixed>,
1070
- timeout?: number
1071
-): void;
1072
-/** An individual test unit */
1073
-declare var test: typeof it;
1074
-/** A disabled group of tests */
1075
-declare var xdescribe: typeof describe;
1076
-/** A focused group of tests */
1077
-declare var fdescribe: typeof describe;
1078
-/** A disabled individual test */
1079
-declare var xit: typeof it;
1080
-/** A disabled individual test */
1081
-declare var xtest: typeof it;
1082
-
1083
-type JestPrettyFormatColors = {
1084
- comment: {close: string, open: string},
1085
- content: {close: string, open: string},
1086
- prop: {close: string, open: string},
1087
- tag: {close: string, open: string},
1088
- value: {close: string, open: string},
1089
-};
1090
-
1091
-type JestPrettyFormatIndent = string => string;
1092
-// eslint-disable-next-line no-unused-vars
1093
-type JestPrettyFormatRefs = Array<any>;
1094
-type JestPrettyFormatPrint = any => string;
1095
-// eslint-disable-next-line no-unused-vars
1096
-type JestPrettyFormatStringOrNull = string | null;
1097
-
1098
-type JestPrettyFormatOptions = {|
1099
- callToJSON: boolean,
1100
- edgeSpacing: string,
1101
- escapeRegex: boolean,
1102
- highlight: boolean,
1103
- indent: number,
1104
- maxDepth: number,
1105
- min: boolean,
1106
- // eslint-disable-next-line no-use-before-define
1107
- plugins: JestPrettyFormatPlugins,
1108
- printFunctionName: boolean,
1109
- spacing: string,
1110
- theme: {|
1111
- comment: string,
1112
- content: string,
1113
- prop: string,
1114
- tag: string,
1115
- value: string,
1116
- |},
1117
-|};
1118
-
1119
-type JestPrettyFormatPlugin = {
1120
- print: (
1121
- val: any,
1122
- serialize: JestPrettyFormatPrint,
1123
- indent: JestPrettyFormatIndent,
1124
- opts: JestPrettyFormatOptions,
1125
- colors: JestPrettyFormatColors
1126
- ) => string,
1127
- test: any => boolean,
1128
-};
1129
-
1130
-type JestPrettyFormatPlugins = Array<JestPrettyFormatPlugin>;
1131
-
1132
-/** The expect function is used every time you want to test a value */
1133
-declare var expect: {
1134
- /** The object that you want to make assertions against */
1135
- (
1136
- value: any
1137
- ): JestExpectType &
1138
- JestPromiseType &
1139
- EnzymeMatchersType &
1140
- DomTestingLibraryType &
1141
- JestJQueryMatchersType &
1142
- JestStyledComponentsMatchersType &
1143
- JestExtendedMatchersType,
1144
-
1145
- /** Add additional Jasmine matchers to Jest's roster */
1146
- extend(matchers: {[name: string]: JestMatcher}): void,
1147
- /** Add a module that formats application-specific data structures. */
1148
- addSnapshotSerializer(pluginModule: JestPrettyFormatPlugin): void,
1149
- assertions(expectedAssertions: number): void,
1150
- hasAssertions(): void,
1151
- any(value: mixed): JestAsymmetricEqualityType,
1152
- anything(): any,
1153
- arrayContaining(value: Array<mixed>): Array<mixed>,
1154
- objectContaining(value: Object): Object,
1155
- /** Matches any received string that contains the exact expected string. */
1156
- stringContaining(value: string): string,
1157
- stringMatching(value: string | RegExp): string,
1158
- not: {
1159
- arrayContaining: (value: $ReadOnlyArray<mixed>) => Array<mixed>,
1160
- objectContaining: (value: {}) => Object,
1161
- stringContaining: (value: string) => string,
1162
- stringMatching: (value: string | RegExp) => string,
1163
- },
1164
-};
1165
-
1166
-// TODO handle return type
1167
-// http://jasmine.github.io/2.4/introduction.html#section-Spies
1168
-declare function spyOn(value: mixed, method: string): Object;
1169
-
1170
-/** Holds all functions related to manipulating test runner */
1171
-declare var jest: JestObjectType;
1172
-
1173
-/**
1174
- * The global Jasmine object, this is generally not exposed as the public API,
1175
- * using features inside here could break in later versions of Jest.
1176
- */
1177
-declare var jasmine: {
1178
- DEFAULT_TIMEOUT_INTERVAL: number,
1179
- any(value: mixed): JestAsymmetricEqualityType,
1180
- anything(): any,
1181
- arrayContaining(value: Array<mixed>): Array<mixed>,
1182
- clock(): JestClockType,
1183
- createSpy(name: string): JestSpyType,
1184
- createSpyObj(
1185
- baseName: string,
1186
- methodNames: Array<string>
1187
- ): {[methodName: string]: JestSpyType},
1188
- objectContaining(value: Object): Object,
1189
- stringMatching(value: string): string,
1190
-};
packages/react-devtools-extensions/flow-typed/npm/react-test-renderer_v16.x.x.js
deleted
-84
@@ -1,84 +0,0 @@
1
-// flow-typed signature: b6bb53397d83d2d821e258cc73818d1b
2
-// flow-typed version: 9c71eca8ef/react-test-renderer_v16.x.x/flow_>=v0.47.x
3
-
4
-// Type definitions for react-test-renderer 16.x.x
5
-// Ported from: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-test-renderer
6
-
7
-'use strict';
8
-
9
-type ReactComponentInstance = React$Component<any>;
10
-
11
-type ReactTestRendererJSON = {
12
- type: string,
13
- props: {[propName: string]: any},
14
- children: null | ReactTestRendererJSON[],
15
-};
16
-
17
-type ReactTestRendererTree = ReactTestRendererJSON & {
18
- nodeType: 'component' | 'host',
19
- instance: ?ReactComponentInstance,
20
- rendered: null | ReactTestRendererTree,
21
-};
22
-
23
-type ReactTestInstance = {
24
- instance: ?ReactComponentInstance,
25
- type: string,
26
- props: {[propName: string]: any},
27
- parent: null | ReactTestInstance,
28
- children: Array<ReactTestInstance | string>,
29
-
30
- find(predicate: (node: ReactTestInstance) => boolean): ReactTestInstance,
31
- findByType(type: React$ElementType): ReactTestInstance,
32
- findByProps(props: {[propName: string]: any}): ReactTestInstance,
33
-
34
- findAll(
35
- predicate: (node: ReactTestInstance) => boolean,
36
- options?: {deep: boolean}
37
- ): ReactTestInstance[],
38
- findAllByType(
39
- type: React$ElementType,
40
- options?: {deep: boolean}
41
- ): ReactTestInstance[],
42
- findAllByProps(
43
- props: {[propName: string]: any},
44
- options?: {deep: boolean}
45
- ): ReactTestInstance[],
46
-};
47
-
48
-type TestRendererOptions = {
49
- createNodeMock(element: React$Element<any>): any,
50
-};
51
-
52
-declare module 'react-test-renderer' {
53
- // eslint-disable-next-line no-inner-declarations
54
- declare export type ReactTestRenderer = {
55
- toJSON(): null | ReactTestRendererJSON,
56
- toTree(): null | ReactTestRendererTree,
57
- unmount(nextElement?: React$Element<any>): void,
58
- update(nextElement: React$Element<any>): void,
59
- getInstance(): ?ReactComponentInstance,
60
- root: ReactTestInstance,
61
- };
62
-
63
- declare type Thenable = {
64
- then(resolve: () => mixed, reject?: () => mixed): mixed,
65
- };
66
-
67
- declare function create(
68
- nextElement: React$Element<any>,
69
- options?: TestRendererOptions
70
- ): ReactTestRenderer;
71
-
72
- declare function act(callback: () => ?Thenable): Thenable;
73
-}
74
-
75
-declare module 'react-test-renderer/shallow' {
76
- declare export default class ShallowRenderer {
77
- static createRenderer(): ShallowRenderer;
78
- getMountedInstance(): ReactTestInstance;
79
- getRenderOutput<E: React$Element<any>>(): E;
80
- getRenderOutput(): React$Element<any>;
81
- render(element: React$Element<any>, context?: any): void;
82
- unmount(): void;
83
- }
84
-}
packages/react-devtools-extensions/icons/128-deadcode.png
Binary files a/packages/react-devtools-extensions/icons/128-deadcode.png and /dev/null differ
packages/react-devtools-extensions/icons/128-development.png
Binary files a/packages/react-devtools-extensions/icons/128-development.png and /dev/null differ
packages/react-devtools-extensions/icons/128-disabled.png
Binary files a/packages/react-devtools-extensions/icons/128-disabled.png and /dev/null differ
packages/react-devtools-extensions/icons/128-outdated.png
Binary files a/packages/react-devtools-extensions/icons/128-outdated.png and /dev/null differ
packages/react-devtools-extensions/icons/128-production.png
Binary files a/packages/react-devtools-extensions/icons/128-production.png and /dev/null differ
packages/react-devtools-extensions/icons/128-unminified.png
Binary files a/packages/react-devtools-extensions/icons/128-unminified.png and /dev/null differ
packages/react-devtools-extensions/icons/16-deadcode.png
Binary files a/packages/react-devtools-extensions/icons/16-deadcode.png and /dev/null differ
packages/react-devtools-extensions/icons/16-development.png
Binary files a/packages/react-devtools-extensions/icons/16-development.png and /dev/null differ
packages/react-devtools-extensions/icons/16-disabled.png
Binary files a/packages/react-devtools-extensions/icons/16-disabled.png and /dev/null differ
packages/react-devtools-extensions/icons/16-outdated.png
Binary files a/packages/react-devtools-extensions/icons/16-outdated.png and /dev/null differ
packages/react-devtools-extensions/icons/16-production.png
Binary files a/packages/react-devtools-extensions/icons/16-production.png and /dev/null differ
packages/react-devtools-extensions/icons/16-unminified.png
Binary files a/packages/react-devtools-extensions/icons/16-unminified.png and /dev/null differ
packages/react-devtools-extensions/icons/32-deadcode.png
Binary files a/packages/react-devtools-extensions/icons/32-deadcode.png and /dev/null differ
packages/react-devtools-extensions/icons/32-development.png
Binary files a/packages/react-devtools-extensions/icons/32-development.png and /dev/null differ
packages/react-devtools-extensions/icons/32-disabled.png
Binary files a/packages/react-devtools-extensions/icons/32-disabled.png and /dev/null differ
packages/react-devtools-extensions/icons/32-outdated.png
Binary files a/packages/react-devtools-extensions/icons/32-outdated.png and /dev/null differ
packages/react-devtools-extensions/icons/32-production.png
Binary files a/packages/react-devtools-extensions/icons/32-production.png and /dev/null differ
packages/react-devtools-extensions/icons/32-unminified.png
Binary files a/packages/react-devtools-extensions/icons/32-unminified.png and /dev/null differ
packages/react-devtools-extensions/icons/48-deadcode.png
Binary files a/packages/react-devtools-extensions/icons/48-deadcode.png and /dev/null differ
packages/react-devtools-extensions/icons/48-development.png
Binary files a/packages/react-devtools-extensions/icons/48-development.png and /dev/null differ
packages/react-devtools-extensions/icons/48-disabled.png
Binary files a/packages/react-devtools-extensions/icons/48-disabled.png and /dev/null differ
packages/react-devtools-extensions/icons/48-outdated.png
Binary files a/packages/react-devtools-extensions/icons/48-outdated.png and /dev/null differ
packages/react-devtools-extensions/icons/48-production.png
Binary files a/packages/react-devtools-extensions/icons/48-production.png and /dev/null differ
packages/react-devtools-extensions/icons/48-unminified.png
Binary files a/packages/react-devtools-extensions/icons/48-unminified.png and /dev/null differ
packages/react-devtools-extensions/icons/deadcode.svg
deleted
-1
@@ -1 +0,0 @@
1
-<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>
\ No newline at end of file
packages/react-devtools-extensions/icons/development.svg
deleted
-1
@@ -1 +0,0 @@
1
-<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>
\ No newline at end of file
packages/react-devtools-extensions/icons/disabled.svg
deleted
-1
@@ -1 +0,0 @@
1
-<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>
\ No newline at end of file
packages/react-devtools-extensions/icons/outdated.svg
deleted
-1
@@ -1 +0,0 @@
1
-<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>
\ No newline at end of file
packages/react-devtools-extensions/icons/production.svg
deleted
-1
@@ -1 +0,0 @@
1
-<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>
\ No newline at end of file
packages/react-devtools-extensions/main.html
deleted
-9
@@ -1,9 +0,0 @@
1
-<!doctype html>
2
-<html>
3
- <head>
4
- <meta charset="utf-8">
5
- <script src="./build/main.js"></script>
6
- </head>
7
- <body>
8
- </body>
9
-</html>
packages/react-devtools-extensions/package.json
deleted
-43
@@ -1,43 +0,0 @@
1
-{
2
-
3
- "name": "react-devtools-extensions",
4
- "version": "0.0.0",
5
- "private": true,
6
- "scripts": {
7
- "build": "cross-env NODE_ENV=production yarn run build:chrome && yarn run build:firefox",
8
- "build:dev": "cross-env NODE_ENV=development yarn run build:chrome && yarn run build:firefox",
9
- "build:chrome": "cross-env NODE_ENV=production node ./chrome/build",
10
- "build:chrome:crx": "cross-env NODE_ENV=production node ./chrome/build --crx",
11
- "build:chrome:dev": "cross-env NODE_ENV=development node ./chrome/build",
12
- "build:firefox": "cross-env NODE_ENV=production node ./firefox/build",
13
- "build:firefox:dev": "cross-env NODE_ENV=development node ./firefox/build",
14
- "test:chrome": "node ./chrome/test",
15
- "test:firefox": "node ./firefox/test"
16
- },
17
- "devDependencies": {
18
- "@babel/core": "^7.1.6",
19
- "@babel/plugin-proposal-class-properties": "^7.1.0",
20
- "@babel/plugin-transform-flow-strip-types": "^7.1.6",
21
- "@babel/plugin-transform-react-jsx-source": "^7.2.0",
22
- "@babel/preset-env": "^7.1.6",
23
- "@babel/preset-flow": "^7.0.0",
24
- "@babel/preset-react": "^7.0.0",
25
- "archiver": "^3.0.0",
26
- "babel-core": "^7.0.0-bridge",
27
- "babel-eslint": "^9.0.0",
28
- "babel-jest": "^24.7.1",
29
- "babel-loader": "^8.0.4",
30
- "chrome-launch": "^1.1.4",
31
- "child-process-promise": "^2.2.1",
32
- "css-loader": "^1.0.1",
33
- "firefox-profile": "^1.0.2",
34
- "node-libs-browser": "0.5.3",
35
- "nullthrows": "^1.0.0",
36
- "raw-loader": "^3.1.0",
37
- "style-loader": "^0.23.1",
38
- "web-ext": "^3.0.0",
39
- "webpack": "^4.26.0",
40
- "webpack-cli": "^3.1.2",
41
- "webpack-dev-server": "^3.3.1"
42
- }
43
-}
packages/react-devtools-extensions/panel.html
deleted
-32
@@ -1,32 +0,0 @@
1
-<!doctype html>
2
-<html style="display: flex">
3
- <head>
4
- <meta charset="utf8">
5
- <style>
6
- html {
7
- display: flex;
8
- }
9
- body {
10
- margin: 0;
11
- padding: 0;
12
- flex: 1;
13
- display: flex;
14
- }
15
- #container {
16
- display: flex;
17
- flex: 1;
18
- width: 100%;
19
- position: fixed;
20
- top: 0;
21
- left: 0;
22
- right: 0;
23
- bottom: 0;
24
- }
25
- </style>
26
- </head>
27
- <body>
28
- <!-- main react mount point -->
29
- <div id="container">Unable to find React on the page.</div>
30
- <script src="./build/panel.js"></script>
31
- </body>
32
-</html>
packages/react-devtools-extensions/popups/deadcode.html
deleted
-32
@@ -1,32 +0,0 @@
1
-<script src="shared.js"></script>
2
-<style>
3
- html, body {
4
- font-size: 14px;
5
- min-width: 460px;
6
- min-height: 133px;
7
- }
8
-
9
- body {
10
- margin: 8px;
11
- }
12
-
13
- hr {
14
- width: 100%;
15
- }
16
-</style>
17
-<p>
18
- <b>This page includes an extra development build of React. 🚧</b>
19
-</p>
20
-<p>
21
- The React build on this page includes both development and production versions because dead code elimination has not been applied correctly.
22
- <br />
23
- <br />
24
- This makes its size larger, and causes React to run slower.
25
- <br />
26
- <br />
27
- 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.
28
-</p>
29
-<hr />
30
-<p>
31
- Open the developer tools, and "Components" and "Profiler" tabs will appear to the right.
32
-</p>
packages/react-devtools-extensions/popups/development.html
deleted
-28
@@ -1,28 +0,0 @@
1
-<script src="shared.js"></script>
2
-<style>
3
- html, body {
4
- font-size: 14px;
5
- min-width: 460px;
6
- min-height: 101px;
7
- }
8
-
9
- body {
10
- margin: 8px;
11
- }
12
-
13
- hr {
14
- width: 100%;
15
- }
16
-</style>
17
-<p>
18
- <b>This page is using the development build of React. 🚧</b>
19
-</p>
20
-<p>
21
- Note that the development build is not suitable for production.
22
- <br />
23
- 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.
24
-</p>
25
-<hr />
26
-<p>
27
- Open the developer tools, and "Components" and "Profiler" tabs will appear to the right.
28
-</p>
packages/react-devtools-extensions/popups/disabled.html
deleted
-21
@@ -1,21 +0,0 @@
1
-<script src="shared.js"></script>
2
-<style>
3
- html, body {
4
- font-size: 14px;
5
- min-width: 410px;
6
- min-height: 33px;
7
- }
8
-
9
- body {
10
- margin: 8px;
11
- }
12
-
13
- hr {
14
- width: 100%;
15
- }
16
-</style>
17
-<p>
18
- <b>This page doesn’t appear to be using React.</b>
19
- <br />
20
- 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>.
21
-</p>
packages/react-devtools-extensions/popups/outdated.html
deleted
-29
@@ -1,29 +0,0 @@
1
-<script src="shared.js"></script>
2
-<style>
3
- html, body {
4
- font-size: 14px;
5
- min-width: 460px;
6
- min-height: 117px;
7
- }
8
-
9
- body {
10
- margin: 8px;
11
- }
12
-
13
- hr {
14
- width: 100%;
15
- }
16
-</style>
17
-<p>
18
- <b>This page is using an outdated version of React. ⌛</b>
19
-</p>
20
-<p>
21
- We recommend updating React to ensure that you receive important bugfixes and performance improvements.
22
- <br />
23
- <br />
24
- You can find the upgrade instructions on the <a href="https://facebook.github.io/react/blog/">React blog</a>.
25
-</p>
26
-<hr />
27
-<p>
28
- Open the developer tools, and "Components" and "Profiler" tabs will appear to the right.
29
-</p>
packages/react-devtools-extensions/popups/production.html
deleted
-21
@@ -1,21 +0,0 @@
1
-<script src="shared.js"></script>
2
-<style>
3
- html, body {
4
- font-size: 14px;
5
- min-width: 460px;
6
- min-height: 39px;
7
- }
8
-
9
- body {
10
- margin: 8px;
11
- }
12
-
13
- hr {
14
- width: 100%;
15
- }
16
-</style>
17
-<p>
18
- <b>This page is using the production build of React. ✅</b>
19
- <br />
20
- Open the developer tools, and "Components" and "Profiler" tabs will appear to the right.
21
-</p>
packages/react-devtools-extensions/popups/shared.js
deleted
-24
@@ -1,24 +0,0 @@
1
-/* globals chrome */
2
-
3
-'use strict';
4
-
5
-document.addEventListener('DOMContentLoaded', function() {
6
- // Make links work
7
- const links = document.getElementsByTagName('a');
8
- for (let i = 0; i < links.length; i++) {
9
- (function() {
10
- const ln = links[i];
11
- const location = ln.href;
12
- ln.onclick = function() {
13
- chrome.tabs.create({active: true, url: location});
14
- };
15
- })();
16
- }
17
-
18
- // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=428044
19
- document.body.style.opacity = 0;
20
- document.body.style.transition = 'opacity ease-out .4s';
21
- requestAnimationFrame(function() {
22
- document.body.style.opacity = 1;
23
- });
24
-});
packages/react-devtools-extensions/popups/unminified.html
deleted
-31
@@ -1,31 +0,0 @@
1
-<script src="shared.js"></script>
2
-<style>
3
- html, body {
4
- font-size: 14px;
5
- min-width: 460px;
6
- min-height: 133px;
7
- }
8
-
9
- body {
10
- margin: 8px;
11
- }
12
-
13
- hr {
14
- width: 100%;
15
- }
16
-</style>
17
-<p>
18
- <b>This page is using an unminified build of React. 🚧</b>
19
-</p>
20
-<p>
21
- The React build on this page appears to be unminified.
22
- <br />
23
- This makes its size larger, and causes React to run slower.
24
- <br />
25
- <br />
26
- Make sure to <a href="https://facebook.github.io/react/docs/optimizing-performance.html#use-the-production-build">set up minification</a> before deployment.
27
-</p>
28
-<hr />
29
-<p>
30
- Open the developer tools, and "Components" and "Profiler" tabs will appear to the right.
31
-</p>
packages/react-devtools-extensions/src/backend.js
deleted
-79
@@ -1,79 +0,0 @@
1
-// Do not use imports or top-level requires here!
2
-// Running module factories is intentionally delayed until we know the hook exists.
3
-// This is to avoid issues like: https://github.com/facebook/react-devtools/issues/1039
4
-
5
-/** @flow */
6
-
7
-'use strict';
8
-
9
-function welcome(event) {
10
- if (
11
- event.source !== window ||
12
- event.data.source !== 'react-devtools-content-script'
13
- ) {
14
- return;
15
- }
16
-
17
- window.removeEventListener('message', welcome);
18
-
19
- setup(window.__REACT_DEVTOOLS_GLOBAL_HOOK__);
20
-}
21
-
22
-window.addEventListener('message', welcome);
23
-
24
-function setup(hook) {
25
- const Agent = require('react-devtools-shared/src/backend/agent').default;
26
- const Bridge = require('react-devtools-shared/src/bridge').default;
27
- const {initBackend} = require('react-devtools-shared/src/backend');
28
- const setupNativeStyleEditor = require('react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor')
29
- .default;
30
-
31
- const bridge = new Bridge({
32
- listen(fn) {
33
- const listener = event => {
34
- if (
35
- event.source !== window ||
36
- !event.data ||
37
- event.data.source !== 'react-devtools-content-script' ||
38
- !event.data.payload
39
- ) {
40
- return;
41
- }
42
- fn(event.data.payload);
43
- };
44
- window.addEventListener('message', listener);
45
- return () => {
46
- window.removeEventListener('message', listener);
47
- };
48
- },
49
- send(event: string, payload: any, transferable?: Array<any>) {
50
- window.postMessage(
51
- {
52
- source: 'react-devtools-bridge',
53
- payload: {event, payload},
54
- },
55
- '*',
56
- transferable,
57
- );
58
- },
59
- });
60
-
61
- const agent = new Agent(bridge);
62
- agent.addListener('shutdown', () => {
63
- // If we received 'shutdown' from `agent`, we assume the `bridge` is already shutting down,
64
- // and that caused the 'shutdown' event on the `agent`, so we don't need to call `bridge.shutdown()` here.
65
- hook.emit('shutdown');
66
- });
67
-
68
- initBackend(hook, agent, window);
69
-
70
- // Setup React Native style editor if a renderer like react-native-web has injected it.
71
- if (hook.resolveRNStyle) {
72
- setupNativeStyleEditor(
73
- bridge,
74
- agent,
75
- hook.resolveRNStyle,
76
- hook.nativeStyleEditorValidAttributes,
77
- );
78
- }
79
-}
packages/react-devtools-extensions/src/background.js
deleted
-115
@@ -1,115 +0,0 @@
1
-/* global chrome */
2
-
3
-'use strict';
4
-
5
-const ports = {};
6
-
7
-const IS_FIREFOX = navigator.userAgent.indexOf('Firefox') >= 0;
8
-
9
-chrome.runtime.onConnect.addListener(function(port) {
10
- let tab = null;
11
- let name = null;
12
- if (isNumeric(port.name)) {
13
- tab = port.name;
14
- name = 'devtools';
15
- installContentScript(+port.name);
16
- } else {
17
- tab = port.sender.tab.id;
18
- name = 'content-script';
19
- }
20
-
21
- if (!ports[tab]) {
22
- ports[tab] = {
23
- devtools: null,
24
- 'content-script': null,
25
- };
26
- }
27
- ports[tab][name] = port;
28
-
29
- if (ports[tab].devtools && ports[tab]['content-script']) {
30
- doublePipe(ports[tab].devtools, ports[tab]['content-script']);
31
- }
32
-});
33
-
34
-function isNumeric(str: string): boolean {
35
- return +str + '' === str;
36
-}
37
-
38
-function installContentScript(tabId: number) {
39
- chrome.tabs.executeScript(
40
- tabId,
41
- {file: '/build/contentScript.js'},
42
- function() {},
43
- );
44
-}
45
-
46
-function doublePipe(one, two) {
47
- one.onMessage.addListener(lOne);
48
- function lOne(message) {
49
- two.postMessage(message);
50
- }
51
- two.onMessage.addListener(lTwo);
52
- function lTwo(message) {
53
- one.postMessage(message);
54
- }
55
- function shutdown() {
56
- one.onMessage.removeListener(lOne);
57
- two.onMessage.removeListener(lTwo);
58
- one.disconnect();
59
- two.disconnect();
60
- }
61
- one.onDisconnect.addListener(shutdown);
62
- two.onDisconnect.addListener(shutdown);
63
-}
64
-
65
-function setIconAndPopup(reactBuildType, tabId) {
66
- chrome.browserAction.setIcon({
67
- tabId: tabId,
68
- path: {
69
- '16': 'icons/16-' + reactBuildType + '.png',
70
- '32': 'icons/32-' + reactBuildType + '.png',
71
- '48': 'icons/48-' + reactBuildType + '.png',
72
- '128': 'icons/128-' + reactBuildType + '.png',
73
- },
74
- });
75
- chrome.browserAction.setPopup({
76
- tabId: tabId,
77
- popup: 'popups/' + reactBuildType + '.html',
78
- });
79
-}
80
-
81
-// Listen to URL changes on the active tab and reset the DevTools icon.
82
-// This prevents non-disabled icons from sticking in Firefox.
83
-// Don't listen to this event in Chrome though.
84
-// It fires more frequently, often after onMessage() has been called.
85
-if (IS_FIREFOX) {
86
- chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
87
- if (tab.active && changeInfo.status === 'loading') {
88
- setIconAndPopup('disabled', tabId);
89
- }
90
- });
91
-}
92
-
93
-chrome.runtime.onMessage.addListener((request, sender) => {
94
- if (sender.tab) {
95
- // This is sent from the hook content script.
96
- // It tells us a renderer has attached.
97
- if (request.hasDetectedReact) {
98
- // We use browserAction instead of pageAction because this lets us
99
- // display a custom default popup when React is *not* detected.
100
- // It is specified in the manifest.
101
- let reactBuildType = request.reactBuildType;
102
- if (sender.url.indexOf('facebook.github.io/react') !== -1) {
103
- // Cheat: We use the development version on the website because
104
- // it is better for interactive examples. However we're going
105
- // to get misguided bug reports if the extension highlights it
106
- // as using the dev version. We're just going to special case
107
- // our own documentation and cheat. It is acceptable to use dev
108
- // version of React in React docs, but not in any other case.
109
- reactBuildType = 'production';
110
- }
111
-
112
- setIconAndPopup(reactBuildType, sender.tab.id);
113
- }
114
- }
115
-});
packages/react-devtools-extensions/src/contentScript.js
deleted
-79
@@ -1,79 +0,0 @@
1
-/* global chrome */
2
-
3
-'use strict';
4
-
5
-let backendDisconnected: boolean = false;
6
-let backendInitialized: boolean = false;
7
-
8
-function sayHelloToBackend() {
9
- window.postMessage(
10
- {
11
- source: 'react-devtools-content-script',
12
- hello: true,
13
- },
14
- '*',
15
- );
16
-}
17
-
18
-function handleMessageFromDevtools(message) {
19
- window.postMessage(
20
- {
21
- source: 'react-devtools-content-script',
22
- payload: message,
23
- },
24
- '*',
25
- );
26
-}
27
-
28
-function handleMessageFromPage(evt) {
29
- if (
30
- evt.source === window &&
31
- evt.data &&
32
- evt.data.source === 'react-devtools-bridge'
33
- ) {
34
- backendInitialized = true;
35
-
36
- port.postMessage(evt.data.payload);
37
- }
38
-}
39
-
40
-function handleDisconnect() {
41
- backendDisconnected = true;
42
-
43
- window.removeEventListener('message', handleMessageFromPage);
44
-
45
- window.postMessage(
46
- {
47
- source: 'react-devtools-content-script',
48
- payload: {
49
- type: 'event',
50
- event: 'shutdown',
51
- },
52
- },
53
- '*',
54
- );
55
-}
56
-
57
-// proxy from main page to devtools (via the background page)
58
-const port = chrome.runtime.connect({
59
- name: 'content-script',
60
-});
61
-port.onMessage.addListener(handleMessageFromDevtools);
62
-port.onDisconnect.addListener(handleDisconnect);
63
-
64
-window.addEventListener('message', handleMessageFromPage);
65
-
66
-sayHelloToBackend();
67
-
68
-// The backend waits to install the global hook until notified by the content script.
69
-// In the event of a page reload, the content script might be loaded before the backend is injected.
70
-// Because of this we need to poll the backend until it has been initialized.
71
-if (!backendInitialized) {
72
- const intervalID = setInterval(() => {
73
- if (backendInitialized || backendDisconnected) {
74
- clearInterval(intervalID);
75
- } else {
76
- sayHelloToBackend();
77
- }
78
- }, 500);
79
-}
packages/react-devtools-extensions/src/inject.js
deleted
-24
@@ -1,24 +0,0 @@
1
-/* global chrome */
2
-
3
-export default function inject(scriptName: string, done: ?Function) {
4
- const source = `
5
- // the prototype stuff is in case document.createElement has been modified
6
- (function () {
7
- var script = document.constructor.prototype.createElement.call(document, 'script');
8
- script.src = "${scriptName}";
9
- script.charset = "utf-8";
10
- document.documentElement.appendChild(script);
11
- script.parentNode.removeChild(script);
12
- })()
13
- `;
14
-
15
- chrome.devtools.inspectedWindow.eval(source, function(response, error) {
16
- if (error) {
17
- console.log(error);
18
- }
19
-
20
- if (typeof done === 'function') {
21
- done();
22
- }
23
- });
24
-}
packages/react-devtools-extensions/src/injectGlobalHook.js
deleted
-89
@@ -1,89 +0,0 @@
1
-/* global chrome */
2
-
3
-import nullthrows from 'nullthrows';
4
-import {installHook} from 'react-devtools-shared/src/hook';
5
-import {SESSION_STORAGE_RELOAD_AND_PROFILE_KEY} from 'react-devtools-shared/src/constants';
6
-import {sessionStorageGetItem} from 'react-devtools-shared/src/storage';
7
-
8
-function injectCode(code) {
9
- const script = document.createElement('script');
10
- script.textContent = code;
11
-
12
- // This script runs before the <head> element is created,
13
- // so we add the script to <html> instead.
14
- nullthrows(document.documentElement).appendChild(script);
15
- nullthrows(script.parentNode).removeChild(script);
16
-}
17
-
18
-let lastDetectionResult;
19
-
20
-// We want to detect when a renderer attaches, and notify the "background page"
21
-// (which is shared between tabs and can highlight the React icon).
22
-// Currently we are in "content script" context, so we can't listen to the hook directly
23
-// (it will be injected directly into the page).
24
-// So instead, the hook will use postMessage() to pass message to us here.
25
-// And when this happens, we'll send a message to the "background page".
26
-window.addEventListener('message', function(evt) {
27
- if (
28
- evt.source === window &&
29
- evt.data &&
30
- evt.data.source === 'react-devtools-detector'
31
- ) {
32
- lastDetectionResult = {
33
- hasDetectedReact: true,
34
- reactBuildType: evt.data.reactBuildType,
35
- };
36
- chrome.runtime.sendMessage(lastDetectionResult);
37
- }
38
-});
39
-
40
-// NOTE: Firefox WebExtensions content scripts are still alive and not re-injected
41
-// while navigating the history to a document that has not been destroyed yet,
42
-// replay the last detection result if the content script is active and the
43
-// document has been hidden and shown again.
44
-window.addEventListener('pageshow', function(evt) {
45
- if (!lastDetectionResult || evt.target !== window.document) {
46
- return;
47
- }
48
- chrome.runtime.sendMessage(lastDetectionResult);
49
-});
50
-
51
-const detectReact = `
52
-window.__REACT_DEVTOOLS_GLOBAL_HOOK__.on('renderer', function(evt) {
53
- window.postMessage({
54
- source: 'react-devtools-detector',
55
- reactBuildType: evt.reactBuildType,
56
- }, '*');
57
-});
58
-`;
59
-const saveNativeValues = `
60
-window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeObjectCreate = Object.create;
61
-window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeMap = Map;
62
-window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeWeakMap = WeakMap;
63
-window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeSet = Set;
64
-`;
65
-
66
-// If we have just reloaded to profile, we need to inject the renderer interface before the app loads.
67
-if (sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true') {
68
- const rendererURL = chrome.runtime.getURL('build/renderer.js');
69
- let rendererCode;
70
-
71
- // We need to inject in time to catch the initial mount.
72
- // This means we need to synchronously read the renderer code itself,
73
- // and synchronously inject it into the page.
74
- // There are very few ways to actually do this.
75
- // This seems to be the best approach.
76
- const request = new XMLHttpRequest();
77
- request.addEventListener('load', function() {
78
- rendererCode = this.responseText;
79
- });
80
- request.open('GET', rendererURL, false);
81
- request.send();
82
- injectCode(rendererCode);
83
-}
84
-
85
-// Inject a `__REACT_DEVTOOLS_GLOBAL_HOOK__` global so that React can detect that the
86
-// devtools are installed (and skip its suggestion to install the devtools).
87
-injectCode(
88
- ';(' + installHook.toString() + '(window))' + saveNativeValues + detectReact,
89
-);
packages/react-devtools-extensions/src/main.js
deleted
-322
@@ -1,322 +0,0 @@
1
-/* global chrome */
2
-
3
-import {createElement} from 'react';
4
-import {unstable_createRoot as createRoot, flushSync} from 'react-dom';
5
-import Bridge from 'react-devtools-shared/src/bridge';
6
-import Store from 'react-devtools-shared/src/devtools/store';
7
-import inject from './inject';
8
-import {
9
- createViewElementSource,
10
- getBrowserName,
11
- getBrowserTheme,
12
-} from './utils';
13
-import {
14
- getSavedComponentFilters,
15
- getAppendComponentStack,
16
-} from 'react-devtools-shared/src/utils';
17
-import {
18
- localStorageGetItem,
19
- localStorageRemoveItem,
20
- localStorageSetItem,
21
-} from 'react-devtools-shared/src/storage';
22
-import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
23
-
24
-const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY =
25
- 'React::DevTools::supportsProfiling';
26
-
27
-const isChrome = getBrowserName() === 'Chrome';
28
-
29
-let panelCreated = false;
30
-
31
-// The renderer interface can't read saved component filters directly,
32
-// because they are stored in localStorage within the context of the extension.
33
-// Instead it relies on the extension to pass filters through.
34
-function syncSavedPreferences() {
35
- const componentFilters = getSavedComponentFilters();
36
- chrome.devtools.inspectedWindow.eval(
37
- `window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = ${JSON.stringify(
38
- componentFilters,
39
- )};`,
40
- );
41
-
42
- const appendComponentStack = getAppendComponentStack();
43
- chrome.devtools.inspectedWindow.eval(
44
- `window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = ${JSON.stringify(
45
- appendComponentStack,
46
- )};`,
47
- );
48
-}
49
-
50
-syncSavedPreferences();
51
-
52
-function createPanelIfReactLoaded() {
53
- if (panelCreated) {
54
- return;
55
- }
56
-
57
- chrome.devtools.inspectedWindow.eval(
58
- 'window.__REACT_DEVTOOLS_GLOBAL_HOOK__ && window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.size > 0',
59
- function(pageHasReact, error) {
60
- if (!pageHasReact || panelCreated) {
61
- return;
62
- }
63
-
64
- panelCreated = true;
65
-
66
- clearInterval(loadCheckInterval);
67
-
68
- let bridge = null;
69
- let store = null;
70
-
71
- let profilingData = null;
72
-
73
- let componentsPortalContainer = null;
74
- let profilerPortalContainer = null;
75
-
76
- let cloneStyleTags = null;
77
- let mostRecentOverrideTab = null;
78
- let render = null;
79
- let root = null;
80
-
81
- const tabId = chrome.devtools.inspectedWindow.tabId;
82
-
83
- function initBridgeAndStore() {
84
- const port = chrome.runtime.connect({
85
- name: '' + tabId,
86
- });
87
- // Looks like `port.onDisconnect` does not trigger on in-tab navigation like new URL or back/forward navigation,
88
- // so it makes no sense to handle it here.
89
-
90
- bridge = new Bridge({
91
- listen(fn) {
92
- const listener = message => fn(message);
93
- // Store the reference so that we unsubscribe from the same object.
94
- const portOnMessage = port.onMessage;
95
- portOnMessage.addListener(listener);
96
- return () => {
97
- portOnMessage.removeListener(listener);
98
- };
99
- },
100
- send(event: string, payload: any, transferable?: Array<any>) {
101
- port.postMessage({event, payload}, transferable);
102
- },
103
- });
104
- bridge.addListener('reloadAppForProfiling', () => {
105
- localStorageSetItem(LOCAL_STORAGE_SUPPORTS_PROFILING_KEY, 'true');
106
- chrome.devtools.inspectedWindow.eval('window.location.reload();');
107
- });
108
- bridge.addListener('syncSelectionToNativeElementsPanel', () => {
109
- setBrowserSelectionFromReact();
110
- });
111
-
112
- // This flag lets us tip the Store off early that we expect to be profiling.
113
- // This avoids flashing a temporary "Profiling not supported" message in the Profiler tab,
114
- // after a user has clicked the "reload and profile" button.
115
- let isProfiling = false;
116
- let supportsProfiling = false;
117
- if (
118
- localStorageGetItem(LOCAL_STORAGE_SUPPORTS_PROFILING_KEY) === 'true'
119
- ) {
120
- supportsProfiling = true;
121
- isProfiling = true;
122
- localStorageRemoveItem(LOCAL_STORAGE_SUPPORTS_PROFILING_KEY);
123
- }
124
-
125
- if (store !== null) {
126
- profilingData = store.profilerStore.profilingData;
127
- }
128
-
129
- store = new Store(bridge, {
130
- isProfiling,
131
- supportsReloadAndProfile: isChrome,
132
- supportsProfiling,
133
- });
134
- store.profilerStore.profilingData = profilingData;
135
-
136
- // Initialize the backend only once the Store has been initialized.
137
- // Otherwise the Store may miss important initial tree op codes.
138
- inject(chrome.runtime.getURL('build/backend.js'));
139
-
140
- const viewElementSourceFunction = createViewElementSource(
141
- bridge,
142
- store,
143
- );
144
-
145
- root = createRoot(document.createElement('div'));
146
-
147
- render = (overrideTab = mostRecentOverrideTab) => {
148
- mostRecentOverrideTab = overrideTab;
149
-
150
- root.render(
151
- createElement(DevTools, {
152
- bridge,
153
- browserTheme: getBrowserTheme(),
154
- componentsPortalContainer,
155
- overrideTab,
156
- profilerPortalContainer,
157
- showTabBar: false,
158
- showWelcomeToTheNewDevToolsDialog: true,
159
- store,
160
- viewElementSourceFunction,
161
- }),
162
- );
163
- };
164
-
165
- render();
166
- }
167
-
168
- cloneStyleTags = () => {
169
- const linkTags = [];
170
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
171
- for (let linkTag of document.getElementsByTagName('link')) {
172
- if (linkTag.rel === 'stylesheet') {
173
- const newLinkTag = document.createElement('link');
174
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
175
- for (let attribute of linkTag.attributes) {
176
- newLinkTag.setAttribute(attribute.nodeName, attribute.nodeValue);
177
- }
178
- linkTags.push(newLinkTag);
179
- }
180
- }
181
- return linkTags;
182
- };
183
-
184
- initBridgeAndStore();
185
-
186
- function ensureInitialHTMLIsCleared(container) {
187
- if (container._hasInitialHTMLBeenCleared) {
188
- return;
189
- }
190
- container.innerHTML = '';
191
- container._hasInitialHTMLBeenCleared = true;
192
- }
193
-
194
- function setBrowserSelectionFromReact() {
195
- // This is currently only called on demand when you press "view DOM".
196
- // In the future, if Chrome adds an inspect() that doesn't switch tabs,
197
- // we could make this happen automatically when you select another component.
198
- chrome.devtools.inspectedWindow.eval(
199
- '(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 !== $0) ?' +
200
- '(inspect(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0), true) :' +
201
- 'false',
202
- (didSelectionChange, evalError) => {
203
- if (evalError) {
204
- console.error(evalError);
205
- }
206
- },
207
- );
208
- }
209
-
210
- function setReactSelectionFromBrowser() {
211
- // When the user chooses a different node in the browser Elements tab,
212
- // copy it over to the hook object so that we can sync the selection.
213
- chrome.devtools.inspectedWindow.eval(
214
- '(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 !== $0) ?' +
215
- '(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 = $0, true) :' +
216
- 'false',
217
- (didSelectionChange, evalError) => {
218
- if (evalError) {
219
- console.error(evalError);
220
- } else if (didSelectionChange) {
221
- // Remember to sync the selection next time we show Components tab.
222
- needsToSyncElementSelection = true;
223
- }
224
- },
225
- );
226
- }
227
-
228
- setReactSelectionFromBrowser();
229
- chrome.devtools.panels.elements.onSelectionChanged.addListener(() => {
230
- setReactSelectionFromBrowser();
231
- });
232
-
233
- let currentPanel = null;
234
- let needsToSyncElementSelection = false;
235
-
236
- chrome.devtools.panels.create(
237
- isChrome ? '⚛ Components' : 'Components',
238
- '',
239
- 'panel.html',
240
- extensionPanel => {
241
- extensionPanel.onShown.addListener(panel => {
242
- if (needsToSyncElementSelection) {
243
- needsToSyncElementSelection = false;
244
- bridge.send('syncSelectionFromNativeElementsPanel');
245
- }
246
-
247
- if (currentPanel === panel) {
248
- return;
249
- }
250
-
251
- currentPanel = panel;
252
- componentsPortalContainer = panel.container;
253
-
254
- if (componentsPortalContainer != null) {
255
- ensureInitialHTMLIsCleared(componentsPortalContainer);
256
- render('components');
257
- panel.injectStyles(cloneStyleTags);
258
- }
259
- });
260
- extensionPanel.onHidden.addListener(panel => {
261
- // TODO: Stop highlighting and stuff.
262
- });
263
- },
264
- );
265
-
266
- chrome.devtools.panels.create(
267
- isChrome ? '⚛ Profiler' : 'Profiler',
268
- '',
269
- 'panel.html',
270
- extensionPanel => {
271
- extensionPanel.onShown.addListener(panel => {
272
- if (currentPanel === panel) {
273
- return;
274
- }
275
-
276
- currentPanel = panel;
277
- profilerPortalContainer = panel.container;
278
-
279
- if (profilerPortalContainer != null) {
280
- ensureInitialHTMLIsCleared(profilerPortalContainer);
281
- render('profiler');
282
- panel.injectStyles(cloneStyleTags);
283
- }
284
- });
285
- },
286
- );
287
-
288
- chrome.devtools.network.onNavigated.removeListener(checkPageForReact);
289
-
290
- // Re-initialize DevTools panel when a new page is loaded.
291
- chrome.devtools.network.onNavigated.addListener(function onNavigated() {
292
- // Re-initialize saved filters on navigation,
293
- // since global values stored on window get reset in this case.
294
- syncSavedPreferences();
295
-
296
- // It's easiest to recreate the DevTools panel (to clean up potential stale state).
297
- // We can revisit this in the future as a small optimization.
298
- flushSync(() => {
299
- root.unmount(() => {
300
- initBridgeAndStore();
301
- });
302
- });
303
- });
304
- },
305
- );
306
-}
307
-
308
-// Load (or reload) the DevTools extension when the user navigates to a new page.
309
-function checkPageForReact() {
310
- syncSavedPreferences();
311
- createPanelIfReactLoaded();
312
-}
313
-
314
-chrome.devtools.network.onNavigated.addListener(checkPageForReact);
315
-
316
-// Check to see if React has loaded once per second in case React is added
317
-// after page load
318
-const loadCheckInterval = setInterval(function() {
319
- createPanelIfReactLoaded();
320
-}, 1000);
321
-
322
-createPanelIfReactLoaded();
packages/react-devtools-extensions/src/panel.js
deleted
-19
@@ -1,19 +0,0 @@
1
-// Portal target container.
2
-window.container = document.getElementById('container');
3
-
4
-let hasInjectedStyles = false;
5
-
6
-// DevTools styles are injected into the top-level document head (where the main React app is rendered).
7
-// This method copies those styles to the child window where each panel (e.g. Elements, Profiler) is portaled.
8
-window.injectStyles = getLinkTags => {
9
- if (!hasInjectedStyles) {
10
- hasInjectedStyles = true;
11
-
12
- const linkTags = getLinkTags();
13
-
14
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
15
- for (let linkTag of linkTags) {
16
- document.head.appendChild(linkTag);
17
- }
18
- }
19
-};
packages/react-devtools-extensions/src/renderer.js
deleted
-26
@@ -1,26 +0,0 @@
1
-/**
2
- * In order to support reload-and-profile functionality, the renderer needs to be injected before any other scripts.
3
- * Since it is a complex file (with imports) we can't just toString() it like we do with the hook itself,
4
- * So this entry point (one of the web_accessible_resources) provcides a way to eagerly inject it.
5
- * The hook will look for the presence of a global __REACT_DEVTOOLS_ATTACH__ and attach an injected renderer early.
6
- * The normal case (not a reload-and-profile) will not make use of this entry point though.
7
- *
8
- * @flow
9
- */
10
-
11
-import {attach} from 'react-devtools-shared/src/backend/renderer';
12
-
13
-Object.defineProperty(
14
- window,
15
- '__REACT_DEVTOOLS_ATTACH__',
16
- ({
17
- enumerable: false,
18
- // This property needs to be configurable to allow third-party integrations
19
- // to attach their own renderer. Note that using third-party integrations
20
- // is not officially supported. Use at your own risk.
21
- configurable: true,
22
- get() {
23
- return attach;
24
- },
25
- }: Object),
26
-);
packages/react-devtools-extensions/src/utils.js
deleted
-51
@@ -1,51 +0,0 @@
1
-/* global chrome */
2
-
3
-const IS_CHROME = navigator.userAgent.indexOf('Firefox') < 0;
4
-
5
-export function createViewElementSource(bridge: Bridge, store: Store) {
6
- return function viewElementSource(id) {
7
- const rendererID = store.getRendererIDForElement(id);
8
- if (rendererID != null) {
9
- // Ask the renderer interface to determine the component function,
10
- // and store it as a global variable on the window
11
- bridge.send('viewElementSource', {id, rendererID});
12
-
13
- setTimeout(() => {
14
- // Ask Chrome to display the location of the component function,
15
- // assuming the renderer found one.
16
- chrome.devtools.inspectedWindow.eval(`
17
- if (window.$type != null) {
18
- inspect(window.$type);
19
- }
20
- `);
21
- }, 100);
22
- }
23
- };
24
-}
25
-
26
-export type BrowserName = 'Chrome' | 'Firefox';
27
-
28
-export function getBrowserName(): BrowserName {
29
- return IS_CHROME ? 'Chrome' : 'Firefox';
30
-}
31
-
32
-export type BrowserTheme = 'dark' | 'light';
33
-
34
-export function getBrowserTheme(): BrowserTheme {
35
- if (IS_CHROME) {
36
- // chrome.devtools.panels added in Chrome 18.
37
- // chrome.devtools.panels.themeName added in Chrome 54.
38
- return chrome.devtools.panels.themeName === 'dark' ? 'dark' : 'light';
39
- } else {
40
- // chrome.devtools.panels.themeName added in Firefox 55.
41
- // https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools.panels/themeName
42
- if (chrome.devtools && chrome.devtools.panels) {
43
- switch (chrome.devtools.panels.themeName) {
44
- case 'dark':
45
- return 'dark';
46
- default:
47
- return 'light';
48
- }
49
- }
50
- }
51
-}
packages/react-devtools-extensions/utils.js
deleted
-39
@@ -1,39 +0,0 @@
1
-const {execSync} = require('child_process');
2
-const {readFileSync} = require('fs');
3
-const {resolve} = require('path');
4
-
5
-function getGitCommit() {
6
- return execSync('git show -s --format=%h')
7
- .toString()
8
- .trim();
9
-}
10
-
11
-function getGitHubURL() {
12
- // TODO potentially replace this with an fb.me URL (assuming it can forward the query params)
13
- const url = execSync('git remote get-url origin')
14
- .toString()
15
- .trim();
16
-
17
- if (url.startsWith('https://')) {
18
- return url.replace('.git', '');
19
- } else {
20
- return url
21
- .replace(':', '/')
22
- .replace('git@', 'https://')
23
- .replace('.git', '');
24
- }
25
-}
26
-
27
-function getVersionString() {
28
- const packageVersion = JSON.parse(
29
- readFileSync(
30
- resolve(__dirname, '..', 'react-devtools-core', './package.json'),
31
- ),
32
- ).version;
33
-
34
- const commit = getGitCommit();
35
-
36
- return `${packageVersion}-${commit}`;
37
-}
38
-
39
-module.exports = {getGitCommit, getGitHubURL, getVersionString};
packages/react-devtools-extensions/webpack.backend.js
deleted
-62
@@ -1,62 +0,0 @@
1
-'use strict';
2
-
3
-const {resolve} = require('path');
4
-const {DefinePlugin} = require('webpack');
5
-const {getGitHubURL, getVersionString} = require('./utils');
6
-
7
-const NODE_ENV = process.env.NODE_ENV;
8
-if (!NODE_ENV) {
9
- console.error('NODE_ENV not set');
10
- process.exit(1);
11
-}
12
-
13
-const builtModulesDir = resolve(__dirname, '..', '..', 'build', 'node_modules');
14
-
15
-const __DEV__ = NODE_ENV === 'development';
16
-
17
-const GITHUB_URL = getGitHubURL();
18
-const DEVTOOLS_VERSION = getVersionString();
19
-
20
-module.exports = {
21
- mode: __DEV__ ? 'development' : 'production',
22
- devtool: __DEV__ ? 'cheap-module-eval-source-map' : false,
23
- entry: {
24
- backend: './src/backend.js',
25
- },
26
- output: {
27
- path: __dirname + '/build',
28
- filename: '[name].js',
29
- },
30
- resolve: {
31
- alias: {
32
- react: resolve(builtModulesDir, 'react'),
33
- 'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
34
- 'react-dom': resolve(builtModulesDir, 'react-dom'),
35
- 'react-is': resolve(builtModulesDir, 'react-is'),
36
- scheduler: resolve(builtModulesDir, 'scheduler'),
37
- },
38
- },
39
- plugins: [
40
- new DefinePlugin({
41
- __DEV__: true,
42
- 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
43
- 'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
44
- }),
45
- ],
46
- module: {
47
- rules: [
48
- {
49
- test: /\.js$/,
50
- loader: 'babel-loader',
51
- options: {
52
- configFile: resolve(
53
- __dirname,
54
- '..',
55
- 'react-devtools-shared',
56
- 'babel.config.js',
57
- ),
58
- },
59
- },
60
- ],
61
- },
62
-};
packages/react-devtools-extensions/webpack.config.js
deleted
-84
@@ -1,84 +0,0 @@
1
-'use strict';
2
-
3
-const {resolve} = require('path');
4
-const {DefinePlugin} = require('webpack');
5
-const {getGitHubURL, getVersionString} = require('./utils');
6
-
7
-const NODE_ENV = process.env.NODE_ENV;
8
-if (!NODE_ENV) {
9
- console.error('NODE_ENV not set');
10
- process.exit(1);
11
-}
12
-
13
-const builtModulesDir = resolve(__dirname, '..', '..', 'build', 'node_modules');
14
-
15
-const __DEV__ = NODE_ENV === 'development';
16
-
17
-const GITHUB_URL = getGitHubURL();
18
-const DEVTOOLS_VERSION = getVersionString();
19
-
20
-module.exports = {
21
- mode: __DEV__ ? 'development' : 'production',
22
- devtool: __DEV__ ? 'cheap-module-eval-source-map' : false,
23
- entry: {
24
- background: './src/background.js',
25
- contentScript: './src/contentScript.js',
26
- injectGlobalHook: './src/injectGlobalHook.js',
27
- main: './src/main.js',
28
- panel: './src/panel.js',
29
- renderer: './src/renderer.js',
30
- },
31
- output: {
32
- path: __dirname + '/build',
33
- filename: '[name].js',
34
- },
35
- resolve: {
36
- alias: {
37
- react: resolve(builtModulesDir, 'react'),
38
- 'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
39
- 'react-dom': resolve(builtModulesDir, 'react-dom'),
40
- 'react-is': resolve(builtModulesDir, 'react-is'),
41
- scheduler: resolve(builtModulesDir, 'scheduler'),
42
- },
43
- },
44
- plugins: [
45
- new DefinePlugin({
46
- __DEV__: false,
47
- 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
48
- 'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
49
- 'process.env.NODE_ENV': `"${NODE_ENV}"`,
50
- }),
51
- ],
52
- module: {
53
- rules: [
54
- {
55
- test: /\.js$/,
56
- loader: 'babel-loader',
57
- options: {
58
- configFile: resolve(
59
- __dirname,
60
- '..',
61
- 'react-devtools-shared',
62
- 'babel.config.js',
63
- ),
64
- },
65
- },
66
- {
67
- test: /\.css$/,
68
- use: [
69
- {
70
- loader: 'style-loader',
71
- },
72
- {
73
- loader: 'css-loader',
74
- options: {
75
- sourceMap: true,
76
- modules: true,
77
- localIdentName: '[local]___[hash:base64:5]',
78
- },
79
- },
80
- ],
81
- },
82
- ],
83
- },
84
-};
packages/react-devtools-inline/README.md
+5
-20
@@ -21,32 +21,24 @@ The frontend and backend can be initialized in any order, but **the backend must
21
### `react-devtools-inline/backend`
22
23
* **`initialize(contentWindow)`** -
24
-Installs the global hook on the window. This hook is how React and DevTools communicate. **This method must be called before React is loaded.**<sup>2</sup>
24
+Installs the global hook on the window. This hook is how React and DevTools communicate. **This method must be called before React is loaded.** (This means before any `import` or `require` statements!)
25
* **`activate(contentWindow)`** -
26
Lets the backend know when the frontend is ready. It should not be called until after the frontend has been initialized, else the frontend might miss important tree-initialization events.
27
28
```js
29
import { activate, initialize } from 'react-devtools-inline/backend';
30
31
-// This should be the iframe the React application is running in.
32
-const iframe = document.getElementById(frameID);
33
-const contentWindow = iframe.contentWindow;
34
-
31
// Call this before importing React (or any other packages that might import React).
36
-initialize(contentWindow);
37
-
38
-// Initialize the frontend...
32
+initialize();
33
34
// Call this only once the frontend has been initialized.
41
-activate(contentWindow);
35
+activate();
36
```
37
44
-<sup>2</sup> The backend must be initialized before React is loaded. (This means before any `import` or `require` statements or `<script>` tags that include React.)
45
-
38
### `react-devtools-inline/frontend`
39
40
* **`initialize(contentWindow)`** -
49
-Configures the DevTools interface to listen to the `window` the backend was injected into. This method returns a React component that can be rendered directly<sup>3</sup>.
41
+Configures the DevTools interface to listen to the `window` the backend was injected into. This method returns a React component that can be rendered directly<sup>2</sup>.
42
43
```js
44
import { initialize } from 'react-devtools-inline/frontend';
@@ -60,7 +52,7 @@ const contentWindow = iframe.contentWindow;
52
const DevTools = initialize(contentWindow);
53
```
54
63
-<sup>3</sup> Because the DevTools interface makes use of several new React APIs (e.g. suspense, concurrent mode) it should be rendered using either `ReactDOM.unstable_createRoot` or `ReactDOM.unstable_createSyncRoot`. **It should not be rendered with `ReactDOM.render`.**
55
+<sup>2</sup> Because the DevTools interface makes use of several new React APIs (e.g. suspense, concurrent mode) it should be rendered using either `ReactDOM.unstable_createRoot` or `ReactDOM.unstable_createSyncRoot`. It should not be rendered with `ReactDOM.render`.
56
57
## Examples
58
@@ -151,11 +143,4 @@ iframe.onload = () => {
143
"*"
144
);
145
};
154
-```
155
-
156
-## Development
157
-
158
-Watch for changes made to the source code and rebuild:
159
-```sh
160
-yarn start
146
```
\ No newline at end of file
packages/react-devtools-inline/backend.js
deleted
-1
@@ -1 +0,0 @@
1
-module.exports = require('./dist/backend');
packages/react-devtools-inline/frontend.js
deleted
-1
@@ -1 +0,0 @@
1
-module.exports = require('./dist/frontend');
packages/react-devtools-inline/package.json
+2
-43
@@ -1,46 +1,5 @@
1
{
2
+ "private": true,
3
"name": "react-devtools-inline",
3
- "version": "4.0.6",
4
- "description": "Embed react-devtools within a website",
5
- "license": "MIT",
6
- "main": "./dist/backend.js",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/facebook/react.git",
10
- "directory": "packages/react-devtools-inline"
11
- },
12
- "files": [
13
- "dist",
14
- "backend.js",
15
- "build-info.json",
16
- "frontend.js"
17
- ],
18
- "scripts": {
19
- "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
20
- "prepublish": "yarn run build",
21
- "start": "cross-env NODE_ENV=development webpack --config webpack.config.js --watch"
22
- },
23
- "dependencies": {
24
- "es6-symbol": "^3"
25
- },
26
- "devDependencies": {
27
- "@babel/core": "^7.1.6",
28
- "@babel/plugin-proposal-class-properties": "^7.1.0",
29
- "@babel/plugin-transform-flow-strip-types": "^7.1.6",
30
- "@babel/plugin-transform-react-jsx-source": "^7.2.0",
31
- "@babel/preset-env": "^7.1.6",
32
- "@babel/preset-flow": "^7.0.0",
33
- "@babel/preset-react": "^7.0.0",
34
- "babel-core": "^7.0.0-bridge",
35
- "babel-eslint": "^9.0.0",
36
- "babel-jest": "^24.7.1",
37
- "babel-loader": "^8.0.4",
38
- "cross-env": "^3.1.4",
39
- "css-loader": "^1.0.1",
40
- "raw-loader": "^3.1.0",
41
- "style-loader": "^0.23.1",
42
- "webpack": "^4.26.0",
43
- "webpack-cli": "^3.1.2",
44
- "webpack-dev-server": "^3.3.1"
45
- }
4
+ "version": "0.0.0"
5
}
packages/react-devtools-inline/src/backend.js
deleted
-96
@@ -1,96 +0,0 @@
1
-/** @flow */
2
-
3
-import Agent from 'react-devtools-shared/src/backend/agent';
4
-import Bridge from 'react-devtools-shared/src/bridge';
5
-import {initBackend} from 'react-devtools-shared/src/backend';
6
-import {installHook} from 'react-devtools-shared/src/hook';
7
-import setupNativeStyleEditor from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
8
-import {
9
- MESSAGE_TYPE_GET_SAVED_PREFERENCES,
10
- MESSAGE_TYPE_SAVED_PREFERENCES,
11
-} from './constants';
12
-
13
-function startActivation(contentWindow: window) {
14
- const {parent} = contentWindow;
15
-
16
- const onMessage = ({data}) => {
17
- switch (data.type) {
18
- case MESSAGE_TYPE_SAVED_PREFERENCES:
19
- // This is the only message we're listening for,
20
- // so it's safe to cleanup after we've received it.
21
- contentWindow.removeEventListener('message', onMessage);
22
-
23
- const {appendComponentStack, componentFilters} = data;
24
-
25
- contentWindow.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = appendComponentStack;
26
- contentWindow.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
27
-
28
- // TRICKY
29
- // The backend entry point may be required in the context of an iframe or the parent window.
30
- // If it's required within the parent window, store the saved values on it as well,
31
- // since the injected renderer interface will read from window.
32
- // Technically we don't need to store them on the contentWindow in this case,
33
- // but it doesn't really hurt anything to store them there too.
34
- if (contentWindow !== window) {
35
- window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = appendComponentStack;
36
- window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
37
- }
38
-
39
- finishActivation(contentWindow);
40
- break;
41
- default:
42
- break;
43
- }
44
- };
45
-
46
- contentWindow.addEventListener('message', onMessage);
47
-
48
- // The backend may be unable to read saved preferences directly,
49
- // because they are stored in localStorage within the context of the extension (on the frontend).
50
- // Instead it relies on the extension to pass preferences through.
51
- // Because we might be in a sandboxed iframe, we have to ask for them by way of postMessage().
52
- parent.postMessage({type: MESSAGE_TYPE_GET_SAVED_PREFERENCES}, '*');
53
-}
54
-
55
-function finishActivation(contentWindow: window) {
56
- const {parent} = contentWindow;
57
-
58
- const bridge = new Bridge({
59
- listen(fn) {
60
- const onMessage = event => {
61
- fn(event.data);
62
- };
63
- contentWindow.addEventListener('message', onMessage);
64
- return () => {
65
- contentWindow.removeEventListener('message', onMessage);
66
- };
67
- },
68
- send(event: string, payload: any, transferable?: Array<any>) {
69
- parent.postMessage({event, payload}, '*', transferable);
70
- },
71
- });
72
-
73
- const agent = new Agent(bridge);
74
-
75
- const hook = contentWindow.__REACT_DEVTOOLS_GLOBAL_HOOK__;
76
-
77
- initBackend(hook, agent, contentWindow);
78
-
79
- // Setup React Native style editor if a renderer like react-native-web has injected it.
80
- if (hook.resolveRNStyle) {
81
- setupNativeStyleEditor(
82
- bridge,
83
- agent,
84
- hook.resolveRNStyle,
85
- hook.nativeStyleEditorValidAttributes,
86
- );
87
- }
88
-}
89
-
90
-export function activate(contentWindow: window): void {
91
- startActivation(contentWindow);
92
-}
93
-
94
-export function initialize(contentWindow: window): void {
95
- installHook(contentWindow);
96
-}
packages/react-devtools-inline/src/constants.js
deleted
-6
@@ -1,6 +0,0 @@
1
-/** @flow */
2
-
3
-export const MESSAGE_TYPE_GET_SAVED_PREFERENCES =
4
- 'React::DevTools::getSavedPreferences';
5
-export const MESSAGE_TYPE_SAVED_PREFERENCES =
6
- 'React::DevTools::savedPreferences';
packages/react-devtools-inline/src/frontend.js
deleted
-75
@@ -1,75 +0,0 @@
1
-/** @flow */
2
-
3
-import React, {forwardRef} from 'react';
4
-import Bridge from 'react-devtools-shared/src/bridge';
5
-import Store from 'react-devtools-shared/src/devtools/store';
6
-import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
7
-import {
8
- getSavedComponentFilters,
9
- getAppendComponentStack,
10
-} from 'react-devtools-shared/src/utils';
11
-import {
12
- MESSAGE_TYPE_GET_SAVED_PREFERENCES,
13
- MESSAGE_TYPE_SAVED_PREFERENCES,
14
-} from './constants';
15
-
16
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
17
-import type {Props} from 'react-devtools-shared/src/devtools/views/DevTools';
18
-
19
-export function initialize(
20
- contentWindow: window,
21
-): React.AbstractComponent<Props, mixed> {
22
- const onGetSavedPreferencesMessage = ({data, source}) => {
23
- if (source === 'react-devtools-content-script') {
24
- // Ignore messages from the DevTools browser extension.
25
- }
26
-
27
- switch (data.type) {
28
- case MESSAGE_TYPE_GET_SAVED_PREFERENCES:
29
- // This is the only message we're listening for,
30
- // so it's safe to cleanup after we've received it.
31
- window.removeEventListener('message', onGetSavedPreferencesMessage);
32
-
33
- // The renderer interface can't read saved preferences directly,
34
- // because they are stored in localStorage within the context of the extension.
35
- // Instead it relies on the extension to pass them through.
36
- contentWindow.postMessage(
37
- {
38
- type: MESSAGE_TYPE_SAVED_PREFERENCES,
39
- appendComponentStack: getAppendComponentStack(),
40
- componentFilters: getSavedComponentFilters(),
41
- },
42
- '*',
43
- );
44
- break;
45
- default:
46
- break;
47
- }
48
- };
49
-
50
- window.addEventListener('message', onGetSavedPreferencesMessage);
51
-
52
- const bridge: FrontendBridge = new Bridge({
53
- listen(fn) {
54
- const onMessage = ({data}) => {
55
- fn(data);
56
- };
57
- window.addEventListener('message', onMessage);
58
- return () => {
59
- window.removeEventListener('message', onMessage);
60
- };
61
- },
62
- send(event: string, payload: any, transferable?: Array<any>) {
63
- contentWindow.postMessage({event, payload}, '*', transferable);
64
- },
65
- });
66
-
67
- const store: Store = new Store(bridge);
68
-
69
- const ForwardRef = forwardRef<Props, mixed>((props, ref) => (
70
- <DevTools ref={ref} bridge={bridge} store={store} {...props} />
71
- ));
72
- ForwardRef.displayName = 'DevTools';
73
-
74
- return ForwardRef;
75
-}
packages/react-devtools-inline/webpack.config.js
deleted
-80
@@ -1,80 +0,0 @@
1
-const {resolve} = require('path');
2
-const {DefinePlugin} = require('webpack');
3
-const {
4
- getGitHubURL,
5
- getVersionString,
6
-} = require('react-devtools-extensions/utils');
7
-
8
-const NODE_ENV = process.env.NODE_ENV;
9
-if (!NODE_ENV) {
10
- console.error('NODE_ENV not set');
11
- process.exit(1);
12
-}
13
-
14
-const __DEV__ = true; // NODE_ENV === 'development';
15
-
16
-const GITHUB_URL = getGitHubURL();
17
-const DEVTOOLS_VERSION = getVersionString();
18
-
19
-module.exports = {
20
- mode: __DEV__ ? 'development' : 'production',
21
- devtool: false,
22
- entry: {
23
- backend: './src/backend.js',
24
- frontend: './src/frontend.js',
25
- },
26
- output: {
27
- path: __dirname + '/dist',
28
- filename: '[name].js',
29
- library: '[name]',
30
- libraryTarget: 'commonjs2',
31
- },
32
- externals: {
33
- react: 'react',
34
- // TODO: Once this package is published, remove the external
35
- // 'react-debug-tools': 'react-debug-tools',
36
- 'react-dom': 'react-dom',
37
- 'react-is': 'react-is',
38
- scheduler: 'scheduler',
39
- },
40
- plugins: [
41
- new DefinePlugin({
42
- __DEV__,
43
- 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
44
- 'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
45
- 'process.env.NODE_ENV': `"${NODE_ENV}"`,
46
- }),
47
- ],
48
- module: {
49
- rules: [
50
- {
51
- test: /\.js$/,
52
- loader: 'babel-loader',
53
- options: {
54
- configFile: resolve(
55
- __dirname,
56
- '..',
57
- 'react-devtools-shared',
58
- 'babel.config.js',
59
- ),
60
- },
61
- },
62
- {
63
- test: /\.css$/,
64
- use: [
65
- {
66
- loader: 'style-loader',
67
- },
68
- {
69
- loader: 'css-loader',
70
- options: {
71
- sourceMap: true,
72
- modules: true,
73
- localIdentName: '[local]___[hash:base64:5]',
74
- },
75
- },
76
- ],
77
- },
78
- ],
79
- },
80
-};
packages/react-devtools-shared/babel.config.js
deleted
-46
@@ -1,46 +0,0 @@
1
-const chromeManifest = require('../react-devtools-extensions/chrome/manifest.json');
2
-const firefoxManifest = require('../react-devtools-extensions/firefox/manifest.json');
3
-
4
-const minChromeVersion = parseInt(chromeManifest.minimum_chrome_version, 10);
5
-const minFirefoxVersion = parseInt(
6
- firefoxManifest.applications.gecko.strict_min_version,
7
- 10,
8
-);
9
-validateVersion(minChromeVersion);
10
-validateVersion(minFirefoxVersion);
11
-
12
-function validateVersion(version) {
13
- if (version > 0 && version < 200) {
14
- return;
15
- }
16
- throw new Error('Suspicious browser version in manifest: ' + version);
17
-}
18
-
19
-module.exports = api => {
20
- const isTest = api.env('test');
21
- const targets = {};
22
- if (isTest) {
23
- targets.node = 'current';
24
- } else {
25
- targets.chrome = minChromeVersion.toString();
26
- targets.firefox = minFirefoxVersion.toString();
27
-
28
- // This targets RN/Hermes.
29
- targets.ie = '11';
30
- }
31
- const plugins = [
32
- ['@babel/plugin-transform-flow-strip-types'],
33
- ['@babel/plugin-proposal-class-properties', {loose: false}],
34
- ];
35
- if (process.env.NODE_ENV !== 'production') {
36
- plugins.push(['@babel/plugin-transform-react-jsx-source']);
37
- }
38
- return {
39
- plugins,
40
- presets: [
41
- ['@babel/preset-env', {targets}],
42
- '@babel/preset-react',
43
- '@babel/preset-flow',
44
- ],
45
- };
46
-};
packages/react-devtools-shared/package.json
deleted
-20
@@ -1,20 +0,0 @@
1
-{
2
- "private": true,
3
- "name": "react-devtools-shared",
4
- "version": "0.0.0",
5
- "devDependencies": {
6
- "react-15": "npm:react@^15",
7
- "react-dom-15": "npm:react-dom@^15"
8
- },
9
- "dependencies": {
10
- "@babel/runtime": "^7.0.0",
11
- "@reach/menu-button": "^0.1.17",
12
- "@reach/tooltip": "^0.2.2",
13
- "clipboard-js": "^0.3.6",
14
- "events": "^3.0.0",
15
- "local-storage-fallback": "^4.1.1",
16
- "lodash.throttle": "^4.1.1",
17
- "memoize-one": "^3.1.1",
18
- "react-virtualized-auto-sizer": "^1.0.2"
19
- }
20
-}
packages/react-devtools-shared/src/__tests__/__mocks__/cssMock.js
deleted
-1
@@ -1 +0,0 @@
1
-module.exports = {};
packages/react-devtools-shared/src/__tests__/__snapshots__/inspectedElementContext-test.js.snap
deleted
-561
@@ -1,561 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`InspectedElementContext should dehydrate complex nested values when requested: 1: Initially inspect element 1`] = `
4
-{
5
- "id": 2,
6
- "owners": null,
7
- "context": null,
8
- "hooks": null,
9
- "props": {
10
- "set_of_sets": {
11
- "0": {},
12
- "1": {}
13
- }
14
- },
15
- "state": null
16
-}
17
-`;
18
-
19
-exports[`InspectedElementContext should dehydrate complex nested values when requested: 2: Inspect props.set_of_sets.0 1`] = `
20
-{
21
- "id": 2,
22
- "owners": null,
23
- "context": null,
24
- "hooks": null,
25
- "props": {
26
- "set_of_sets": {
27
- "0": {
28
- "0": 1,
29
- "1": 2,
30
- "2": 3
31
- },
32
- "1": {}
33
- }
34
- },
35
- "state": null
36
-}
37
-`;
38
-
39
-exports[`InspectedElementContext should include updates for nested values that were previously hydrated: 1: Initially inspect element 1`] = `
40
-{
41
- "id": 2,
42
- "owners": null,
43
- "context": null,
44
- "hooks": null,
45
- "props": {
46
- "nestedObject": {
47
- "a": {},
48
- "c": {}
49
- }
50
- },
51
- "state": null
52
-}
53
-`;
54
-
55
-exports[`InspectedElementContext should include updates for nested values that were previously hydrated: 2: Inspect props.nestedObject.a 1`] = `
56
-{
57
- "id": 2,
58
- "owners": null,
59
- "context": null,
60
- "hooks": null,
61
- "props": {
62
- "nestedObject": {
63
- "a": {
64
- "value": 1,
65
- "b": {
66
- "value": 1
67
- }
68
- },
69
- "c": {}
70
- }
71
- },
72
- "state": null
73
-}
74
-`;
75
-
76
-exports[`InspectedElementContext should include updates for nested values that were previously hydrated: 3: Inspect props.nestedObject.c 1`] = `
77
-{
78
- "id": 2,
79
- "owners": null,
80
- "context": null,
81
- "hooks": null,
82
- "props": {
83
- "nestedObject": {
84
- "a": {
85
- "value": 1,
86
- "b": {
87
- "value": 1
88
- }
89
- },
90
- "c": {
91
- "value": 1,
92
- "d": {
93
- "value": 1,
94
- "e": {}
95
- }
96
- }
97
- }
98
- },
99
- "state": null
100
-}
101
-`;
102
-
103
-exports[`InspectedElementContext should include updates for nested values that were previously hydrated: 4: update inspected element 1`] = `
104
-{
105
- "id": 2,
106
- "owners": null,
107
- "context": null,
108
- "hooks": null,
109
- "props": {
110
- "nestedObject": {
111
- "a": {
112
- "value": 2,
113
- "b": {
114
- "value": 2
115
- }
116
- },
117
- "c": {
118
- "value": 2,
119
- "d": {
120
- "value": 2,
121
- "e": {}
122
- }
123
- }
124
- }
125
- },
126
- "state": null
127
-}
128
-`;
129
-
130
-exports[`InspectedElementContext should inspect hooks for components that only use context: 1: Inspected element 2 1`] = `
131
-{
132
- "id": 2,
133
- "owners": null,
134
- "context": null,
135
- "hooks": [
136
- {
137
- "id": null,
138
- "isStateEditable": false,
139
- "name": "Context",
140
- "value": true,
141
- "subHooks": []
142
- }
143
- ],
144
- "props": {
145
- "a": 1,
146
- "b": "abc"
147
- },
148
- "state": null
149
-}
150
-`;
151
-
152
-exports[`InspectedElementContext should inspect the currently selected element: 1: Inspected element 2 1`] = `
153
-{
154
- "id": 2,
155
- "owners": null,
156
- "context": null,
157
- "hooks": [
158
- {
159
- "id": 0,
160
- "isStateEditable": true,
161
- "name": "State",
162
- "value": 1,
163
- "subHooks": []
164
- }
165
- ],
166
- "props": {
167
- "a": 1,
168
- "b": "abc"
169
- },
170
- "state": null
171
-}
172
-`;
173
-
174
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 1: Initially inspect element 1`] = `
175
-{
176
- "id": 2,
177
- "owners": null,
178
- "context": null,
179
- "hooks": [
180
- {
181
- "id": 0,
182
- "isStateEditable": true,
183
- "name": "State",
184
- "value": {
185
- "foo": {}
186
- },
187
- "subHooks": []
188
- }
189
- ],
190
- "props": {
191
- "nestedObject": {
192
- "a": {}
193
- }
194
- },
195
- "state": null
196
-}
197
-`;
198
-
199
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 2: Inspect props.nestedObject.a 1`] = `
200
-{
201
- "id": 2,
202
- "owners": null,
203
- "context": null,
204
- "hooks": [
205
- {
206
- "id": 0,
207
- "isStateEditable": true,
208
- "name": "State",
209
- "value": {
210
- "foo": {}
211
- },
212
- "subHooks": []
213
- }
214
- ],
215
- "props": {
216
- "nestedObject": {
217
- "a": {
218
- "b": {
219
- "c": {}
220
- }
221
- }
222
- }
223
- },
224
- "state": null
225
-}
226
-`;
227
-
228
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 3: Inspect props.nestedObject.a.b.c 1`] = `
229
-{
230
- "id": 2,
231
- "owners": null,
232
- "context": null,
233
- "hooks": [
234
- {
235
- "id": 0,
236
- "isStateEditable": true,
237
- "name": "State",
238
- "value": {
239
- "foo": {}
240
- },
241
- "subHooks": []
242
- }
243
- ],
244
- "props": {
245
- "nestedObject": {
246
- "a": {
247
- "b": {
248
- "c": [
249
- {
250
- "d": {}
251
- }
252
- ]
253
- }
254
- }
255
- }
256
- },
257
- "state": null
258
-}
259
-`;
260
-
261
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 4: Inspect props.nestedObject.a.b.c.0.d 1`] = `
262
-{
263
- "id": 2,
264
- "owners": null,
265
- "context": null,
266
- "hooks": [
267
- {
268
- "id": 0,
269
- "isStateEditable": true,
270
- "name": "State",
271
- "value": {
272
- "foo": {}
273
- },
274
- "subHooks": []
275
- }
276
- ],
277
- "props": {
278
- "nestedObject": {
279
- "a": {
280
- "b": {
281
- "c": [
282
- {
283
- "d": {
284
- "e": {}
285
- }
286
- }
287
- ]
288
- }
289
- }
290
- }
291
- },
292
- "state": null
293
-}
294
-`;
295
-
296
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 5: Inspect hooks.0.value 1`] = `
297
-{
298
- "id": 2,
299
- "owners": null,
300
- "context": null,
301
- "hooks": [
302
- {
303
- "id": 0,
304
- "isStateEditable": true,
305
- "name": "State",
306
- "value": {
307
- "foo": {
308
- "bar": {}
309
- }
310
- },
311
- "subHooks": []
312
- }
313
- ],
314
- "props": {
315
- "nestedObject": {
316
- "a": {
317
- "b": {
318
- "c": [
319
- {
320
- "d": {
321
- "e": {}
322
- }
323
- }
324
- ]
325
- }
326
- }
327
- }
328
- },
329
- "state": null
330
-}
331
-`;
332
-
333
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 6: Inspect hooks.0.value.foo.bar 1`] = `
334
-{
335
- "id": 2,
336
- "owners": null,
337
- "context": null,
338
- "hooks": [
339
- {
340
- "id": 0,
341
- "isStateEditable": true,
342
- "name": "State",
343
- "value": {
344
- "foo": {
345
- "bar": {
346
- "baz": "hi"
347
- }
348
- }
349
- },
350
- "subHooks": []
351
- }
352
- ],
353
- "props": {
354
- "nestedObject": {
355
- "a": {
356
- "b": {
357
- "c": [
358
- {
359
- "d": {
360
- "e": {}
361
- }
362
- }
363
- ]
364
- }
365
- }
366
- }
367
- },
368
- "state": null
369
-}
370
-`;
371
-
372
-exports[`InspectedElementContext should not re-render a function with hooks if it did not update since it was last inspected: 1: initial render 1`] = `
373
-{
374
- "id": 3,
375
- "owners": null,
376
- "context": null,
377
- "hooks": [
378
- {
379
- "id": 0,
380
- "isStateEditable": true,
381
- "name": "State",
382
- "value": 0,
383
- "subHooks": []
384
- }
385
- ],
386
- "props": {
387
- "a": 1,
388
- "b": "abc"
389
- },
390
- "state": null
391
-}
392
-`;
393
-
394
-exports[`InspectedElementContext should not re-render a function with hooks if it did not update since it was last inspected: 2: updated state 1`] = `
395
-{
396
- "id": 3,
397
- "owners": null,
398
- "context": null,
399
- "hooks": [
400
- {
401
- "id": 0,
402
- "isStateEditable": true,
403
- "name": "State",
404
- "value": 0,
405
- "subHooks": []
406
- }
407
- ],
408
- "props": {
409
- "a": 2,
410
- "b": "def"
411
- },
412
- "state": null
413
-}
414
-`;
415
-
416
-exports[`InspectedElementContext should not tear if hydration is requested after an update: 1: Initially inspect element 1`] = `
417
-{
418
- "id": 2,
419
- "owners": null,
420
- "context": null,
421
- "hooks": null,
422
- "props": {
423
- "nestedObject": {
424
- "value": 1,
425
- "a": {}
426
- }
427
- },
428
- "state": null
429
-}
430
-`;
431
-
432
-exports[`InspectedElementContext should not tear if hydration is requested after an update: 2: Inspect props.nestedObject.a 1`] = `
433
-{
434
- "id": 2,
435
- "owners": null,
436
- "context": null,
437
- "hooks": null,
438
- "props": {
439
- "nestedObject": {
440
- "value": 2,
441
- "a": {
442
- "value": 2,
443
- "b": {
444
- "value": 2
445
- }
446
- }
447
- }
448
- },
449
- "state": null
450
-}
451
-`;
452
-
453
-exports[`InspectedElementContext should poll for updates for the currently selected element: 1: initial render 1`] = `
454
-{
455
- "id": 2,
456
- "owners": null,
457
- "context": null,
458
- "hooks": null,
459
- "props": {
460
- "a": 1,
461
- "b": "abc"
462
- },
463
- "state": null
464
-}
465
-`;
466
-
467
-exports[`InspectedElementContext should poll for updates for the currently selected element: 2: updated state 1`] = `
468
-{
469
- "id": 2,
470
- "owners": null,
471
- "context": null,
472
- "hooks": null,
473
- "props": {
474
- "a": 2,
475
- "b": "def"
476
- },
477
- "state": null
478
-}
479
-`;
480
-
481
-exports[`InspectedElementContext should support complex data types: 1: Inspected element 2 1`] = `
482
-{
483
- "id": 2,
484
- "owners": null,
485
- "context": null,
486
- "hooks": null,
487
- "props": {
488
- "array_buffer": {},
489
- "date": {},
490
- "fn": {},
491
- "html_element": {},
492
- "immutable": {
493
- "0": {},
494
- "1": {},
495
- "2": {}
496
- },
497
- "map": {
498
- "0": {},
499
- "1": {}
500
- },
501
- "map_of_maps": {
502
- "0": {},
503
- "1": {}
504
- },
505
- "react_element": {},
506
- "set": {
507
- "0": "abc",
508
- "1": 123
509
- },
510
- "set_of_sets": {
511
- "0": {},
512
- "1": {}
513
- },
514
- "symbol": {},
515
- "typed_array": {
516
- "0": 100,
517
- "1": -100,
518
- "2": 0
519
- }
520
- },
521
- "state": null
522
-}
523
-`;
524
-
525
-exports[`InspectedElementContext should support custom objects with enumerable properties and getters: 1: Inspected element 2 1`] = `
526
-{
527
- "id": 2,
528
- "owners": null,
529
- "context": null,
530
- "hooks": null,
531
- "props": {
532
- "data": {
533
- "_number": 42,
534
- "number": 42
535
- }
536
- },
537
- "state": null
538
-}
539
-`;
540
-
541
-exports[`InspectedElementContext should support simple data types: 1: Initial inspection 1`] = `
542
-{
543
- "id": 2,
544
- "owners": null,
545
- "context": null,
546
- "hooks": null,
547
- "props": {
548
- "boolean_false": false,
549
- "boolean_true": true,
550
- "infinity": null,
551
- "integer_zero": 0,
552
- "integer_one": 1,
553
- "float": 1.23,
554
- "string": "abc",
555
- "string_empty": "",
556
- "nan": null,
557
- "value_null": null
558
- },
559
- "state": null
560
-}
561
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/ownersListContext-test.js.snap
deleted
-95
@@ -1,95 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`OwnersListContext should fetch the owners list for the selected element that includes filtered components: mount 1`] = `
4
-[root]
5
- ▾ <Grandparent>
6
- <Child>
7
- <Child>
8
-`;
9
-
10
-exports[`OwnersListContext should fetch the owners list for the selected element that includes filtered components: owners for "Child" 1`] = `
11
-Array [
12
- Object {
13
- "displayName": "Grandparent",
14
- "hocDisplayNames": null,
15
- "id": 7,
16
- "type": 5,
17
- },
18
- Object {
19
- "displayName": "Parent",
20
- "hocDisplayNames": null,
21
- "id": 9,
22
- "type": 5,
23
- },
24
- Object {
25
- "displayName": "Child",
26
- "hocDisplayNames": null,
27
- "id": 8,
28
- "type": 5,
29
- },
30
-]
31
-`;
32
-
33
-exports[`OwnersListContext should fetch the owners list for the selected element: mount 1`] = `
34
-[root]
35
- ▾ <Grandparent>
36
- ▾ <Parent>
37
- <Child>
38
- <Child>
39
-`;
40
-
41
-exports[`OwnersListContext should fetch the owners list for the selected element: owners for "Child" 1`] = `
42
-Array [
43
- Object {
44
- "displayName": "Grandparent",
45
- "hocDisplayNames": null,
46
- "id": 2,
47
- "type": 5,
48
- },
49
- Object {
50
- "displayName": "Parent",
51
- "hocDisplayNames": null,
52
- "id": 3,
53
- "type": 5,
54
- },
55
- Object {
56
- "displayName": "Child",
57
- "hocDisplayNames": null,
58
- "id": 4,
59
- "type": 5,
60
- },
61
-]
62
-`;
63
-
64
-exports[`OwnersListContext should fetch the owners list for the selected element: owners for "Parent" 1`] = `
65
-Array [
66
- Object {
67
- "displayName": "Grandparent",
68
- "hocDisplayNames": null,
69
- "id": 2,
70
- "type": 5,
71
- },
72
- Object {
73
- "displayName": "Parent",
74
- "hocDisplayNames": null,
75
- "id": 3,
76
- "type": 5,
77
- },
78
-]
79
-`;
80
-
81
-exports[`OwnersListContext should include the current element even if there are no other owners: mount 1`] = `
82
-[root]
83
- <Grandparent>
84
-`;
85
-
86
-exports[`OwnersListContext should include the current element even if there are no other owners: owners for "Grandparent" 1`] = `
87
-Array [
88
- Object {
89
- "displayName": "Grandparent",
90
- "hocDisplayNames": null,
91
- "id": 5,
92
- "type": 5,
93
- },
94
-]
95
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/profilerContext-test.js.snap
deleted
-41
@@ -1,41 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`ProfilerContext should auto-select the root ID matching the Components tab selection if it has profiling data: mounted 1`] = `
4
-[root]
5
- ▾ <Parent>
6
- <Child>
7
-[root]
8
- ▾ <Parent>
9
- <Child>
10
-`;
11
-
12
-exports[`ProfilerContext should maintain root selection between profiling sessions so long as there is data for that root: mounted 1`] = `
13
-[root]
14
- ▾ <Parent>
15
- <Child>
16
-[root]
17
- ▾ <Parent>
18
- <Child>
19
-`;
20
-
21
-exports[`ProfilerContext should not select the root ID matching the Components tab selection if it has no profiling data: mounted 1`] = `
22
-[root]
23
- ▾ <Parent>
24
- <Child>
25
-[root]
26
- ▾ <Parent>
27
- <Child>
28
-`;
29
-
30
-exports[`ProfilerContext should sync selected element in the Components tab too, provided the element is a match: mounted 1`] = `
31
-[root]
32
- ▾ <GrandParent>
33
- ▾ <Parent>
34
- <Child>
35
-`;
36
-
37
-exports[`ProfilerContext should sync selected element in the Components tab too, provided the element is a match: updated 1`] = `
38
-[root]
39
- ▾ <GrandParent>
40
- <Parent>
41
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/profilingCache-test.js.snap
deleted
-3632
@@ -1,3632 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`ProfilingCache should calculate a self duration based on actual children (not filtered children): CommitDetails with filtered self durations 1`] = `
4
-Object {
5
- "changeDescriptions": Map {
6
- 2 => Object {
7
- "context": null,
8
- "didHooksChange": false,
9
- "isFirstMount": true,
10
- "props": null,
11
- "state": null,
12
- },
13
- 3 => Object {
14
- "context": null,
15
- "didHooksChange": false,
16
- "isFirstMount": true,
17
- "props": null,
18
- "state": null,
19
- },
20
- 5 => Object {
21
- "context": null,
22
- "didHooksChange": false,
23
- "isFirstMount": true,
24
- "props": null,
25
- "state": null,
26
- },
27
- },
28
- "duration": 16,
29
- "fiberActualDurations": Map {
30
- 1 => 16,
31
- 2 => 16,
32
- 3 => 1,
33
- 5 => 1,
34
- },
35
- "fiberSelfDurations": Map {
36
- 1 => 0,
37
- 2 => 10,
38
- 3 => 1,
39
- 5 => 1,
40
- },
41
- "interactionIDs": Array [],
42
- "priorityLevel": "Immediate",
43
- "timestamp": 16,
44
-}
45
-`;
46
-
47
-exports[`ProfilingCache should calculate self duration correctly for suspended views: CommitDetails with filtered self durations 1`] = `
48
-Object {
49
- "changeDescriptions": Map {
50
- 2 => Object {
51
- "context": null,
52
- "didHooksChange": false,
53
- "isFirstMount": true,
54
- "props": null,
55
- "state": null,
56
- },
57
- 4 => Object {
58
- "context": null,
59
- "didHooksChange": false,
60
- "isFirstMount": true,
61
- "props": null,
62
- "state": null,
63
- },
64
- },
65
- "duration": 15,
66
- "fiberActualDurations": Map {
67
- 1 => 15,
68
- 2 => 15,
69
- 3 => 5,
70
- 4 => 2,
71
- },
72
- "fiberSelfDurations": Map {
73
- 1 => 0,
74
- 2 => 10,
75
- 3 => 3,
76
- 4 => 2,
77
- },
78
- "interactionIDs": Array [],
79
- "priorityLevel": "Immediate",
80
- "timestamp": 15,
81
-}
82
-`;
83
-
84
-exports[`ProfilingCache should calculate self duration correctly for suspended views: CommitDetails with filtered self durations 2`] = `
85
-Object {
86
- "changeDescriptions": Map {
87
- 5 => Object {
88
- "context": null,
89
- "didHooksChange": false,
90
- "isFirstMount": true,
91
- "props": null,
92
- "state": null,
93
- },
94
- },
95
- "duration": 3,
96
- "fiberActualDurations": Map {
97
- 5 => 3,
98
- 3 => 3,
99
- },
100
- "fiberSelfDurations": Map {
101
- 5 => 3,
102
- 3 => 0,
103
- },
104
- "interactionIDs": Array [],
105
- "priorityLevel": "Immediate",
106
- "timestamp": 18,
107
-}
108
-`;
109
-
110
-exports[`ProfilingCache should collect data for each commit: CommitDetails commitIndex: 0 1`] = `
111
-Object {
112
- "changeDescriptions": Map {
113
- 2 => Object {
114
- "context": null,
115
- "didHooksChange": false,
116
- "isFirstMount": true,
117
- "props": null,
118
- "state": null,
119
- },
120
- 3 => Object {
121
- "context": null,
122
- "didHooksChange": false,
123
- "isFirstMount": true,
124
- "props": null,
125
- "state": null,
126
- },
127
- 4 => Object {
128
- "context": null,
129
- "didHooksChange": false,
130
- "isFirstMount": true,
131
- "props": null,
132
- "state": null,
133
- },
134
- 5 => Object {
135
- "context": null,
136
- "didHooksChange": false,
137
- "isFirstMount": true,
138
- "props": null,
139
- "state": null,
140
- },
141
- },
142
- "duration": 12,
143
- "fiberActualDurations": Map {
144
- 1 => 12,
145
- 2 => 12,
146
- 3 => 0,
147
- 4 => 1,
148
- 5 => 1,
149
- },
150
- "fiberSelfDurations": Map {
151
- 1 => 0,
152
- 2 => 10,
153
- 3 => 0,
154
- 4 => 1,
155
- 5 => 1,
156
- },
157
- "interactionIDs": Array [],
158
- "priorityLevel": "Immediate",
159
- "timestamp": 12,
160
-}
161
-`;
162
-
163
-exports[`ProfilingCache should collect data for each commit: CommitDetails commitIndex: 1 1`] = `
164
-Object {
165
- "changeDescriptions": Map {
166
- 3 => Object {
167
- "context": null,
168
- "didHooksChange": false,
169
- "isFirstMount": false,
170
- "props": Array [],
171
- "state": null,
172
- },
173
- 4 => Object {
174
- "context": null,
175
- "didHooksChange": false,
176
- "isFirstMount": false,
177
- "props": Array [],
178
- "state": null,
179
- },
180
- 6 => Object {
181
- "context": null,
182
- "didHooksChange": false,
183
- "isFirstMount": true,
184
- "props": null,
185
- "state": null,
186
- },
187
- 2 => Object {
188
- "context": null,
189
- "didHooksChange": false,
190
- "isFirstMount": false,
191
- "props": Array [
192
- "count",
193
- ],
194
- "state": null,
195
- },
196
- },
197
- "duration": 13,
198
- "fiberActualDurations": Map {
199
- 3 => 0,
200
- 4 => 1,
201
- 6 => 2,
202
- 2 => 13,
203
- 1 => 13,
204
- },
205
- "fiberSelfDurations": Map {
206
- 3 => 0,
207
- 4 => 1,
208
- 6 => 2,
209
- 2 => 10,
210
- 1 => 0,
211
- },
212
- "interactionIDs": Array [],
213
- "priorityLevel": "Immediate",
214
- "timestamp": 25,
215
-}
216
-`;
217
-
218
-exports[`ProfilingCache should collect data for each commit: CommitDetails commitIndex: 2 1`] = `
219
-Object {
220
- "changeDescriptions": Map {
221
- 3 => Object {
222
- "context": null,
223
- "didHooksChange": false,
224
- "isFirstMount": false,
225
- "props": Array [],
226
- "state": null,
227
- },
228
- 2 => Object {
229
- "context": null,
230
- "didHooksChange": false,
231
- "isFirstMount": false,
232
- "props": Array [
233
- "count",
234
- ],
235
- "state": null,
236
- },
237
- },
238
- "duration": 10,
239
- "fiberActualDurations": Map {
240
- 3 => 0,
241
- 2 => 10,
242
- 1 => 10,
243
- },
244
- "fiberSelfDurations": Map {
245
- 3 => 0,
246
- 2 => 10,
247
- 1 => 0,
248
- },
249
- "interactionIDs": Array [],
250
- "priorityLevel": "Immediate",
251
- "timestamp": 35,
252
-}
253
-`;
254
-
255
-exports[`ProfilingCache should collect data for each commit: CommitDetails commitIndex: 3 1`] = `
256
-Object {
257
- "changeDescriptions": Map {
258
- 2 => Object {
259
- "context": null,
260
- "didHooksChange": false,
261
- "isFirstMount": false,
262
- "props": Array [
263
- "count",
264
- ],
265
- "state": null,
266
- },
267
- },
268
- "duration": 10,
269
- "fiberActualDurations": Map {
270
- 2 => 10,
271
- 1 => 10,
272
- },
273
- "fiberSelfDurations": Map {
274
- 2 => 10,
275
- 1 => 0,
276
- },
277
- "interactionIDs": Array [],
278
- "priorityLevel": "Immediate",
279
- "timestamp": 45,
280
-}
281
-`;
282
-
283
-exports[`ProfilingCache should collect data for each commit: imported data 1`] = `
284
-Object {
285
- "dataForRoots": Array [
286
- Object {
287
- "commitData": Array [
288
- Object {
289
- "changeDescriptions": Array [
290
- Array [
291
- 2,
292
- Object {
293
- "context": null,
294
- "didHooksChange": false,
295
- "isFirstMount": true,
296
- "props": null,
297
- "state": null,
298
- },
299
- ],
300
- Array [
301
- 3,
302
- Object {
303
- "context": null,
304
- "didHooksChange": false,
305
- "isFirstMount": true,
306
- "props": null,
307
- "state": null,
308
- },
309
- ],
310
- Array [
311
- 4,
312
- Object {
313
- "context": null,
314
- "didHooksChange": false,
315
- "isFirstMount": true,
316
- "props": null,
317
- "state": null,
318
- },
319
- ],
320
- Array [
321
- 5,
322
- Object {
323
- "context": null,
324
- "didHooksChange": false,
325
- "isFirstMount": true,
326
- "props": null,
327
- "state": null,
328
- },
329
- ],
330
- ],
331
- "duration": 12,
332
- "fiberActualDurations": Array [
333
- Array [
334
- 1,
335
- 12,
336
- ],
337
- Array [
338
- 2,
339
- 12,
340
- ],
341
- Array [
342
- 3,
343
- 0,
344
- ],
345
- Array [
346
- 4,
347
- 1,
348
- ],
349
- Array [
350
- 5,
351
- 1,
352
- ],
353
- ],
354
- "fiberSelfDurations": Array [
355
- Array [
356
- 1,
357
- 0,
358
- ],
359
- Array [
360
- 2,
361
- 10,
362
- ],
363
- Array [
364
- 3,
365
- 0,
366
- ],
367
- Array [
368
- 4,
369
- 1,
370
- ],
371
- Array [
372
- 5,
373
- 1,
374
- ],
375
- ],
376
- "interactionIDs": Array [],
377
- "priorityLevel": "Immediate",
378
- "timestamp": 12,
379
- },
380
- Object {
381
- "changeDescriptions": Array [
382
- Array [
383
- 3,
384
- Object {
385
- "context": null,
386
- "didHooksChange": false,
387
- "isFirstMount": false,
388
- "props": Array [],
389
- "state": null,
390
- },
391
- ],
392
- Array [
393
- 4,
394
- Object {
395
- "context": null,
396
- "didHooksChange": false,
397
- "isFirstMount": false,
398
- "props": Array [],
399
- "state": null,
400
- },
401
- ],
402
- Array [
403
- 6,
404
- Object {
405
- "context": null,
406
- "didHooksChange": false,
407
- "isFirstMount": true,
408
- "props": null,
409
- "state": null,
410
- },
411
- ],
412
- Array [
413
- 2,
414
- Object {
415
- "context": null,
416
- "didHooksChange": false,
417
- "isFirstMount": false,
418
- "props": Array [
419
- "count",
420
- ],
421
- "state": null,
422
- },
423
- ],
424
- ],
425
- "duration": 13,
426
- "fiberActualDurations": Array [
427
- Array [
428
- 3,
429
- 0,
430
- ],
431
- Array [
432
- 4,
433
- 1,
434
- ],
435
- Array [
436
- 6,
437
- 2,
438
- ],
439
- Array [
440
- 2,
441
- 13,
442
- ],
443
- Array [
444
- 1,
445
- 13,
446
- ],
447
- ],
448
- "fiberSelfDurations": Array [
449
- Array [
450
- 3,
451
- 0,
452
- ],
453
- Array [
454
- 4,
455
- 1,
456
- ],
457
- Array [
458
- 6,
459
- 2,
460
- ],
461
- Array [
462
- 2,
463
- 10,
464
- ],
465
- Array [
466
- 1,
467
- 0,
468
- ],
469
- ],
470
- "interactionIDs": Array [],
471
- "priorityLevel": "Immediate",
472
- "timestamp": 25,
473
- },
474
- Object {
475
- "changeDescriptions": Array [
476
- Array [
477
- 3,
478
- Object {
479
- "context": null,
480
- "didHooksChange": false,
481
- "isFirstMount": false,
482
- "props": Array [],
483
- "state": null,
484
- },
485
- ],
486
- Array [
487
- 2,
488
- Object {
489
- "context": null,
490
- "didHooksChange": false,
491
- "isFirstMount": false,
492
- "props": Array [
493
- "count",
494
- ],
495
- "state": null,
496
- },
497
- ],
498
- ],
499
- "duration": 10,
500
- "fiberActualDurations": Array [
501
- Array [
502
- 3,
503
- 0,
504
- ],
505
- Array [
506
- 2,
507
- 10,
508
- ],
509
- Array [
510
- 1,
511
- 10,
512
- ],
513
- ],
514
- "fiberSelfDurations": Array [
515
- Array [
516
- 3,
517
- 0,
518
- ],
519
- Array [
520
- 2,
521
- 10,
522
- ],
523
- Array [
524
- 1,
525
- 0,
526
- ],
527
- ],
528
- "interactionIDs": Array [],
529
- "priorityLevel": "Immediate",
530
- "timestamp": 35,
531
- },
532
- Object {
533
- "changeDescriptions": Array [
534
- Array [
535
- 2,
536
- Object {
537
- "context": null,
538
- "didHooksChange": false,
539
- "isFirstMount": false,
540
- "props": Array [
541
- "count",
542
- ],
543
- "state": null,
544
- },
545
- ],
546
- ],
547
- "duration": 10,
548
- "fiberActualDurations": Array [
549
- Array [
550
- 2,
551
- 10,
552
- ],
553
- Array [
554
- 1,
555
- 10,
556
- ],
557
- ],
558
- "fiberSelfDurations": Array [
559
- Array [
560
- 2,
561
- 10,
562
- ],
563
- Array [
564
- 1,
565
- 0,
566
- ],
567
- ],
568
- "interactionIDs": Array [],
569
- "priorityLevel": "Immediate",
570
- "timestamp": 45,
571
- },
572
- ],
573
- "displayName": "Parent",
574
- "initialTreeBaseDurations": Array [],
575
- "interactionCommits": Array [],
576
- "interactions": Array [],
577
- "operations": Array [
578
- Array [
579
- 1,
580
- 1,
581
- 17,
582
- 6,
583
- 80,
584
- 97,
585
- 114,
586
- 101,
587
- 110,
588
- 116,
589
- 5,
590
- 67,
591
- 104,
592
- 105,
593
- 108,
594
- 100,
595
- 1,
596
- 48,
597
- 1,
598
- 49,
599
- 1,
600
- 1,
601
- 11,
602
- 1,
603
- 1,
604
- 4,
605
- 1,
606
- 12000,
607
- 1,
608
- 2,
609
- 5,
610
- 1,
611
- 0,
612
- 1,
613
- 0,
614
- 4,
615
- 2,
616
- 12000,
617
- 1,
618
- 3,
619
- 5,
620
- 2,
621
- 2,
622
- 2,
623
- 3,
624
- 4,
625
- 3,
626
- 0,
627
- 1,
628
- 4,
629
- 5,
630
- 2,
631
- 2,
632
- 2,
633
- 4,
634
- 4,
635
- 4,
636
- 1000,
637
- 1,
638
- 5,
639
- 8,
640
- 2,
641
- 2,
642
- 2,
643
- 0,
644
- 4,
645
- 5,
646
- 1000,
647
- ],
648
- Array [
649
- 1,
650
- 1,
651
- 8,
652
- 5,
653
- 67,
654
- 104,
655
- 105,
656
- 108,
657
- 100,
658
- 1,
659
- 50,
660
- 1,
661
- 6,
662
- 5,
663
- 2,
664
- 2,
665
- 1,
666
- 2,
667
- 4,
668
- 6,
669
- 2000,
670
- 4,
671
- 2,
672
- 14000,
673
- 3,
674
- 2,
675
- 4,
676
- 3,
677
- 4,
678
- 6,
679
- 5,
680
- 4,
681
- 1,
682
- 14000,
683
- ],
684
- Array [
685
- 1,
686
- 1,
687
- 0,
688
- 2,
689
- 2,
690
- 6,
691
- 4,
692
- 4,
693
- 2,
694
- 11000,
695
- 3,
696
- 2,
697
- 2,
698
- 3,
699
- 5,
700
- 4,
701
- 1,
702
- 11000,
703
- ],
704
- Array [
705
- 1,
706
- 1,
707
- 0,
708
- 2,
709
- 1,
710
- 3,
711
- ],
712
- ],
713
- "rootID": 1,
714
- "snapshots": Array [],
715
- },
716
- ],
717
- "version": 4,
718
-}
719
-`;
720
-
721
-exports[`ProfilingCache should collect data for each rendered fiber: FiberCommits: element 2 1`] = `
722
-Array [
723
- 0,
724
- 1,
725
- 2,
726
-]
727
-`;
728
-
729
-exports[`ProfilingCache should collect data for each rendered fiber: FiberCommits: element 3 1`] = `
730
-Array [
731
- 0,
732
- 1,
733
- 2,
734
-]
735
-`;
736
-
737
-exports[`ProfilingCache should collect data for each rendered fiber: FiberCommits: element 4 1`] = `
738
-Array [
739
- 0,
740
-]
741
-`;
742
-
743
-exports[`ProfilingCache should collect data for each rendered fiber: FiberCommits: element 5 1`] = `
744
-Array [
745
- 1,
746
- 2,
747
-]
748
-`;
749
-
750
-exports[`ProfilingCache should collect data for each rendered fiber: FiberCommits: element 6 1`] = `
751
-Array [
752
- 2,
753
-]
754
-`;
755
-
756
-exports[`ProfilingCache should collect data for each rendered fiber: imported data 1`] = `
757
-Object {
758
- "dataForRoots": Array [
759
- Object {
760
- "commitData": Array [
761
- Object {
762
- "changeDescriptions": Array [
763
- Array [
764
- 2,
765
- Object {
766
- "context": null,
767
- "didHooksChange": false,
768
- "isFirstMount": true,
769
- "props": null,
770
- "state": null,
771
- },
772
- ],
773
- Array [
774
- 3,
775
- Object {
776
- "context": null,
777
- "didHooksChange": false,
778
- "isFirstMount": true,
779
- "props": null,
780
- "state": null,
781
- },
782
- ],
783
- Array [
784
- 4,
785
- Object {
786
- "context": null,
787
- "didHooksChange": false,
788
- "isFirstMount": true,
789
- "props": null,
790
- "state": null,
791
- },
792
- ],
793
- ],
794
- "duration": 11,
795
- "fiberActualDurations": Array [
796
- Array [
797
- 1,
798
- 11,
799
- ],
800
- Array [
801
- 2,
802
- 11,
803
- ],
804
- Array [
805
- 3,
806
- 0,
807
- ],
808
- Array [
809
- 4,
810
- 1,
811
- ],
812
- ],
813
- "fiberSelfDurations": Array [
814
- Array [
815
- 1,
816
- 0,
817
- ],
818
- Array [
819
- 2,
820
- 10,
821
- ],
822
- Array [
823
- 3,
824
- 0,
825
- ],
826
- Array [
827
- 4,
828
- 1,
829
- ],
830
- ],
831
- "interactionIDs": Array [],
832
- "priorityLevel": "Immediate",
833
- "timestamp": 11,
834
- },
835
- Object {
836
- "changeDescriptions": Array [
837
- Array [
838
- 3,
839
- Object {
840
- "context": null,
841
- "didHooksChange": false,
842
- "isFirstMount": false,
843
- "props": Array [],
844
- "state": null,
845
- },
846
- ],
847
- Array [
848
- 5,
849
- Object {
850
- "context": null,
851
- "didHooksChange": false,
852
- "isFirstMount": true,
853
- "props": null,
854
- "state": null,
855
- },
856
- ],
857
- Array [
858
- 2,
859
- Object {
860
- "context": null,
861
- "didHooksChange": false,
862
- "isFirstMount": false,
863
- "props": Array [
864
- "count",
865
- ],
866
- "state": null,
867
- },
868
- ],
869
- ],
870
- "duration": 11,
871
- "fiberActualDurations": Array [
872
- Array [
873
- 3,
874
- 0,
875
- ],
876
- Array [
877
- 5,
878
- 1,
879
- ],
880
- Array [
881
- 2,
882
- 11,
883
- ],
884
- Array [
885
- 1,
886
- 11,
887
- ],
888
- ],
889
- "fiberSelfDurations": Array [
890
- Array [
891
- 3,
892
- 0,
893
- ],
894
- Array [
895
- 5,
896
- 1,
897
- ],
898
- Array [
899
- 2,
900
- 10,
901
- ],
902
- Array [
903
- 1,
904
- 0,
905
- ],
906
- ],
907
- "interactionIDs": Array [],
908
- "priorityLevel": "Immediate",
909
- "timestamp": 22,
910
- },
911
- Object {
912
- "changeDescriptions": Array [
913
- Array [
914
- 3,
915
- Object {
916
- "context": null,
917
- "didHooksChange": false,
918
- "isFirstMount": false,
919
- "props": Array [],
920
- "state": null,
921
- },
922
- ],
923
- Array [
924
- 5,
925
- Object {
926
- "context": null,
927
- "didHooksChange": false,
928
- "isFirstMount": false,
929
- "props": Array [],
930
- "state": null,
931
- },
932
- ],
933
- Array [
934
- 6,
935
- Object {
936
- "context": null,
937
- "didHooksChange": false,
938
- "isFirstMount": true,
939
- "props": null,
940
- "state": null,
941
- },
942
- ],
943
- Array [
944
- 2,
945
- Object {
946
- "context": null,
947
- "didHooksChange": false,
948
- "isFirstMount": false,
949
- "props": Array [
950
- "count",
951
- ],
952
- "state": null,
953
- },
954
- ],
955
- ],
956
- "duration": 13,
957
- "fiberActualDurations": Array [
958
- Array [
959
- 3,
960
- 0,
961
- ],
962
- Array [
963
- 5,
964
- 1,
965
- ],
966
- Array [
967
- 6,
968
- 2,
969
- ],
970
- Array [
971
- 2,
972
- 13,
973
- ],
974
- Array [
975
- 1,
976
- 13,
977
- ],
978
- ],
979
- "fiberSelfDurations": Array [
980
- Array [
981
- 3,
982
- 0,
983
- ],
984
- Array [
985
- 5,
986
- 1,
987
- ],
988
- Array [
989
- 6,
990
- 2,
991
- ],
992
- Array [
993
- 2,
994
- 10,
995
- ],
996
- Array [
997
- 1,
998
- 0,
999
- ],
1000
- ],
1001
- "interactionIDs": Array [],
1002
- "priorityLevel": "Immediate",
1003
- "timestamp": 35,
1004
- },
1005
- ],
1006
- "displayName": "Parent",
1007
- "initialTreeBaseDurations": Array [],
1008
- "interactionCommits": Array [],
1009
- "interactions": Array [],
1010
- "operations": Array [
1011
- Array [
1012
- 1,
1013
- 1,
1014
- 15,
1015
- 6,
1016
- 80,
1017
- 97,
1018
- 114,
1019
- 101,
1020
- 110,
1021
- 116,
1022
- 5,
1023
- 67,
1024
- 104,
1025
- 105,
1026
- 108,
1027
- 100,
1028
- 1,
1029
- 48,
1030
- 1,
1031
- 1,
1032
- 11,
1033
- 1,
1034
- 1,
1035
- 4,
1036
- 1,
1037
- 11000,
1038
- 1,
1039
- 2,
1040
- 5,
1041
- 1,
1042
- 0,
1043
- 1,
1044
- 0,
1045
- 4,
1046
- 2,
1047
- 11000,
1048
- 1,
1049
- 3,
1050
- 5,
1051
- 2,
1052
- 2,
1053
- 2,
1054
- 3,
1055
- 4,
1056
- 3,
1057
- 0,
1058
- 1,
1059
- 4,
1060
- 8,
1061
- 2,
1062
- 2,
1063
- 2,
1064
- 0,
1065
- 4,
1066
- 4,
1067
- 1000,
1068
- ],
1069
- Array [
1070
- 1,
1071
- 1,
1072
- 8,
1073
- 5,
1074
- 67,
1075
- 104,
1076
- 105,
1077
- 108,
1078
- 100,
1079
- 1,
1080
- 49,
1081
- 1,
1082
- 5,
1083
- 5,
1084
- 2,
1085
- 2,
1086
- 1,
1087
- 2,
1088
- 4,
1089
- 5,
1090
- 1000,
1091
- 4,
1092
- 2,
1093
- 12000,
1094
- 3,
1095
- 2,
1096
- 3,
1097
- 3,
1098
- 5,
1099
- 4,
1100
- 4,
1101
- 1,
1102
- 12000,
1103
- ],
1104
- Array [
1105
- 1,
1106
- 1,
1107
- 8,
1108
- 5,
1109
- 67,
1110
- 104,
1111
- 105,
1112
- 108,
1113
- 100,
1114
- 1,
1115
- 50,
1116
- 1,
1117
- 6,
1118
- 5,
1119
- 2,
1120
- 2,
1121
- 1,
1122
- 2,
1123
- 4,
1124
- 6,
1125
- 2000,
1126
- 4,
1127
- 2,
1128
- 14000,
1129
- 3,
1130
- 2,
1131
- 4,
1132
- 3,
1133
- 5,
1134
- 6,
1135
- 4,
1136
- 4,
1137
- 1,
1138
- 14000,
1139
- ],
1140
- ],
1141
- "rootID": 1,
1142
- "snapshots": Array [],
1143
- },
1144
- ],
1145
- "version": 4,
1146
-}
1147
-`;
1148
-
1149
-exports[`ProfilingCache should collect data for each root (including ones added or mounted after profiling started): Data for root Parent 1`] = `
1150
-Object {
1151
- "commitData": Array [
1152
- Object {
1153
- "changeDescriptions": Map {
1154
- 3 => Object {
1155
- "context": null,
1156
- "didHooksChange": false,
1157
- "isFirstMount": false,
1158
- "props": Array [],
1159
- "state": null,
1160
- },
1161
- 4 => Object {
1162
- "context": null,
1163
- "didHooksChange": false,
1164
- "isFirstMount": false,
1165
- "props": Array [],
1166
- "state": null,
1167
- },
1168
- 10 => Object {
1169
- "context": null,
1170
- "didHooksChange": false,
1171
- "isFirstMount": true,
1172
- "props": null,
1173
- "state": null,
1174
- },
1175
- 2 => Object {
1176
- "context": null,
1177
- "didHooksChange": false,
1178
- "isFirstMount": false,
1179
- "props": Array [
1180
- "count",
1181
- ],
1182
- "state": null,
1183
- },
1184
- },
1185
- "duration": 13,
1186
- "fiberActualDurations": Map {
1187
- 3 => 0,
1188
- 4 => 1,
1189
- 10 => 2,
1190
- 2 => 13,
1191
- 1 => 13,
1192
- },
1193
- "fiberSelfDurations": Map {
1194
- 3 => 0,
1195
- 4 => 1,
1196
- 10 => 2,
1197
- 2 => 10,
1198
- 1 => 0,
1199
- },
1200
- "interactionIDs": Array [],
1201
- "priorityLevel": "Immediate",
1202
- "timestamp": 13,
1203
- },
1204
- Object {
1205
- "changeDescriptions": Map {
1206
- 3 => Object {
1207
- "context": null,
1208
- "didHooksChange": false,
1209
- "isFirstMount": false,
1210
- "props": Array [],
1211
- "state": null,
1212
- },
1213
- 2 => Object {
1214
- "context": null,
1215
- "didHooksChange": false,
1216
- "isFirstMount": false,
1217
- "props": Array [
1218
- "count",
1219
- ],
1220
- "state": null,
1221
- },
1222
- },
1223
- "duration": 10,
1224
- "fiberActualDurations": Map {
1225
- 3 => 0,
1226
- 2 => 10,
1227
- 1 => 10,
1228
- },
1229
- "fiberSelfDurations": Map {
1230
- 3 => 0,
1231
- 2 => 10,
1232
- 1 => 0,
1233
- },
1234
- "interactionIDs": Array [],
1235
- "priorityLevel": "Immediate",
1236
- "timestamp": 34,
1237
- },
1238
- Object {
1239
- "changeDescriptions": Map {
1240
- 2 => Object {
1241
- "context": null,
1242
- "didHooksChange": false,
1243
- "isFirstMount": false,
1244
- "props": Array [
1245
- "count",
1246
- ],
1247
- "state": null,
1248
- },
1249
- },
1250
- "duration": 10,
1251
- "fiberActualDurations": Map {
1252
- 2 => 10,
1253
- 1 => 10,
1254
- },
1255
- "fiberSelfDurations": Map {
1256
- 2 => 10,
1257
- 1 => 0,
1258
- },
1259
- "interactionIDs": Array [],
1260
- "priorityLevel": "Immediate",
1261
- "timestamp": 44,
1262
- },
1263
- ],
1264
- "displayName": "Parent",
1265
- "initialTreeBaseDurations": Map {
1266
- 1 => 12,
1267
- 2 => 12,
1268
- 3 => 0,
1269
- 4 => 1,
1270
- 5 => 1,
1271
- },
1272
- "interactionCommits": Map {},
1273
- "interactions": Map {},
1274
- "operations": Array [
1275
- Array [
1276
- 1,
1277
- 1,
1278
- 8,
1279
- 5,
1280
- 67,
1281
- 104,
1282
- 105,
1283
- 108,
1284
- 100,
1285
- 1,
1286
- 50,
1287
- 1,
1288
- 10,
1289
- 5,
1290
- 2,
1291
- 2,
1292
- 1,
1293
- 2,
1294
- 4,
1295
- 10,
1296
- 2000,
1297
- 4,
1298
- 2,
1299
- 14000,
1300
- 3,
1301
- 2,
1302
- 4,
1303
- 3,
1304
- 4,
1305
- 10,
1306
- 5,
1307
- 4,
1308
- 1,
1309
- 14000,
1310
- ],
1311
- Array [
1312
- 1,
1313
- 1,
1314
- 0,
1315
- 2,
1316
- 2,
1317
- 10,
1318
- 4,
1319
- 4,
1320
- 2,
1321
- 11000,
1322
- 3,
1323
- 2,
1324
- 2,
1325
- 3,
1326
- 5,
1327
- 4,
1328
- 1,
1329
- 11000,
1330
- ],
1331
- Array [
1332
- 1,
1333
- 1,
1334
- 0,
1335
- 2,
1336
- 1,
1337
- 3,
1338
- ],
1339
- ],
1340
- "rootID": 1,
1341
- "snapshots": Map {
1342
- 1 => Object {
1343
- "children": Array [
1344
- 2,
1345
- ],
1346
- "displayName": null,
1347
- "id": 1,
1348
- "key": null,
1349
- "type": 11,
1350
- },
1351
- 2 => Object {
1352
- "children": Array [
1353
- 3,
1354
- 4,
1355
- 5,
1356
- ],
1357
- "displayName": "Parent",
1358
- "id": 2,
1359
- "key": null,
1360
- "type": 5,
1361
- },
1362
- 3 => Object {
1363
- "children": Array [],
1364
- "displayName": "Child",
1365
- "id": 3,
1366
- "key": "0",
1367
- "type": 5,
1368
- },
1369
- 4 => Object {
1370
- "children": Array [],
1371
- "displayName": "Child",
1372
- "id": 4,
1373
- "key": "1",
1374
- "type": 5,
1375
- },
1376
- 5 => Object {
1377
- "children": Array [],
1378
- "displayName": "Child",
1379
- "id": 5,
1380
- "key": null,
1381
- "type": 8,
1382
- },
1383
- },
1384
-}
1385
-`;
1386
-
1387
-exports[`ProfilingCache should collect data for each root (including ones added or mounted after profiling started): Data for root Parent 2`] = `
1388
-Object {
1389
- "commitData": Array [
1390
- Object {
1391
- "changeDescriptions": Map {
1392
- 12 => Object {
1393
- "context": null,
1394
- "didHooksChange": false,
1395
- "isFirstMount": true,
1396
- "props": null,
1397
- "state": null,
1398
- },
1399
- 13 => Object {
1400
- "context": null,
1401
- "didHooksChange": false,
1402
- "isFirstMount": true,
1403
- "props": null,
1404
- "state": null,
1405
- },
1406
- 14 => Object {
1407
- "context": null,
1408
- "didHooksChange": false,
1409
- "isFirstMount": true,
1410
- "props": null,
1411
- "state": null,
1412
- },
1413
- },
1414
- "duration": 11,
1415
- "fiberActualDurations": Map {
1416
- 11 => 11,
1417
- 12 => 11,
1418
- 13 => 0,
1419
- 14 => 1,
1420
- },
1421
- "fiberSelfDurations": Map {
1422
- 11 => 0,
1423
- 12 => 10,
1424
- 13 => 0,
1425
- 14 => 1,
1426
- },
1427
- "interactionIDs": Array [],
1428
- "priorityLevel": "Immediate",
1429
- "timestamp": 24,
1430
- },
1431
- ],
1432
- "displayName": "Parent",
1433
- "initialTreeBaseDurations": Map {},
1434
- "interactionCommits": Map {},
1435
- "interactions": Map {},
1436
- "operations": Array [
1437
- Array [
1438
- 1,
1439
- 11,
1440
- 15,
1441
- 6,
1442
- 80,
1443
- 97,
1444
- 114,
1445
- 101,
1446
- 110,
1447
- 116,
1448
- 5,
1449
- 67,
1450
- 104,
1451
- 105,
1452
- 108,
1453
- 100,
1454
- 1,
1455
- 48,
1456
- 1,
1457
- 11,
1458
- 11,
1459
- 1,
1460
- 1,
1461
- 4,
1462
- 11,
1463
- 11000,
1464
- 1,
1465
- 12,
1466
- 5,
1467
- 11,
1468
- 0,
1469
- 1,
1470
- 0,
1471
- 4,
1472
- 12,
1473
- 11000,
1474
- 1,
1475
- 13,
1476
- 5,
1477
- 12,
1478
- 12,
1479
- 2,
1480
- 3,
1481
- 4,
1482
- 13,
1483
- 0,
1484
- 1,
1485
- 14,
1486
- 8,
1487
- 12,
1488
- 12,
1489
- 2,
1490
- 0,
1491
- 4,
1492
- 14,
1493
- 1000,
1494
- ],
1495
- ],
1496
- "rootID": 11,
1497
- "snapshots": Map {},
1498
-}
1499
-`;
1500
-
1501
-exports[`ProfilingCache should collect data for each root (including ones added or mounted after profiling started): Data for root Parent 3`] = `
1502
-Object {
1503
- "commitData": Array [
1504
- Object {
1505
- "changeDescriptions": Map {},
1506
- "duration": 0,
1507
- "fiberActualDurations": Map {},
1508
- "fiberSelfDurations": Map {},
1509
- "interactionIDs": Array [],
1510
- "priorityLevel": "Immediate",
1511
- "timestamp": 34,
1512
- },
1513
- ],
1514
- "displayName": "Parent",
1515
- "initialTreeBaseDurations": Map {
1516
- 6 => 11,
1517
- 7 => 11,
1518
- 8 => 0,
1519
- 9 => 1,
1520
- },
1521
- "interactionCommits": Map {},
1522
- "interactions": Map {},
1523
- "operations": Array [
1524
- Array [
1525
- 1,
1526
- 6,
1527
- 0,
1528
- 2,
1529
- 4,
1530
- 9,
1531
- 8,
1532
- 7,
1533
- 6,
1534
- ],
1535
- ],
1536
- "rootID": 6,
1537
- "snapshots": Map {
1538
- 6 => Object {
1539
- "children": Array [
1540
- 7,
1541
- ],
1542
- "displayName": null,
1543
- "id": 6,
1544
- "key": null,
1545
- "type": 11,
1546
- },
1547
- 7 => Object {
1548
- "children": Array [
1549
- 8,
1550
- 9,
1551
- ],
1552
- "displayName": "Parent",
1553
- "id": 7,
1554
- "key": null,
1555
- "type": 5,
1556
- },
1557
- 8 => Object {
1558
- "children": Array [],
1559
- "displayName": "Child",
1560
- "id": 8,
1561
- "key": "0",
1562
- "type": 5,
1563
- },
1564
- 9 => Object {
1565
- "children": Array [],
1566
- "displayName": "Child",
1567
- "id": 9,
1568
- "key": null,
1569
- "type": 8,
1570
- },
1571
- },
1572
-}
1573
-`;
1574
-
1575
-exports[`ProfilingCache should collect data for each root (including ones added or mounted after profiling started): imported data 1`] = `
1576
-Object {
1577
- "dataForRoots": Array [
1578
- Object {
1579
- "commitData": Array [
1580
- Object {
1581
- "changeDescriptions": Array [
1582
- Array [
1583
- 3,
1584
- Object {
1585
- "context": null,
1586
- "didHooksChange": false,
1587
- "isFirstMount": false,
1588
- "props": Array [],
1589
- "state": null,
1590
- },
1591
- ],
1592
- Array [
1593
- 4,
1594
- Object {
1595
- "context": null,
1596
- "didHooksChange": false,
1597
- "isFirstMount": false,
1598
- "props": Array [],
1599
- "state": null,
1600
- },
1601
- ],
1602
- Array [
1603
- 10,
1604
- Object {
1605
- "context": null,
1606
- "didHooksChange": false,
1607
- "isFirstMount": true,
1608
- "props": null,
1609
- "state": null,
1610
- },
1611
- ],
1612
- Array [
1613
- 2,
1614
- Object {
1615
- "context": null,
1616
- "didHooksChange": false,
1617
- "isFirstMount": false,
1618
- "props": Array [
1619
- "count",
1620
- ],
1621
- "state": null,
1622
- },
1623
- ],
1624
- ],
1625
- "duration": 13,
1626
- "fiberActualDurations": Array [
1627
- Array [
1628
- 3,
1629
- 0,
1630
- ],
1631
- Array [
1632
- 4,
1633
- 1,
1634
- ],
1635
- Array [
1636
- 10,
1637
- 2,
1638
- ],
1639
- Array [
1640
- 2,
1641
- 13,
1642
- ],
1643
- Array [
1644
- 1,
1645
- 13,
1646
- ],
1647
- ],
1648
- "fiberSelfDurations": Array [
1649
- Array [
1650
- 3,
1651
- 0,
1652
- ],
1653
- Array [
1654
- 4,
1655
- 1,
1656
- ],
1657
- Array [
1658
- 10,
1659
- 2,
1660
- ],
1661
- Array [
1662
- 2,
1663
- 10,
1664
- ],
1665
- Array [
1666
- 1,
1667
- 0,
1668
- ],
1669
- ],
1670
- "interactionIDs": Array [],
1671
- "priorityLevel": "Immediate",
1672
- "timestamp": 13,
1673
- },
1674
- Object {
1675
- "changeDescriptions": Array [
1676
- Array [
1677
- 3,
1678
- Object {
1679
- "context": null,
1680
- "didHooksChange": false,
1681
- "isFirstMount": false,
1682
- "props": Array [],
1683
- "state": null,
1684
- },
1685
- ],
1686
- Array [
1687
- 2,
1688
- Object {
1689
- "context": null,
1690
- "didHooksChange": false,
1691
- "isFirstMount": false,
1692
- "props": Array [
1693
- "count",
1694
- ],
1695
- "state": null,
1696
- },
1697
- ],
1698
- ],
1699
- "duration": 10,
1700
- "fiberActualDurations": Array [
1701
- Array [
1702
- 3,
1703
- 0,
1704
- ],
1705
- Array [
1706
- 2,
1707
- 10,
1708
- ],
1709
- Array [
1710
- 1,
1711
- 10,
1712
- ],
1713
- ],
1714
- "fiberSelfDurations": Array [
1715
- Array [
1716
- 3,
1717
- 0,
1718
- ],
1719
- Array [
1720
- 2,
1721
- 10,
1722
- ],
1723
- Array [
1724
- 1,
1725
- 0,
1726
- ],
1727
- ],
1728
- "interactionIDs": Array [],
1729
- "priorityLevel": "Immediate",
1730
- "timestamp": 34,
1731
- },
1732
- Object {
1733
- "changeDescriptions": Array [
1734
- Array [
1735
- 2,
1736
- Object {
1737
- "context": null,
1738
- "didHooksChange": false,
1739
- "isFirstMount": false,
1740
- "props": Array [
1741
- "count",
1742
- ],
1743
- "state": null,
1744
- },
1745
- ],
1746
- ],
1747
- "duration": 10,
1748
- "fiberActualDurations": Array [
1749
- Array [
1750
- 2,
1751
- 10,
1752
- ],
1753
- Array [
1754
- 1,
1755
- 10,
1756
- ],
1757
- ],
1758
- "fiberSelfDurations": Array [
1759
- Array [
1760
- 2,
1761
- 10,
1762
- ],
1763
- Array [
1764
- 1,
1765
- 0,
1766
- ],
1767
- ],
1768
- "interactionIDs": Array [],
1769
- "priorityLevel": "Immediate",
1770
- "timestamp": 44,
1771
- },
1772
- ],
1773
- "displayName": "Parent",
1774
- "initialTreeBaseDurations": Array [
1775
- Array [
1776
- 1,
1777
- 12,
1778
- ],
1779
- Array [
1780
- 2,
1781
- 12,
1782
- ],
1783
- Array [
1784
- 3,
1785
- 0,
1786
- ],
1787
- Array [
1788
- 4,
1789
- 1,
1790
- ],
1791
- Array [
1792
- 5,
1793
- 1,
1794
- ],
1795
- ],
1796
- "interactionCommits": Array [],
1797
- "interactions": Array [],
1798
- "operations": Array [
1799
- Array [
1800
- 1,
1801
- 1,
1802
- 8,
1803
- 5,
1804
- 67,
1805
- 104,
1806
- 105,
1807
- 108,
1808
- 100,
1809
- 1,
1810
- 50,
1811
- 1,
1812
- 10,
1813
- 5,
1814
- 2,
1815
- 2,
1816
- 1,
1817
- 2,
1818
- 4,
1819
- 10,
1820
- 2000,
1821
- 4,
1822
- 2,
1823
- 14000,
1824
- 3,
1825
- 2,
1826
- 4,
1827
- 3,
1828
- 4,
1829
- 10,
1830
- 5,
1831
- 4,
1832
- 1,
1833
- 14000,
1834
- ],
1835
- Array [
1836
- 1,
1837
- 1,
1838
- 0,
1839
- 2,
1840
- 2,
1841
- 10,
1842
- 4,
1843
- 4,
1844
- 2,
1845
- 11000,
1846
- 3,
1847
- 2,
1848
- 2,
1849
- 3,
1850
- 5,
1851
- 4,
1852
- 1,
1853
- 11000,
1854
- ],
1855
- Array [
1856
- 1,
1857
- 1,
1858
- 0,
1859
- 2,
1860
- 1,
1861
- 3,
1862
- ],
1863
- ],
1864
- "rootID": 1,
1865
- "snapshots": Array [
1866
- Array [
1867
- 1,
1868
- Object {
1869
- "children": Array [
1870
- 2,
1871
- ],
1872
- "displayName": null,
1873
- "id": 1,
1874
- "key": null,
1875
- "type": 11,
1876
- },
1877
- ],
1878
- Array [
1879
- 2,
1880
- Object {
1881
- "children": Array [
1882
- 3,
1883
- 4,
1884
- 5,
1885
- ],
1886
- "displayName": "Parent",
1887
- "id": 2,
1888
- "key": null,
1889
- "type": 5,
1890
- },
1891
- ],
1892
- Array [
1893
- 3,
1894
- Object {
1895
- "children": Array [],
1896
- "displayName": "Child",
1897
- "id": 3,
1898
- "key": "0",
1899
- "type": 5,
1900
- },
1901
- ],
1902
- Array [
1903
- 4,
1904
- Object {
1905
- "children": Array [],
1906
- "displayName": "Child",
1907
- "id": 4,
1908
- "key": "1",
1909
- "type": 5,
1910
- },
1911
- ],
1912
- Array [
1913
- 5,
1914
- Object {
1915
- "children": Array [],
1916
- "displayName": "Child",
1917
- "id": 5,
1918
- "key": null,
1919
- "type": 8,
1920
- },
1921
- ],
1922
- ],
1923
- },
1924
- Object {
1925
- "commitData": Array [
1926
- Object {
1927
- "changeDescriptions": Array [
1928
- Array [
1929
- 12,
1930
- Object {
1931
- "context": null,
1932
- "didHooksChange": false,
1933
- "isFirstMount": true,
1934
- "props": null,
1935
- "state": null,
1936
- },
1937
- ],
1938
- Array [
1939
- 13,
1940
- Object {
1941
- "context": null,
1942
- "didHooksChange": false,
1943
- "isFirstMount": true,
1944
- "props": null,
1945
- "state": null,
1946
- },
1947
- ],
1948
- Array [
1949
- 14,
1950
- Object {
1951
- "context": null,
1952
- "didHooksChange": false,
1953
- "isFirstMount": true,
1954
- "props": null,
1955
- "state": null,
1956
- },
1957
- ],
1958
- ],
1959
- "duration": 11,
1960
- "fiberActualDurations": Array [
1961
- Array [
1962
- 11,
1963
- 11,
1964
- ],
1965
- Array [
1966
- 12,
1967
- 11,
1968
- ],
1969
- Array [
1970
- 13,
1971
- 0,
1972
- ],
1973
- Array [
1974
- 14,
1975
- 1,
1976
- ],
1977
- ],
1978
- "fiberSelfDurations": Array [
1979
- Array [
1980
- 11,
1981
- 0,
1982
- ],
1983
- Array [
1984
- 12,
1985
- 10,
1986
- ],
1987
- Array [
1988
- 13,
1989
- 0,
1990
- ],
1991
- Array [
1992
- 14,
1993
- 1,
1994
- ],
1995
- ],
1996
- "interactionIDs": Array [],
1997
- "priorityLevel": "Immediate",
1998
- "timestamp": 24,
1999
- },
2000
- ],
2001
- "displayName": "Parent",
2002
- "initialTreeBaseDurations": Array [],
2003
- "interactionCommits": Array [],
2004
- "interactions": Array [],
2005
- "operations": Array [
2006
- Array [
2007
- 1,
2008
- 11,
2009
- 15,
2010
- 6,
2011
- 80,
2012
- 97,
2013
- 114,
2014
- 101,
2015
- 110,
2016
- 116,
2017
- 5,
2018
- 67,
2019
- 104,
2020
- 105,
2021
- 108,
2022
- 100,
2023
- 1,
2024
- 48,
2025
- 1,
2026
- 11,
2027
- 11,
2028
- 1,
2029
- 1,
2030
- 4,
2031
- 11,
2032
- 11000,
2033
- 1,
2034
- 12,
2035
- 5,
2036
- 11,
2037
- 0,
2038
- 1,
2039
- 0,
2040
- 4,
2041
- 12,
2042
- 11000,
2043
- 1,
2044
- 13,
2045
- 5,
2046
- 12,
2047
- 12,
2048
- 2,
2049
- 3,
2050
- 4,
2051
- 13,
2052
- 0,
2053
- 1,
2054
- 14,
2055
- 8,
2056
- 12,
2057
- 12,
2058
- 2,
2059
- 0,
2060
- 4,
2061
- 14,
2062
- 1000,
2063
- ],
2064
- ],
2065
- "rootID": 11,
2066
- "snapshots": Array [],
2067
- },
2068
- Object {
2069
- "commitData": Array [
2070
- Object {
2071
- "changeDescriptions": Array [],
2072
- "duration": 0,
2073
- "fiberActualDurations": Array [],
2074
- "fiberSelfDurations": Array [],
2075
- "interactionIDs": Array [],
2076
- "priorityLevel": "Immediate",
2077
- "timestamp": 34,
2078
- },
2079
- ],
2080
- "displayName": "Parent",
2081
- "initialTreeBaseDurations": Array [
2082
- Array [
2083
- 6,
2084
- 11,
2085
- ],
2086
- Array [
2087
- 7,
2088
- 11,
2089
- ],
2090
- Array [
2091
- 8,
2092
- 0,
2093
- ],
2094
- Array [
2095
- 9,
2096
- 1,
2097
- ],
2098
- ],
2099
- "interactionCommits": Array [],
2100
- "interactions": Array [],
2101
- "operations": Array [
2102
- Array [
2103
- 1,
2104
- 6,
2105
- 0,
2106
- 2,
2107
- 4,
2108
- 9,
2109
- 8,
2110
- 7,
2111
- 6,
2112
- ],
2113
- ],
2114
- "rootID": 6,
2115
- "snapshots": Array [
2116
- Array [
2117
- 6,
2118
- Object {
2119
- "children": Array [
2120
- 7,
2121
- ],
2122
- "displayName": null,
2123
- "id": 6,
2124
- "key": null,
2125
- "type": 11,
2126
- },
2127
- ],
2128
- Array [
2129
- 7,
2130
- Object {
2131
- "children": Array [
2132
- 8,
2133
- 9,
2134
- ],
2135
- "displayName": "Parent",
2136
- "id": 7,
2137
- "key": null,
2138
- "type": 5,
2139
- },
2140
- ],
2141
- Array [
2142
- 8,
2143
- Object {
2144
- "children": Array [],
2145
- "displayName": "Child",
2146
- "id": 8,
2147
- "key": "0",
2148
- "type": 5,
2149
- },
2150
- ],
2151
- Array [
2152
- 9,
2153
- Object {
2154
- "children": Array [],
2155
- "displayName": "Child",
2156
- "id": 9,
2157
- "key": null,
2158
- "type": 8,
2159
- },
2160
- ],
2161
- ],
2162
- },
2163
- ],
2164
- "version": 4,
2165
-}
2166
-`;
2167
-
2168
-exports[`ProfilingCache should record changed props/state/context/hooks: CommitDetails commitIndex: 0 1`] = `
2169
-Object {
2170
- "changeDescriptions": Map {
2171
- 2 => Object {
2172
- "context": null,
2173
- "didHooksChange": false,
2174
- "isFirstMount": true,
2175
- "props": null,
2176
- "state": null,
2177
- },
2178
- 4 => Object {
2179
- "context": null,
2180
- "didHooksChange": false,
2181
- "isFirstMount": true,
2182
- "props": null,
2183
- "state": null,
2184
- },
2185
- 5 => Object {
2186
- "context": null,
2187
- "didHooksChange": false,
2188
- "isFirstMount": true,
2189
- "props": null,
2190
- "state": null,
2191
- },
2192
- 6 => Object {
2193
- "context": null,
2194
- "didHooksChange": false,
2195
- "isFirstMount": true,
2196
- "props": null,
2197
- "state": null,
2198
- },
2199
- 7 => Object {
2200
- "context": null,
2201
- "didHooksChange": false,
2202
- "isFirstMount": true,
2203
- "props": null,
2204
- "state": null,
2205
- },
2206
- },
2207
- "duration": 0,
2208
- "fiberActualDurations": Map {
2209
- 1 => 0,
2210
- 2 => 0,
2211
- 3 => 0,
2212
- 4 => 0,
2213
- 5 => 0,
2214
- 6 => 0,
2215
- 7 => 0,
2216
- },
2217
- "fiberSelfDurations": Map {
2218
- 1 => 0,
2219
- 2 => 0,
2220
- 3 => 0,
2221
- 4 => 0,
2222
- 5 => 0,
2223
- 6 => 0,
2224
- 7 => 0,
2225
- },
2226
- "interactionIDs": Array [],
2227
- "priorityLevel": "Immediate",
2228
- "timestamp": 0,
2229
-}
2230
-`;
2231
-
2232
-exports[`ProfilingCache should record changed props/state/context/hooks: CommitDetails commitIndex: 1 1`] = `
2233
-Object {
2234
- "changeDescriptions": Map {
2235
- 5 => Object {
2236
- "context": null,
2237
- "didHooksChange": true,
2238
- "isFirstMount": false,
2239
- "props": Array [
2240
- "count",
2241
- ],
2242
- "state": null,
2243
- },
2244
- 4 => Object {
2245
- "context": true,
2246
- "didHooksChange": false,
2247
- "isFirstMount": false,
2248
- "props": Array [],
2249
- "state": null,
2250
- },
2251
- 7 => Object {
2252
- "context": null,
2253
- "didHooksChange": true,
2254
- "isFirstMount": false,
2255
- "props": Array [
2256
- "count",
2257
- ],
2258
- "state": null,
2259
- },
2260
- 6 => Object {
2261
- "context": Array [
2262
- "count",
2263
- ],
2264
- "didHooksChange": false,
2265
- "isFirstMount": false,
2266
- "props": Array [],
2267
- "state": null,
2268
- },
2269
- 2 => Object {
2270
- "context": null,
2271
- "didHooksChange": false,
2272
- "isFirstMount": false,
2273
- "props": Array [],
2274
- "state": Array [
2275
- "count",
2276
- ],
2277
- },
2278
- },
2279
- "duration": 0,
2280
- "fiberActualDurations": Map {
2281
- 5 => 0,
2282
- 4 => 0,
2283
- 7 => 0,
2284
- 6 => 0,
2285
- 3 => 0,
2286
- 2 => 0,
2287
- },
2288
- "fiberSelfDurations": Map {
2289
- 5 => 0,
2290
- 4 => 0,
2291
- 7 => 0,
2292
- 6 => 0,
2293
- 3 => 0,
2294
- 2 => 0,
2295
- },
2296
- "interactionIDs": Array [],
2297
- "priorityLevel": "Immediate",
2298
- "timestamp": 0,
2299
-}
2300
-`;
2301
-
2302
-exports[`ProfilingCache should record changed props/state/context/hooks: CommitDetails commitIndex: 2 1`] = `
2303
-Object {
2304
- "changeDescriptions": Map {
2305
- 5 => Object {
2306
- "context": null,
2307
- "didHooksChange": false,
2308
- "isFirstMount": false,
2309
- "props": Array [],
2310
- "state": null,
2311
- },
2312
- 4 => Object {
2313
- "context": false,
2314
- "didHooksChange": false,
2315
- "isFirstMount": false,
2316
- "props": Array [],
2317
- "state": null,
2318
- },
2319
- 7 => Object {
2320
- "context": null,
2321
- "didHooksChange": false,
2322
- "isFirstMount": false,
2323
- "props": Array [],
2324
- "state": null,
2325
- },
2326
- 6 => Object {
2327
- "context": Array [],
2328
- "didHooksChange": false,
2329
- "isFirstMount": false,
2330
- "props": Array [],
2331
- "state": null,
2332
- },
2333
- 2 => Object {
2334
- "context": null,
2335
- "didHooksChange": false,
2336
- "isFirstMount": false,
2337
- "props": Array [
2338
- "foo",
2339
- ],
2340
- "state": Array [],
2341
- },
2342
- },
2343
- "duration": 0,
2344
- "fiberActualDurations": Map {
2345
- 5 => 0,
2346
- 4 => 0,
2347
- 7 => 0,
2348
- 6 => 0,
2349
- 3 => 0,
2350
- 2 => 0,
2351
- 1 => 0,
2352
- },
2353
- "fiberSelfDurations": Map {
2354
- 5 => 0,
2355
- 4 => 0,
2356
- 7 => 0,
2357
- 6 => 0,
2358
- 3 => 0,
2359
- 2 => 0,
2360
- 1 => 0,
2361
- },
2362
- "interactionIDs": Array [],
2363
- "priorityLevel": "Immediate",
2364
- "timestamp": 0,
2365
-}
2366
-`;
2367
-
2368
-exports[`ProfilingCache should record changed props/state/context/hooks: CommitDetails commitIndex: 3 1`] = `
2369
-Object {
2370
- "changeDescriptions": Map {
2371
- 5 => Object {
2372
- "context": null,
2373
- "didHooksChange": false,
2374
- "isFirstMount": false,
2375
- "props": Array [],
2376
- "state": null,
2377
- },
2378
- 4 => Object {
2379
- "context": false,
2380
- "didHooksChange": false,
2381
- "isFirstMount": false,
2382
- "props": Array [],
2383
- "state": null,
2384
- },
2385
- 7 => Object {
2386
- "context": null,
2387
- "didHooksChange": false,
2388
- "isFirstMount": false,
2389
- "props": Array [],
2390
- "state": null,
2391
- },
2392
- 6 => Object {
2393
- "context": Array [],
2394
- "didHooksChange": false,
2395
- "isFirstMount": false,
2396
- "props": Array [],
2397
- "state": null,
2398
- },
2399
- 2 => Object {
2400
- "context": null,
2401
- "didHooksChange": false,
2402
- "isFirstMount": false,
2403
- "props": Array [
2404
- "foo",
2405
- "bar",
2406
- ],
2407
- "state": Array [],
2408
- },
2409
- },
2410
- "duration": 0,
2411
- "fiberActualDurations": Map {
2412
- 5 => 0,
2413
- 4 => 0,
2414
- 7 => 0,
2415
- 6 => 0,
2416
- 3 => 0,
2417
- 2 => 0,
2418
- 1 => 0,
2419
- },
2420
- "fiberSelfDurations": Map {
2421
- 5 => 0,
2422
- 4 => 0,
2423
- 7 => 0,
2424
- 6 => 0,
2425
- 3 => 0,
2426
- 2 => 0,
2427
- 1 => 0,
2428
- },
2429
- "interactionIDs": Array [],
2430
- "priorityLevel": "Immediate",
2431
- "timestamp": 0,
2432
-}
2433
-`;
2434
-
2435
-exports[`ProfilingCache should record changed props/state/context/hooks: CommitDetails commitIndex: 4 1`] = `
2436
-Object {
2437
- "changeDescriptions": Map {
2438
- 5 => Object {
2439
- "context": null,
2440
- "didHooksChange": false,
2441
- "isFirstMount": false,
2442
- "props": Array [],
2443
- "state": null,
2444
- },
2445
- 4 => Object {
2446
- "context": false,
2447
- "didHooksChange": false,
2448
- "isFirstMount": false,
2449
- "props": Array [],
2450
- "state": null,
2451
- },
2452
- 7 => Object {
2453
- "context": null,
2454
- "didHooksChange": false,
2455
- "isFirstMount": false,
2456
- "props": Array [],
2457
- "state": null,
2458
- },
2459
- 6 => Object {
2460
- "context": Array [],
2461
- "didHooksChange": false,
2462
- "isFirstMount": false,
2463
- "props": Array [],
2464
- "state": null,
2465
- },
2466
- 2 => Object {
2467
- "context": null,
2468
- "didHooksChange": false,
2469
- "isFirstMount": false,
2470
- "props": Array [
2471
- "bar",
2472
- ],
2473
- "state": Array [],
2474
- },
2475
- },
2476
- "duration": 0,
2477
- "fiberActualDurations": Map {
2478
- 5 => 0,
2479
- 4 => 0,
2480
- 7 => 0,
2481
- 6 => 0,
2482
- 3 => 0,
2483
- 2 => 0,
2484
- 1 => 0,
2485
- },
2486
- "fiberSelfDurations": Map {
2487
- 5 => 0,
2488
- 4 => 0,
2489
- 7 => 0,
2490
- 6 => 0,
2491
- 3 => 0,
2492
- 2 => 0,
2493
- 1 => 0,
2494
- },
2495
- "interactionIDs": Array [],
2496
- "priorityLevel": "Immediate",
2497
- "timestamp": 0,
2498
-}
2499
-`;
2500
-
2501
-exports[`ProfilingCache should record changed props/state/context/hooks: imported data 1`] = `
2502
-Object {
2503
- "dataForRoots": Array [
2504
- Object {
2505
- "commitData": Array [
2506
- Object {
2507
- "changeDescriptions": Array [
2508
- Array [
2509
- 2,
2510
- Object {
2511
- "context": null,
2512
- "didHooksChange": false,
2513
- "isFirstMount": true,
2514
- "props": null,
2515
- "state": null,
2516
- },
2517
- ],
2518
- Array [
2519
- 4,
2520
- Object {
2521
- "context": null,
2522
- "didHooksChange": false,
2523
- "isFirstMount": true,
2524
- "props": null,
2525
- "state": null,
2526
- },
2527
- ],
2528
- Array [
2529
- 5,
2530
- Object {
2531
- "context": null,
2532
- "didHooksChange": false,
2533
- "isFirstMount": true,
2534
- "props": null,
2535
- "state": null,
2536
- },
2537
- ],
2538
- Array [
2539
- 6,
2540
- Object {
2541
- "context": null,
2542
- "didHooksChange": false,
2543
- "isFirstMount": true,
2544
- "props": null,
2545
- "state": null,
2546
- },
2547
- ],
2548
- Array [
2549
- 7,
2550
- Object {
2551
- "context": null,
2552
- "didHooksChange": false,
2553
- "isFirstMount": true,
2554
- "props": null,
2555
- "state": null,
2556
- },
2557
- ],
2558
- ],
2559
- "duration": 0,
2560
- "fiberActualDurations": Array [
2561
- Array [
2562
- 1,
2563
- 0,
2564
- ],
2565
- Array [
2566
- 2,
2567
- 0,
2568
- ],
2569
- Array [
2570
- 3,
2571
- 0,
2572
- ],
2573
- Array [
2574
- 4,
2575
- 0,
2576
- ],
2577
- Array [
2578
- 5,
2579
- 0,
2580
- ],
2581
- Array [
2582
- 6,
2583
- 0,
2584
- ],
2585
- Array [
2586
- 7,
2587
- 0,
2588
- ],
2589
- ],
2590
- "fiberSelfDurations": Array [
2591
- Array [
2592
- 1,
2593
- 0,
2594
- ],
2595
- Array [
2596
- 2,
2597
- 0,
2598
- ],
2599
- Array [
2600
- 3,
2601
- 0,
2602
- ],
2603
- Array [
2604
- 4,
2605
- 0,
2606
- ],
2607
- Array [
2608
- 5,
2609
- 0,
2610
- ],
2611
- Array [
2612
- 6,
2613
- 0,
2614
- ],
2615
- Array [
2616
- 7,
2617
- 0,
2618
- ],
2619
- ],
2620
- "interactionIDs": Array [],
2621
- "priorityLevel": "Immediate",
2622
- "timestamp": 0,
2623
- },
2624
- Object {
2625
- "changeDescriptions": Array [
2626
- Array [
2627
- 5,
2628
- Object {
2629
- "context": null,
2630
- "didHooksChange": true,
2631
- "isFirstMount": false,
2632
- "props": Array [
2633
- "count",
2634
- ],
2635
- "state": null,
2636
- },
2637
- ],
2638
- Array [
2639
- 4,
2640
- Object {
2641
- "context": true,
2642
- "didHooksChange": false,
2643
- "isFirstMount": false,
2644
- "props": Array [],
2645
- "state": null,
2646
- },
2647
- ],
2648
- Array [
2649
- 7,
2650
- Object {
2651
- "context": null,
2652
- "didHooksChange": true,
2653
- "isFirstMount": false,
2654
- "props": Array [
2655
- "count",
2656
- ],
2657
- "state": null,
2658
- },
2659
- ],
2660
- Array [
2661
- 6,
2662
- Object {
2663
- "context": Array [
2664
- "count",
2665
- ],
2666
- "didHooksChange": false,
2667
- "isFirstMount": false,
2668
- "props": Array [],
2669
- "state": null,
2670
- },
2671
- ],
2672
- Array [
2673
- 2,
2674
- Object {
2675
- "context": null,
2676
- "didHooksChange": false,
2677
- "isFirstMount": false,
2678
- "props": Array [],
2679
- "state": Array [
2680
- "count",
2681
- ],
2682
- },
2683
- ],
2684
- ],
2685
- "duration": 0,
2686
- "fiberActualDurations": Array [
2687
- Array [
2688
- 5,
2689
- 0,
2690
- ],
2691
- Array [
2692
- 4,
2693
- 0,
2694
- ],
2695
- Array [
2696
- 7,
2697
- 0,
2698
- ],
2699
- Array [
2700
- 6,
2701
- 0,
2702
- ],
2703
- Array [
2704
- 3,
2705
- 0,
2706
- ],
2707
- Array [
2708
- 2,
2709
- 0,
2710
- ],
2711
- ],
2712
- "fiberSelfDurations": Array [
2713
- Array [
2714
- 5,
2715
- 0,
2716
- ],
2717
- Array [
2718
- 4,
2719
- 0,
2720
- ],
2721
- Array [
2722
- 7,
2723
- 0,
2724
- ],
2725
- Array [
2726
- 6,
2727
- 0,
2728
- ],
2729
- Array [
2730
- 3,
2731
- 0,
2732
- ],
2733
- Array [
2734
- 2,
2735
- 0,
2736
- ],
2737
- ],
2738
- "interactionIDs": Array [],
2739
- "priorityLevel": "Immediate",
2740
- "timestamp": 0,
2741
- },
2742
- Object {
2743
- "changeDescriptions": Array [
2744
- Array [
2745
- 5,
2746
- Object {
2747
- "context": null,
2748
- "didHooksChange": false,
2749
- "isFirstMount": false,
2750
- "props": Array [],
2751
- "state": null,
2752
- },
2753
- ],
2754
- Array [
2755
- 4,
2756
- Object {
2757
- "context": false,
2758
- "didHooksChange": false,
2759
- "isFirstMount": false,
2760
- "props": Array [],
2761
- "state": null,
2762
- },
2763
- ],
2764
- Array [
2765
- 7,
2766
- Object {
2767
- "context": null,
2768
- "didHooksChange": false,
2769
- "isFirstMount": false,
2770
- "props": Array [],
2771
- "state": null,
2772
- },
2773
- ],
2774
- Array [
2775
- 6,
2776
- Object {
2777
- "context": Array [],
2778
- "didHooksChange": false,
2779
- "isFirstMount": false,
2780
- "props": Array [],
2781
- "state": null,
2782
- },
2783
- ],
2784
- Array [
2785
- 2,
2786
- Object {
2787
- "context": null,
2788
- "didHooksChange": false,
2789
- "isFirstMount": false,
2790
- "props": Array [
2791
- "foo",
2792
- ],
2793
- "state": Array [],
2794
- },
2795
- ],
2796
- ],
2797
- "duration": 0,
2798
- "fiberActualDurations": Array [
2799
- Array [
2800
- 5,
2801
- 0,
2802
- ],
2803
- Array [
2804
- 4,
2805
- 0,
2806
- ],
2807
- Array [
2808
- 7,
2809
- 0,
2810
- ],
2811
- Array [
2812
- 6,
2813
- 0,
2814
- ],
2815
- Array [
2816
- 3,
2817
- 0,
2818
- ],
2819
- Array [
2820
- 2,
2821
- 0,
2822
- ],
2823
- Array [
2824
- 1,
2825
- 0,
2826
- ],
2827
- ],
2828
- "fiberSelfDurations": Array [
2829
- Array [
2830
- 5,
2831
- 0,
2832
- ],
2833
- Array [
2834
- 4,
2835
- 0,
2836
- ],
2837
- Array [
2838
- 7,
2839
- 0,
2840
- ],
2841
- Array [
2842
- 6,
2843
- 0,
2844
- ],
2845
- Array [
2846
- 3,
2847
- 0,
2848
- ],
2849
- Array [
2850
- 2,
2851
- 0,
2852
- ],
2853
- Array [
2854
- 1,
2855
- 0,
2856
- ],
2857
- ],
2858
- "interactionIDs": Array [],
2859
- "priorityLevel": "Immediate",
2860
- "timestamp": 0,
2861
- },
2862
- Object {
2863
- "changeDescriptions": Array [
2864
- Array [
2865
- 5,
2866
- Object {
2867
- "context": null,
2868
- "didHooksChange": false,
2869
- "isFirstMount": false,
2870
- "props": Array [],
2871
- "state": null,
2872
- },
2873
- ],
2874
- Array [
2875
- 4,
2876
- Object {
2877
- "context": false,
2878
- "didHooksChange": false,
2879
- "isFirstMount": false,
2880
- "props": Array [],
2881
- "state": null,
2882
- },
2883
- ],
2884
- Array [
2885
- 7,
2886
- Object {
2887
- "context": null,
2888
- "didHooksChange": false,
2889
- "isFirstMount": false,
2890
- "props": Array [],
2891
- "state": null,
2892
- },
2893
- ],
2894
- Array [
2895
- 6,
2896
- Object {
2897
- "context": Array [],
2898
- "didHooksChange": false,
2899
- "isFirstMount": false,
2900
- "props": Array [],
2901
- "state": null,
2902
- },
2903
- ],
2904
- Array [
2905
- 2,
2906
- Object {
2907
- "context": null,
2908
- "didHooksChange": false,
2909
- "isFirstMount": false,
2910
- "props": Array [
2911
- "foo",
2912
- "bar",
2913
- ],
2914
- "state": Array [],
2915
- },
2916
- ],
2917
- ],
2918
- "duration": 0,
2919
- "fiberActualDurations": Array [
2920
- Array [
2921
- 5,
2922
- 0,
2923
- ],
2924
- Array [
2925
- 4,
2926
- 0,
2927
- ],
2928
- Array [
2929
- 7,
2930
- 0,
2931
- ],
2932
- Array [
2933
- 6,
2934
- 0,
2935
- ],
2936
- Array [
2937
- 3,
2938
- 0,
2939
- ],
2940
- Array [
2941
- 2,
2942
- 0,
2943
- ],
2944
- Array [
2945
- 1,
2946
- 0,
2947
- ],
2948
- ],
2949
- "fiberSelfDurations": Array [
2950
- Array [
2951
- 5,
2952
- 0,
2953
- ],
2954
- Array [
2955
- 4,
2956
- 0,
2957
- ],
2958
- Array [
2959
- 7,
2960
- 0,
2961
- ],
2962
- Array [
2963
- 6,
2964
- 0,
2965
- ],
2966
- Array [
2967
- 3,
2968
- 0,
2969
- ],
2970
- Array [
2971
- 2,
2972
- 0,
2973
- ],
2974
- Array [
2975
- 1,
2976
- 0,
2977
- ],
2978
- ],
2979
- "interactionIDs": Array [],
2980
- "priorityLevel": "Immediate",
2981
- "timestamp": 0,
2982
- },
2983
- Object {
2984
- "changeDescriptions": Array [
2985
- Array [
2986
- 5,
2987
- Object {
2988
- "context": null,
2989
- "didHooksChange": false,
2990
- "isFirstMount": false,
2991
- "props": Array [],
2992
- "state": null,
2993
- },
2994
- ],
2995
- Array [
2996
- 4,
2997
- Object {
2998
- "context": false,
2999
- "didHooksChange": false,
3000
- "isFirstMount": false,
3001
- "props": Array [],
3002
- "state": null,
3003
- },
3004
- ],
3005
- Array [
3006
- 7,
3007
- Object {
3008
- "context": null,
3009
- "didHooksChange": false,
3010
- "isFirstMount": false,
3011
- "props": Array [],
3012
- "state": null,
3013
- },
3014
- ],
3015
- Array [
3016
- 6,
3017
- Object {
3018
- "context": Array [],
3019
- "didHooksChange": false,
3020
- "isFirstMount": false,
3021
- "props": Array [],
3022
- "state": null,
3023
- },
3024
- ],
3025
- Array [
3026
- 2,
3027
- Object {
3028
- "context": null,
3029
- "didHooksChange": false,
3030
- "isFirstMount": false,
3031
- "props": Array [
3032
- "bar",
3033
- ],
3034
- "state": Array [],
3035
- },
3036
- ],
3037
- ],
3038
- "duration": 0,
3039
- "fiberActualDurations": Array [
3040
- Array [
3041
- 5,
3042
- 0,
3043
- ],
3044
- Array [
3045
- 4,
3046
- 0,
3047
- ],
3048
- Array [
3049
- 7,
3050
- 0,
3051
- ],
3052
- Array [
3053
- 6,
3054
- 0,
3055
- ],
3056
- Array [
3057
- 3,
3058
- 0,
3059
- ],
3060
- Array [
3061
- 2,
3062
- 0,
3063
- ],
3064
- Array [
3065
- 1,
3066
- 0,
3067
- ],
3068
- ],
3069
- "fiberSelfDurations": Array [
3070
- Array [
3071
- 5,
3072
- 0,
3073
- ],
3074
- Array [
3075
- 4,
3076
- 0,
3077
- ],
3078
- Array [
3079
- 7,
3080
- 0,
3081
- ],
3082
- Array [
3083
- 6,
3084
- 0,
3085
- ],
3086
- Array [
3087
- 3,
3088
- 0,
3089
- ],
3090
- Array [
3091
- 2,
3092
- 0,
3093
- ],
3094
- Array [
3095
- 1,
3096
- 0,
3097
- ],
3098
- ],
3099
- "interactionIDs": Array [],
3100
- "priorityLevel": "Immediate",
3101
- "timestamp": 0,
3102
- },
3103
- ],
3104
- "displayName": "LegacyContextProvider",
3105
- "initialTreeBaseDurations": Array [],
3106
- "interactionCommits": Array [],
3107
- "interactions": Array [],
3108
- "operations": Array [
3109
- Array [
3110
- 1,
3111
- 1,
3112
- 110,
3113
- 21,
3114
- 76,
3115
- 101,
3116
- 103,
3117
- 97,
3118
- 99,
3119
- 121,
3120
- 67,
3121
- 111,
3122
- 110,
3123
- 116,
3124
- 101,
3125
- 120,
3126
- 116,
3127
- 80,
3128
- 114,
3129
- 111,
3130
- 118,
3131
- 105,
3132
- 100,
3133
- 101,
3134
- 114,
3135
- 16,
3136
- 67,
3137
- 111,
3138
- 110,
3139
- 116,
3140
- 101,
3141
- 120,
3142
- 116,
3143
- 46,
3144
- 80,
3145
- 114,
3146
- 111,
3147
- 118,
3148
- 105,
3149
- 100,
3150
- 101,
3151
- 114,
3152
- 21,
3153
- 77,
3154
- 111,
3155
- 100,
3156
- 101,
3157
- 114,
3158
- 110,
3159
- 67,
3160
- 111,
3161
- 110,
3162
- 116,
3163
- 101,
3164
- 120,
3165
- 116,
3166
- 67,
3167
- 111,
3168
- 110,
3169
- 115,
3170
- 117,
3171
- 109,
3172
- 101,
3173
- 114,
3174
- 26,
3175
- 70,
3176
- 117,
3177
- 110,
3178
- 99,
3179
- 116,
3180
- 105,
3181
- 111,
3182
- 110,
3183
- 67,
3184
- 111,
3185
- 109,
3186
- 112,
3187
- 111,
3188
- 110,
3189
- 101,
3190
- 110,
3191
- 116,
3192
- 87,
3193
- 105,
3194
- 116,
3195
- 104,
3196
- 72,
3197
- 111,
3198
- 111,
3199
- 107,
3200
- 115,
3201
- 21,
3202
- 76,
3203
- 101,
3204
- 103,
3205
- 97,
3206
- 99,
3207
- 121,
3208
- 67,
3209
- 111,
3210
- 110,
3211
- 116,
3212
- 101,
3213
- 120,
3214
- 116,
3215
- 67,
3216
- 111,
3217
- 110,
3218
- 115,
3219
- 117,
3220
- 109,
3221
- 101,
3222
- 114,
3223
- 1,
3224
- 1,
3225
- 11,
3226
- 1,
3227
- 1,
3228
- 1,
3229
- 2,
3230
- 1,
3231
- 1,
3232
- 0,
3233
- 1,
3234
- 0,
3235
- 4,
3236
- 2,
3237
- 0,
3238
- 1,
3239
- 3,
3240
- 2,
3241
- 2,
3242
- 2,
3243
- 2,
3244
- 0,
3245
- 4,
3246
- 3,
3247
- 0,
3248
- 1,
3249
- 4,
3250
- 1,
3251
- 3,
3252
- 2,
3253
- 3,
3254
- 0,
3255
- 4,
3256
- 4,
3257
- 0,
3258
- 1,
3259
- 5,
3260
- 5,
3261
- 4,
3262
- 4,
3263
- 4,
3264
- 0,
3265
- 4,
3266
- 5,
3267
- 0,
3268
- 1,
3269
- 6,
3270
- 1,
3271
- 3,
3272
- 2,
3273
- 5,
3274
- 0,
3275
- 4,
3276
- 6,
3277
- 0,
3278
- 1,
3279
- 7,
3280
- 5,
3281
- 6,
3282
- 6,
3283
- 4,
3284
- 0,
3285
- 4,
3286
- 7,
3287
- 0,
3288
- ],
3289
- Array [
3290
- 1,
3291
- 1,
3292
- 0,
3293
- ],
3294
- Array [
3295
- 1,
3296
- 1,
3297
- 0,
3298
- ],
3299
- Array [
3300
- 1,
3301
- 1,
3302
- 0,
3303
- ],
3304
- Array [
3305
- 1,
3306
- 1,
3307
- 0,
3308
- ],
3309
- ],
3310
- "rootID": 1,
3311
- "snapshots": Array [],
3312
- },
3313
- ],
3314
- "version": 4,
3315
-}
3316
-`;
3317
-
3318
-exports[`ProfilingCache should report every traced interaction: Interactions 1`] = `
3319
-Array [
3320
- Object {
3321
- "__count": 1,
3322
- "id": 0,
3323
- "name": "mount: one child",
3324
- "timestamp": 0,
3325
- },
3326
- Object {
3327
- "__count": 0,
3328
- "id": 1,
3329
- "name": "update: two children",
3330
- "timestamp": 11,
3331
- },
3332
-]
3333
-`;
3334
-
3335
-exports[`ProfilingCache should report every traced interaction: imported data 1`] = `
3336
-Object {
3337
- "dataForRoots": Array [
3338
- Object {
3339
- "commitData": Array [
3340
- Object {
3341
- "changeDescriptions": Array [
3342
- Array [
3343
- 2,
3344
- Object {
3345
- "context": null,
3346
- "didHooksChange": false,
3347
- "isFirstMount": true,
3348
- "props": null,
3349
- "state": null,
3350
- },
3351
- ],
3352
- Array [
3353
- 3,
3354
- Object {
3355
- "context": null,
3356
- "didHooksChange": false,
3357
- "isFirstMount": true,
3358
- "props": null,
3359
- "state": null,
3360
- },
3361
- ],
3362
- Array [
3363
- 4,
3364
- Object {
3365
- "context": null,
3366
- "didHooksChange": false,
3367
- "isFirstMount": true,
3368
- "props": null,
3369
- "state": null,
3370
- },
3371
- ],
3372
- ],
3373
- "duration": 11,
3374
- "fiberActualDurations": Array [
3375
- Array [
3376
- 1,
3377
- 11,
3378
- ],
3379
- Array [
3380
- 2,
3381
- 11,
3382
- ],
3383
- Array [
3384
- 3,
3385
- 0,
3386
- ],
3387
- Array [
3388
- 4,
3389
- 1,
3390
- ],
3391
- ],
3392
- "fiberSelfDurations": Array [
3393
- Array [
3394
- 1,
3395
- 0,
3396
- ],
3397
- Array [
3398
- 2,
3399
- 10,
3400
- ],
3401
- Array [
3402
- 3,
3403
- 0,
3404
- ],
3405
- Array [
3406
- 4,
3407
- 1,
3408
- ],
3409
- ],
3410
- "interactionIDs": Array [
3411
- 0,
3412
- ],
3413
- "priorityLevel": "Immediate",
3414
- "timestamp": 11,
3415
- },
3416
- Object {
3417
- "changeDescriptions": Array [
3418
- Array [
3419
- 3,
3420
- Object {
3421
- "context": null,
3422
- "didHooksChange": false,
3423
- "isFirstMount": false,
3424
- "props": Array [],
3425
- "state": null,
3426
- },
3427
- ],
3428
- Array [
3429
- 5,
3430
- Object {
3431
- "context": null,
3432
- "didHooksChange": false,
3433
- "isFirstMount": true,
3434
- "props": null,
3435
- "state": null,
3436
- },
3437
- ],
3438
- Array [
3439
- 2,
3440
- Object {
3441
- "context": null,
3442
- "didHooksChange": false,
3443
- "isFirstMount": false,
3444
- "props": Array [
3445
- "count",
3446
- ],
3447
- "state": null,
3448
- },
3449
- ],
3450
- ],
3451
- "duration": 11,
3452
- "fiberActualDurations": Array [
3453
- Array [
3454
- 3,
3455
- 0,
3456
- ],
3457
- Array [
3458
- 5,
3459
- 1,
3460
- ],
3461
- Array [
3462
- 2,
3463
- 11,
3464
- ],
3465
- Array [
3466
- 1,
3467
- 11,
3468
- ],
3469
- ],
3470
- "fiberSelfDurations": Array [
3471
- Array [
3472
- 3,
3473
- 0,
3474
- ],
3475
- Array [
3476
- 5,
3477
- 1,
3478
- ],
3479
- Array [
3480
- 2,
3481
- 10,
3482
- ],
3483
- Array [
3484
- 1,
3485
- 0,
3486
- ],
3487
- ],
3488
- "interactionIDs": Array [
3489
- 1,
3490
- ],
3491
- "priorityLevel": "Immediate",
3492
- "timestamp": 22,
3493
- },
3494
- ],
3495
- "displayName": "Parent",
3496
- "initialTreeBaseDurations": Array [],
3497
- "interactionCommits": Array [
3498
- Array [
3499
- 0,
3500
- Array [
3501
- 0,
3502
- ],
3503
- ],
3504
- Array [
3505
- 1,
3506
- Array [
3507
- 1,
3508
- ],
3509
- ],
3510
- ],
3511
- "interactions": Array [
3512
- Array [
3513
- 0,
3514
- Object {
3515
- "__count": 1,
3516
- "id": 0,
3517
- "name": "mount: one child",
3518
- "timestamp": 0,
3519
- },
3520
- ],
3521
- Array [
3522
- 1,
3523
- Object {
3524
- "__count": 0,
3525
- "id": 1,
3526
- "name": "update: two children",
3527
- "timestamp": 11,
3528
- },
3529
- ],
3530
- ],
3531
- "operations": Array [
3532
- Array [
3533
- 1,
3534
- 1,
3535
- 15,
3536
- 6,
3537
- 80,
3538
- 97,
3539
- 114,
3540
- 101,
3541
- 110,
3542
- 116,
3543
- 5,
3544
- 67,
3545
- 104,
3546
- 105,
3547
- 108,
3548
- 100,
3549
- 1,
3550
- 48,
3551
- 1,
3552
- 1,
3553
- 11,
3554
- 1,
3555
- 1,
3556
- 4,
3557
- 1,
3558
- 11000,
3559
- 1,
3560
- 2,
3561
- 5,
3562
- 1,
3563
- 0,
3564
- 1,
3565
- 0,
3566
- 4,
3567
- 2,
3568
- 11000,
3569
- 1,
3570
- 3,
3571
- 5,
3572
- 2,
3573
- 2,
3574
- 2,
3575
- 3,
3576
- 4,
3577
- 3,
3578
- 0,
3579
- 1,
3580
- 4,
3581
- 8,
3582
- 2,
3583
- 2,
3584
- 2,
3585
- 0,
3586
- 4,
3587
- 4,
3588
- 1000,
3589
- ],
3590
- Array [
3591
- 1,
3592
- 1,
3593
- 8,
3594
- 5,
3595
- 67,
3596
- 104,
3597
- 105,
3598
- 108,
3599
- 100,
3600
- 1,
3601
- 49,
3602
- 1,
3603
- 5,
3604
- 5,
3605
- 2,
3606
- 2,
3607
- 1,
3608
- 2,
3609
- 4,
3610
- 5,
3611
- 1000,
3612
- 4,
3613
- 2,
3614
- 12000,
3615
- 3,
3616
- 2,
3617
- 3,
3618
- 3,
3619
- 5,
3620
- 4,
3621
- 4,
3622
- 1,
3623
- 12000,
3624
- ],
3625
- ],
3626
- "rootID": 1,
3627
- "snapshots": Array [],
3628
- },
3629
- ],
3630
- "version": 4,
3631
-}
3632
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/profilingCharts-test.js.snap
deleted
-452
@@ -1,452 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`profiling charts flamegraph chart should contain valid data: 0: CommitTree 1`] = `
4
-Object {
5
- "nodes": Map {
6
- 1 => Object {
7
- "children": Array [
8
- 2,
9
- ],
10
- "displayName": null,
11
- "id": 1,
12
- "key": null,
13
- "parentID": 0,
14
- "treeBaseDuration": 15,
15
- "type": 11,
16
- },
17
- 2 => Object {
18
- "children": Array [
19
- 3,
20
- 4,
21
- 5,
22
- ],
23
- "displayName": "Parent",
24
- "id": 2,
25
- "key": null,
26
- "parentID": 1,
27
- "treeBaseDuration": 15,
28
- "type": 5,
29
- },
30
- 3 => Object {
31
- "children": Array [],
32
- "displayName": "Child",
33
- "id": 3,
34
- "key": "first",
35
- "parentID": 2,
36
- "treeBaseDuration": 3,
37
- "type": 8,
38
- },
39
- 4 => Object {
40
- "children": Array [],
41
- "displayName": "Child",
42
- "id": 4,
43
- "key": "second",
44
- "parentID": 2,
45
- "treeBaseDuration": 2,
46
- "type": 8,
47
- },
48
- 5 => Object {
49
- "children": Array [],
50
- "displayName": "Child",
51
- "id": 5,
52
- "key": "third",
53
- "parentID": 2,
54
- "treeBaseDuration": 0,
55
- "type": 8,
56
- },
57
- },
58
- "rootID": 1,
59
-}
60
-`;
61
-
62
-exports[`profiling charts flamegraph chart should contain valid data: 0: FlamegraphChartData 1`] = `
63
-Object {
64
- "baseDuration": 15,
65
- "depth": 2,
66
- "idToDepthMap": Map {
67
- 2 => 1,
68
- 5 => 2,
69
- 4 => 2,
70
- 3 => 2,
71
- },
72
- "maxSelfDuration": 10,
73
- "renderPathNodes": Set {
74
- 1,
75
- 2,
76
- },
77
- "rows": Array [
78
- Array [
79
- Object {
80
- "actualDuration": 15,
81
- "didRender": true,
82
- "id": 2,
83
- "label": "Parent (10ms of 15ms)",
84
- "name": "Parent",
85
- "offset": 0,
86
- "selfDuration": 10,
87
- "treeBaseDuration": 15,
88
- },
89
- ],
90
- Array [
91
- Object {
92
- "actualDuration": 0,
93
- "didRender": true,
94
- "id": 5,
95
- "label": "Child (Memo) key=\\"third\\" (<0.1ms of <0.1ms)",
96
- "name": "Child",
97
- "offset": 15,
98
- "selfDuration": 0,
99
- "treeBaseDuration": 0,
100
- },
101
- Object {
102
- "actualDuration": 2,
103
- "didRender": true,
104
- "id": 4,
105
- "label": "Child (Memo) key=\\"second\\" (2ms of 2ms)",
106
- "name": "Child",
107
- "offset": 13,
108
- "selfDuration": 2,
109
- "treeBaseDuration": 2,
110
- },
111
- Object {
112
- "actualDuration": 3,
113
- "didRender": true,
114
- "id": 3,
115
- "label": "Child (Memo) key=\\"first\\" (3ms of 3ms)",
116
- "name": "Child",
117
- "offset": 10,
118
- "selfDuration": 3,
119
- "treeBaseDuration": 3,
120
- },
121
- ],
122
- ],
123
-}
124
-`;
125
-
126
-exports[`profiling charts flamegraph chart should contain valid data: 1: CommitTree 1`] = `
127
-Object {
128
- "nodes": Map {
129
- 1 => Object {
130
- "children": Array [
131
- 2,
132
- ],
133
- "displayName": null,
134
- "id": 1,
135
- "key": null,
136
- "parentID": 0,
137
- "treeBaseDuration": 15,
138
- "type": 11,
139
- },
140
- 2 => Object {
141
- "children": Array [
142
- 3,
143
- 4,
144
- 5,
145
- ],
146
- "displayName": "Parent",
147
- "id": 2,
148
- "key": null,
149
- "parentID": 1,
150
- "treeBaseDuration": 15,
151
- "type": 5,
152
- },
153
- 3 => Object {
154
- "children": Array [],
155
- "displayName": "Child",
156
- "id": 3,
157
- "key": "first",
158
- "parentID": 2,
159
- "treeBaseDuration": 3,
160
- "type": 8,
161
- },
162
- 4 => Object {
163
- "children": Array [],
164
- "displayName": "Child",
165
- "id": 4,
166
- "key": "second",
167
- "parentID": 2,
168
- "treeBaseDuration": 2,
169
- "type": 8,
170
- },
171
- 5 => Object {
172
- "children": Array [],
173
- "displayName": "Child",
174
- "id": 5,
175
- "key": "third",
176
- "parentID": 2,
177
- "treeBaseDuration": 0,
178
- "type": 8,
179
- },
180
- },
181
- "rootID": 1,
182
-}
183
-`;
184
-
185
-exports[`profiling charts flamegraph chart should contain valid data: 1: FlamegraphChartData 1`] = `
186
-Object {
187
- "baseDuration": 15,
188
- "depth": 2,
189
- "idToDepthMap": Map {
190
- 2 => 1,
191
- 5 => 2,
192
- 4 => 2,
193
- 3 => 2,
194
- },
195
- "maxSelfDuration": 10,
196
- "renderPathNodes": Set {
197
- 1,
198
- },
199
- "rows": Array [
200
- Array [
201
- Object {
202
- "actualDuration": 10,
203
- "didRender": true,
204
- "id": 2,
205
- "label": "Parent (10ms of 10ms)",
206
- "name": "Parent",
207
- "offset": 0,
208
- "selfDuration": 10,
209
- "treeBaseDuration": 15,
210
- },
211
- ],
212
- Array [
213
- Object {
214
- "actualDuration": 0,
215
- "didRender": false,
216
- "id": 5,
217
- "label": "Child (Memo) key=\\"third\\"",
218
- "name": "Child",
219
- "offset": 15,
220
- "selfDuration": 0,
221
- "treeBaseDuration": 0,
222
- },
223
- Object {
224
- "actualDuration": 0,
225
- "didRender": false,
226
- "id": 4,
227
- "label": "Child (Memo) key=\\"second\\"",
228
- "name": "Child",
229
- "offset": 13,
230
- "selfDuration": 0,
231
- "treeBaseDuration": 2,
232
- },
233
- Object {
234
- "actualDuration": 0,
235
- "didRender": false,
236
- "id": 3,
237
- "label": "Child (Memo) key=\\"first\\"",
238
- "name": "Child",
239
- "offset": 10,
240
- "selfDuration": 0,
241
- "treeBaseDuration": 3,
242
- },
243
- ],
244
- ],
245
-}
246
-`;
247
-
248
-exports[`profiling charts interactions should contain valid data: Interactions 1`] = `
249
-Object {
250
- "interactions": Array [
251
- Object {
252
- "__count": 1,
253
- "id": 0,
254
- "name": "mount",
255
- "timestamp": 0,
256
- },
257
- Object {
258
- "__count": 0,
259
- "id": 1,
260
- "name": "update",
261
- "timestamp": 15,
262
- },
263
- ],
264
- "lastInteractionTime": 25,
265
- "maxCommitDuration": 15,
266
-}
267
-`;
268
-
269
-exports[`profiling charts interactions should contain valid data: Interactions 2`] = `
270
-Object {
271
- "interactions": Array [
272
- Object {
273
- "__count": 1,
274
- "id": 0,
275
- "name": "mount",
276
- "timestamp": 0,
277
- },
278
- Object {
279
- "__count": 0,
280
- "id": 1,
281
- "name": "update",
282
- "timestamp": 15,
283
- },
284
- ],
285
- "lastInteractionTime": 25,
286
- "maxCommitDuration": 15,
287
-}
288
-`;
289
-
290
-exports[`profiling charts ranked chart should contain valid data: 0: CommitTree 1`] = `
291
-Object {
292
- "nodes": Map {
293
- 1 => Object {
294
- "children": Array [
295
- 2,
296
- ],
297
- "displayName": null,
298
- "id": 1,
299
- "key": null,
300
- "parentID": 0,
301
- "treeBaseDuration": 15,
302
- "type": 11,
303
- },
304
- 2 => Object {
305
- "children": Array [
306
- 3,
307
- 4,
308
- 5,
309
- ],
310
- "displayName": "Parent",
311
- "id": 2,
312
- "key": null,
313
- "parentID": 1,
314
- "treeBaseDuration": 15,
315
- "type": 5,
316
- },
317
- 3 => Object {
318
- "children": Array [],
319
- "displayName": "Child",
320
- "id": 3,
321
- "key": "first",
322
- "parentID": 2,
323
- "treeBaseDuration": 3,
324
- "type": 8,
325
- },
326
- 4 => Object {
327
- "children": Array [],
328
- "displayName": "Child",
329
- "id": 4,
330
- "key": "second",
331
- "parentID": 2,
332
- "treeBaseDuration": 2,
333
- "type": 8,
334
- },
335
- 5 => Object {
336
- "children": Array [],
337
- "displayName": "Child",
338
- "id": 5,
339
- "key": "third",
340
- "parentID": 2,
341
- "treeBaseDuration": 0,
342
- "type": 8,
343
- },
344
- },
345
- "rootID": 1,
346
-}
347
-`;
348
-
349
-exports[`profiling charts ranked chart should contain valid data: 0: RankedChartData 1`] = `
350
-Object {
351
- "maxValue": 10,
352
- "nodes": Array [
353
- Object {
354
- "id": 2,
355
- "label": "Parent (10ms)",
356
- "name": "Parent",
357
- "value": 10,
358
- },
359
- Object {
360
- "id": 3,
361
- "label": "Child (Memo) key=\\"first\\" (3ms)",
362
- "name": "Child",
363
- "value": 3,
364
- },
365
- Object {
366
- "id": 4,
367
- "label": "Child (Memo) key=\\"second\\" (2ms)",
368
- "name": "Child",
369
- "value": 2,
370
- },
371
- Object {
372
- "id": 5,
373
- "label": "Child (Memo) key=\\"third\\" (<0.1ms)",
374
- "name": "Child",
375
- "value": 0,
376
- },
377
- ],
378
-}
379
-`;
380
-
381
-exports[`profiling charts ranked chart should contain valid data: 1: CommitTree 1`] = `
382
-Object {
383
- "nodes": Map {
384
- 1 => Object {
385
- "children": Array [
386
- 2,
387
- ],
388
- "displayName": null,
389
- "id": 1,
390
- "key": null,
391
- "parentID": 0,
392
- "treeBaseDuration": 15,
393
- "type": 11,
394
- },
395
- 2 => Object {
396
- "children": Array [
397
- 3,
398
- 4,
399
- 5,
400
- ],
401
- "displayName": "Parent",
402
- "id": 2,
403
- "key": null,
404
- "parentID": 1,
405
- "treeBaseDuration": 15,
406
- "type": 5,
407
- },
408
- 3 => Object {
409
- "children": Array [],
410
- "displayName": "Child",
411
- "id": 3,
412
- "key": "first",
413
- "parentID": 2,
414
- "treeBaseDuration": 3,
415
- "type": 8,
416
- },
417
- 4 => Object {
418
- "children": Array [],
419
- "displayName": "Child",
420
- "id": 4,
421
- "key": "second",
422
- "parentID": 2,
423
- "treeBaseDuration": 2,
424
- "type": 8,
425
- },
426
- 5 => Object {
427
- "children": Array [],
428
- "displayName": "Child",
429
- "id": 5,
430
- "key": "third",
431
- "parentID": 2,
432
- "treeBaseDuration": 0,
433
- "type": 8,
434
- },
435
- },
436
- "rootID": 1,
437
-}
438
-`;
439
-
440
-exports[`profiling charts ranked chart should contain valid data: 1: RankedChartData 1`] = `
441
-Object {
442
- "maxValue": 10,
443
- "nodes": Array [
444
- Object {
445
- "id": 2,
446
- "label": "Parent (10ms)",
447
- "name": "Parent",
448
- "value": 10,
449
- },
450
- ],
451
-}
452
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/profilingCommitTreeBuilder-test.js.snap
deleted
-176
@@ -1,176 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`commit tree should be able to rebuild the store tree for each commit: 0: CommitTree 1`] = `
4
-Object {
5
- "nodes": Map {
6
- 1 => Object {
7
- "children": Array [
8
- 2,
9
- ],
10
- "displayName": null,
11
- "id": 1,
12
- "key": null,
13
- "parentID": 0,
14
- "treeBaseDuration": 12,
15
- "type": 11,
16
- },
17
- 2 => Object {
18
- "children": Array [
19
- 3,
20
- ],
21
- "displayName": "Parent",
22
- "id": 2,
23
- "key": null,
24
- "parentID": 1,
25
- "treeBaseDuration": 12,
26
- "type": 5,
27
- },
28
- 3 => Object {
29
- "children": Array [],
30
- "displayName": "Child",
31
- "id": 3,
32
- "key": "0",
33
- "parentID": 2,
34
- "treeBaseDuration": 2,
35
- "type": 8,
36
- },
37
- },
38
- "rootID": 1,
39
-}
40
-`;
41
-
42
-exports[`commit tree should be able to rebuild the store tree for each commit: 1: CommitTree 1`] = `
43
-Object {
44
- "nodes": Map {
45
- 1 => Object {
46
- "children": Array [
47
- 2,
48
- ],
49
- "displayName": null,
50
- "id": 1,
51
- "key": null,
52
- "parentID": 0,
53
- "treeBaseDuration": 16,
54
- "type": 11,
55
- },
56
- 2 => Object {
57
- "children": Array [
58
- 3,
59
- 4,
60
- 5,
61
- ],
62
- "displayName": "Parent",
63
- "id": 2,
64
- "key": null,
65
- "parentID": 1,
66
- "treeBaseDuration": 16,
67
- "type": 5,
68
- },
69
- 3 => Object {
70
- "children": Array [],
71
- "displayName": "Child",
72
- "id": 3,
73
- "key": "0",
74
- "parentID": 2,
75
- "treeBaseDuration": 2,
76
- "type": 8,
77
- },
78
- 4 => Object {
79
- "children": Array [],
80
- "displayName": "Child",
81
- "id": 4,
82
- "key": "1",
83
- "parentID": 2,
84
- "treeBaseDuration": 2,
85
- "type": 8,
86
- },
87
- 5 => Object {
88
- "children": Array [],
89
- "displayName": "Child",
90
- "id": 5,
91
- "key": "2",
92
- "parentID": 2,
93
- "treeBaseDuration": 2,
94
- "type": 8,
95
- },
96
- },
97
- "rootID": 1,
98
-}
99
-`;
100
-
101
-exports[`commit tree should be able to rebuild the store tree for each commit: 2: CommitTree 1`] = `
102
-Object {
103
- "nodes": Map {
104
- 1 => Object {
105
- "children": Array [
106
- 2,
107
- ],
108
- "displayName": null,
109
- "id": 1,
110
- "key": null,
111
- "parentID": 0,
112
- "treeBaseDuration": 14,
113
- "type": 11,
114
- },
115
- 2 => Object {
116
- "children": Array [
117
- 3,
118
- 4,
119
- ],
120
- "displayName": "Parent",
121
- "id": 2,
122
- "key": null,
123
- "parentID": 1,
124
- "treeBaseDuration": 14,
125
- "type": 5,
126
- },
127
- 3 => Object {
128
- "children": Array [],
129
- "displayName": "Child",
130
- "id": 3,
131
- "key": "0",
132
- "parentID": 2,
133
- "treeBaseDuration": 2,
134
- "type": 8,
135
- },
136
- 4 => Object {
137
- "children": Array [],
138
- "displayName": "Child",
139
- "id": 4,
140
- "key": "1",
141
- "parentID": 2,
142
- "treeBaseDuration": 2,
143
- "type": 8,
144
- },
145
- },
146
- "rootID": 1,
147
-}
148
-`;
149
-
150
-exports[`commit tree should be able to rebuild the store tree for each commit: 3: CommitTree 1`] = `
151
-Object {
152
- "nodes": Map {
153
- 1 => Object {
154
- "children": Array [
155
- 2,
156
- ],
157
- "displayName": null,
158
- "id": 1,
159
- "key": null,
160
- "parentID": 0,
161
- "treeBaseDuration": 10,
162
- "type": 11,
163
- },
164
- 2 => Object {
165
- "children": Array [],
166
- "displayName": "Parent",
167
- "id": 2,
168
- "key": null,
169
- "parentID": 1,
170
- "treeBaseDuration": 10,
171
- "type": 5,
172
- },
173
- },
174
- "rootID": 1,
175
-}
176
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap
deleted
-590
@@ -1,590 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`Store collapseNodesByDefault:false should display Suspense nodes properly in various states: 1: loading 1`] = `
4
-[root]
5
- ▾ <Wrapper>
6
- <Component key="Outside">
7
- ▾ <Suspense>
8
- <Loading>
9
-`;
10
-
11
-exports[`Store collapseNodesByDefault:false should display Suspense nodes properly in various states: 2: resolved 1`] = `
12
-[root]
13
- ▾ <Wrapper>
14
- <Component key="Outside">
15
- ▾ <Suspense>
16
- <Component key="Inside">
17
-`;
18
-
19
-exports[`Store collapseNodesByDefault:false should filter DOM nodes from the store tree: 1: mount 1`] = `
20
-[root]
21
- ▾ <Grandparent>
22
- ▾ <Parent>
23
- <Child>
24
- ▾ <Parent>
25
- <Child>
26
-`;
27
-
28
-exports[`Store collapseNodesByDefault:false should support collapsing parts of the tree: 1: mount 1`] = `
29
-[root]
30
- ▾ <Grandparent>
31
- ▾ <Parent>
32
- <Child key="0">
33
- <Child key="1">
34
- ▾ <Parent>
35
- <Child key="0">
36
- <Child key="1">
37
-`;
38
-
39
-exports[`Store collapseNodesByDefault:false should support collapsing parts of the tree: 2: collapse first Parent 1`] = `
40
-[root]
41
- ▾ <Grandparent>
42
- ▸ <Parent>
43
- ▾ <Parent>
44
- <Child key="0">
45
- <Child key="1">
46
-`;
47
-
48
-exports[`Store collapseNodesByDefault:false should support collapsing parts of the tree: 3: collapse second Parent 1`] = `
49
-[root]
50
- ▾ <Grandparent>
51
- ▸ <Parent>
52
- ▸ <Parent>
53
-`;
54
-
55
-exports[`Store collapseNodesByDefault:false should support collapsing parts of the tree: 4: expand first Parent 1`] = `
56
-[root]
57
- ▾ <Grandparent>
58
- ▾ <Parent>
59
- <Child key="0">
60
- <Child key="1">
61
- ▸ <Parent>
62
-`;
63
-
64
-exports[`Store collapseNodesByDefault:false should support collapsing parts of the tree: 5: collapse Grandparent 1`] = `
65
-[root]
66
- ▸ <Grandparent>
67
-`;
68
-
69
-exports[`Store collapseNodesByDefault:false should support collapsing parts of the tree: 6: expand Grandparent 1`] = `
70
-[root]
71
- ▾ <Grandparent>
72
- ▾ <Parent>
73
- <Child key="0">
74
- <Child key="1">
75
- ▸ <Parent>
76
-`;
77
-
78
-exports[`Store collapseNodesByDefault:false should support mount and update operations for multiple roots: 1: mount 1`] = `
79
-[root]
80
- ▾ <Parent key="A">
81
- <Child key="0">
82
- <Child key="1">
83
- <Child key="2">
84
-[root]
85
- ▾ <Parent key="B">
86
- <Child key="0">
87
- <Child key="1">
88
-`;
89
-
90
-exports[`Store collapseNodesByDefault:false should support mount and update operations for multiple roots: 2: update 1`] = `
91
-[root]
92
- ▾ <Parent key="A">
93
- <Child key="0">
94
- <Child key="1">
95
- <Child key="2">
96
- <Child key="3">
97
-[root]
98
- ▾ <Parent key="B">
99
- <Child key="0">
100
-`;
101
-
102
-exports[`Store collapseNodesByDefault:false should support mount and update operations for multiple roots: 3: unmount B 1`] = `
103
-[root]
104
- ▾ <Parent key="A">
105
- <Child key="0">
106
- <Child key="1">
107
- <Child key="2">
108
- <Child key="3">
109
-`;
110
-
111
-exports[`Store collapseNodesByDefault:false should support mount and update operations for multiple roots: 4: unmount A 1`] = ``;
112
-
113
-exports[`Store collapseNodesByDefault:false should support mount and update operations: 1: mount 1`] = `
114
-[root]
115
- ▾ <Grandparent>
116
- ▾ <Parent>
117
- <Child key="0">
118
- <Child key="1">
119
- <Child key="2">
120
- <Child key="3">
121
- ▾ <Parent>
122
- <Child key="0">
123
- <Child key="1">
124
- <Child key="2">
125
- <Child key="3">
126
-`;
127
-
128
-exports[`Store collapseNodesByDefault:false should support mount and update operations: 2: update 1`] = `
129
-[root]
130
- ▾ <Grandparent>
131
- ▾ <Parent>
132
- <Child key="0">
133
- <Child key="1">
134
- ▾ <Parent>
135
- <Child key="0">
136
- <Child key="1">
137
-`;
138
-
139
-exports[`Store collapseNodesByDefault:false should support mount and update operations: 3: unmount 1`] = ``;
140
-
141
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 1: third child is suspended 1`] = `
142
-[root]
143
- ▾ <Wrapper>
144
- <Component key="Outside">
145
- ▾ <Suspense>
146
- <Component key="Unrelated at Start">
147
- ▾ <Suspense>
148
- <Component key="Suspense 1 Content">
149
- ▾ <Suspense>
150
- <Component key="Suspense 2 Content">
151
- ▾ <Suspense>
152
- <Loading key="Suspense 3 Fallback">
153
- <Component key="Unrelated at End">
154
-`;
155
-
156
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 2: first and third child are suspended 1`] = `
157
-[root]
158
- ▾ <Wrapper>
159
- <Component key="Outside">
160
- ▾ <Suspense>
161
- <Component key="Unrelated at Start">
162
- ▾ <Suspense>
163
- <Loading key="Suspense 1 Fallback">
164
- ▾ <Suspense>
165
- <Component key="Suspense 2 Content">
166
- ▾ <Suspense>
167
- <Loading key="Suspense 3 Fallback">
168
- <Component key="Unrelated at End">
169
-`;
170
-
171
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 3: second and third child are suspended 1`] = `
172
-[root]
173
- ▾ <Wrapper>
174
- <Component key="Outside">
175
- ▾ <Suspense>
176
- <Component key="Unrelated at Start">
177
- ▾ <Suspense>
178
- <Component key="Suspense 1 Content">
179
- ▾ <Suspense>
180
- <Loading key="Suspense 2 Fallback">
181
- ▾ <Suspense>
182
- <Loading key="Suspense 3 Fallback">
183
- <Component key="Unrelated at End">
184
-`;
185
-
186
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 4: first and third child are suspended 1`] = `
187
-[root]
188
- ▾ <Wrapper>
189
- <Component key="Outside">
190
- ▾ <Suspense>
191
- <Component key="Unrelated at Start">
192
- ▾ <Suspense>
193
- <Loading key="Suspense 1 Fallback">
194
- ▾ <Suspense>
195
- <Component key="Suspense 2 Content">
196
- ▾ <Suspense>
197
- <Loading key="Suspense 3 Fallback">
198
- <Component key="Unrelated at End">
199
-`;
200
-
201
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 5: parent is suspended 1`] = `
202
-[root]
203
- ▾ <Wrapper>
204
- <Component key="Outside">
205
- ▾ <Suspense>
206
- <Loading key="Parent Fallback">
207
-`;
208
-
209
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 6: all children are suspended 1`] = `
210
-[root]
211
- ▾ <Wrapper>
212
- <Component key="Outside">
213
- ▾ <Suspense>
214
- <Component key="Unrelated at Start">
215
- ▾ <Suspense>
216
- <Loading key="Suspense 1 Fallback">
217
- ▾ <Suspense>
218
- <Loading key="Suspense 2 Fallback">
219
- ▾ <Suspense>
220
- <Loading key="Suspense 3 Fallback">
221
- <Component key="Unrelated at End">
222
-`;
223
-
224
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 7: only third child is suspended 1`] = `
225
-[root]
226
- ▾ <Wrapper>
227
- <Component key="Outside">
228
- ▾ <Suspense>
229
- <Component key="Unrelated at Start">
230
- ▾ <Suspense>
231
- <Component key="Suspense 1 Content">
232
- ▾ <Suspense>
233
- <Component key="Suspense 2 Content">
234
- ▾ <Suspense>
235
- <Loading key="Suspense 3 Fallback">
236
- <Component key="Unrelated at End">
237
-`;
238
-
239
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 8: first and third child are suspended 1`] = `
240
-[root]
241
- ▾ <Wrapper>
242
- <Component key="Outside">
243
- ▾ <Suspense>
244
- <Component key="Unrelated at Start">
245
- ▾ <Suspense>
246
- <Loading key="Suspense 1 Fallback">
247
- ▾ <Suspense>
248
- <Component key="Suspense 2 Content">
249
- ▾ <Suspense>
250
- <Loading key="Suspense 3 Fallback">
251
- <Component key="Unrelated at End">
252
-`;
253
-
254
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 9: parent is suspended 1`] = `
255
-[root]
256
- ▾ <Wrapper>
257
- <Component key="Outside">
258
- ▾ <Suspense>
259
- <Loading key="Parent Fallback">
260
-`;
261
-
262
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 10: parent is suspended 1`] = `
263
-[root]
264
- ▾ <Wrapper>
265
- <Component key="Outside">
266
- ▾ <Suspense>
267
- <Loading key="Parent Fallback">
268
-`;
269
-
270
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 11: all children are suspended 1`] = `
271
-[root]
272
- ▾ <Wrapper>
273
- <Component key="Outside">
274
- ▾ <Suspense>
275
- <Component key="Unrelated at Start">
276
- ▾ <Suspense>
277
- <Loading key="Suspense 1 Fallback">
278
- ▾ <Suspense>
279
- <Loading key="Suspense 2 Fallback">
280
- ▾ <Suspense>
281
- <Loading key="Suspense 3 Fallback">
282
- <Component key="Unrelated at End">
283
-`;
284
-
285
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 12: all children are suspended 1`] = `
286
-[root]
287
- ▾ <Wrapper>
288
- <Component key="Outside">
289
- ▾ <Suspense>
290
- <Component key="Unrelated at Start">
291
- ▾ <Suspense>
292
- <Loading key="Suspense 1 Fallback">
293
- ▾ <Suspense>
294
- <Loading key="Suspense 2 Fallback">
295
- ▾ <Suspense>
296
- <Loading key="Suspense 3 Fallback">
297
- <Component key="Unrelated at End">
298
-`;
299
-
300
-exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 13: third child is suspended 1`] = `
301
-[root]
302
- ▾ <Wrapper>
303
- <Component key="Outside">
304
- ▾ <Suspense>
305
- <Component key="Unrelated at Start">
306
- ▾ <Suspense>
307
- <Component key="Suspense 1 Content">
308
- ▾ <Suspense>
309
- <Component key="Suspense 2 Content">
310
- ▾ <Suspense>
311
- <Loading key="Suspense 3 Fallback">
312
- <Component key="Unrelated at End">
313
-`;
314
-
315
-exports[`Store collapseNodesByDefault:false should support reordering of children: 1: mount 1`] = `
316
-[root]
317
- ▾ <Root>
318
- ▾ <Foo key="foo">
319
- <Component key="0">
320
- ▾ <Bar key="bar">
321
- <Component key="0">
322
- <Component key="1">
323
-`;
324
-
325
-exports[`Store collapseNodesByDefault:false should support reordering of children: 3: reorder children 1`] = `
326
-[root]
327
- ▾ <Root>
328
- ▾ <Bar key="bar">
329
- <Component key="0">
330
- <Component key="1">
331
- ▾ <Foo key="foo">
332
- <Component key="0">
333
-`;
334
-
335
-exports[`Store collapseNodesByDefault:false should support reordering of children: 4: collapse root 1`] = `
336
-[root]
337
- ▸ <Root>
338
-`;
339
-
340
-exports[`Store collapseNodesByDefault:false should support reordering of children: 5: expand root 1`] = `
341
-[root]
342
- ▾ <Root>
343
- ▾ <Bar key="bar">
344
- <Component key="0">
345
- <Component key="1">
346
- ▾ <Foo key="foo">
347
- <Component key="0">
348
-`;
349
-
350
-exports[`Store collapseNodesByDefault:true should display Suspense nodes properly in various states: 1: loading 1`] = `
351
-[root]
352
- ▸ <Wrapper>
353
-`;
354
-
355
-exports[`Store collapseNodesByDefault:true should display Suspense nodes properly in various states: 2: expand Wrapper and Suspense 1`] = `
356
-[root]
357
- ▾ <Wrapper>
358
- <Component key="Outside">
359
- ▾ <Suspense>
360
- <Loading>
361
-`;
362
-
363
-exports[`Store collapseNodesByDefault:true should display Suspense nodes properly in various states: 2: resolved 1`] = `
364
-[root]
365
- ▾ <Wrapper>
366
- <Component key="Outside">
367
- ▾ <Suspense>
368
- <Component key="Inside">
369
-`;
370
-
371
-exports[`Store collapseNodesByDefault:true should filter DOM nodes from the store tree: 1: mount 1`] = `
372
-[root]
373
- ▸ <Grandparent>
374
-`;
375
-
376
-exports[`Store collapseNodesByDefault:true should filter DOM nodes from the store tree: 2: expand Grandparent 1`] = `
377
-[root]
378
- ▾ <Grandparent>
379
- ▸ <Parent>
380
- ▸ <Parent>
381
-`;
382
-
383
-exports[`Store collapseNodesByDefault:true should filter DOM nodes from the store tree: 3: expand Parent 1`] = `
384
-[root]
385
- ▾ <Grandparent>
386
- ▾ <Parent>
387
- <Child>
388
- ▸ <Parent>
389
-`;
390
-
391
-exports[`Store collapseNodesByDefault:true should not add new nodes when suspense is toggled: 1: mount 1`] = `
392
-[root]
393
- ▸ <SuspenseTree>
394
-`;
395
-
396
-exports[`Store collapseNodesByDefault:true should not add new nodes when suspense is toggled: 2: expand tree 1`] = `
397
-[root]
398
- ▾ <SuspenseTree>
399
- ▾ <Suspense>
400
- ▸ <Parent>
401
-`;
402
-
403
-exports[`Store collapseNodesByDefault:true should not add new nodes when suspense is toggled: 3: toggle fallback on 1`] = `
404
-[root]
405
- ▾ <SuspenseTree>
406
- ▾ <Suspense>
407
- <Fallback>
408
-`;
409
-
410
-exports[`Store collapseNodesByDefault:true should not add new nodes when suspense is toggled: 4: toggle fallback on 1`] = `
411
-[root]
412
- ▾ <SuspenseTree>
413
- ▾ <Suspense>
414
- ▸ <Parent>
415
-`;
416
-
417
-exports[`Store collapseNodesByDefault:true should support expanding deep parts of the tree: 1: mount 1`] = `
418
-[root]
419
- ▸ <Wrapper>
420
-`;
421
-
422
-exports[`Store collapseNodesByDefault:true should support expanding deep parts of the tree: 2: expand deepest node 1`] = `
423
-[root]
424
- ▾ <Wrapper>
425
- ▾ <Nested>
426
- ▾ <Nested>
427
- ▾ <Nested>
428
- <Nested>
429
-`;
430
-
431
-exports[`Store collapseNodesByDefault:true should support expanding deep parts of the tree: 3: collapse root 1`] = `
432
-[root]
433
- ▸ <Wrapper>
434
-`;
435
-
436
-exports[`Store collapseNodesByDefault:true should support expanding deep parts of the tree: 4: expand root 1`] = `
437
-[root]
438
- ▾ <Wrapper>
439
- ▾ <Nested>
440
- ▾ <Nested>
441
- ▾ <Nested>
442
- <Nested>
443
-`;
444
-
445
-exports[`Store collapseNodesByDefault:true should support expanding deep parts of the tree: 5: collapse middle node 1`] = `
446
-[root]
447
- ▾ <Wrapper>
448
- ▸ <Nested>
449
-`;
450
-
451
-exports[`Store collapseNodesByDefault:true should support expanding deep parts of the tree: 6: expand middle node 1`] = `
452
-[root]
453
- ▾ <Wrapper>
454
- ▾ <Nested>
455
- ▾ <Nested>
456
- ▾ <Nested>
457
- <Nested>
458
-`;
459
-
460
-exports[`Store collapseNodesByDefault:true should support expanding parts of the tree: 1: mount 1`] = `
461
-[root]
462
- ▸ <Grandparent>
463
-`;
464
-
465
-exports[`Store collapseNodesByDefault:true should support expanding parts of the tree: 2: expand Grandparent 1`] = `
466
-[root]
467
- ▾ <Grandparent>
468
- ▸ <Parent>
469
- ▸ <Parent>
470
-`;
471
-
472
-exports[`Store collapseNodesByDefault:true should support expanding parts of the tree: 3: expand first Parent 1`] = `
473
-[root]
474
- ▾ <Grandparent>
475
- ▾ <Parent>
476
- <Child key="0">
477
- <Child key="1">
478
- ▸ <Parent>
479
-`;
480
-
481
-exports[`Store collapseNodesByDefault:true should support expanding parts of the tree: 4: expand second Parent 1`] = `
482
-[root]
483
- ▾ <Grandparent>
484
- ▾ <Parent>
485
- <Child key="0">
486
- <Child key="1">
487
- ▾ <Parent>
488
- <Child key="0">
489
- <Child key="1">
490
-`;
491
-
492
-exports[`Store collapseNodesByDefault:true should support expanding parts of the tree: 5: collapse first Parent 1`] = `
493
-[root]
494
- ▾ <Grandparent>
495
- ▸ <Parent>
496
- ▾ <Parent>
497
- <Child key="0">
498
- <Child key="1">
499
-`;
500
-
501
-exports[`Store collapseNodesByDefault:true should support expanding parts of the tree: 6: collapse second Parent 1`] = `
502
-[root]
503
- ▾ <Grandparent>
504
- ▸ <Parent>
505
- ▸ <Parent>
506
-`;
507
-
508
-exports[`Store collapseNodesByDefault:true should support expanding parts of the tree: 7: collapse Grandparent 1`] = `
509
-[root]
510
- ▸ <Grandparent>
511
-`;
512
-
513
-exports[`Store collapseNodesByDefault:true should support mount and update operations for multiple roots: 1: mount 1`] = `
514
-[root]
515
- ▸ <Parent key="A">
516
-[root]
517
- ▸ <Parent key="B">
518
-`;
519
-
520
-exports[`Store collapseNodesByDefault:true should support mount and update operations for multiple roots: 2: update 1`] = `
521
-[root]
522
- ▸ <Parent key="A">
523
-[root]
524
- ▸ <Parent key="B">
525
-`;
526
-
527
-exports[`Store collapseNodesByDefault:true should support mount and update operations for multiple roots: 3: unmount B 1`] = `
528
-[root]
529
- ▸ <Parent key="A">
530
-`;
531
-
532
-exports[`Store collapseNodesByDefault:true should support mount and update operations for multiple roots: 4: unmount A 1`] = ``;
533
-
534
-exports[`Store collapseNodesByDefault:true should support mount and update operations: 1: mount 1`] = `
535
-[root]
536
- ▸ <Parent>
537
- ▸ <Parent>
538
-`;
539
-
540
-exports[`Store collapseNodesByDefault:true should support mount and update operations: 2: update 1`] = `
541
-[root]
542
- ▸ <Parent>
543
- ▸ <Parent>
544
-`;
545
-
546
-exports[`Store collapseNodesByDefault:true should support mount and update operations: 3: unmount 1`] = ``;
547
-
548
-exports[`Store collapseNodesByDefault:true should support reordering of children: 1: mount 1`] = `
549
-[root]
550
- ▸ <Root>
551
-`;
552
-
553
-exports[`Store collapseNodesByDefault:true should support reordering of children: 3: reorder children 1`] = `
554
-[root]
555
- ▸ <Root>
556
-`;
557
-
558
-exports[`Store collapseNodesByDefault:true should support reordering of children: 4: expand root 1`] = `
559
-[root]
560
- ▾ <Root>
561
- ▸ <Bar key="bar">
562
- ▸ <Foo key="foo">
563
-`;
564
-
565
-exports[`Store collapseNodesByDefault:true should support reordering of children: 5: expand leaves 1`] = `
566
-[root]
567
- ▾ <Root>
568
- ▾ <Bar key="bar">
569
- <Component key="0">
570
- <Component key="1">
571
- ▾ <Foo key="foo">
572
- <Component key="0">
573
-`;
574
-
575
-exports[`Store collapseNodesByDefault:true should support reordering of children: 6: collapse root 1`] = `
576
-[root]
577
- ▸ <Root>
578
-`;
579
-
580
-exports[`Store should not allow a root node to be collapsed: 1: mount 1`] = `
581
-[root]
582
- <Component>
583
-`;
584
-
585
-exports[`Store should properly handle a root with no visible nodes: 1: mount 1`] = `
586
-[root]
587
- <Root>
588
-`;
589
-
590
-exports[`Store should properly handle a root with no visible nodes: 2: add host nodes 1`] = `[root]`;
packages/react-devtools-shared/src/__tests__/__snapshots__/storeComponentFilters-test.js.snap
deleted
-120
@@ -1,120 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`Store component filters should filter HOCs: 1: mount 1`] = `
4
-[root]
5
- ▾ <Component> [Bar][Foo]
6
- ▾ <Component> [Foo]
7
- ▾ <Component>
8
- <div>
9
-`;
10
-
11
-exports[`Store component filters should filter HOCs: 2: hide all HOCs 1`] = `
12
-[root]
13
- ▾ <Component>
14
- <div>
15
-`;
16
-
17
-exports[`Store component filters should filter HOCs: 3: disable HOC filter 1`] = `
18
-[root]
19
- ▾ <Component> [Bar][Foo]
20
- ▾ <Component> [Foo]
21
- ▾ <Component>
22
- <div>
23
-`;
24
-
25
-exports[`Store component filters should filter by display name: 1: mount 1`] = `
26
-[root]
27
- ▾ <Foo>
28
- <Text>
29
- ▾ <Bar>
30
- <Text>
31
- ▾ <Baz>
32
- <Text>
33
-`;
34
-
35
-exports[`Store component filters should filter by display name: 2: filter "Foo" 1`] = `
36
-[root]
37
- <Text>
38
- ▾ <Bar>
39
- <Text>
40
- ▾ <Baz>
41
- <Text>
42
-`;
43
-
44
-exports[`Store component filters should filter by display name: 3: filter "Ba" 1`] = `
45
-[root]
46
- ▾ <Foo>
47
- <Text>
48
- <Text>
49
- <Text>
50
-`;
51
-
52
-exports[`Store component filters should filter by display name: 4: filter "B.z" 1`] = `
53
-[root]
54
- ▾ <Foo>
55
- <Text>
56
- ▾ <Bar>
57
- <Text>
58
- <Text>
59
-`;
60
-
61
-exports[`Store component filters should filter by path: 1: mount 1`] = `
62
-[root]
63
- ▾ <Component>
64
- <div>
65
-`;
66
-
67
-exports[`Store component filters should filter by path: 2: hide all components declared within this test filed 1`] = `[root]`;
68
-
69
-exports[`Store component filters should filter by path: 3: hide components in a made up fake path 1`] = `
70
-[root]
71
- ▾ <Component>
72
- <div>
73
-`;
74
-
75
-exports[`Store component filters should ignore invalid ElementTypeRoot filter: 1: mount 1`] = `
76
-[root]
77
- ▾ <Root>
78
- <div>
79
-`;
80
-
81
-exports[`Store component filters should ignore invalid ElementTypeRoot filter: 2: add invalid filter 1`] = `
82
-[root]
83
- ▾ <Root>
84
- <div>
85
-`;
86
-
87
-exports[`Store component filters should support filtering by element type: 1: mount 1`] = `
88
-[root]
89
- ▾ <Root>
90
- ▾ <div>
91
- ▾ <Component>
92
- <div>
93
-`;
94
-
95
-exports[`Store component filters should support filtering by element type: 2: hide host components 1`] = `
96
-[root]
97
- ▾ <Root>
98
- <Component>
99
-`;
100
-
101
-exports[`Store component filters should support filtering by element type: 3: hide class components 1`] = `
102
-[root]
103
- ▾ <div>
104
- ▾ <Component>
105
- <div>
106
-`;
107
-
108
-exports[`Store component filters should support filtering by element type: 4: hide class and function components 1`] = `
109
-[root]
110
- ▾ <div>
111
- <div>
112
-`;
113
-
114
-exports[`Store component filters should support filtering by element type: 5: disable all filters 1`] = `
115
-[root]
116
- ▾ <Root>
117
- ▾ <div>
118
- ▾ <Component>
119
- <div>
120
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/storeOwners-test.js.snap
deleted
-121
@@ -1,121 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`Store owners list should drill through interleaved intermediate components: 1: mount 1`] = `
4
-[root]
5
- ▾ <Root>
6
- ▾ <Intermediate key="intermediate">
7
- <Leaf key="leaf">
8
- ▾ <Wrapper key="wrapper">
9
- <Leaf>
10
- <Leaf key="leaf">
11
-`;
12
-
13
-exports[`Store owners list should drill through interleaved intermediate components: 2: components owned by <Root> 1`] = `
14
-" ▾ <Root>
15
- ▾ <Intermediate key=\\"intermediate\\">
16
- <Leaf>
17
- <Leaf key=\\"leaf\\">"
18
-`;
19
-
20
-exports[`Store owners list should drill through interleaved intermediate components: 3: components owned by <Intermediate> 1`] = `
21
-" ▾ <Intermediate key=\\"intermediate\\">
22
- <Leaf key=\\"leaf\\">
23
- ▾ <Wrapper key=\\"wrapper\\">"
24
-`;
25
-
26
-exports[`Store owners list should drill through intermediate components: 1: mount 1`] = `
27
-[root]
28
- ▾ <Root>
29
- ▾ <Intermediate>
30
- ▾ <Wrapper>
31
- <Leaf>
32
-`;
33
-
34
-exports[`Store owners list should drill through intermediate components: 2: components owned by <Root> 1`] = `
35
-" ▾ <Root>
36
- ▾ <Intermediate>
37
- <Leaf>"
38
-`;
39
-
40
-exports[`Store owners list should drill through intermediate components: 3: components owned by <Intermediate> 1`] = `
41
-" ▾ <Intermediate>
42
- ▾ <Wrapper>"
43
-`;
44
-
45
-exports[`Store owners list should show the proper owners list order and contents after insertions and deletions: 1: mount 1`] = `
46
-[root]
47
- ▾ <Root>
48
- ▾ <Intermediate>
49
- ▾ <Wrapper>
50
- <Leaf>
51
-`;
52
-
53
-exports[`Store owners list should show the proper owners list order and contents after insertions and deletions: 2: components owned by <Root> 1`] = `
54
-" ▾ <Root>
55
- ▾ <Intermediate>
56
- <Leaf>"
57
-`;
58
-
59
-exports[`Store owners list should show the proper owners list order and contents after insertions and deletions: 3: update to add direct 1`] = `
60
-[root]
61
- ▾ <Root>
62
- <Leaf>
63
- ▾ <Intermediate>
64
- ▾ <Wrapper>
65
- <Leaf>
66
-`;
67
-
68
-exports[`Store owners list should show the proper owners list order and contents after insertions and deletions: 4: components owned by <Root> 1`] = `
69
-" ▾ <Root>
70
- <Leaf>
71
- ▾ <Intermediate>
72
- <Leaf>"
73
-`;
74
-
75
-exports[`Store owners list should show the proper owners list order and contents after insertions and deletions: 5: update to remove indirect 1`] = `
76
-[root]
77
- ▾ <Root>
78
- <Leaf>
79
-`;
80
-
81
-exports[`Store owners list should show the proper owners list order and contents after insertions and deletions: 6: components owned by <Root> 1`] = `
82
-" ▾ <Root>
83
- <Leaf>"
84
-`;
85
-
86
-exports[`Store owners list should show the proper owners list order and contents after insertions and deletions: 7: update to remove both 1`] = `
87
-[root]
88
- <Root>
89
-`;
90
-
91
-exports[`Store owners list should show the proper owners list order and contents after insertions and deletions: 8: components owned by <Root> 1`] = `" <Root>"`;
92
-
93
-exports[`Store owners list should show the proper owners list ordering after reordered children: 1: mount (ascending) 1`] = `
94
-[root]
95
- ▾ <Root>
96
- <Leaf key="A">
97
- <Leaf key="B">
98
- <Leaf key="C">
99
-`;
100
-
101
-exports[`Store owners list should show the proper owners list ordering after reordered children: 2: components owned by <Root> 1`] = `
102
-" ▾ <Root>
103
- <Leaf key=\\"A\\">
104
- <Leaf key=\\"B\\">
105
- <Leaf key=\\"C\\">"
106
-`;
107
-
108
-exports[`Store owners list should show the proper owners list ordering after reordered children: 3: update (descending) 1`] = `
109
-[root]
110
- ▾ <Root>
111
- <Leaf key="C">
112
- <Leaf key="B">
113
- <Leaf key="A">
114
-`;
115
-
116
-exports[`Store owners list should show the proper owners list ordering after reordered children: 4: components owned by <Root> 1`] = `
117
-" ▾ <Root>
118
- <Leaf key=\\"C\\">
119
- <Leaf key=\\"B\\">
120
- <Leaf key=\\"A\\">"
121
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/storeStressSync-test.js.snap
deleted
-493
@@ -1,493 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 1`] = `
4
-[root]
5
- ▾ <Root>
6
- <X>
7
- ▾ <Suspense>
8
- <A key="a">
9
- <Y>
10
-`;
11
-
12
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 2`] = `
13
-[root]
14
- ▾ <Root>
15
- <X>
16
- ▾ <Suspense>
17
- <A key="a">
18
- <Y>
19
-`;
20
-
21
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 3`] = `
22
-[root]
23
- ▾ <Root>
24
- <X>
25
- ▾ <Suspense>
26
- <A key="a">
27
- <B key="b">
28
- <C key="c">
29
- <Y>
30
-`;
31
-
32
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 4`] = `
33
-[root]
34
- ▾ <Root>
35
- <X>
36
- ▾ <Suspense>
37
- <C key="c">
38
- <B key="b">
39
- <A key="a">
40
- <Y>
41
-`;
42
-
43
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 5`] = `
44
-[root]
45
- ▾ <Root>
46
- <X>
47
- ▾ <Suspense>
48
- <C key="c">
49
- <A key="a">
50
- <Y>
51
-`;
52
-
53
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 6`] = `
54
-[root]
55
- ▾ <Root>
56
- <X>
57
- ▾ <Suspense>
58
- <C key="c">
59
- <A key="a">
60
- <Y>
61
-`;
62
-
63
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 7`] = `
64
-[root]
65
- ▾ <Root>
66
- <X>
67
- ▾ <Suspense>
68
- <C key="c">
69
- <A key="a">
70
- <Y>
71
-`;
72
-
73
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 8`] = `
74
-[root]
75
- ▾ <Root>
76
- <X>
77
- ▾ <Suspense>
78
- <A key="a">
79
- <B key="b">
80
- <Y>
81
-`;
82
-
83
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 9`] = `
84
-[root]
85
- ▾ <Root>
86
- <X>
87
- ▾ <Suspense>
88
- <A key="a">
89
- <Y>
90
-`;
91
-
92
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 10`] = `
93
-[root]
94
- ▾ <Root>
95
- <X>
96
- <Suspense>
97
- <Y>
98
-`;
99
-
100
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 11`] = `
101
-[root]
102
- ▾ <Root>
103
- <X>
104
- ▾ <Suspense>
105
- <B key="b">
106
- <Y>
107
-`;
108
-
109
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 12`] = `
110
-[root]
111
- ▾ <Root>
112
- <X>
113
- ▾ <Suspense>
114
- <A key="a">
115
- <Y>
116
-`;
117
-
118
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 1`] = `
119
-[root]
120
- ▾ <Root>
121
- <X>
122
- ▾ <Suspense>
123
- ▾ <MaybeSuspend>
124
- <A key="a">
125
- <Z>
126
- <Y>
127
-`;
128
-
129
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 2`] = `
130
-[root]
131
- ▾ <Root>
132
- <X>
133
- ▾ <Suspense>
134
- ▾ <MaybeSuspend>
135
- <A key="a">
136
- <Z>
137
- <Y>
138
-`;
139
-
140
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 3`] = `
141
-[root]
142
- ▾ <Root>
143
- <X>
144
- ▾ <Suspense>
145
- ▾ <MaybeSuspend>
146
- <A key="a">
147
- <B key="b">
148
- <C key="c">
149
- <Z>
150
- <Y>
151
-`;
152
-
153
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 4`] = `
154
-[root]
155
- ▾ <Root>
156
- <X>
157
- ▾ <Suspense>
158
- ▾ <MaybeSuspend>
159
- <C key="c">
160
- <B key="b">
161
- <A key="a">
162
- <Z>
163
- <Y>
164
-`;
165
-
166
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 5`] = `
167
-[root]
168
- ▾ <Root>
169
- <X>
170
- ▾ <Suspense>
171
- ▾ <MaybeSuspend>
172
- <C key="c">
173
- <A key="a">
174
- <Z>
175
- <Y>
176
-`;
177
-
178
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 6`] = `
179
-[root]
180
- ▾ <Root>
181
- <X>
182
- ▾ <Suspense>
183
- ▾ <MaybeSuspend>
184
- <C key="c">
185
- <A key="a">
186
- <Z>
187
- <Y>
188
-`;
189
-
190
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 7`] = `
191
-[root]
192
- ▾ <Root>
193
- <X>
194
- ▾ <Suspense>
195
- ▾ <MaybeSuspend>
196
- <C key="c">
197
- <A key="a">
198
- <Z>
199
- <Y>
200
-`;
201
-
202
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 8`] = `
203
-[root]
204
- ▾ <Root>
205
- <X>
206
- ▾ <Suspense>
207
- ▾ <MaybeSuspend>
208
- <A key="a">
209
- <B key="b">
210
- <Z>
211
- <Y>
212
-`;
213
-
214
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 9`] = `
215
-[root]
216
- ▾ <Root>
217
- <X>
218
- ▾ <Suspense>
219
- ▾ <MaybeSuspend>
220
- <A key="a">
221
- <Z>
222
- <Y>
223
-`;
224
-
225
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 10`] = `
226
-[root]
227
- ▾ <Root>
228
- <X>
229
- ▾ <Suspense>
230
- ▾ <MaybeSuspend>
231
- <Z>
232
- <Y>
233
-`;
234
-
235
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 11`] = `
236
-[root]
237
- ▾ <Root>
238
- <X>
239
- ▾ <Suspense>
240
- ▾ <MaybeSuspend>
241
- <B key="b">
242
- <Z>
243
- <Y>
244
-`;
245
-
246
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 12`] = `
247
-[root]
248
- ▾ <Root>
249
- <X>
250
- ▾ <Suspense>
251
- ▾ <MaybeSuspend>
252
- <A key="a">
253
- <Z>
254
- <Y>
255
-`;
256
-
257
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 13`] = `
258
-[root]
259
- ▾ <Root>
260
- <X>
261
- ▾ <Suspense>
262
- <A key="a">
263
- <Y>
264
-`;
265
-
266
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 14`] = `
267
-[root]
268
- ▾ <Root>
269
- <X>
270
- ▾ <Suspense>
271
- <A key="a">
272
- <Y>
273
-`;
274
-
275
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 15`] = `
276
-[root]
277
- ▾ <Root>
278
- <X>
279
- ▾ <Suspense>
280
- <A key="a">
281
- <B key="b">
282
- <C key="c">
283
- <Y>
284
-`;
285
-
286
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 16`] = `
287
-[root]
288
- ▾ <Root>
289
- <X>
290
- ▾ <Suspense>
291
- <C key="c">
292
- <B key="b">
293
- <A key="a">
294
- <Y>
295
-`;
296
-
297
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 17`] = `
298
-[root]
299
- ▾ <Root>
300
- <X>
301
- ▾ <Suspense>
302
- <C key="c">
303
- <A key="a">
304
- <Y>
305
-`;
306
-
307
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 18`] = `
308
-[root]
309
- ▾ <Root>
310
- <X>
311
- ▾ <Suspense>
312
- <C key="c">
313
- <A key="a">
314
- <Y>
315
-`;
316
-
317
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 19`] = `
318
-[root]
319
- ▾ <Root>
320
- <X>
321
- ▾ <Suspense>
322
- <C key="c">
323
- <A key="a">
324
- <Y>
325
-`;
326
-
327
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 20`] = `
328
-[root]
329
- ▾ <Root>
330
- <X>
331
- ▾ <Suspense>
332
- <A key="a">
333
- <B key="b">
334
- <Y>
335
-`;
336
-
337
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 21`] = `
338
-[root]
339
- ▾ <Root>
340
- <X>
341
- ▾ <Suspense>
342
- <A key="a">
343
- <Y>
344
-`;
345
-
346
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 22`] = `
347
-[root]
348
- ▾ <Root>
349
- <X>
350
- <Suspense>
351
- <Y>
352
-`;
353
-
354
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 23`] = `
355
-[root]
356
- ▾ <Root>
357
- <X>
358
- ▾ <Suspense>
359
- <B key="b">
360
- <Y>
361
-`;
362
-
363
-exports[`StoreStress (Sync Mode) should handle a stress test for Suspense without type change (Sync Mode) 24`] = `
364
-[root]
365
- ▾ <Root>
366
- <X>
367
- ▾ <Suspense>
368
- <A key="a">
369
- <Y>
370
-`;
371
-
372
-exports[`StoreStress (Sync Mode) should handle a stress test with different tree operations (Sync Mode): 1: abcde 1`] = `
373
-[root]
374
- ▾ <Parent>
375
- <A key="a">
376
- <B key="b">
377
- <C key="c">
378
- <D key="d">
379
- <E key="e">
380
-`;
381
-
382
-exports[`StoreStress (Sync Mode) should handle a stress test with different tree operations (Sync Mode): 2: abxde 1`] = `
383
-[root]
384
- ▾ <Parent>
385
- <A key="a">
386
- <B key="b">
387
- ▾ <C key="c">
388
- <X>
389
- <D key="d">
390
- <E key="e">
391
-`;
392
-
393
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 1`] = `
394
-[root]
395
- ▾ <Root>
396
- <A key="a">
397
-`;
398
-
399
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 2`] = `
400
-[root]
401
- ▾ <Root>
402
- <B key="b">
403
-`;
404
-
405
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 3`] = `
406
-[root]
407
- ▾ <Root>
408
- <C key="c">
409
-`;
410
-
411
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 4`] = `
412
-[root]
413
- ▾ <Root>
414
- <D key="d">
415
-`;
416
-
417
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 5`] = `
418
-[root]
419
- ▾ <Root>
420
- <E key="e">
421
-`;
422
-
423
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 6`] = `
424
-[root]
425
- ▾ <Root>
426
- <A key="a">
427
-`;
428
-
429
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 7`] = `
430
-[root]
431
- ▾ <Root>
432
- <B key="b">
433
-`;
434
-
435
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 8`] = `
436
-[root]
437
- ▾ <Root>
438
- <C key="c">
439
-`;
440
-
441
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 9`] = `
442
-[root]
443
- ▾ <Root>
444
- <D key="d">
445
-`;
446
-
447
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 10`] = `
448
-[root]
449
- ▾ <Root>
450
- <E key="e">
451
-`;
452
-
453
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 11`] = `
454
-[root]
455
- ▾ <Root>
456
- <A key="a">
457
- <B key="b">
458
-`;
459
-
460
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 12`] = `
461
-[root]
462
- ▾ <Root>
463
- <B key="b">
464
- <A key="a">
465
-`;
466
-
467
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 13`] = `
468
-[root]
469
- ▾ <Root>
470
- <B key="b">
471
- <C key="c">
472
-`;
473
-
474
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 14`] = `
475
-[root]
476
- ▾ <Root>
477
- <C key="c">
478
- <B key="b">
479
-`;
480
-
481
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 15`] = `
482
-[root]
483
- ▾ <Root>
484
- <A key="a">
485
- <C key="c">
486
-`;
487
-
488
-exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 16`] = `
489
-[root]
490
- ▾ <Root>
491
- <C key="c">
492
- <A key="a">
493
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/storeStressTestConcurrent-test.js.snap
deleted
-493
@@ -1,493 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 1`] = `
4
-[root]
5
- ▾ <Root>
6
- <X>
7
- ▾ <Suspense>
8
- <A key="a">
9
- <Y>
10
-`;
11
-
12
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 2`] = `
13
-[root]
14
- ▾ <Root>
15
- <X>
16
- ▾ <Suspense>
17
- <A key="a">
18
- <Y>
19
-`;
20
-
21
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 3`] = `
22
-[root]
23
- ▾ <Root>
24
- <X>
25
- ▾ <Suspense>
26
- <A key="a">
27
- <B key="b">
28
- <C key="c">
29
- <Y>
30
-`;
31
-
32
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 4`] = `
33
-[root]
34
- ▾ <Root>
35
- <X>
36
- ▾ <Suspense>
37
- <C key="c">
38
- <B key="b">
39
- <A key="a">
40
- <Y>
41
-`;
42
-
43
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 5`] = `
44
-[root]
45
- ▾ <Root>
46
- <X>
47
- ▾ <Suspense>
48
- <C key="c">
49
- <A key="a">
50
- <Y>
51
-`;
52
-
53
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 6`] = `
54
-[root]
55
- ▾ <Root>
56
- <X>
57
- ▾ <Suspense>
58
- <C key="c">
59
- <A key="a">
60
- <Y>
61
-`;
62
-
63
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 7`] = `
64
-[root]
65
- ▾ <Root>
66
- <X>
67
- ▾ <Suspense>
68
- <C key="c">
69
- <A key="a">
70
- <Y>
71
-`;
72
-
73
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 8`] = `
74
-[root]
75
- ▾ <Root>
76
- <X>
77
- ▾ <Suspense>
78
- <A key="a">
79
- <B key="b">
80
- <Y>
81
-`;
82
-
83
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 9`] = `
84
-[root]
85
- ▾ <Root>
86
- <X>
87
- ▾ <Suspense>
88
- <A key="a">
89
- <Y>
90
-`;
91
-
92
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 10`] = `
93
-[root]
94
- ▾ <Root>
95
- <X>
96
- <Suspense>
97
- <Y>
98
-`;
99
-
100
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 11`] = `
101
-[root]
102
- ▾ <Root>
103
- <X>
104
- ▾ <Suspense>
105
- <B key="b">
106
- <Y>
107
-`;
108
-
109
-exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 12`] = `
110
-[root]
111
- ▾ <Root>
112
- <X>
113
- ▾ <Suspense>
114
- <A key="a">
115
- <Y>
116
-`;
117
-
118
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 1`] = `
119
-[root]
120
- ▾ <Root>
121
- <X>
122
- ▾ <Suspense>
123
- ▾ <MaybeSuspend>
124
- <A key="a">
125
- <Z>
126
- <Y>
127
-`;
128
-
129
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 2`] = `
130
-[root]
131
- ▾ <Root>
132
- <X>
133
- ▾ <Suspense>
134
- ▾ <MaybeSuspend>
135
- <A key="a">
136
- <Z>
137
- <Y>
138
-`;
139
-
140
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 3`] = `
141
-[root]
142
- ▾ <Root>
143
- <X>
144
- ▾ <Suspense>
145
- ▾ <MaybeSuspend>
146
- <A key="a">
147
- <B key="b">
148
- <C key="c">
149
- <Z>
150
- <Y>
151
-`;
152
-
153
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 4`] = `
154
-[root]
155
- ▾ <Root>
156
- <X>
157
- ▾ <Suspense>
158
- ▾ <MaybeSuspend>
159
- <C key="c">
160
- <B key="b">
161
- <A key="a">
162
- <Z>
163
- <Y>
164
-`;
165
-
166
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 5`] = `
167
-[root]
168
- ▾ <Root>
169
- <X>
170
- ▾ <Suspense>
171
- ▾ <MaybeSuspend>
172
- <C key="c">
173
- <A key="a">
174
- <Z>
175
- <Y>
176
-`;
177
-
178
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 6`] = `
179
-[root]
180
- ▾ <Root>
181
- <X>
182
- ▾ <Suspense>
183
- ▾ <MaybeSuspend>
184
- <C key="c">
185
- <A key="a">
186
- <Z>
187
- <Y>
188
-`;
189
-
190
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 7`] = `
191
-[root]
192
- ▾ <Root>
193
- <X>
194
- ▾ <Suspense>
195
- ▾ <MaybeSuspend>
196
- <C key="c">
197
- <A key="a">
198
- <Z>
199
- <Y>
200
-`;
201
-
202
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 8`] = `
203
-[root]
204
- ▾ <Root>
205
- <X>
206
- ▾ <Suspense>
207
- ▾ <MaybeSuspend>
208
- <A key="a">
209
- <B key="b">
210
- <Z>
211
- <Y>
212
-`;
213
-
214
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 9`] = `
215
-[root]
216
- ▾ <Root>
217
- <X>
218
- ▾ <Suspense>
219
- ▾ <MaybeSuspend>
220
- <A key="a">
221
- <Z>
222
- <Y>
223
-`;
224
-
225
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 10`] = `
226
-[root]
227
- ▾ <Root>
228
- <X>
229
- ▾ <Suspense>
230
- ▾ <MaybeSuspend>
231
- <Z>
232
- <Y>
233
-`;
234
-
235
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 11`] = `
236
-[root]
237
- ▾ <Root>
238
- <X>
239
- ▾ <Suspense>
240
- ▾ <MaybeSuspend>
241
- <B key="b">
242
- <Z>
243
- <Y>
244
-`;
245
-
246
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 12`] = `
247
-[root]
248
- ▾ <Root>
249
- <X>
250
- ▾ <Suspense>
251
- ▾ <MaybeSuspend>
252
- <A key="a">
253
- <Z>
254
- <Y>
255
-`;
256
-
257
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 13`] = `
258
-[root]
259
- ▾ <Root>
260
- <X>
261
- ▾ <Suspense>
262
- <A key="a">
263
- <Y>
264
-`;
265
-
266
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 14`] = `
267
-[root]
268
- ▾ <Root>
269
- <X>
270
- ▾ <Suspense>
271
- <A key="a">
272
- <Y>
273
-`;
274
-
275
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 15`] = `
276
-[root]
277
- ▾ <Root>
278
- <X>
279
- ▾ <Suspense>
280
- <A key="a">
281
- <B key="b">
282
- <C key="c">
283
- <Y>
284
-`;
285
-
286
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 16`] = `
287
-[root]
288
- ▾ <Root>
289
- <X>
290
- ▾ <Suspense>
291
- <C key="c">
292
- <B key="b">
293
- <A key="a">
294
- <Y>
295
-`;
296
-
297
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 17`] = `
298
-[root]
299
- ▾ <Root>
300
- <X>
301
- ▾ <Suspense>
302
- <C key="c">
303
- <A key="a">
304
- <Y>
305
-`;
306
-
307
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 18`] = `
308
-[root]
309
- ▾ <Root>
310
- <X>
311
- ▾ <Suspense>
312
- <C key="c">
313
- <A key="a">
314
- <Y>
315
-`;
316
-
317
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 19`] = `
318
-[root]
319
- ▾ <Root>
320
- <X>
321
- ▾ <Suspense>
322
- <C key="c">
323
- <A key="a">
324
- <Y>
325
-`;
326
-
327
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 20`] = `
328
-[root]
329
- ▾ <Root>
330
- <X>
331
- ▾ <Suspense>
332
- <A key="a">
333
- <B key="b">
334
- <Y>
335
-`;
336
-
337
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 21`] = `
338
-[root]
339
- ▾ <Root>
340
- <X>
341
- ▾ <Suspense>
342
- <A key="a">
343
- <Y>
344
-`;
345
-
346
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 22`] = `
347
-[root]
348
- ▾ <Root>
349
- <X>
350
- <Suspense>
351
- <Y>
352
-`;
353
-
354
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 23`] = `
355
-[root]
356
- ▾ <Root>
357
- <X>
358
- ▾ <Suspense>
359
- <B key="b">
360
- <Y>
361
-`;
362
-
363
-exports[`StoreStressConcurrent should handle a stress test for Suspense without type change (Concurrent Mode) 24`] = `
364
-[root]
365
- ▾ <Root>
366
- <X>
367
- ▾ <Suspense>
368
- <A key="a">
369
- <Y>
370
-`;
371
-
372
-exports[`StoreStressConcurrent should handle a stress test with different tree operations (Concurrent Mode): 1: abcde 1`] = `
373
-[root]
374
- ▾ <Parent>
375
- <A key="a">
376
- <B key="b">
377
- <C key="c">
378
- <D key="d">
379
- <E key="e">
380
-`;
381
-
382
-exports[`StoreStressConcurrent should handle a stress test with different tree operations (Concurrent Mode): 2: abxde 1`] = `
383
-[root]
384
- ▾ <Parent>
385
- <A key="a">
386
- <B key="b">
387
- ▾ <C key="c">
388
- <X>
389
- <D key="d">
390
- <E key="e">
391
-`;
392
-
393
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 1`] = `
394
-[root]
395
- ▾ <Root>
396
- <A key="a">
397
-`;
398
-
399
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 2`] = `
400
-[root]
401
- ▾ <Root>
402
- <B key="b">
403
-`;
404
-
405
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 3`] = `
406
-[root]
407
- ▾ <Root>
408
- <C key="c">
409
-`;
410
-
411
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 4`] = `
412
-[root]
413
- ▾ <Root>
414
- <D key="d">
415
-`;
416
-
417
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 5`] = `
418
-[root]
419
- ▾ <Root>
420
- <E key="e">
421
-`;
422
-
423
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 6`] = `
424
-[root]
425
- ▾ <Root>
426
- <A key="a">
427
-`;
428
-
429
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 7`] = `
430
-[root]
431
- ▾ <Root>
432
- <B key="b">
433
-`;
434
-
435
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 8`] = `
436
-[root]
437
- ▾ <Root>
438
- <C key="c">
439
-`;
440
-
441
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 9`] = `
442
-[root]
443
- ▾ <Root>
444
- <D key="d">
445
-`;
446
-
447
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 10`] = `
448
-[root]
449
- ▾ <Root>
450
- <E key="e">
451
-`;
452
-
453
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 11`] = `
454
-[root]
455
- ▾ <Root>
456
- <A key="a">
457
- <B key="b">
458
-`;
459
-
460
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 12`] = `
461
-[root]
462
- ▾ <Root>
463
- <B key="b">
464
- <A key="a">
465
-`;
466
-
467
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 13`] = `
468
-[root]
469
- ▾ <Root>
470
- <B key="b">
471
- <C key="c">
472
-`;
473
-
474
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 14`] = `
475
-[root]
476
- ▾ <Root>
477
- <C key="c">
478
- <B key="b">
479
-`;
480
-
481
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 15`] = `
482
-[root]
483
- ▾ <Root>
484
- <A key="a">
485
- <C key="c">
486
-`;
487
-
488
-exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 16`] = `
489
-[root]
490
- ▾ <Root>
491
- <C key="c">
492
- <A key="a">
493
-`;
packages/react-devtools-shared/src/__tests__/__snapshots__/treeContext-test.js.snap
deleted
-1204
@@ -1,1204 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 0: mount 1`] = `
4
-[root]
5
- ▾ <Parent>
6
- ▾ <Suspense>
7
- ▾ <Child>
8
- ▾ <Suspense>
9
- <Grandchild>
10
-`;
11
-
12
-exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 1: initial state 1`] = `
13
-Object {
14
- "inspectedElementID": null,
15
- "numElements": 5,
16
- "ownerFlatTree": null,
17
- "ownerID": null,
18
- "searchIndex": null,
19
- "searchResults": Array [],
20
- "searchText": "",
21
- "selectedElementID": null,
22
- "selectedElementIndex": null,
23
-}
24
-`;
25
-
26
-exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 2: child owners tree 1`] = `
27
-Object {
28
- "inspectedElementID": 4,
29
- "numElements": 3,
30
- "ownerFlatTree": Array [
31
- Object {
32
- "children": Array [
33
- 5,
34
- ],
35
- "depth": 0,
36
- "displayName": "Child",
37
- "hocDisplayNames": null,
38
- "id": 4,
39
- "isCollapsed": false,
40
- "key": null,
41
- "ownerID": 2,
42
- "parentID": 3,
43
- "type": 5,
44
- "weight": 3,
45
- },
46
- Object {
47
- "children": Array [
48
- 6,
49
- ],
50
- "depth": 1,
51
- "displayName": "Suspense",
52
- "hocDisplayNames": null,
53
- "id": 5,
54
- "isCollapsed": false,
55
- "key": null,
56
- "ownerID": 4,
57
- "parentID": 4,
58
- "type": 12,
59
- "weight": 2,
60
- },
61
- Object {
62
- "children": Array [],
63
- "depth": 2,
64
- "displayName": "Grandchild",
65
- "hocDisplayNames": null,
66
- "id": 6,
67
- "isCollapsed": false,
68
- "key": null,
69
- "ownerID": 4,
70
- "parentID": 5,
71
- "type": 5,
72
- "weight": 1,
73
- },
74
- ],
75
- "ownerID": 4,
76
- "searchIndex": null,
77
- "searchResults": Array [],
78
- "searchText": "",
79
- "selectedElementID": 4,
80
- "selectedElementIndex": 0,
81
-}
82
-`;
83
-
84
-exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 3: child owners tree 1`] = `
85
-Object {
86
- "inspectedElementID": 5,
87
- "numElements": 3,
88
- "ownerFlatTree": Array [
89
- Object {
90
- "children": Array [
91
- 5,
92
- ],
93
- "depth": 0,
94
- "displayName": "Child",
95
- "hocDisplayNames": null,
96
- "id": 4,
97
- "isCollapsed": false,
98
- "key": null,
99
- "ownerID": 2,
100
- "parentID": 3,
101
- "type": 5,
102
- "weight": 3,
103
- },
104
- Object {
105
- "children": Array [
106
- 6,
107
- ],
108
- "depth": 1,
109
- "displayName": "Suspense",
110
- "hocDisplayNames": null,
111
- "id": 5,
112
- "isCollapsed": false,
113
- "key": null,
114
- "ownerID": 4,
115
- "parentID": 4,
116
- "type": 12,
117
- "weight": 2,
118
- },
119
- Object {
120
- "children": Array [],
121
- "depth": 2,
122
- "displayName": "Grandchild",
123
- "hocDisplayNames": null,
124
- "id": 6,
125
- "isCollapsed": false,
126
- "key": null,
127
- "ownerID": 4,
128
- "parentID": 5,
129
- "type": 5,
130
- "weight": 1,
131
- },
132
- ],
133
- "ownerID": 4,
134
- "searchIndex": null,
135
- "searchResults": Array [],
136
- "searchText": "",
137
- "selectedElementID": 5,
138
- "selectedElementIndex": 1,
139
-}
140
-`;
141
-
142
-exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 4: main tree 1`] = `
143
-Object {
144
- "inspectedElementID": 5,
145
- "numElements": 5,
146
- "ownerFlatTree": null,
147
- "ownerID": null,
148
- "searchIndex": null,
149
- "searchResults": Array [],
150
- "searchText": "",
151
- "selectedElementID": 5,
152
- "selectedElementIndex": 1,
153
-}
154
-`;
155
-
156
-exports[`TreeListContext owners state should exit the owners list if the current owner is unmounted: 0: mount 1`] = `
157
-[root]
158
- ▾ <Parent>
159
- <Child>
160
-`;
161
-
162
-exports[`TreeListContext owners state should exit the owners list if the current owner is unmounted: 1: initial state 1`] = `
163
-Object {
164
- "inspectedElementID": null,
165
- "numElements": 2,
166
- "ownerFlatTree": null,
167
- "ownerID": null,
168
- "searchIndex": null,
169
- "searchResults": Array [],
170
- "searchText": "",
171
- "selectedElementID": null,
172
- "selectedElementIndex": null,
173
-}
174
-`;
175
-
176
-exports[`TreeListContext owners state should exit the owners list if the current owner is unmounted: 2: child owners tree 1`] = `
177
-Object {
178
- "inspectedElementID": 3,
179
- "numElements": 1,
180
- "ownerFlatTree": Array [
181
- Object {
182
- "children": Array [],
183
- "depth": 0,
184
- "displayName": "Child",
185
- "hocDisplayNames": null,
186
- "id": 3,
187
- "isCollapsed": false,
188
- "key": null,
189
- "ownerID": 0,
190
- "parentID": 2,
191
- "type": 5,
192
- "weight": 1,
193
- },
194
- ],
195
- "ownerID": 3,
196
- "searchIndex": null,
197
- "searchResults": Array [],
198
- "searchText": "",
199
- "selectedElementID": 3,
200
- "selectedElementIndex": 0,
201
-}
202
-`;
203
-
204
-exports[`TreeListContext owners state should exit the owners list if the current owner is unmounted: 3: remove child 1`] = `
205
-Object {
206
- "inspectedElementID": null,
207
- "numElements": 1,
208
- "ownerFlatTree": null,
209
- "ownerID": null,
210
- "searchIndex": null,
211
- "searchResults": Array [],
212
- "searchText": "",
213
- "selectedElementID": null,
214
- "selectedElementIndex": 0,
215
-}
216
-`;
217
-
218
-exports[`TreeListContext owners state should exit the owners list if the current owner is unmounted: 4: parent owners tree 1`] = `
219
-Object {
220
- "inspectedElementID": 2,
221
- "numElements": 1,
222
- "ownerFlatTree": Array [
223
- Object {
224
- "children": Array [],
225
- "depth": 0,
226
- "displayName": "Parent",
227
- "hocDisplayNames": null,
228
- "id": 2,
229
- "isCollapsed": false,
230
- "key": null,
231
- "ownerID": 0,
232
- "parentID": 1,
233
- "type": 5,
234
- "weight": 1,
235
- },
236
- ],
237
- "ownerID": 2,
238
- "searchIndex": null,
239
- "searchResults": Array [],
240
- "searchText": "",
241
- "selectedElementID": 2,
242
- "selectedElementIndex": 0,
243
-}
244
-`;
245
-
246
-exports[`TreeListContext owners state should exit the owners list if the current owner is unmounted: 5: unmount root 1`] = `
247
-Object {
248
- "inspectedElementID": null,
249
- "numElements": 0,
250
- "ownerFlatTree": null,
251
- "ownerID": null,
252
- "searchIndex": null,
253
- "searchResults": Array [],
254
- "searchText": "",
255
- "selectedElementID": null,
256
- "selectedElementIndex": 0,
257
-}
258
-`;
259
-
260
-exports[`TreeListContext owners state should remove an element from the owners list if it is unmounted: 0: mount 1`] = `
261
-[root]
262
- ▾ <Grandparent>
263
- ▾ <Parent>
264
- <Child key="0">
265
- <Child key="1">
266
-`;
267
-
268
-exports[`TreeListContext owners state should remove an element from the owners list if it is unmounted: 1: initial state 1`] = `
269
-Object {
270
- "inspectedElementID": null,
271
- "numElements": 4,
272
- "ownerFlatTree": null,
273
- "ownerID": null,
274
- "searchIndex": null,
275
- "searchResults": Array [],
276
- "searchText": "",
277
- "selectedElementID": null,
278
- "selectedElementIndex": null,
279
-}
280
-`;
281
-
282
-exports[`TreeListContext owners state should remove an element from the owners list if it is unmounted: 2: parent owners tree 1`] = `
283
-Object {
284
- "inspectedElementID": 3,
285
- "numElements": 3,
286
- "ownerFlatTree": Array [
287
- Object {
288
- "children": Array [
289
- 4,
290
- 5,
291
- ],
292
- "depth": 0,
293
- "displayName": "Parent",
294
- "hocDisplayNames": null,
295
- "id": 3,
296
- "isCollapsed": false,
297
- "key": null,
298
- "ownerID": 2,
299
- "parentID": 2,
300
- "type": 5,
301
- "weight": 3,
302
- },
303
- Object {
304
- "children": Array [],
305
- "depth": 1,
306
- "displayName": "Child",
307
- "hocDisplayNames": null,
308
- "id": 4,
309
- "isCollapsed": false,
310
- "key": "0",
311
- "ownerID": 3,
312
- "parentID": 3,
313
- "type": 5,
314
- "weight": 1,
315
- },
316
- Object {
317
- "children": Array [],
318
- "depth": 1,
319
- "displayName": "Child",
320
- "hocDisplayNames": null,
321
- "id": 5,
322
- "isCollapsed": false,
323
- "key": "1",
324
- "ownerID": 3,
325
- "parentID": 3,
326
- "type": 5,
327
- "weight": 1,
328
- },
329
- ],
330
- "ownerID": 3,
331
- "searchIndex": null,
332
- "searchResults": Array [],
333
- "searchText": "",
334
- "selectedElementID": 3,
335
- "selectedElementIndex": 0,
336
-}
337
-`;
338
-
339
-exports[`TreeListContext owners state should remove an element from the owners list if it is unmounted: 3: remove second child 1`] = `
340
-Object {
341
- "inspectedElementID": 3,
342
- "numElements": 2,
343
- "ownerFlatTree": Array [
344
- Object {
345
- "children": Array [
346
- 4,
347
- ],
348
- "depth": 0,
349
- "displayName": "Parent",
350
- "hocDisplayNames": null,
351
- "id": 3,
352
- "isCollapsed": false,
353
- "key": null,
354
- "ownerID": 2,
355
- "parentID": 2,
356
- "type": 5,
357
- "weight": 2,
358
- },
359
- Object {
360
- "children": Array [],
361
- "depth": 1,
362
- "displayName": "Child",
363
- "hocDisplayNames": null,
364
- "id": 4,
365
- "isCollapsed": false,
366
- "key": "0",
367
- "ownerID": 3,
368
- "parentID": 3,
369
- "type": 5,
370
- "weight": 1,
371
- },
372
- ],
373
- "ownerID": 3,
374
- "searchIndex": null,
375
- "searchResults": Array [],
376
- "searchText": "",
377
- "selectedElementID": 3,
378
- "selectedElementIndex": 0,
379
-}
380
-`;
381
-
382
-exports[`TreeListContext owners state should remove an element from the owners list if it is unmounted: 4: remove first child 1`] = `
383
-Object {
384
- "inspectedElementID": 3,
385
- "numElements": 1,
386
- "ownerFlatTree": Array [
387
- Object {
388
- "children": Array [],
389
- "depth": 0,
390
- "displayName": "Parent",
391
- "hocDisplayNames": null,
392
- "id": 3,
393
- "isCollapsed": false,
394
- "key": null,
395
- "ownerID": 2,
396
- "parentID": 2,
397
- "type": 5,
398
- "weight": 1,
399
- },
400
- ],
401
- "ownerID": 3,
402
- "searchIndex": null,
403
- "searchResults": Array [],
404
- "searchText": "",
405
- "selectedElementID": 3,
406
- "selectedElementIndex": 0,
407
-}
408
-`;
409
-
410
-exports[`TreeListContext owners state should support entering and existing the owners tree view: 0: mount 1`] = `
411
-[root]
412
- ▾ <Grandparent>
413
- ▾ <Parent>
414
- <Child>
415
- <Child>
416
-`;
417
-
418
-exports[`TreeListContext owners state should support entering and existing the owners tree view: 1: initial state 1`] = `
419
-Object {
420
- "inspectedElementID": null,
421
- "numElements": 4,
422
- "ownerFlatTree": null,
423
- "ownerID": null,
424
- "searchIndex": null,
425
- "searchResults": Array [],
426
- "searchText": "",
427
- "selectedElementID": null,
428
- "selectedElementIndex": null,
429
-}
430
-`;
431
-
432
-exports[`TreeListContext owners state should support entering and existing the owners tree view: 2: parent owners tree 1`] = `
433
-Object {
434
- "inspectedElementID": 3,
435
- "numElements": 3,
436
- "ownerFlatTree": Array [
437
- Object {
438
- "children": Array [
439
- 4,
440
- 5,
441
- ],
442
- "depth": 0,
443
- "displayName": "Parent",
444
- "hocDisplayNames": null,
445
- "id": 3,
446
- "isCollapsed": false,
447
- "key": null,
448
- "ownerID": 2,
449
- "parentID": 2,
450
- "type": 5,
451
- "weight": 3,
452
- },
453
- Object {
454
- "children": Array [],
455
- "depth": 1,
456
- "displayName": "Child",
457
- "hocDisplayNames": null,
458
- "id": 4,
459
- "isCollapsed": false,
460
- "key": null,
461
- "ownerID": 3,
462
- "parentID": 3,
463
- "type": 5,
464
- "weight": 1,
465
- },
466
- Object {
467
- "children": Array [],
468
- "depth": 1,
469
- "displayName": "Child",
470
- "hocDisplayNames": null,
471
- "id": 5,
472
- "isCollapsed": false,
473
- "key": null,
474
- "ownerID": 3,
475
- "parentID": 3,
476
- "type": 5,
477
- "weight": 1,
478
- },
479
- ],
480
- "ownerID": 3,
481
- "searchIndex": null,
482
- "searchResults": Array [],
483
- "searchText": "",
484
- "selectedElementID": 3,
485
- "selectedElementIndex": 0,
486
-}
487
-`;
488
-
489
-exports[`TreeListContext owners state should support entering and existing the owners tree view: 3: final state 1`] = `
490
-Object {
491
- "inspectedElementID": 3,
492
- "numElements": 4,
493
- "ownerFlatTree": null,
494
- "ownerID": null,
495
- "searchIndex": null,
496
- "searchResults": Array [],
497
- "searchText": "",
498
- "selectedElementID": 3,
499
- "selectedElementIndex": 1,
500
-}
501
-`;
502
-
503
-exports[`TreeListContext search state should add newly mounted elements to the search results set if they match the current text: 0: mount 1`] = `
504
-[root]
505
- <Foo>
506
- <Bar>
507
-`;
508
-
509
-exports[`TreeListContext search state should add newly mounted elements to the search results set if they match the current text: 1: initial state 1`] = `
510
-Object {
511
- "inspectedElementID": null,
512
- "numElements": 2,
513
- "ownerFlatTree": null,
514
- "ownerID": null,
515
- "searchIndex": null,
516
- "searchResults": Array [],
517
- "searchText": "",
518
- "selectedElementID": null,
519
- "selectedElementIndex": null,
520
-}
521
-`;
522
-
523
-exports[`TreeListContext search state should add newly mounted elements to the search results set if they match the current text: 2: search for "ba" 1`] = `
524
-Object {
525
- "inspectedElementID": 3,
526
- "numElements": 2,
527
- "ownerFlatTree": null,
528
- "ownerID": null,
529
- "searchIndex": 0,
530
- "searchResults": Array [
531
- 3,
532
- ],
533
- "searchText": "ba",
534
- "selectedElementID": 3,
535
- "selectedElementIndex": 1,
536
-}
537
-`;
538
-
539
-exports[`TreeListContext search state should add newly mounted elements to the search results set if they match the current text: 3: mount Baz 1`] = `
540
-Object {
541
- "inspectedElementID": 3,
542
- "numElements": 3,
543
- "ownerFlatTree": null,
544
- "ownerID": null,
545
- "searchIndex": 0,
546
- "searchResults": Array [
547
- 3,
548
- 4,
549
- ],
550
- "searchText": "ba",
551
- "selectedElementID": 3,
552
- "selectedElementIndex": 1,
553
-}
554
-`;
555
-
556
-exports[`TreeListContext search state should find elements matching search text: 0: mount 1`] = `
557
-[root]
558
- <Foo>
559
- <Bar>
560
- <Baz>
561
- <Qux> [withHOC]
562
-`;
563
-
564
-exports[`TreeListContext search state should find elements matching search text: 1: initial state 1`] = `
565
-Object {
566
- "inspectedElementID": null,
567
- "numElements": 4,
568
- "ownerFlatTree": null,
569
- "ownerID": null,
570
- "searchIndex": null,
571
- "searchResults": Array [],
572
- "searchText": "",
573
- "selectedElementID": null,
574
- "selectedElementIndex": null,
575
-}
576
-`;
577
-
578
-exports[`TreeListContext search state should find elements matching search text: 2: search for "ba" 1`] = `
579
-Object {
580
- "inspectedElementID": 3,
581
- "numElements": 4,
582
- "ownerFlatTree": null,
583
- "ownerID": null,
584
- "searchIndex": 0,
585
- "searchResults": Array [
586
- 3,
587
- 4,
588
- ],
589
- "searchText": "ba",
590
- "selectedElementID": 3,
591
- "selectedElementIndex": 1,
592
-}
593
-`;
594
-
595
-exports[`TreeListContext search state should find elements matching search text: 3: search for "f" 1`] = `
596
-Object {
597
- "inspectedElementID": 2,
598
- "numElements": 4,
599
- "ownerFlatTree": null,
600
- "ownerID": null,
601
- "searchIndex": 0,
602
- "searchResults": Array [
603
- 2,
604
- ],
605
- "searchText": "f",
606
- "selectedElementID": 2,
607
- "selectedElementIndex": 0,
608
-}
609
-`;
610
-
611
-exports[`TreeListContext search state should find elements matching search text: 4: search for "y" 1`] = `
612
-Object {
613
- "inspectedElementID": 2,
614
- "numElements": 4,
615
- "ownerFlatTree": null,
616
- "ownerID": null,
617
- "searchIndex": null,
618
- "searchResults": Array [],
619
- "searchText": "y",
620
- "selectedElementID": 2,
621
- "selectedElementIndex": 0,
622
-}
623
-`;
624
-
625
-exports[`TreeListContext search state should find elements matching search text: 5: search for "w" 1`] = `
626
-Object {
627
- "inspectedElementID": 5,
628
- "numElements": 4,
629
- "ownerFlatTree": null,
630
- "ownerID": null,
631
- "searchIndex": 0,
632
- "searchResults": Array [
633
- 5,
634
- ],
635
- "searchText": "w",
636
- "selectedElementID": 5,
637
- "selectedElementIndex": 3,
638
-}
639
-`;
640
-
641
-exports[`TreeListContext search state should remove unmounted elements from the search results set: 0: mount 1`] = `
642
-[root]
643
- <Foo>
644
- <Bar>
645
- <Baz>
646
-`;
647
-
648
-exports[`TreeListContext search state should remove unmounted elements from the search results set: 1: initial state 1`] = `
649
-Object {
650
- "inspectedElementID": null,
651
- "numElements": 3,
652
- "ownerFlatTree": null,
653
- "ownerID": null,
654
- "searchIndex": null,
655
- "searchResults": Array [],
656
- "searchText": "",
657
- "selectedElementID": null,
658
- "selectedElementIndex": null,
659
-}
660
-`;
661
-
662
-exports[`TreeListContext search state should remove unmounted elements from the search results set: 2: search for "ba" 1`] = `
663
-Object {
664
- "inspectedElementID": 3,
665
- "numElements": 3,
666
- "ownerFlatTree": null,
667
- "ownerID": null,
668
- "searchIndex": 0,
669
- "searchResults": Array [
670
- 3,
671
- 4,
672
- ],
673
- "searchText": "ba",
674
- "selectedElementID": 3,
675
- "selectedElementIndex": 1,
676
-}
677
-`;
678
-
679
-exports[`TreeListContext search state should remove unmounted elements from the search results set: 3: go to second result 1`] = `
680
-Object {
681
- "inspectedElementID": 4,
682
- "numElements": 3,
683
- "ownerFlatTree": null,
684
- "ownerID": null,
685
- "searchIndex": 1,
686
- "searchResults": Array [
687
- 3,
688
- 4,
689
- ],
690
- "searchText": "ba",
691
- "selectedElementID": 4,
692
- "selectedElementIndex": 2,
693
-}
694
-`;
695
-
696
-exports[`TreeListContext search state should remove unmounted elements from the search results set: 4: unmount Baz 1`] = `
697
-Object {
698
- "inspectedElementID": null,
699
- "numElements": 2,
700
- "ownerFlatTree": null,
701
- "ownerID": null,
702
- "searchIndex": 0,
703
- "searchResults": Array [
704
- 3,
705
- ],
706
- "searchText": "ba",
707
- "selectedElementID": null,
708
- "selectedElementIndex": null,
709
-}
710
-`;
711
-
712
-exports[`TreeListContext search state should select the next and previous items within the search results: 0: mount 1`] = `
713
-[root]
714
- <Foo>
715
- <Baz>
716
- <Bar>
717
- <Baz>
718
-`;
719
-
720
-exports[`TreeListContext search state should select the next and previous items within the search results: 1: initial state 1`] = `
721
-Object {
722
- "inspectedElementID": null,
723
- "numElements": 4,
724
- "ownerFlatTree": null,
725
- "ownerID": null,
726
- "searchIndex": null,
727
- "searchResults": Array [],
728
- "searchText": "",
729
- "selectedElementID": null,
730
- "selectedElementIndex": null,
731
-}
732
-`;
733
-
734
-exports[`TreeListContext search state should select the next and previous items within the search results: 2: search for "ba" 1`] = `
735
-Object {
736
- "inspectedElementID": 3,
737
- "numElements": 4,
738
- "ownerFlatTree": null,
739
- "ownerID": null,
740
- "searchIndex": 0,
741
- "searchResults": Array [
742
- 3,
743
- 4,
744
- 5,
745
- ],
746
- "searchText": "ba",
747
- "selectedElementID": 3,
748
- "selectedElementIndex": 1,
749
-}
750
-`;
751
-
752
-exports[`TreeListContext search state should select the next and previous items within the search results: 3: go to second result 1`] = `
753
-Object {
754
- "inspectedElementID": 4,
755
- "numElements": 4,
756
- "ownerFlatTree": null,
757
- "ownerID": null,
758
- "searchIndex": 1,
759
- "searchResults": Array [
760
- 3,
761
- 4,
762
- 5,
763
- ],
764
- "searchText": "ba",
765
- "selectedElementID": 4,
766
- "selectedElementIndex": 2,
767
-}
768
-`;
769
-
770
-exports[`TreeListContext search state should select the next and previous items within the search results: 4: go to third result 1`] = `
771
-Object {
772
- "inspectedElementID": 5,
773
- "numElements": 4,
774
- "ownerFlatTree": null,
775
- "ownerID": null,
776
- "searchIndex": 2,
777
- "searchResults": Array [
778
- 3,
779
- 4,
780
- 5,
781
- ],
782
- "searchText": "ba",
783
- "selectedElementID": 5,
784
- "selectedElementIndex": 3,
785
-}
786
-`;
787
-
788
-exports[`TreeListContext search state should select the next and previous items within the search results: 5: go to second result 1`] = `
789
-Object {
790
- "inspectedElementID": 4,
791
- "numElements": 4,
792
- "ownerFlatTree": null,
793
- "ownerID": null,
794
- "searchIndex": 1,
795
- "searchResults": Array [
796
- 3,
797
- 4,
798
- 5,
799
- ],
800
- "searchText": "ba",
801
- "selectedElementID": 4,
802
- "selectedElementIndex": 2,
803
-}
804
-`;
805
-
806
-exports[`TreeListContext search state should select the next and previous items within the search results: 6: go to first result 1`] = `
807
-Object {
808
- "inspectedElementID": 3,
809
- "numElements": 4,
810
- "ownerFlatTree": null,
811
- "ownerID": null,
812
- "searchIndex": 0,
813
- "searchResults": Array [
814
- 3,
815
- 4,
816
- 5,
817
- ],
818
- "searchText": "ba",
819
- "selectedElementID": 3,
820
- "selectedElementIndex": 1,
821
-}
822
-`;
823
-
824
-exports[`TreeListContext search state should select the next and previous items within the search results: 7: wrap to last result 1`] = `
825
-Object {
826
- "inspectedElementID": 5,
827
- "numElements": 4,
828
- "ownerFlatTree": null,
829
- "ownerID": null,
830
- "searchIndex": 2,
831
- "searchResults": Array [
832
- 3,
833
- 4,
834
- 5,
835
- ],
836
- "searchText": "ba",
837
- "selectedElementID": 5,
838
- "selectedElementIndex": 3,
839
-}
840
-`;
841
-
842
-exports[`TreeListContext search state should select the next and previous items within the search results: 8: wrap to first result 1`] = `
843
-Object {
844
- "inspectedElementID": 3,
845
- "numElements": 4,
846
- "ownerFlatTree": null,
847
- "ownerID": null,
848
- "searchIndex": 0,
849
- "searchResults": Array [
850
- 3,
851
- 4,
852
- 5,
853
- ],
854
- "searchText": "ba",
855
- "selectedElementID": 3,
856
- "selectedElementIndex": 1,
857
-}
858
-`;
859
-
860
-exports[`TreeListContext tree state should clear selection if the selected element is unmounted: 0: mount 1`] = `
861
-[root]
862
- ▾ <Grandparent>
863
- ▾ <Parent>
864
- <Child>
865
- <Child>
866
-`;
867
-
868
-exports[`TreeListContext tree state should clear selection if the selected element is unmounted: 1: initial state 1`] = `
869
-Object {
870
- "inspectedElementID": null,
871
- "numElements": 4,
872
- "ownerFlatTree": null,
873
- "ownerID": null,
874
- "searchIndex": null,
875
- "searchResults": Array [],
876
- "searchText": "",
877
- "selectedElementID": null,
878
- "selectedElementIndex": null,
879
-}
880
-`;
881
-
882
-exports[`TreeListContext tree state should clear selection if the selected element is unmounted: 2: select second child 1`] = `
883
-Object {
884
- "inspectedElementID": 5,
885
- "numElements": 4,
886
- "ownerFlatTree": null,
887
- "ownerID": null,
888
- "searchIndex": null,
889
- "searchResults": Array [],
890
- "searchText": "",
891
- "selectedElementID": 5,
892
- "selectedElementIndex": 3,
893
-}
894
-`;
895
-
896
-exports[`TreeListContext tree state should clear selection if the selected element is unmounted: 3: remove children (parent should now be selected) 1`] = `
897
-Object {
898
- "inspectedElementID": 3,
899
- "numElements": 2,
900
- "ownerFlatTree": null,
901
- "ownerID": null,
902
- "searchIndex": null,
903
- "searchResults": Array [],
904
- "searchText": "",
905
- "selectedElementID": 3,
906
- "selectedElementIndex": 1,
907
-}
908
-`;
909
-
910
-exports[`TreeListContext tree state should clear selection if the selected element is unmounted: 4: unmount root (nothing should be selected) 1`] = `
911
-Object {
912
- "inspectedElementID": null,
913
- "numElements": 0,
914
- "ownerFlatTree": null,
915
- "ownerID": null,
916
- "searchIndex": null,
917
- "searchResults": Array [],
918
- "searchText": "",
919
- "selectedElementID": null,
920
- "selectedElementIndex": null,
921
-}
922
-`;
923
-
924
-exports[`TreeListContext tree state should select child elements: 0: mount 1`] = `
925
-[root]
926
- ▾ <Grandparent>
927
- ▾ <Parent>
928
- <Child>
929
- <Child>
930
- ▾ <Parent>
931
- <Child>
932
- <Child>
933
-`;
934
-
935
-exports[`TreeListContext tree state should select child elements: 1: initial state 1`] = `
936
-Object {
937
- "inspectedElementID": null,
938
- "numElements": 7,
939
- "ownerFlatTree": null,
940
- "ownerID": null,
941
- "searchIndex": null,
942
- "searchResults": Array [],
943
- "searchText": "",
944
- "selectedElementID": null,
945
- "selectedElementIndex": null,
946
-}
947
-`;
948
-
949
-exports[`TreeListContext tree state should select child elements: 2: select first element 1`] = `
950
-Object {
951
- "inspectedElementID": 2,
952
- "numElements": 7,
953
- "ownerFlatTree": null,
954
- "ownerID": null,
955
- "searchIndex": null,
956
- "searchResults": Array [],
957
- "searchText": "",
958
- "selectedElementID": 2,
959
- "selectedElementIndex": 0,
960
-}
961
-`;
962
-
963
-exports[`TreeListContext tree state should select child elements: 3: select Parent 1`] = `
964
-Object {
965
- "inspectedElementID": 3,
966
- "numElements": 7,
967
- "ownerFlatTree": null,
968
- "ownerID": null,
969
- "searchIndex": null,
970
- "searchResults": Array [],
971
- "searchText": "",
972
- "selectedElementID": 3,
973
- "selectedElementIndex": 1,
974
-}
975
-`;
976
-
977
-exports[`TreeListContext tree state should select child elements: 4: select Child 1`] = `
978
-Object {
979
- "inspectedElementID": 4,
980
- "numElements": 7,
981
- "ownerFlatTree": null,
982
- "ownerID": null,
983
- "searchIndex": null,
984
- "searchResults": Array [],
985
- "searchText": "",
986
- "selectedElementID": 4,
987
- "selectedElementIndex": 2,
988
-}
989
-`;
990
-
991
-exports[`TreeListContext tree state should select parent elements and then collapse: 0: mount 1`] = `
992
-[root]
993
- ▾ <Grandparent>
994
- ▾ <Parent>
995
- <Child>
996
- <Child>
997
- ▾ <Parent>
998
- <Child>
999
- <Child>
1000
-`;
1001
-
1002
-exports[`TreeListContext tree state should select parent elements and then collapse: 1: initial state 1`] = `
1003
-Object {
1004
- "inspectedElementID": null,
1005
- "numElements": 7,
1006
- "ownerFlatTree": null,
1007
- "ownerID": null,
1008
- "searchIndex": null,
1009
- "searchResults": Array [],
1010
- "searchText": "",
1011
- "selectedElementID": null,
1012
- "selectedElementIndex": null,
1013
-}
1014
-`;
1015
-
1016
-exports[`TreeListContext tree state should select parent elements and then collapse: 2: select last child 1`] = `
1017
-Object {
1018
- "inspectedElementID": 8,
1019
- "numElements": 7,
1020
- "ownerFlatTree": null,
1021
- "ownerID": null,
1022
- "searchIndex": null,
1023
- "searchResults": Array [],
1024
- "searchText": "",
1025
- "selectedElementID": 8,
1026
- "selectedElementIndex": 6,
1027
-}
1028
-`;
1029
-
1030
-exports[`TreeListContext tree state should select parent elements and then collapse: 3: select Parent 1`] = `
1031
-Object {
1032
- "inspectedElementID": 6,
1033
- "numElements": 7,
1034
- "ownerFlatTree": null,
1035
- "ownerID": null,
1036
- "searchIndex": null,
1037
- "searchResults": Array [],
1038
- "searchText": "",
1039
- "selectedElementID": 6,
1040
- "selectedElementIndex": 4,
1041
-}
1042
-`;
1043
-
1044
-exports[`TreeListContext tree state should select parent elements and then collapse: 4: select Grandparent 1`] = `
1045
-Object {
1046
- "inspectedElementID": 2,
1047
- "numElements": 7,
1048
- "ownerFlatTree": null,
1049
- "ownerID": null,
1050
- "searchIndex": null,
1051
- "searchResults": Array [],
1052
- "searchText": "",
1053
- "selectedElementID": 2,
1054
- "selectedElementIndex": 0,
1055
-}
1056
-`;
1057
-
1058
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 0: mount 1`] = `
1059
-[root]
1060
- ▾ <Grandparent>
1061
- ▾ <Parent>
1062
- <Child>
1063
- <Child>
1064
-`;
1065
-
1066
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 1: initial state 1`] = `
1067
-Object {
1068
- "inspectedElementID": null,
1069
- "numElements": 4,
1070
- "ownerFlatTree": null,
1071
- "ownerID": null,
1072
- "searchIndex": null,
1073
- "searchResults": Array [],
1074
- "searchText": "",
1075
- "selectedElementID": null,
1076
- "selectedElementIndex": null,
1077
-}
1078
-`;
1079
-
1080
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 2: select first element 1`] = `
1081
-Object {
1082
- "inspectedElementID": 2,
1083
- "numElements": 4,
1084
- "ownerFlatTree": null,
1085
- "ownerID": null,
1086
- "searchIndex": null,
1087
- "searchResults": Array [],
1088
- "searchText": "",
1089
- "selectedElementID": 2,
1090
- "selectedElementIndex": 0,
1091
-}
1092
-`;
1093
-
1094
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 3: select element after (0) 1`] = `
1095
-Object {
1096
- "inspectedElementID": 3,
1097
- "numElements": 4,
1098
- "ownerFlatTree": null,
1099
- "ownerID": null,
1100
- "searchIndex": null,
1101
- "searchResults": Array [],
1102
- "searchText": "",
1103
- "selectedElementID": 3,
1104
- "selectedElementIndex": 1,
1105
-}
1106
-`;
1107
-
1108
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 3: select element after (1) 1`] = `
1109
-Object {
1110
- "inspectedElementID": 4,
1111
- "numElements": 4,
1112
- "ownerFlatTree": null,
1113
- "ownerID": null,
1114
- "searchIndex": null,
1115
- "searchResults": Array [],
1116
- "searchText": "",
1117
- "selectedElementID": 4,
1118
- "selectedElementIndex": 2,
1119
-}
1120
-`;
1121
-
1122
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 3: select element after (2) 1`] = `
1123
-Object {
1124
- "inspectedElementID": 5,
1125
- "numElements": 4,
1126
- "ownerFlatTree": null,
1127
- "ownerID": null,
1128
- "searchIndex": null,
1129
- "searchResults": Array [],
1130
- "searchText": "",
1131
- "selectedElementID": 5,
1132
- "selectedElementIndex": 3,
1133
-}
1134
-`;
1135
-
1136
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 4: select element before (1) 1`] = `
1137
-Object {
1138
- "inspectedElementID": 2,
1139
- "numElements": 4,
1140
- "ownerFlatTree": null,
1141
- "ownerID": null,
1142
- "searchIndex": null,
1143
- "searchResults": Array [],
1144
- "searchText": "",
1145
- "selectedElementID": 2,
1146
- "selectedElementIndex": 0,
1147
-}
1148
-`;
1149
-
1150
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 4: select element before (2) 1`] = `
1151
-Object {
1152
- "inspectedElementID": 3,
1153
- "numElements": 4,
1154
- "ownerFlatTree": null,
1155
- "ownerID": null,
1156
- "searchIndex": null,
1157
- "searchResults": Array [],
1158
- "searchText": "",
1159
- "selectedElementID": 3,
1160
- "selectedElementIndex": 1,
1161
-}
1162
-`;
1163
-
1164
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 4: select element before (3) 1`] = `
1165
-Object {
1166
- "inspectedElementID": 4,
1167
- "numElements": 4,
1168
- "ownerFlatTree": null,
1169
- "ownerID": null,
1170
- "searchIndex": null,
1171
- "searchResults": Array [],
1172
- "searchText": "",
1173
- "selectedElementID": 4,
1174
- "selectedElementIndex": 2,
1175
-}
1176
-`;
1177
-
1178
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 5: select previous wraps around to last 1`] = `
1179
-Object {
1180
- "inspectedElementID": 5,
1181
- "numElements": 4,
1182
- "ownerFlatTree": null,
1183
- "ownerID": null,
1184
- "searchIndex": null,
1185
- "searchResults": Array [],
1186
- "searchText": "",
1187
- "selectedElementID": 5,
1188
- "selectedElementIndex": 3,
1189
-}
1190
-`;
1191
-
1192
-exports[`TreeListContext tree state should select the next and previous elements in the tree: 6: select next wraps around to first 1`] = `
1193
-Object {
1194
- "inspectedElementID": 2,
1195
- "numElements": 4,
1196
- "ownerFlatTree": null,
1197
- "ownerID": null,
1198
- "searchIndex": null,
1199
- "searchResults": Array [],
1200
- "searchText": "",
1201
- "selectedElementID": 2,
1202
- "selectedElementIndex": 0,
1203
-}
1204
-`;
packages/react-devtools-shared/src/__tests__/bridge-test.js
deleted
-49
@@ -1,49 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-describe('Bridge', () => {
11
- let Bridge;
12
-
13
- beforeEach(() => {
14
- Bridge = require('react-devtools-shared/src/bridge').default;
15
- });
16
-
17
- it('should shutdown properly', () => {
18
- const wall = {
19
- listen: jest.fn(() => () => {}),
20
- send: jest.fn(),
21
- };
22
- const bridge = new Bridge(wall);
23
-
24
- // Check that we're wired up correctly.
25
- bridge.send('reloadAppForProfiling');
26
- jest.runAllTimers();
27
- expect(wall.send).toHaveBeenCalledWith('reloadAppForProfiling');
28
-
29
- // Should flush pending messages and then shut down.
30
- wall.send.mockClear();
31
- bridge.send('update', '1');
32
- bridge.send('update', '2');
33
- bridge.shutdown();
34
- jest.runAllTimers();
35
- expect(wall.send).toHaveBeenCalledWith('update', '1');
36
- expect(wall.send).toHaveBeenCalledWith('update', '2');
37
- expect(wall.send).toHaveBeenCalledWith('shutdown');
38
-
39
- // Verify that the Bridge doesn't send messages after shutdown.
40
- spyOn(console, 'warn');
41
- wall.send.mockClear();
42
- bridge.send('should not send');
43
- jest.runAllTimers();
44
- expect(wall.send).not.toHaveBeenCalled();
45
- expect(console.warn).toHaveBeenCalledWith(
46
- 'Cannot send message "should not send" through a Bridge that has been shutdown.',
47
- );
48
- });
49
-});
packages/react-devtools-shared/src/__tests__/console-test.js
deleted
-344
@@ -1,344 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-describe('console', () => {
11
- let React;
12
- let ReactDOM;
13
- let act;
14
- let fakeConsole;
15
- let mockError;
16
- let mockInfo;
17
- let mockLog;
18
- let mockWarn;
19
- let patchConsole;
20
- let unpatchConsole;
21
-
22
- beforeEach(() => {
23
- jest.resetModules();
24
-
25
- const Console = require('react-devtools-shared/src/backend/console');
26
- patchConsole = Console.patch;
27
- unpatchConsole = Console.unpatch;
28
-
29
- // Patch a fake console so we can verify with tests below.
30
- // Patching the real console is too complicated,
31
- // because Jest itself has hooks into it as does our test env setup.
32
- mockError = jest.fn();
33
- mockInfo = jest.fn();
34
- mockLog = jest.fn();
35
- mockWarn = jest.fn();
36
- fakeConsole = {
37
- error: mockError,
38
- info: mockInfo,
39
- log: mockLog,
40
- warn: mockWarn,
41
- };
42
-
43
- Console.dangerous_setTargetConsoleForTesting(fakeConsole);
44
-
45
- // Note the Console module only patches once,
46
- // so it's important to patch the test console before injection.
47
- patchConsole();
48
-
49
- const inject = global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject;
50
- global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = internals => {
51
- inject(internals);
52
-
53
- Console.registerRenderer(internals);
54
- };
55
-
56
- React = require('react');
57
- ReactDOM = require('react-dom');
58
-
59
- const utils = require('./utils');
60
- act = utils.act;
61
- });
62
-
63
- function normalizeCodeLocInfo(str) {
64
- return str && str.replace(/\(at .+?:\d+\)/g, '(at **)');
65
- }
66
-
67
- it('should not patch console methods that do not receive component stacks', () => {
68
- expect(fakeConsole.error).not.toBe(mockError);
69
- expect(fakeConsole.info).toBe(mockInfo);
70
- expect(fakeConsole.log).toBe(mockLog);
71
- expect(fakeConsole.warn).not.toBe(mockWarn);
72
- });
73
-
74
- it('should only patch the console once', () => {
75
- const {error, warn} = fakeConsole;
76
-
77
- patchConsole();
78
-
79
- expect(fakeConsole.error).toBe(error);
80
- expect(fakeConsole.warn).toBe(warn);
81
- });
82
-
83
- it('should un-patch when requested', () => {
84
- expect(fakeConsole.error).not.toBe(mockError);
85
- expect(fakeConsole.warn).not.toBe(mockWarn);
86
-
87
- unpatchConsole();
88
-
89
- expect(fakeConsole.error).toBe(mockError);
90
- expect(fakeConsole.warn).toBe(mockWarn);
91
- });
92
-
93
- it('should pass through logs when there is no current fiber', () => {
94
- expect(mockLog).toHaveBeenCalledTimes(0);
95
- expect(mockWarn).toHaveBeenCalledTimes(0);
96
- expect(mockError).toHaveBeenCalledTimes(0);
97
- fakeConsole.log('log');
98
- fakeConsole.warn('warn');
99
- fakeConsole.error('error');
100
- expect(mockLog).toHaveBeenCalledTimes(1);
101
- expect(mockLog.mock.calls[0]).toHaveLength(1);
102
- expect(mockLog.mock.calls[0][0]).toBe('log');
103
- expect(mockWarn).toHaveBeenCalledTimes(1);
104
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
105
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
106
- expect(mockError).toHaveBeenCalledTimes(1);
107
- expect(mockError.mock.calls[0]).toHaveLength(1);
108
- expect(mockError.mock.calls[0][0]).toBe('error');
109
- });
110
-
111
- it('should not append multiple stacks', () => {
112
- const Child = () => {
113
- fakeConsole.warn('warn\n in Child (at fake.js:123)');
114
- fakeConsole.error('error', '\n in Child (at fake.js:123)');
115
- return null;
116
- };
117
-
118
- act(() => ReactDOM.render(<Child />, document.createElement('div')));
119
-
120
- expect(mockWarn).toHaveBeenCalledTimes(1);
121
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
122
- expect(mockWarn.mock.calls[0][0]).toBe(
123
- 'warn\n in Child (at fake.js:123)',
124
- );
125
- expect(mockError).toHaveBeenCalledTimes(1);
126
- expect(mockError.mock.calls[0]).toHaveLength(2);
127
- expect(mockError.mock.calls[0][0]).toBe('error');
128
- expect(mockError.mock.calls[0][1]).toBe('\n in Child (at fake.js:123)');
129
- });
130
-
131
- it('should append component stacks to errors and warnings logged during render', () => {
132
- const Intermediate = ({children}) => children;
133
- const Parent = () => (
134
- <Intermediate>
135
- <Child />
136
- </Intermediate>
137
- );
138
- const Child = () => {
139
- fakeConsole.error('error');
140
- fakeConsole.log('log');
141
- fakeConsole.warn('warn');
142
- return null;
143
- };
144
-
145
- act(() => ReactDOM.render(<Parent />, document.createElement('div')));
146
-
147
- expect(mockLog).toHaveBeenCalledTimes(1);
148
- expect(mockLog.mock.calls[0]).toHaveLength(1);
149
- expect(mockLog.mock.calls[0][0]).toBe('log');
150
- expect(mockWarn).toHaveBeenCalledTimes(1);
151
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
152
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
153
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
154
- '\n in Child (at **)\n in Parent (at **)',
155
- );
156
- expect(mockError).toHaveBeenCalledTimes(1);
157
- expect(mockError.mock.calls[0]).toHaveLength(2);
158
- expect(mockError.mock.calls[0][0]).toBe('error');
159
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
160
- '\n in Child (at **)\n in Parent (at **)',
161
- );
162
- });
163
-
164
- it('should append component stacks to errors and warnings logged from effects', () => {
165
- const Intermediate = ({children}) => children;
166
- const Parent = () => (
167
- <Intermediate>
168
- <Child />
169
- </Intermediate>
170
- );
171
- const Child = () => {
172
- React.useLayoutEffect(() => {
173
- fakeConsole.error('active error');
174
- fakeConsole.log('active log');
175
- fakeConsole.warn('active warn');
176
- });
177
- React.useEffect(() => {
178
- fakeConsole.error('passive error');
179
- fakeConsole.log('passive log');
180
- fakeConsole.warn('passive warn');
181
- });
182
- return null;
183
- };
184
-
185
- act(() => ReactDOM.render(<Parent />, document.createElement('div')));
186
-
187
- expect(mockLog).toHaveBeenCalledTimes(2);
188
- expect(mockLog.mock.calls[0]).toHaveLength(1);
189
- expect(mockLog.mock.calls[0][0]).toBe('active log');
190
- expect(mockLog.mock.calls[1]).toHaveLength(1);
191
- expect(mockLog.mock.calls[1][0]).toBe('passive log');
192
- expect(mockWarn).toHaveBeenCalledTimes(2);
193
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
194
- expect(mockWarn.mock.calls[0][0]).toBe('active warn');
195
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
196
- '\n in Child (at **)\n in Parent (at **)',
197
- );
198
- expect(mockWarn.mock.calls[1]).toHaveLength(2);
199
- expect(mockWarn.mock.calls[1][0]).toBe('passive warn');
200
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][1])).toEqual(
201
- '\n in Child (at **)\n in Parent (at **)',
202
- );
203
- expect(mockError).toHaveBeenCalledTimes(2);
204
- expect(mockError.mock.calls[0]).toHaveLength(2);
205
- expect(mockError.mock.calls[0][0]).toBe('active error');
206
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
207
- '\n in Child (at **)\n in Parent (at **)',
208
- );
209
- expect(mockError.mock.calls[1]).toHaveLength(2);
210
- expect(mockError.mock.calls[1][0]).toBe('passive error');
211
- expect(normalizeCodeLocInfo(mockError.mock.calls[1][1])).toBe(
212
- '\n in Child (at **)\n in Parent (at **)',
213
- );
214
- });
215
-
216
- it('should append component stacks to errors and warnings logged from commit hooks', () => {
217
- const Intermediate = ({children}) => children;
218
- const Parent = () => (
219
- <Intermediate>
220
- <Child />
221
- </Intermediate>
222
- );
223
- class Child extends React.Component<any> {
224
- componentDidMount() {
225
- fakeConsole.error('didMount error');
226
- fakeConsole.log('didMount log');
227
- fakeConsole.warn('didMount warn');
228
- }
229
- componentDidUpdate() {
230
- fakeConsole.error('didUpdate error');
231
- fakeConsole.log('didUpdate log');
232
- fakeConsole.warn('didUpdate warn');
233
- }
234
- render() {
235
- return null;
236
- }
237
- }
238
-
239
- const container = document.createElement('div');
240
- act(() => ReactDOM.render(<Parent />, container));
241
- act(() => ReactDOM.render(<Parent />, container));
242
-
243
- expect(mockLog).toHaveBeenCalledTimes(2);
244
- expect(mockLog.mock.calls[0]).toHaveLength(1);
245
- expect(mockLog.mock.calls[0][0]).toBe('didMount log');
246
- expect(mockLog.mock.calls[1]).toHaveLength(1);
247
- expect(mockLog.mock.calls[1][0]).toBe('didUpdate log');
248
- expect(mockWarn).toHaveBeenCalledTimes(2);
249
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
250
- expect(mockWarn.mock.calls[0][0]).toBe('didMount warn');
251
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
252
- '\n in Child (at **)\n in Parent (at **)',
253
- );
254
- expect(mockWarn.mock.calls[1]).toHaveLength(2);
255
- expect(mockWarn.mock.calls[1][0]).toBe('didUpdate warn');
256
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][1])).toEqual(
257
- '\n in Child (at **)\n in Parent (at **)',
258
- );
259
- expect(mockError).toHaveBeenCalledTimes(2);
260
- expect(mockError.mock.calls[0]).toHaveLength(2);
261
- expect(mockError.mock.calls[0][0]).toBe('didMount error');
262
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
263
- '\n in Child (at **)\n in Parent (at **)',
264
- );
265
- expect(mockError.mock.calls[1]).toHaveLength(2);
266
- expect(mockError.mock.calls[1][0]).toBe('didUpdate error');
267
- expect(normalizeCodeLocInfo(mockError.mock.calls[1][1])).toBe(
268
- '\n in Child (at **)\n in Parent (at **)',
269
- );
270
- });
271
-
272
- it('should append component stacks to errors and warnings logged from gDSFP', () => {
273
- const Intermediate = ({children}) => children;
274
- const Parent = () => (
275
- <Intermediate>
276
- <Child />
277
- </Intermediate>
278
- );
279
- class Child extends React.Component<any, any> {
280
- state = {};
281
- static getDerivedStateFromProps() {
282
- fakeConsole.error('error');
283
- fakeConsole.log('log');
284
- fakeConsole.warn('warn');
285
- return null;
286
- }
287
- render() {
288
- return null;
289
- }
290
- }
291
-
292
- act(() => ReactDOM.render(<Parent />, document.createElement('div')));
293
-
294
- expect(mockLog).toHaveBeenCalledTimes(1);
295
- expect(mockLog.mock.calls[0]).toHaveLength(1);
296
- expect(mockLog.mock.calls[0][0]).toBe('log');
297
- expect(mockWarn).toHaveBeenCalledTimes(1);
298
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
299
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
300
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
301
- '\n in Child (at **)\n in Parent (at **)',
302
- );
303
- expect(mockError).toHaveBeenCalledTimes(1);
304
- expect(mockError.mock.calls[0]).toHaveLength(2);
305
- expect(mockError.mock.calls[0][0]).toBe('error');
306
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
307
- '\n in Child (at **)\n in Parent (at **)',
308
- );
309
- });
310
-
311
- it('should append stacks after being uninstalled and reinstalled', () => {
312
- const Child = () => {
313
- fakeConsole.warn('warn');
314
- fakeConsole.error('error');
315
- return null;
316
- };
317
-
318
- unpatchConsole();
319
- act(() => ReactDOM.render(<Child />, document.createElement('div')));
320
-
321
- expect(mockWarn).toHaveBeenCalledTimes(1);
322
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
323
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
324
- expect(mockError).toHaveBeenCalledTimes(1);
325
- expect(mockError.mock.calls[0]).toHaveLength(1);
326
- expect(mockError.mock.calls[0][0]).toBe('error');
327
-
328
- patchConsole();
329
- act(() => ReactDOM.render(<Child />, document.createElement('div')));
330
-
331
- expect(mockWarn).toHaveBeenCalledTimes(2);
332
- expect(mockWarn.mock.calls[1]).toHaveLength(2);
333
- expect(mockWarn.mock.calls[1][0]).toBe('warn');
334
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][1])).toEqual(
335
- '\n in Child (at **)',
336
- );
337
- expect(mockError).toHaveBeenCalledTimes(2);
338
- expect(mockError.mock.calls[1]).toHaveLength(2);
339
- expect(mockError.mock.calls[1][0]).toBe('error');
340
- expect(normalizeCodeLocInfo(mockError.mock.calls[1][1])).toBe(
341
- '\n in Child (at **)',
342
- );
343
- });
344
-});
packages/react-devtools-shared/src/__tests__/inspectedElementContext-test.js
deleted
-1012
@@ -1,1012 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import typeof ReactTestRenderer from 'react-test-renderer';
11
-import type {GetInspectedElementPath} from 'react-devtools-shared/src/devtools/views/Components/InspectedElementContext';
12
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
13
-import type Store from 'react-devtools-shared/src/devtools/store';
14
-
15
-describe('InspectedElementContext', () => {
16
- let React;
17
- let ReactDOM;
18
- let TestRenderer: ReactTestRenderer;
19
- let bridge: FrontendBridge;
20
- let store: Store;
21
- let meta;
22
- let utils;
23
-
24
- let BridgeContext;
25
- let InspectedElementContext;
26
- let InspectedElementContextController;
27
- let StoreContext;
28
- let TestUtils;
29
- let TreeContextController;
30
-
31
- beforeEach(() => {
32
- utils = require('./utils');
33
- utils.beforeEachProfiling();
34
-
35
- meta = require('react-devtools-shared/src/hydration').meta;
36
-
37
- bridge = global.bridge;
38
- store = global.store;
39
- store.collapseNodesByDefault = false;
40
-
41
- React = require('react');
42
- ReactDOM = require('react-dom');
43
- TestUtils = require('react-dom/test-utils');
44
- TestRenderer = utils.requireTestRenderer();
45
-
46
- BridgeContext = require('react-devtools-shared/src/devtools/views/context')
47
- .BridgeContext;
48
- InspectedElementContext = require('react-devtools-shared/src/devtools/views/Components/InspectedElementContext')
49
- .InspectedElementContext;
50
- InspectedElementContextController = require('react-devtools-shared/src/devtools/views/Components/InspectedElementContext')
51
- .InspectedElementContextController;
52
- StoreContext = require('react-devtools-shared/src/devtools/views/context')
53
- .StoreContext;
54
- TreeContextController = require('react-devtools-shared/src/devtools/views/Components/TreeContext')
55
- .TreeContextController;
56
- });
57
-
58
- const Contexts = ({
59
- children,
60
- defaultSelectedElementID = null,
61
- defaultSelectedElementIndex = null,
62
- }) => (
63
- <BridgeContext.Provider value={bridge}>
64
- <StoreContext.Provider value={store}>
65
- <TreeContextController
66
- defaultSelectedElementID={defaultSelectedElementID}
67
- defaultSelectedElementIndex={defaultSelectedElementIndex}>
68
- <InspectedElementContextController>
69
- {children}
70
- </InspectedElementContextController>
71
- </TreeContextController>
72
- </StoreContext.Provider>
73
- </BridgeContext.Provider>
74
- );
75
-
76
- it('should inspect the currently selected element', async done => {
77
- const Example = () => {
78
- const [count] = React.useState(1);
79
- return count;
80
- };
81
-
82
- const container = document.createElement('div');
83
- await utils.actAsync(() =>
84
- ReactDOM.render(<Example a={1} b="abc" />, container),
85
- );
86
-
87
- const id = ((store.getElementIDAtIndex(0): any): number);
88
-
89
- let didFinish = false;
90
-
91
- function Suspender({target}) {
92
- const {getInspectedElement} = React.useContext(InspectedElementContext);
93
- const inspectedElement = getInspectedElement(id);
94
- expect(inspectedElement).toMatchSnapshot(`1: Inspected element ${id}`);
95
- didFinish = true;
96
- return null;
97
- }
98
-
99
- await utils.actAsync(
100
- () =>
101
- TestRenderer.create(
102
- <Contexts
103
- defaultSelectedElementID={id}
104
- defaultSelectedElementIndex={0}>
105
- <React.Suspense fallback={null}>
106
- <Suspender target={id} />
107
- </React.Suspense>
108
- </Contexts>,
109
- ),
110
- false,
111
- );
112
- expect(didFinish).toBe(true);
113
-
114
- done();
115
- });
116
-
117
- it('should poll for updates for the currently selected element', async done => {
118
- const Example = () => null;
119
-
120
- const container = document.createElement('div');
121
- await utils.actAsync(
122
- () => ReactDOM.render(<Example a={1} b="abc" />, container),
123
- false,
124
- );
125
-
126
- const id = ((store.getElementIDAtIndex(0): any): number);
127
-
128
- let inspectedElement = null;
129
-
130
- function Suspender({target}) {
131
- const {getInspectedElement} = React.useContext(InspectedElementContext);
132
- inspectedElement = getInspectedElement(id);
133
- return null;
134
- }
135
-
136
- let renderer;
137
-
138
- await utils.actAsync(() => {
139
- renderer = TestRenderer.create(
140
- <Contexts defaultSelectedElementID={id} defaultSelectedElementIndex={0}>
141
- <React.Suspense fallback={null}>
142
- <Suspender target={id} />
143
- </React.Suspense>
144
- </Contexts>,
145
- );
146
- }, false);
147
- expect(inspectedElement).toMatchSnapshot('1: initial render');
148
-
149
- await utils.actAsync(
150
- () => ReactDOM.render(<Example a={2} b="def" />, container),
151
- false,
152
- );
153
-
154
- inspectedElement = null;
155
- await utils.actAsync(
156
- () =>
157
- renderer.update(
158
- <Contexts
159
- defaultSelectedElementID={id}
160
- defaultSelectedElementIndex={0}>
161
- <React.Suspense fallback={null}>
162
- <Suspender target={id} />
163
- </React.Suspense>
164
- </Contexts>,
165
- ),
166
- false,
167
- );
168
- expect(inspectedElement).toMatchSnapshot('2: updated state');
169
-
170
- done();
171
- });
172
-
173
- it('should not re-render a function with hooks if it did not update since it was last inspected', async done => {
174
- let targetRenderCount = 0;
175
-
176
- const Wrapper = ({children}) => children;
177
- const Target = React.memo(props => {
178
- targetRenderCount++;
179
- React.useState(0);
180
- return null;
181
- });
182
-
183
- const container = document.createElement('div');
184
- await utils.actAsync(() =>
185
- ReactDOM.render(
186
- <Wrapper>
187
- <Target a={1} b="abc" />
188
- </Wrapper>,
189
- container,
190
- ),
191
- );
192
-
193
- const id = ((store.getElementIDAtIndex(1): any): number);
194
-
195
- let inspectedElement = null;
196
-
197
- function Suspender({target}) {
198
- const {getInspectedElement} = React.useContext(InspectedElementContext);
199
- inspectedElement = getInspectedElement(target);
200
- return null;
201
- }
202
-
203
- targetRenderCount = 0;
204
-
205
- let renderer;
206
- await utils.actAsync(
207
- () =>
208
- (renderer = TestRenderer.create(
209
- <Contexts
210
- defaultSelectedElementID={id}
211
- defaultSelectedElementIndex={1}>
212
- <React.Suspense fallback={null}>
213
- <Suspender target={id} />
214
- </React.Suspense>
215
- </Contexts>,
216
- )),
217
- false,
218
- );
219
- expect(targetRenderCount).toBe(1);
220
- expect(inspectedElement).toMatchSnapshot('1: initial render');
221
-
222
- const initialInspectedElement = inspectedElement;
223
-
224
- targetRenderCount = 0;
225
- inspectedElement = null;
226
- await utils.actAsync(
227
- () =>
228
- renderer.update(
229
- <Contexts
230
- defaultSelectedElementID={id}
231
- defaultSelectedElementIndex={1}>
232
- <React.Suspense fallback={null}>
233
- <Suspender target={id} />
234
- </React.Suspense>
235
- </Contexts>,
236
- ),
237
- false,
238
- );
239
- expect(targetRenderCount).toBe(0);
240
- expect(inspectedElement).toEqual(initialInspectedElement);
241
-
242
- targetRenderCount = 0;
243
-
244
- await utils.actAsync(
245
- () =>
246
- ReactDOM.render(
247
- <Wrapper>
248
- <Target a={2} b="def" />
249
- </Wrapper>,
250
- container,
251
- ),
252
- false,
253
- );
254
-
255
- // Target should have been rendered once (by ReactDOM) and once by DevTools for inspection.
256
- expect(targetRenderCount).toBe(2);
257
- expect(inspectedElement).toMatchSnapshot('2: updated state');
258
-
259
- done();
260
- });
261
-
262
- it('should temporarily disable console logging when re-running a component to inspect its hooks', async done => {
263
- let targetRenderCount = 0;
264
-
265
- const errorSpy = ((console: any).error = jest.fn());
266
- const infoSpy = ((console: any).info = jest.fn());
267
- const logSpy = ((console: any).log = jest.fn());
268
- const warnSpy = ((console: any).warn = jest.fn());
269
-
270
- const Target = React.memo(props => {
271
- targetRenderCount++;
272
- console.error('error');
273
- console.info('info');
274
- console.log('log');
275
- console.warn('warn');
276
- React.useState(0);
277
- return null;
278
- });
279
-
280
- const container = document.createElement('div');
281
- await utils.actAsync(() =>
282
- ReactDOM.render(<Target a={1} b="abc" />, container),
283
- );
284
-
285
- expect(targetRenderCount).toBe(1);
286
- expect(errorSpy).toHaveBeenCalledTimes(1);
287
- expect(errorSpy).toHaveBeenCalledWith('error');
288
- expect(infoSpy).toHaveBeenCalledTimes(1);
289
- expect(infoSpy).toHaveBeenCalledWith('info');
290
- expect(logSpy).toHaveBeenCalledTimes(1);
291
- expect(logSpy).toHaveBeenCalledWith('log');
292
- expect(warnSpy).toHaveBeenCalledTimes(1);
293
- expect(warnSpy).toHaveBeenCalledWith('warn');
294
-
295
- const id = ((store.getElementIDAtIndex(0): any): number);
296
-
297
- let inspectedElement = null;
298
-
299
- function Suspender({target}) {
300
- const {getInspectedElement} = React.useContext(InspectedElementContext);
301
- inspectedElement = getInspectedElement(target);
302
- return null;
303
- }
304
-
305
- await utils.actAsync(
306
- () =>
307
- TestRenderer.create(
308
- <Contexts
309
- defaultSelectedElementID={id}
310
- defaultSelectedElementIndex={1}>
311
- <React.Suspense fallback={null}>
312
- <Suspender target={id} />
313
- </React.Suspense>
314
- </Contexts>,
315
- ),
316
- false,
317
- );
318
-
319
- expect(inspectedElement).not.toBe(null);
320
- expect(targetRenderCount).toBe(2);
321
- expect(errorSpy).toHaveBeenCalledTimes(1);
322
- expect(infoSpy).toHaveBeenCalledTimes(1);
323
- expect(logSpy).toHaveBeenCalledTimes(1);
324
- expect(warnSpy).toHaveBeenCalledTimes(1);
325
-
326
- done();
327
- });
328
-
329
- it('should support simple data types', async done => {
330
- const Example = () => null;
331
-
332
- const container = document.createElement('div');
333
- await utils.actAsync(() =>
334
- ReactDOM.render(
335
- <Example
336
- boolean_false={false}
337
- boolean_true={true}
338
- infinity={Infinity}
339
- integer_zero={0}
340
- integer_one={1}
341
- float={1.23}
342
- string="abc"
343
- string_empty=""
344
- nan={NaN}
345
- value_null={null}
346
- value_undefined={undefined}
347
- />,
348
- container,
349
- ),
350
- );
351
-
352
- const id = ((store.getElementIDAtIndex(0): any): number);
353
- let inspectedElement = null;
354
-
355
- function Suspender({target}) {
356
- const {getInspectedElement} = React.useContext(InspectedElementContext);
357
- inspectedElement = getInspectedElement(id);
358
- return null;
359
- }
360
-
361
- await utils.actAsync(
362
- () =>
363
- TestRenderer.create(
364
- <Contexts
365
- defaultSelectedElementID={id}
366
- defaultSelectedElementIndex={0}>
367
- <React.Suspense fallback={null}>
368
- <Suspender target={id} />
369
- </React.Suspense>
370
- </Contexts>,
371
- ),
372
- false,
373
- );
374
-
375
- expect(inspectedElement).not.toBeNull();
376
- expect(inspectedElement).toMatchSnapshot('1: Initial inspection');
377
-
378
- const {props} = (inspectedElement: any);
379
- expect(props.boolean_false).toBe(false);
380
- expect(props.boolean_true).toBe(true);
381
- expect(Number.isFinite(props.infinity)).toBe(false);
382
- expect(props.integer_zero).toEqual(0);
383
- expect(props.integer_one).toEqual(1);
384
- expect(props.float).toEqual(1.23);
385
- expect(props.string).toEqual('abc');
386
- expect(props.string_empty).toEqual('');
387
- expect(props.nan).toBeNaN();
388
- expect(props.value_null).toBeNull();
389
- expect(props.value_undefined).toBeUndefined();
390
-
391
- done();
392
- });
393
-
394
- it('should support complex data types', async done => {
395
- const Immutable = require('immutable');
396
-
397
- const Example = () => null;
398
-
399
- const div = document.createElement('div');
400
- const exampleFunction = () => {};
401
- const setShallow = new Set(['abc', 123]);
402
- const mapShallow = new Map([['name', 'Brian'], ['food', 'sushi']]);
403
- const setOfSets = new Set([new Set(['a', 'b', 'c']), new Set([1, 2, 3])]);
404
- const mapOfMaps = new Map([['first', mapShallow], ['second', mapShallow]]);
405
- const typedArray = Int8Array.from([100, -100, 0]);
406
- const immutableMap = Immutable.fromJS({
407
- a: [{hello: 'there'}, 'fixed', true],
408
- b: 123,
409
- c: {
410
- '1': 'xyz',
411
- xyz: 1,
412
- },
413
- });
414
-
415
- const container = document.createElement('div');
416
- await utils.actAsync(() =>
417
- ReactDOM.render(
418
- <Example
419
- array_buffer={typedArray.buffer}
420
- date={new Date()}
421
- fn={exampleFunction}
422
- html_element={div}
423
- immutable={immutableMap}
424
- map={mapShallow}
425
- map_of_maps={mapOfMaps}
426
- react_element={<span />}
427
- set={setShallow}
428
- set_of_sets={setOfSets}
429
- symbol={Symbol('symbol')}
430
- typed_array={typedArray}
431
- />,
432
- container,
433
- ),
434
- );
435
-
436
- const id = ((store.getElementIDAtIndex(0): any): number);
437
-
438
- let inspectedElement = null;
439
-
440
- function Suspender({target}) {
441
- const {getInspectedElement} = React.useContext(InspectedElementContext);
442
- inspectedElement = getInspectedElement(id);
443
- return null;
444
- }
445
-
446
- await utils.actAsync(
447
- () =>
448
- TestRenderer.create(
449
- <Contexts
450
- defaultSelectedElementID={id}
451
- defaultSelectedElementIndex={0}>
452
- <React.Suspense fallback={null}>
453
- <Suspender target={id} />
454
- </React.Suspense>
455
- </Contexts>,
456
- ),
457
- false,
458
- );
459
-
460
- expect(inspectedElement).not.toBeNull();
461
- expect(inspectedElement).toMatchSnapshot(`1: Inspected element ${id}`);
462
-
463
- const {
464
- array_buffer,
465
- date,
466
- fn,
467
- html_element,
468
- immutable,
469
- map,
470
- map_of_maps,
471
- react_element,
472
- set,
473
- set_of_sets,
474
- symbol,
475
- typed_array,
476
- } = (inspectedElement: any).props;
477
-
478
- expect(array_buffer[meta.size]).toBe(3);
479
- expect(array_buffer[meta.inspectable]).toBe(false);
480
- expect(array_buffer[meta.name]).toBe('ArrayBuffer');
481
- expect(array_buffer[meta.type]).toBe('array_buffer');
482
-
483
- expect(date[meta.inspectable]).toBe(false);
484
- expect(date[meta.type]).toBe('date');
485
-
486
- expect(fn[meta.inspectable]).toBe(false);
487
- expect(fn[meta.name]).toBe('exampleFunction');
488
- expect(fn[meta.type]).toBe('function');
489
-
490
- expect(html_element[meta.inspectable]).toBe(false);
491
- expect(html_element[meta.name]).toBe('DIV');
492
- expect(html_element[meta.type]).toBe('html_element');
493
-
494
- expect(immutable[meta.inspectable]).toBeUndefined(); // Complex type
495
- expect(immutable[meta.name]).toBe('Map');
496
- expect(immutable[meta.type]).toBe('iterator');
497
-
498
- expect(map[meta.inspectable]).toBeUndefined(); // Complex type
499
- expect(map[meta.name]).toBe('Map');
500
- expect(map[meta.type]).toBe('iterator');
501
- expect(map[0][meta.type]).toBe('array');
502
-
503
- expect(map_of_maps[meta.inspectable]).toBeUndefined(); // Complex type
504
- expect(map_of_maps[meta.name]).toBe('Map');
505
- expect(map_of_maps[meta.type]).toBe('iterator');
506
- expect(map_of_maps[0][meta.type]).toBe('array');
507
-
508
- expect(react_element[meta.inspectable]).toBe(false);
509
- expect(react_element[meta.name]).toBe('span');
510
- expect(react_element[meta.type]).toBe('react_element');
511
-
512
- expect(set[meta.inspectable]).toBeUndefined(); // Complex type
513
- expect(set[meta.name]).toBe('Set');
514
- expect(set[meta.type]).toBe('iterator');
515
- expect(set[0]).toBe('abc');
516
- expect(set[1]).toBe(123);
517
-
518
- expect(set_of_sets[meta.inspectable]).toBeUndefined(); // Complex type
519
- expect(set_of_sets[meta.name]).toBe('Set');
520
- expect(set_of_sets[meta.type]).toBe('iterator');
521
- expect(set_of_sets['0'][meta.inspectable]).toBe(true);
522
-
523
- expect(symbol[meta.inspectable]).toBe(false);
524
- expect(symbol[meta.name]).toBe('Symbol(symbol)');
525
- expect(symbol[meta.type]).toBe('symbol');
526
-
527
- expect(typed_array[meta.inspectable]).toBeUndefined(); // Complex type
528
- expect(typed_array[meta.size]).toBe(3);
529
- expect(typed_array[meta.name]).toBe('Int8Array');
530
- expect(typed_array[meta.type]).toBe('typed_array');
531
- expect(typed_array[0]).toBe(100);
532
- expect(typed_array[1]).toBe(-100);
533
- expect(typed_array[2]).toBe(0);
534
-
535
- done();
536
- });
537
-
538
- it('should support custom objects with enumerable properties and getters', async done => {
539
- class CustomData {
540
- _number = 42;
541
- get number() {
542
- return this._number;
543
- }
544
- set number(value) {
545
- this._number = value;
546
- }
547
- }
548
-
549
- const descriptor = ((Object.getOwnPropertyDescriptor(
550
- CustomData.prototype,
551
- 'number',
552
- ): any): PropertyDescriptor<number>);
553
- descriptor.enumerable = true;
554
- Object.defineProperty(CustomData.prototype, 'number', descriptor);
555
-
556
- const Example = () => null;
557
-
558
- const container = document.createElement('div');
559
- await utils.actAsync(() =>
560
- ReactDOM.render(<Example data={new CustomData()} />, container),
561
- );
562
-
563
- const id = ((store.getElementIDAtIndex(0): any): number);
564
-
565
- let didFinish = false;
566
-
567
- function Suspender({target}) {
568
- const {getInspectedElement} = React.useContext(InspectedElementContext);
569
- const inspectedElement = getInspectedElement(id);
570
- expect(inspectedElement).toMatchSnapshot(`1: Inspected element ${id}`);
571
- didFinish = true;
572
- return null;
573
- }
574
-
575
- await utils.actAsync(
576
- () =>
577
- TestRenderer.create(
578
- <Contexts
579
- defaultSelectedElementID={id}
580
- defaultSelectedElementIndex={0}>
581
- <React.Suspense fallback={null}>
582
- <Suspender target={id} />
583
- </React.Suspense>
584
- </Contexts>,
585
- ),
586
- false,
587
- );
588
- expect(didFinish).toBe(true);
589
-
590
- done();
591
- });
592
-
593
- it('should not dehydrate nested values until explicitly requested', async done => {
594
- const Example = () => {
595
- const [state] = React.useState({
596
- foo: {
597
- bar: {
598
- baz: 'hi',
599
- },
600
- },
601
- });
602
-
603
- return state.foo.bar.baz;
604
- };
605
-
606
- const container = document.createElement('div');
607
- await utils.actAsync(() =>
608
- ReactDOM.render(
609
- <Example
610
- nestedObject={{
611
- a: {
612
- b: {
613
- c: [
614
- {
615
- d: {
616
- e: {},
617
- },
618
- },
619
- ],
620
- },
621
- },
622
- }}
623
- />,
624
- container,
625
- ),
626
- );
627
-
628
- const id = ((store.getElementIDAtIndex(0): any): number);
629
-
630
- let getInspectedElementPath: GetInspectedElementPath = ((null: any): GetInspectedElementPath);
631
- let inspectedElement = null;
632
-
633
- function Suspender({target}) {
634
- const context = React.useContext(InspectedElementContext);
635
- getInspectedElementPath = context.getInspectedElementPath;
636
- inspectedElement = context.getInspectedElement(target);
637
- return null;
638
- }
639
-
640
- await utils.actAsync(
641
- () =>
642
- TestRenderer.create(
643
- <Contexts
644
- defaultSelectedElementID={id}
645
- defaultSelectedElementIndex={0}>
646
- <React.Suspense fallback={null}>
647
- <Suspender target={id} />
648
- </React.Suspense>
649
- </Contexts>,
650
- ),
651
- false,
652
- );
653
- expect(getInspectedElementPath).not.toBeNull();
654
- expect(inspectedElement).not.toBeNull();
655
- expect(inspectedElement).toMatchSnapshot('1: Initially inspect element');
656
-
657
- inspectedElement = null;
658
- TestUtils.act(() => {
659
- TestRenderer.act(() => {
660
- getInspectedElementPath(id, ['props', 'nestedObject', 'a']);
661
- jest.runOnlyPendingTimers();
662
- });
663
- });
664
- expect(inspectedElement).not.toBeNull();
665
- expect(inspectedElement).toMatchSnapshot('2: Inspect props.nestedObject.a');
666
-
667
- inspectedElement = null;
668
- TestUtils.act(() => {
669
- TestRenderer.act(() => {
670
- getInspectedElementPath(id, ['props', 'nestedObject', 'a', 'b', 'c']);
671
- jest.runOnlyPendingTimers();
672
- });
673
- });
674
- expect(inspectedElement).not.toBeNull();
675
- expect(inspectedElement).toMatchSnapshot(
676
- '3: Inspect props.nestedObject.a.b.c',
677
- );
678
-
679
- inspectedElement = null;
680
- TestUtils.act(() => {
681
- TestRenderer.act(() => {
682
- getInspectedElementPath(id, [
683
- 'props',
684
- 'nestedObject',
685
- 'a',
686
- 'b',
687
- 'c',
688
- 0,
689
- 'd',
690
- ]);
691
- jest.runOnlyPendingTimers();
692
- });
693
- });
694
- expect(inspectedElement).not.toBeNull();
695
- expect(inspectedElement).toMatchSnapshot(
696
- '4: Inspect props.nestedObject.a.b.c.0.d',
697
- );
698
-
699
- inspectedElement = null;
700
- TestUtils.act(() => {
701
- TestRenderer.act(() => {
702
- getInspectedElementPath(id, ['hooks', 0, 'value']);
703
- jest.runOnlyPendingTimers();
704
- });
705
- });
706
- expect(inspectedElement).not.toBeNull();
707
- expect(inspectedElement).toMatchSnapshot('5: Inspect hooks.0.value');
708
-
709
- inspectedElement = null;
710
- TestUtils.act(() => {
711
- TestRenderer.act(() => {
712
- getInspectedElementPath(id, ['hooks', 0, 'value', 'foo', 'bar']);
713
- jest.runOnlyPendingTimers();
714
- });
715
- });
716
- expect(inspectedElement).not.toBeNull();
717
- expect(inspectedElement).toMatchSnapshot(
718
- '6: Inspect hooks.0.value.foo.bar',
719
- );
720
-
721
- done();
722
- });
723
-
724
- it('should dehydrate complex nested values when requested', async done => {
725
- const Example = () => null;
726
-
727
- const container = document.createElement('div');
728
- await utils.actAsync(() =>
729
- ReactDOM.render(
730
- <Example
731
- set_of_sets={new Set([new Set([1, 2, 3]), new Set(['a', 'b', 'c'])])}
732
- />,
733
- container,
734
- ),
735
- );
736
-
737
- const id = ((store.getElementIDAtIndex(0): any): number);
738
-
739
- let getInspectedElementPath: GetInspectedElementPath = ((null: any): GetInspectedElementPath);
740
- let inspectedElement = null;
741
-
742
- function Suspender({target}) {
743
- const context = React.useContext(InspectedElementContext);
744
- getInspectedElementPath = context.getInspectedElementPath;
745
- inspectedElement = context.getInspectedElement(target);
746
- return null;
747
- }
748
-
749
- await utils.actAsync(
750
- () =>
751
- TestRenderer.create(
752
- <Contexts
753
- defaultSelectedElementID={id}
754
- defaultSelectedElementIndex={0}>
755
- <React.Suspense fallback={null}>
756
- <Suspender target={id} />
757
- </React.Suspense>
758
- </Contexts>,
759
- ),
760
- false,
761
- );
762
- expect(getInspectedElementPath).not.toBeNull();
763
- expect(inspectedElement).not.toBeNull();
764
- expect(inspectedElement).toMatchSnapshot('1: Initially inspect element');
765
-
766
- inspectedElement = null;
767
- TestUtils.act(() => {
768
- TestRenderer.act(() => {
769
- getInspectedElementPath(id, ['props', 'set_of_sets', 0]);
770
- jest.runOnlyPendingTimers();
771
- });
772
- });
773
- expect(inspectedElement).not.toBeNull();
774
- expect(inspectedElement).toMatchSnapshot('2: Inspect props.set_of_sets.0');
775
-
776
- done();
777
- });
778
-
779
- it('should include updates for nested values that were previously hydrated', async done => {
780
- const Example = () => null;
781
-
782
- const container = document.createElement('div');
783
- await utils.actAsync(() =>
784
- ReactDOM.render(
785
- <Example
786
- nestedObject={{
787
- a: {
788
- value: 1,
789
- b: {
790
- value: 1,
791
- },
792
- },
793
- c: {
794
- value: 1,
795
- d: {
796
- value: 1,
797
- e: {
798
- value: 1,
799
- },
800
- },
801
- },
802
- }}
803
- />,
804
- container,
805
- ),
806
- );
807
-
808
- const id = ((store.getElementIDAtIndex(0): any): number);
809
-
810
- let getInspectedElementPath: GetInspectedElementPath = ((null: any): GetInspectedElementPath);
811
- let inspectedElement = null;
812
-
813
- function Suspender({target}) {
814
- const context = React.useContext(InspectedElementContext);
815
- getInspectedElementPath = context.getInspectedElementPath;
816
- inspectedElement = context.getInspectedElement(id);
817
- return null;
818
- }
819
-
820
- await utils.actAsync(
821
- () =>
822
- TestRenderer.create(
823
- <Contexts
824
- defaultSelectedElementID={id}
825
- defaultSelectedElementIndex={0}>
826
- <React.Suspense fallback={null}>
827
- <Suspender target={id} />
828
- </React.Suspense>
829
- </Contexts>,
830
- ),
831
- false,
832
- );
833
- expect(getInspectedElementPath).not.toBeNull();
834
- expect(inspectedElement).not.toBeNull();
835
- expect(inspectedElement).toMatchSnapshot('1: Initially inspect element');
836
-
837
- inspectedElement = null;
838
- TestRenderer.act(() => {
839
- getInspectedElementPath(id, ['props', 'nestedObject', 'a']);
840
- jest.runOnlyPendingTimers();
841
- });
842
- expect(inspectedElement).not.toBeNull();
843
- expect(inspectedElement).toMatchSnapshot('2: Inspect props.nestedObject.a');
844
-
845
- inspectedElement = null;
846
- TestRenderer.act(() => {
847
- getInspectedElementPath(id, ['props', 'nestedObject', 'c']);
848
- jest.runOnlyPendingTimers();
849
- });
850
- expect(inspectedElement).not.toBeNull();
851
- expect(inspectedElement).toMatchSnapshot('3: Inspect props.nestedObject.c');
852
-
853
- TestRenderer.act(() => {
854
- TestUtils.act(() => {
855
- ReactDOM.render(
856
- <Example
857
- nestedObject={{
858
- a: {
859
- value: 2,
860
- b: {
861
- value: 2,
862
- },
863
- },
864
- c: {
865
- value: 2,
866
- d: {
867
- value: 2,
868
- e: {
869
- value: 2,
870
- },
871
- },
872
- },
873
- }}
874
- />,
875
- container,
876
- );
877
- });
878
- });
879
-
880
- TestRenderer.act(() => {
881
- inspectedElement = null;
882
- jest.advanceTimersByTime(1000);
883
- });
884
- expect(inspectedElement).not.toBeNull();
885
- expect(inspectedElement).toMatchSnapshot('4: update inspected element');
886
-
887
- done();
888
- });
889
-
890
- it('should not tear if hydration is requested after an update', async done => {
891
- const Example = () => null;
892
-
893
- const container = document.createElement('div');
894
- await utils.actAsync(() =>
895
- ReactDOM.render(
896
- <Example
897
- nestedObject={{
898
- value: 1,
899
- a: {
900
- value: 1,
901
- b: {
902
- value: 1,
903
- },
904
- },
905
- }}
906
- />,
907
- container,
908
- ),
909
- );
910
-
911
- const id = ((store.getElementIDAtIndex(0): any): number);
912
-
913
- let getInspectedElementPath: GetInspectedElementPath = ((null: any): GetInspectedElementPath);
914
- let inspectedElement = null;
915
-
916
- function Suspender({target}) {
917
- const context = React.useContext(InspectedElementContext);
918
- getInspectedElementPath = context.getInspectedElementPath;
919
- inspectedElement = context.getInspectedElement(id);
920
- return null;
921
- }
922
-
923
- await utils.actAsync(
924
- () =>
925
- TestRenderer.create(
926
- <Contexts
927
- defaultSelectedElementID={id}
928
- defaultSelectedElementIndex={0}>
929
- <React.Suspense fallback={null}>
930
- <Suspender target={id} />
931
- </React.Suspense>
932
- </Contexts>,
933
- ),
934
- false,
935
- );
936
- expect(getInspectedElementPath).not.toBeNull();
937
- expect(inspectedElement).not.toBeNull();
938
- expect(inspectedElement).toMatchSnapshot('1: Initially inspect element');
939
-
940
- TestUtils.act(() => {
941
- ReactDOM.render(
942
- <Example
943
- nestedObject={{
944
- value: 2,
945
- a: {
946
- value: 2,
947
- b: {
948
- value: 2,
949
- },
950
- },
951
- }}
952
- />,
953
- container,
954
- );
955
- });
956
-
957
- inspectedElement = null;
958
-
959
- TestRenderer.act(() => {
960
- TestUtils.act(() => {
961
- getInspectedElementPath(id, ['props', 'nestedObject', 'a']);
962
- jest.runOnlyPendingTimers();
963
- });
964
- });
965
- expect(inspectedElement).not.toBeNull();
966
- expect(inspectedElement).toMatchSnapshot('2: Inspect props.nestedObject.a');
967
-
968
- done();
969
- });
970
-
971
- it('should inspect hooks for components that only use context', async done => {
972
- const Context = React.createContext(true);
973
- const Example = () => {
974
- const value = React.useContext(Context);
975
- return value;
976
- };
977
-
978
- const container = document.createElement('div');
979
- await utils.actAsync(() =>
980
- ReactDOM.render(<Example a={1} b="abc" />, container),
981
- );
982
-
983
- const id = ((store.getElementIDAtIndex(0): any): number);
984
-
985
- let didFinish = false;
986
-
987
- function Suspender({target}) {
988
- const {getInspectedElement} = React.useContext(InspectedElementContext);
989
- const inspectedElement = getInspectedElement(id);
990
- expect(inspectedElement).toMatchSnapshot(`1: Inspected element ${id}`);
991
- didFinish = true;
992
- return null;
993
- }
994
-
995
- await utils.actAsync(
996
- () =>
997
- TestRenderer.create(
998
- <Contexts
999
- defaultSelectedElementID={id}
1000
- defaultSelectedElementIndex={0}>
1001
- <React.Suspense fallback={null}>
1002
- <Suspender target={id} />
1003
- </React.Suspense>
1004
- </Contexts>,
1005
- ),
1006
- false,
1007
- );
1008
- expect(didFinish).toBe(true);
1009
-
1010
- done();
1011
- });
1012
-});
packages/react-devtools-shared/src/__tests__/inspectedElementSerializer.js
deleted
-28
@@ -1,28 +0,0 @@
1
-// test() is part of Jest's serializer API
2
-export function test(maybeInspectedElement) {
3
- return (
4
- maybeInspectedElement !== null &&
5
- typeof maybeInspectedElement === 'object' &&
6
- maybeInspectedElement.hasOwnProperty('canEditFunctionProps') &&
7
- maybeInspectedElement.hasOwnProperty('canEditHooks') &&
8
- maybeInspectedElement.hasOwnProperty('canToggleSuspense') &&
9
- maybeInspectedElement.hasOwnProperty('canViewSource')
10
- );
11
-}
12
-
13
-// print() is part of Jest's serializer API
14
-export function print(inspectedElement, serialize, indent) {
15
- return JSON.stringify(
16
- {
17
- id: inspectedElement.id,
18
- owners: inspectedElement.owners,
19
- context: inspectedElement.context,
20
- events: inspectedElement.events,
21
- hooks: inspectedElement.hooks,
22
- props: inspectedElement.props,
23
- state: inspectedElement.state,
24
- },
25
- null,
26
- 2,
27
- );
28
-}
packages/react-devtools-shared/src/__tests__/legacy/__snapshots__/inspectElement-test.js.snap
deleted
-211
@@ -1,211 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`InspectedElementContext should inspect the currently selected element: 1: Initial inspection 1`] = `
4
-Object {
5
- "id": 2,
6
- "type": "full-data",
7
- "value": {
8
- "id": 2,
9
- "owners": null,
10
- "context": {},
11
- "hooks": null,
12
- "props": {
13
- "a": 1,
14
- "b": "abc"
15
- },
16
- "state": null
17
-},
18
-}
19
-`;
20
-
21
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 1: Initially inspect element 1`] = `
22
-Object {
23
- "id": 2,
24
- "type": "full-data",
25
- "value": {
26
- "id": 2,
27
- "owners": null,
28
- "context": {},
29
- "hooks": null,
30
- "props": {
31
- "nestedObject": {
32
- "a": {}
33
- }
34
- },
35
- "state": null
36
-},
37
-}
38
-`;
39
-
40
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 2: Inspect props.nestedObject.a 1`] = `
41
-Object {
42
- "id": 2,
43
- "type": "full-data",
44
- "value": {
45
- "id": 2,
46
- "owners": null,
47
- "context": {},
48
- "hooks": null,
49
- "props": {
50
- "nestedObject": {
51
- "a": {
52
- "b": {
53
- "c": {}
54
- }
55
- }
56
- }
57
- },
58
- "state": null
59
-},
60
-}
61
-`;
62
-
63
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 3: Inspect props.nestedObject.a.b.c 1`] = `
64
-Object {
65
- "id": 2,
66
- "type": "full-data",
67
- "value": {
68
- "id": 2,
69
- "owners": null,
70
- "context": {},
71
- "hooks": null,
72
- "props": {
73
- "nestedObject": {
74
- "a": {
75
- "b": {
76
- "c": [
77
- {
78
- "d": {}
79
- }
80
- ]
81
- }
82
- }
83
- }
84
- },
85
- "state": null
86
-},
87
-}
88
-`;
89
-
90
-exports[`InspectedElementContext should not dehydrate nested values until explicitly requested: 4: Inspect props.nestedObject.a.b.c.0.d 1`] = `
91
-Object {
92
- "id": 2,
93
- "type": "full-data",
94
- "value": {
95
- "id": 2,
96
- "owners": null,
97
- "context": {},
98
- "hooks": null,
99
- "props": {
100
- "nestedObject": {
101
- "a": {
102
- "b": {
103
- "c": [
104
- {
105
- "d": {
106
- "e": {}
107
- }
108
- }
109
- ]
110
- }
111
- }
112
- }
113
- },
114
- "state": null
115
-},
116
-}
117
-`;
118
-
119
-exports[`InspectedElementContext should support complex data types: 1: Initial inspection 1`] = `
120
-Object {
121
- "id": 2,
122
- "type": "full-data",
123
- "value": {
124
- "id": 2,
125
- "owners": null,
126
- "context": {},
127
- "hooks": null,
128
- "props": {
129
- "array_buffer": {},
130
- "date": {},
131
- "fn": {},
132
- "html_element": {},
133
- "immutable": {
134
- "0": {},
135
- "1": {},
136
- "2": {}
137
- },
138
- "map": {
139
- "0": {},
140
- "1": {}
141
- },
142
- "map_of_maps": {
143
- "0": {},
144
- "1": {}
145
- },
146
- "react_element": {},
147
- "set": {
148
- "0": "abc",
149
- "1": 123
150
- },
151
- "set_of_sets": {
152
- "0": {},
153
- "1": {}
154
- },
155
- "symbol": {},
156
- "typed_array": {
157
- "0": 100,
158
- "1": -100,
159
- "2": 0
160
- }
161
- },
162
- "state": null
163
-},
164
-}
165
-`;
166
-
167
-exports[`InspectedElementContext should support custom objects with enumerable properties and getters: 1: Initial inspection 1`] = `
168
-Object {
169
- "id": 2,
170
- "type": "full-data",
171
- "value": {
172
- "id": 2,
173
- "owners": null,
174
- "context": {},
175
- "hooks": null,
176
- "props": {
177
- "data": {
178
- "_number": 42,
179
- "number": 42
180
- }
181
- },
182
- "state": null
183
-},
184
-}
185
-`;
186
-
187
-exports[`InspectedElementContext should support simple data types: 1: Initial inspection 1`] = `
188
-Object {
189
- "id": 2,
190
- "type": "full-data",
191
- "value": {
192
- "id": 2,
193
- "owners": null,
194
- "context": {},
195
- "hooks": null,
196
- "props": {
197
- "boolean_false": false,
198
- "boolean_true": true,
199
- "infinity": null,
200
- "integer_zero": 0,
201
- "integer_one": 1,
202
- "float": 1.23,
203
- "string": "abc",
204
- "string_empty": "",
205
- "nan": null,
206
- "value_null": null
207
- },
208
- "state": null
209
-},
210
-}
211
-`;
packages/react-devtools-shared/src/__tests__/legacy/__snapshots__/storeLegacy-v15-test.js.snap
deleted
-499
@@ -1,499 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`Store (legacy) collapseNodesByDefault:false should not filter DOM nodes from the store tree: 1: mount 1`] = `
4
-[root]
5
- ▾ <Grandparent>
6
- ▾ <div>
7
- ▾ <div>
8
- ▾ <Parent>
9
- ▾ <div>
10
- ▾ <Child>
11
- <div>
12
- ▾ <Parent>
13
- ▾ <div>
14
- ▾ <Child>
15
- <div>
16
- <Nothing>
17
-`;
18
-
19
-exports[`Store (legacy) collapseNodesByDefault:false should not filter DOM nodes from the store tree: 2: update 1`] = `
20
-[root]
21
- ▾ <Grandparent>
22
- ▾ <div>
23
- ▾ <div>
24
- ▾ <Parent>
25
- ▾ <div>
26
- ▾ <Child>
27
- <div>
28
- ▾ <Parent>
29
- ▾ <div>
30
- ▾ <Child>
31
- <div>
32
- <Nothing>
33
-`;
34
-
35
-exports[`Store (legacy) collapseNodesByDefault:false should not filter DOM nodes from the store tree: 5: unmount 1`] = ``;
36
-
37
-exports[`Store (legacy) collapseNodesByDefault:false should support adding and removing children: 1: mount 1`] = `
38
-[root]
39
- ▾ <Root>
40
- ▾ <div>
41
- ▾ <Component key="a">
42
- <div>
43
-`;
44
-
45
-exports[`Store (legacy) collapseNodesByDefault:false should support adding and removing children: 2: add child 1`] = `
46
-[root]
47
- ▾ <Root>
48
- ▾ <div>
49
- ▾ <Component key="a">
50
- <div>
51
- ▾ <Component key="b">
52
- <div>
53
-`;
54
-
55
-exports[`Store (legacy) collapseNodesByDefault:false should support adding and removing children: 3: remove child 1`] = `
56
-[root]
57
- ▾ <Root>
58
- ▾ <div>
59
- ▾ <Component key="b">
60
- <div>
61
-`;
62
-
63
-exports[`Store (legacy) collapseNodesByDefault:false should support collapsing parts of the tree: 1: mount 1`] = `
64
-[root]
65
- ▾ <Grandparent>
66
- ▾ <div>
67
- ▾ <Parent>
68
- ▾ <div>
69
- ▾ <Child key="0">
70
- <div>
71
- ▾ <Child key="1">
72
- <div>
73
- ▾ <Parent>
74
- ▾ <div>
75
- ▾ <Child key="0">
76
- <div>
77
- ▾ <Child key="1">
78
- <div>
79
-`;
80
-
81
-exports[`Store (legacy) collapseNodesByDefault:false should support collapsing parts of the tree: 2: collapse first Parent 1`] = `
82
-[root]
83
- ▾ <Grandparent>
84
- ▾ <div>
85
- ▸ <Parent>
86
- ▾ <Parent>
87
- ▾ <div>
88
- ▾ <Child key="0">
89
- <div>
90
- ▾ <Child key="1">
91
- <div>
92
-`;
93
-
94
-exports[`Store (legacy) collapseNodesByDefault:false should support collapsing parts of the tree: 3: collapse second Parent 1`] = `
95
-[root]
96
- ▾ <Grandparent>
97
- ▾ <div>
98
- ▸ <Parent>
99
- ▸ <Parent>
100
-`;
101
-
102
-exports[`Store (legacy) collapseNodesByDefault:false should support collapsing parts of the tree: 4: expand first Parent 1`] = `
103
-[root]
104
- ▾ <Grandparent>
105
- ▾ <div>
106
- ▾ <Parent>
107
- ▾ <div>
108
- ▾ <Child key="0">
109
- <div>
110
- ▾ <Child key="1">
111
- <div>
112
- ▸ <Parent>
113
-`;
114
-
115
-exports[`Store (legacy) collapseNodesByDefault:false should support collapsing parts of the tree: 5: collapse Grandparent 1`] = `
116
-[root]
117
- ▸ <Grandparent>
118
-`;
119
-
120
-exports[`Store (legacy) collapseNodesByDefault:false should support collapsing parts of the tree: 6: expand Grandparent 1`] = `
121
-[root]
122
- ▾ <Grandparent>
123
- ▾ <div>
124
- ▾ <Parent>
125
- ▾ <div>
126
- ▾ <Child key="0">
127
- <div>
128
- ▾ <Child key="1">
129
- <div>
130
- ▸ <Parent>
131
-`;
132
-
133
-exports[`Store (legacy) collapseNodesByDefault:false should support mount and update operations for multiple roots: 1: mount 1`] = `
134
-[root]
135
- ▾ <Parent key="A">
136
- ▾ <div>
137
- ▾ <Child key="0">
138
- <div>
139
- ▾ <Child key="1">
140
- <div>
141
- ▾ <Child key="2">
142
- <div>
143
-[root]
144
- ▾ <Parent key="B">
145
- ▾ <div>
146
- ▾ <Child key="0">
147
- <div>
148
- ▾ <Child key="1">
149
- <div>
150
-`;
151
-
152
-exports[`Store (legacy) collapseNodesByDefault:false should support mount and update operations for multiple roots: 2: update 1`] = `
153
-[root]
154
- ▾ <Parent key="A">
155
- ▾ <div>
156
- ▾ <Child key="0">
157
- <div>
158
- ▾ <Child key="1">
159
- <div>
160
- ▾ <Child key="2">
161
- <div>
162
- ▾ <Child key="3">
163
- <div>
164
-[root]
165
- ▾ <Parent key="B">
166
- ▾ <div>
167
- ▾ <Child key="0">
168
- <div>
169
-`;
170
-
171
-exports[`Store (legacy) collapseNodesByDefault:false should support mount and update operations for multiple roots: 3: unmount B 1`] = `
172
-[root]
173
- ▾ <Parent key="A">
174
- ▾ <div>
175
- ▾ <Child key="0">
176
- <div>
177
- ▾ <Child key="1">
178
- <div>
179
- ▾ <Child key="2">
180
- <div>
181
- ▾ <Child key="3">
182
- <div>
183
-`;
184
-
185
-exports[`Store (legacy) collapseNodesByDefault:false should support mount and update operations for multiple roots: 4: unmount A 1`] = ``;
186
-
187
-exports[`Store (legacy) collapseNodesByDefault:false should support mount and update operations: 1: mount 1`] = `
188
-[root]
189
- ▾ <Grandparent>
190
- ▾ <div>
191
- ▾ <Parent>
192
- ▾ <div>
193
- ▾ <Child key="0">
194
- <div>
195
- ▾ <Child key="1">
196
- <div>
197
- ▾ <Child key="2">
198
- <div>
199
- ▾ <Child key="3">
200
- <div>
201
- ▾ <Parent>
202
- ▾ <div>
203
- ▾ <Child key="0">
204
- <div>
205
- ▾ <Child key="1">
206
- <div>
207
- ▾ <Child key="2">
208
- <div>
209
- ▾ <Child key="3">
210
- <div>
211
-`;
212
-
213
-exports[`Store (legacy) collapseNodesByDefault:false should support mount and update operations: 2: update 1`] = `
214
-[root]
215
- ▾ <Grandparent>
216
- ▾ <div>
217
- ▾ <Parent>
218
- ▾ <div>
219
- ▾ <Child key="0">
220
- <div>
221
- ▾ <Child key="1">
222
- <div>
223
- ▾ <Parent>
224
- ▾ <div>
225
- ▾ <Child key="0">
226
- <div>
227
- ▾ <Child key="1">
228
- <div>
229
-`;
230
-
231
-exports[`Store (legacy) collapseNodesByDefault:false should support mount and update operations: 3: unmount 1`] = ``;
232
-
233
-exports[`Store (legacy) collapseNodesByDefault:false should support reordering of children: 1: mount 1`] = `
234
-[root]
235
- ▾ <Root>
236
- ▾ <div>
237
- ▾ <Foo key="foo">
238
- ▾ <div>
239
- ▾ <Component key="0">
240
- <div>
241
- ▾ <Bar key="bar">
242
- ▾ <div>
243
- ▾ <Component key="0">
244
- <div>
245
- ▾ <Component key="1">
246
- <div>
247
-`;
248
-
249
-exports[`Store (legacy) collapseNodesByDefault:false should support reordering of children: 2: reorder children 1`] = `
250
-[root]
251
- ▾ <Root>
252
- ▾ <div>
253
- ▾ <Bar key="bar">
254
- ▾ <div>
255
- ▾ <Component key="0">
256
- <div>
257
- ▾ <Component key="1">
258
- <div>
259
- ▾ <Foo key="foo">
260
- ▾ <div>
261
- ▾ <Component key="0">
262
- <div>
263
-`;
264
-
265
-exports[`Store (legacy) collapseNodesByDefault:false should support reordering of children: 3: collapse root 1`] = `
266
-[root]
267
- ▸ <Root>
268
-`;
269
-
270
-exports[`Store (legacy) collapseNodesByDefault:false should support reordering of children: 4: expand root 1`] = `
271
-[root]
272
- ▾ <Root>
273
- ▾ <div>
274
- ▾ <Bar key="bar">
275
- ▾ <div>
276
- ▾ <Component key="0">
277
- <div>
278
- ▾ <Component key="1">
279
- <div>
280
- ▾ <Foo key="foo">
281
- ▾ <div>
282
- ▾ <Component key="0">
283
- <div>
284
-`;
285
-
286
-exports[`Store (legacy) collapseNodesByDefault:true should not filter DOM nodes from the store tree: 1: mount 1`] = `
287
-[root]
288
- ▸ <Grandparent>
289
-`;
290
-
291
-exports[`Store (legacy) collapseNodesByDefault:true should not filter DOM nodes from the store tree: 2: expand Grandparent 1`] = `
292
-[root]
293
- ▾ <Grandparent>
294
- ▸ <div>
295
-`;
296
-
297
-exports[`Store (legacy) collapseNodesByDefault:true should not filter DOM nodes from the store tree: 3: expand div 1`] = `
298
-[root]
299
- ▾ <Grandparent>
300
- ▾ <div>
301
- ▸ <div>
302
- ▸ <Parent>
303
- <Nothing>
304
-`;
305
-
306
-exports[`Store (legacy) collapseNodesByDefault:true should not filter DOM nodes from the store tree: 4: final update 1`] = `
307
-[root]
308
- ▾ <Grandparent>
309
- ▾ <div>
310
- ▸ <div>
311
- ▸ <Parent>
312
- <Nothing>
313
-`;
314
-
315
-exports[`Store (legacy) collapseNodesByDefault:true should not filter DOM nodes from the store tree: 5: unmount 1`] = ``;
316
-
317
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding deep parts of the tree: 1: mount 1`] = `
318
-[root]
319
- ▸ <Wrapper>
320
-`;
321
-
322
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding deep parts of the tree: 2: expand deepest node 1`] = `
323
-[root]
324
- ▾ <Wrapper>
325
- ▾ <Nested>
326
- ▾ <Nested>
327
- ▾ <Nested>
328
- ▾ <Nested>
329
- <div>
330
-`;
331
-
332
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding deep parts of the tree: 3: collapse root 1`] = `
333
-[root]
334
- ▸ <Wrapper>
335
-`;
336
-
337
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding deep parts of the tree: 4: expand root 1`] = `
338
-[root]
339
- ▾ <Wrapper>
340
- ▾ <Nested>
341
- ▾ <Nested>
342
- ▾ <Nested>
343
- ▾ <Nested>
344
- <div>
345
-`;
346
-
347
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding deep parts of the tree: 5: collapse middle node 1`] = `
348
-[root]
349
- ▾ <Wrapper>
350
- ▸ <Nested>
351
-`;
352
-
353
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding deep parts of the tree: 6: expand middle node 1`] = `
354
-[root]
355
- ▾ <Wrapper>
356
- ▾ <Nested>
357
- ▾ <Nested>
358
- ▾ <Nested>
359
- ▾ <Nested>
360
- <div>
361
-`;
362
-
363
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding parts of the tree: 1: mount 1`] = `
364
-[root]
365
- ▸ <Grandparent>
366
-`;
367
-
368
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding parts of the tree: 2: expand Grandparent 1`] = `
369
-[root]
370
- ▾ <Grandparent>
371
- ▸ <div>
372
-`;
373
-
374
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding parts of the tree: 3: expand parent div 1`] = `
375
-[root]
376
- ▾ <Grandparent>
377
- ▾ <div>
378
- ▸ <Parent>
379
- ▸ <Parent>
380
-`;
381
-
382
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding parts of the tree: 4: expand first Parent 1`] = `
383
-[root]
384
- ▾ <Grandparent>
385
- ▾ <div>
386
- ▾ <Parent>
387
- ▸ <div>
388
- ▸ <Parent>
389
-`;
390
-
391
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding parts of the tree: 5: expand second Parent 1`] = `
392
-[root]
393
- ▾ <Grandparent>
394
- ▾ <div>
395
- ▾ <Parent>
396
- ▸ <div>
397
- ▾ <Parent>
398
- ▸ <div>
399
-`;
400
-
401
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding parts of the tree: 6: collapse first Parent 1`] = `
402
-[root]
403
- ▾ <Grandparent>
404
- ▾ <div>
405
- ▸ <Parent>
406
- ▾ <Parent>
407
- ▸ <div>
408
-`;
409
-
410
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding parts of the tree: 7: collapse second Parent 1`] = `
411
-[root]
412
- ▾ <Grandparent>
413
- ▾ <div>
414
- ▸ <Parent>
415
- ▸ <Parent>
416
-`;
417
-
418
-exports[`Store (legacy) collapseNodesByDefault:true should support expanding parts of the tree: 8: collapse Grandparent 1`] = `
419
-[root]
420
- ▸ <Grandparent>
421
-`;
422
-
423
-exports[`Store (legacy) collapseNodesByDefault:true should support mount and update operations for multiple roots: 1: mount 1`] = `
424
-[root]
425
- ▸ <Parent key="A">
426
-[root]
427
- ▸ <Parent key="B">
428
-`;
429
-
430
-exports[`Store (legacy) collapseNodesByDefault:true should support mount and update operations for multiple roots: 2: update 1`] = `
431
-[root]
432
- ▸ <Parent key="A">
433
-[root]
434
- ▸ <Parent key="B">
435
-`;
436
-
437
-exports[`Store (legacy) collapseNodesByDefault:true should support mount and update operations for multiple roots: 3: unmount B 1`] = `
438
-[root]
439
- ▸ <Parent key="A">
440
-`;
441
-
442
-exports[`Store (legacy) collapseNodesByDefault:true should support mount and update operations for multiple roots: 4: unmount A 1`] = ``;
443
-
444
-exports[`Store (legacy) collapseNodesByDefault:true should support mount and update operations: 1: mount 1`] = `
445
-[root]
446
- ▸ <div>
447
-`;
448
-
449
-exports[`Store (legacy) collapseNodesByDefault:true should support mount and update operations: 2: update 1`] = `
450
-[root]
451
- ▸ <div>
452
-`;
453
-
454
-exports[`Store (legacy) collapseNodesByDefault:true should support mount and update operations: 3: unmount 1`] = ``;
455
-
456
-exports[`Store (legacy) collapseNodesByDefault:true should support reordering of children: 1: mount 1`] = `
457
-[root]
458
- ▸ <Root>
459
-`;
460
-
461
-exports[`Store (legacy) collapseNodesByDefault:true should support reordering of children: 2: reorder children 1`] = `
462
-[root]
463
- ▸ <Root>
464
-`;
465
-
466
-exports[`Store (legacy) collapseNodesByDefault:true should support reordering of children: 3: expand root 1`] = `
467
-[root]
468
- ▾ <Root>
469
- ▸ <div>
470
-`;
471
-
472
-exports[`Store (legacy) collapseNodesByDefault:true should support reordering of children: 4: expand div 1`] = `
473
-[root]
474
- ▾ <Root>
475
- ▾ <div>
476
- ▸ <Bar key="bar">
477
- ▸ <Foo key="foo">
478
-`;
479
-
480
-exports[`Store (legacy) collapseNodesByDefault:true should support reordering of children: 4: expand leaves 1`] = `
481
-[root]
482
- ▾ <Root>
483
- ▾ <div>
484
- ▾ <Bar key="bar">
485
- ▸ <div>
486
- ▾ <Foo key="foo">
487
- ▸ <div>
488
-`;
489
-
490
-exports[`Store (legacy) collapseNodesByDefault:true should support reordering of children: 5: collapse root 1`] = `
491
-[root]
492
- ▸ <Root>
493
-`;
494
-
495
-exports[`Store (legacy) should not allow a root node to be collapsed: 1: mount 1`] = `
496
-[root]
497
- ▾ <Component>
498
- <div>
499
-`;
packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js
deleted
-353
@@ -1,353 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {InspectedElementPayload} from 'react-devtools-shared/src/backend/types';
11
-import type {DehydratedData} from 'react-devtools-shared/src/devtools/views/Components/types';
12
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
13
-import type Store from 'react-devtools-shared/src/devtools/store';
14
-
15
-describe('InspectedElementContext', () => {
16
- let React;
17
- let ReactDOM;
18
- let hydrate;
19
- let meta;
20
- let bridge: FrontendBridge;
21
- let store: Store;
22
-
23
- const act = (callback: Function) => {
24
- callback();
25
-
26
- jest.runAllTimers(); // Flush Bridge operations
27
- };
28
-
29
- function dehydrateHelper(
30
- dehydratedData: DehydratedData | null,
31
- ): Object | null {
32
- if (dehydratedData !== null) {
33
- return hydrate(
34
- dehydratedData.data,
35
- dehydratedData.cleaned,
36
- dehydratedData.unserializable,
37
- );
38
- } else {
39
- return null;
40
- }
41
- }
42
-
43
- async function read(
44
- id: number,
45
- path?: Array<string | number>,
46
- ): Promise<Object> {
47
- return new Promise((resolve, reject) => {
48
- const rendererID = ((store.getRendererIDForElement(id): any): number);
49
-
50
- const onInspectedElement = (payload: InspectedElementPayload) => {
51
- bridge.removeListener('inspectedElement', onInspectedElement);
52
-
53
- if (payload.type === 'full-data' && payload.value !== null) {
54
- payload.value.context = dehydrateHelper(payload.value.context);
55
- payload.value.props = dehydrateHelper(payload.value.props);
56
- payload.value.state = dehydrateHelper(payload.value.state);
57
- }
58
-
59
- resolve(payload);
60
- };
61
-
62
- bridge.addListener('inspectedElement', onInspectedElement);
63
- bridge.send('inspectElement', {id, path, rendererID});
64
-
65
- jest.runOnlyPendingTimers();
66
- });
67
- }
68
-
69
- beforeEach(() => {
70
- bridge = global.bridge;
71
- store = global.store;
72
-
73
- hydrate = require('react-devtools-shared/src/hydration').hydrate;
74
- meta = require('react-devtools-shared/src/hydration').meta;
75
-
76
- // Redirect all React/ReactDOM requires to the v15 UMD.
77
- // We use the UMD because Jest doesn't enable us to mock deep imports (e.g. "react/lib/Something").
78
- jest.mock('react', () => jest.requireActual('react-15/dist/react.js'));
79
- jest.mock('react-dom', () =>
80
- jest.requireActual('react-dom-15/dist/react-dom.js'),
81
- );
82
-
83
- React = require('react');
84
- ReactDOM = require('react-dom');
85
- });
86
-
87
- it('should inspect the currently selected element', async done => {
88
- const Example = () => null;
89
-
90
- act(() =>
91
- ReactDOM.render(<Example a={1} b="abc" />, document.createElement('div')),
92
- );
93
-
94
- const id = ((store.getElementIDAtIndex(0): any): number);
95
- const inspectedElement = await read(id);
96
-
97
- expect(inspectedElement).toMatchSnapshot('1: Initial inspection');
98
-
99
- done();
100
- });
101
-
102
- it('should support simple data types', async done => {
103
- const Example = () => null;
104
-
105
- act(() =>
106
- ReactDOM.render(
107
- <Example
108
- boolean_false={false}
109
- boolean_true={true}
110
- infinity={Infinity}
111
- integer_zero={0}
112
- integer_one={1}
113
- float={1.23}
114
- string="abc"
115
- string_empty=""
116
- nan={NaN}
117
- value_null={null}
118
- value_undefined={undefined}
119
- />,
120
- document.createElement('div'),
121
- ),
122
- );
123
-
124
- const id = ((store.getElementIDAtIndex(0): any): number);
125
- const inspectedElement = await read(id);
126
-
127
- expect(inspectedElement).toMatchSnapshot('1: Initial inspection');
128
-
129
- const {props} = inspectedElement.value;
130
- expect(props.boolean_false).toBe(false);
131
- expect(props.boolean_true).toBe(true);
132
- expect(Number.isFinite(props.infinity)).toBe(false);
133
- expect(props.integer_zero).toEqual(0);
134
- expect(props.integer_one).toEqual(1);
135
- expect(props.float).toEqual(1.23);
136
- expect(props.string).toEqual('abc');
137
- expect(props.string_empty).toEqual('');
138
- expect(props.nan).toBeNaN();
139
- expect(props.value_null).toBeNull();
140
- expect(props.value_undefined).toBeUndefined();
141
-
142
- done();
143
- });
144
-
145
- it('should support complex data types', async done => {
146
- const Immutable = require('immutable');
147
-
148
- const Example = () => null;
149
-
150
- const div = document.createElement('div');
151
- const exampleFunction = () => {};
152
- const setShallow = new Set(['abc', 123]);
153
- const mapShallow = new Map([['name', 'Brian'], ['food', 'sushi']]);
154
- const setOfSets = new Set([new Set(['a', 'b', 'c']), new Set([1, 2, 3])]);
155
- const mapOfMaps = new Map([['first', mapShallow], ['second', mapShallow]]);
156
- const typedArray = Int8Array.from([100, -100, 0]);
157
- const immutableMap = Immutable.fromJS({
158
- a: [{hello: 'there'}, 'fixed', true],
159
- b: 123,
160
- c: {
161
- '1': 'xyz',
162
- xyz: 1,
163
- },
164
- });
165
-
166
- act(() =>
167
- ReactDOM.render(
168
- <Example
169
- array_buffer={typedArray.buffer}
170
- date={new Date()}
171
- fn={exampleFunction}
172
- html_element={div}
173
- immutable={immutableMap}
174
- map={mapShallow}
175
- map_of_maps={mapOfMaps}
176
- react_element={<span />}
177
- set={setShallow}
178
- set_of_sets={setOfSets}
179
- symbol={Symbol('symbol')}
180
- typed_array={typedArray}
181
- />,
182
- document.createElement('div'),
183
- ),
184
- );
185
-
186
- const id = ((store.getElementIDAtIndex(0): any): number);
187
- const inspectedElement = await read(id);
188
-
189
- expect(inspectedElement).toMatchSnapshot('1: Initial inspection');
190
-
191
- const {
192
- array_buffer,
193
- date,
194
- fn,
195
- html_element,
196
- immutable,
197
- map,
198
- map_of_maps,
199
- react_element,
200
- set,
201
- set_of_sets,
202
- symbol,
203
- typed_array,
204
- } = inspectedElement.value.props;
205
-
206
- expect(array_buffer[meta.size]).toBe(3);
207
- expect(array_buffer[meta.inspectable]).toBe(false);
208
- expect(array_buffer[meta.name]).toBe('ArrayBuffer');
209
- expect(array_buffer[meta.type]).toBe('array_buffer');
210
-
211
- expect(date[meta.inspectable]).toBe(false);
212
- expect(date[meta.type]).toBe('date');
213
-
214
- expect(fn[meta.inspectable]).toBe(false);
215
- expect(fn[meta.name]).toBe('exampleFunction');
216
- expect(fn[meta.type]).toBe('function');
217
-
218
- expect(html_element[meta.inspectable]).toBe(false);
219
- expect(html_element[meta.name]).toBe('DIV');
220
- expect(html_element[meta.type]).toBe('html_element');
221
-
222
- expect(immutable[meta.inspectable]).toBeUndefined(); // Complex type
223
- expect(immutable[meta.name]).toBe('Map');
224
- expect(immutable[meta.type]).toBe('iterator');
225
-
226
- expect(map[meta.inspectable]).toBeUndefined(); // Complex type
227
- expect(map[meta.name]).toBe('Map');
228
- expect(map[meta.type]).toBe('iterator');
229
- expect(map[0][meta.type]).toBe('array');
230
-
231
- expect(map_of_maps[meta.inspectable]).toBeUndefined(); // Complex type
232
- expect(map_of_maps[meta.name]).toBe('Map');
233
- expect(map_of_maps[meta.type]).toBe('iterator');
234
- expect(map_of_maps[0][meta.type]).toBe('array');
235
-
236
- expect(react_element[meta.inspectable]).toBe(false);
237
- expect(react_element[meta.name]).toBe('span');
238
- expect(react_element[meta.type]).toBe('react_element');
239
-
240
- expect(set[meta.inspectable]).toBeUndefined(); // Complex type
241
- expect(set[meta.name]).toBe('Set');
242
- expect(set[meta.type]).toBe('iterator');
243
- expect(set[0]).toBe('abc');
244
- expect(set[1]).toBe(123);
245
-
246
- expect(set_of_sets[meta.inspectable]).toBeUndefined(); // Complex type
247
- expect(set_of_sets[meta.name]).toBe('Set');
248
- expect(set_of_sets[meta.type]).toBe('iterator');
249
- expect(set_of_sets['0'][meta.inspectable]).toBe(true);
250
-
251
- expect(symbol[meta.inspectable]).toBe(false);
252
- expect(symbol[meta.name]).toBe('Symbol(symbol)');
253
- expect(symbol[meta.type]).toBe('symbol');
254
-
255
- expect(typed_array[meta.inspectable]).toBeUndefined(); // Complex type
256
- expect(typed_array[meta.size]).toBe(3);
257
- expect(typed_array[meta.name]).toBe('Int8Array');
258
- expect(typed_array[meta.type]).toBe('typed_array');
259
- expect(typed_array[0]).toBe(100);
260
- expect(typed_array[1]).toBe(-100);
261
- expect(typed_array[2]).toBe(0);
262
-
263
- done();
264
- });
265
-
266
- it('should support custom objects with enumerable properties and getters', async done => {
267
- class CustomData {
268
- _number = 42;
269
- get number() {
270
- return this._number;
271
- }
272
- set number(value) {
273
- this._number = value;
274
- }
275
- }
276
-
277
- const descriptor = ((Object.getOwnPropertyDescriptor(
278
- CustomData.prototype,
279
- 'number',
280
- ): any): PropertyDescriptor<number>);
281
- descriptor.enumerable = true;
282
- Object.defineProperty(CustomData.prototype, 'number', descriptor);
283
-
284
- const Example = ({data}) => null;
285
-
286
- act(() =>
287
- ReactDOM.render(
288
- <Example data={new CustomData()} />,
289
- document.createElement('div'),
290
- ),
291
- );
292
-
293
- const id = ((store.getElementIDAtIndex(0): any): number);
294
- const inspectedElement = await read(id);
295
-
296
- expect(inspectedElement).toMatchSnapshot('1: Initial inspection');
297
-
298
- done();
299
- });
300
-
301
- it('should not dehydrate nested values until explicitly requested', async done => {
302
- const Example = () => null;
303
-
304
- act(() =>
305
- ReactDOM.render(
306
- <Example
307
- nestedObject={{
308
- a: {
309
- b: {
310
- c: [
311
- {
312
- d: {
313
- e: {},
314
- },
315
- },
316
- ],
317
- },
318
- },
319
- }}
320
- />,
321
- document.createElement('div'),
322
- ),
323
- );
324
-
325
- const id = ((store.getElementIDAtIndex(0): any): number);
326
-
327
- let inspectedElement = await read(id);
328
- expect(inspectedElement).toMatchSnapshot('1: Initially inspect element');
329
-
330
- inspectedElement = await read(id, ['props', 'nestedObject', 'a']);
331
- expect(inspectedElement).toMatchSnapshot('2: Inspect props.nestedObject.a');
332
-
333
- inspectedElement = await read(id, ['props', 'nestedObject', 'a', 'b', 'c']);
334
- expect(inspectedElement).toMatchSnapshot(
335
- '3: Inspect props.nestedObject.a.b.c',
336
- );
337
-
338
- inspectedElement = await read(id, [
339
- 'props',
340
- 'nestedObject',
341
- 'a',
342
- 'b',
343
- 'c',
344
- 0,
345
- 'd',
346
- ]);
347
- expect(inspectedElement).toMatchSnapshot(
348
- '4: Inspect props.nestedObject.a.b.c.0.d',
349
- );
350
-
351
- done();
352
- });
353
-});
packages/react-devtools-shared/src/__tests__/legacy/storeLegacy-v15-test.js
deleted
-500
@@ -1,500 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-describe('Store (legacy)', () => {
11
- let React;
12
- let ReactDOM;
13
- let store;
14
-
15
- const act = (callback: Function) => {
16
- callback();
17
-
18
- jest.runAllTimers(); // Flush Bridge operations
19
- };
20
-
21
- beforeEach(() => {
22
- store = global.store;
23
-
24
- // Redirect all React/ReactDOM requires to the v15 UMD.
25
- // We use the UMD because Jest doesn't enable us to mock deep imports (e.g. "react/lib/Something").
26
- jest.mock('react', () => jest.requireActual('react-15/dist/react.js'));
27
- jest.mock('react-dom', () =>
28
- jest.requireActual('react-dom-15/dist/react-dom.js'),
29
- );
30
-
31
- React = require('react');
32
- ReactDOM = require('react-dom');
33
- });
34
-
35
- it('should not allow a root node to be collapsed', () => {
36
- const Component = () => <div>Hi</div>;
37
-
38
- act(() =>
39
- ReactDOM.render(<Component count={4} />, document.createElement('div')),
40
- );
41
- expect(store).toMatchSnapshot('1: mount');
42
-
43
- expect(store.roots).toHaveLength(1);
44
-
45
- const rootID = store.roots[0];
46
-
47
- expect(() => store.toggleIsCollapsed(rootID, true)).toThrow(
48
- 'Root nodes cannot be collapsed',
49
- );
50
- });
51
-
52
- describe('collapseNodesByDefault:false', () => {
53
- beforeEach(() => {
54
- store.collapseNodesByDefault = false;
55
- });
56
-
57
- it('should support mount and update operations', () => {
58
- const Grandparent = ({count}) => (
59
- <div>
60
- <Parent count={count} />
61
- <Parent count={count} />
62
- </div>
63
- );
64
- const Parent = ({count}) => (
65
- <div>
66
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
67
- </div>
68
- );
69
- const Child = () => <div>Hi!</div>;
70
-
71
- const container = document.createElement('div');
72
-
73
- act(() => ReactDOM.render(<Grandparent count={4} />, container));
74
- expect(store).toMatchSnapshot('1: mount');
75
-
76
- act(() => ReactDOM.render(<Grandparent count={2} />, container));
77
- expect(store).toMatchSnapshot('2: update');
78
-
79
- act(() => ReactDOM.unmountComponentAtNode(container));
80
- expect(store).toMatchSnapshot('3: unmount');
81
- });
82
-
83
- it('should support mount and update operations for multiple roots', () => {
84
- const Parent = ({count}) => (
85
- <div>
86
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
87
- </div>
88
- );
89
- const Child = () => <div>Hi!</div>;
90
-
91
- const containerA = document.createElement('div');
92
- const containerB = document.createElement('div');
93
-
94
- act(() => {
95
- ReactDOM.render(<Parent key="A" count={3} />, containerA);
96
- ReactDOM.render(<Parent key="B" count={2} />, containerB);
97
- });
98
- expect(store).toMatchSnapshot('1: mount');
99
-
100
- act(() => {
101
- ReactDOM.render(<Parent key="A" count={4} />, containerA);
102
- ReactDOM.render(<Parent key="B" count={1} />, containerB);
103
- });
104
- expect(store).toMatchSnapshot('2: update');
105
-
106
- act(() => ReactDOM.unmountComponentAtNode(containerB));
107
- expect(store).toMatchSnapshot('3: unmount B');
108
-
109
- act(() => ReactDOM.unmountComponentAtNode(containerA));
110
- expect(store).toMatchSnapshot('4: unmount A');
111
- });
112
-
113
- it('should not filter DOM nodes from the store tree', () => {
114
- const Grandparent = ({flip}) => (
115
- <div>
116
- <div>
117
- <Parent flip={flip} />
118
- </div>
119
- <Parent flip={flip} />
120
- <Nothing />
121
- </div>
122
- );
123
- const Parent = ({flip}) => (
124
- <div>
125
- {flip ? 'foo' : null}
126
- <Child />
127
- {flip && [null, 'hello', 42]}
128
- {flip ? 'bar' : 'baz'}
129
- </div>
130
- );
131
- const Child = () => <div>Hi!</div>;
132
- const Nothing = () => null;
133
-
134
- const container = document.createElement('div');
135
- act(() =>
136
- ReactDOM.render(<Grandparent count={4} flip={false} />, container),
137
- );
138
- expect(store).toMatchSnapshot('1: mount');
139
-
140
- act(() =>
141
- ReactDOM.render(<Grandparent count={4} flip={true} />, container),
142
- );
143
- expect(store).toMatchSnapshot('2: update');
144
-
145
- act(() => ReactDOM.unmountComponentAtNode(container));
146
- expect(store).toMatchSnapshot('5: unmount');
147
- });
148
-
149
- it('should support collapsing parts of the tree', () => {
150
- const Grandparent = ({count}) => (
151
- <div>
152
- <Parent count={count} />
153
- <Parent count={count} />
154
- </div>
155
- );
156
- const Parent = ({count}) => (
157
- <div>
158
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
159
- </div>
160
- );
161
- const Child = () => <div>Hi!</div>;
162
-
163
- act(() =>
164
- ReactDOM.render(
165
- <Grandparent count={2} />,
166
- document.createElement('div'),
167
- ),
168
- );
169
- expect(store).toMatchSnapshot('1: mount');
170
-
171
- const grandparentID = store.getElementIDAtIndex(0);
172
- const parentOneID = store.getElementIDAtIndex(2);
173
- const parentTwoID = store.getElementIDAtIndex(8);
174
-
175
- act(() => store.toggleIsCollapsed(parentOneID, true));
176
- expect(store).toMatchSnapshot('2: collapse first Parent');
177
-
178
- act(() => store.toggleIsCollapsed(parentTwoID, true));
179
- expect(store).toMatchSnapshot('3: collapse second Parent');
180
-
181
- act(() => store.toggleIsCollapsed(parentOneID, false));
182
- expect(store).toMatchSnapshot('4: expand first Parent');
183
-
184
- act(() => store.toggleIsCollapsed(grandparentID, true));
185
- expect(store).toMatchSnapshot('5: collapse Grandparent');
186
-
187
- act(() => store.toggleIsCollapsed(grandparentID, false));
188
- expect(store).toMatchSnapshot('6: expand Grandparent');
189
- });
190
-
191
- it('should support adding and removing children', () => {
192
- const Root = ({children}) => <div>{children}</div>;
193
- const Component = () => <div />;
194
-
195
- const container = document.createElement('div');
196
-
197
- act(() =>
198
- ReactDOM.render(
199
- <Root>
200
- <Component key="a" />
201
- </Root>,
202
- container,
203
- ),
204
- );
205
- expect(store).toMatchSnapshot('1: mount');
206
-
207
- act(() =>
208
- ReactDOM.render(
209
- <Root>
210
- <Component key="a" />
211
- <Component key="b" />
212
- </Root>,
213
- container,
214
- ),
215
- );
216
- expect(store).toMatchSnapshot('2: add child');
217
-
218
- act(() =>
219
- ReactDOM.render(
220
- <Root>
221
- <Component key="b" />
222
- </Root>,
223
- container,
224
- ),
225
- );
226
- expect(store).toMatchSnapshot('3: remove child');
227
- });
228
-
229
- it('should support reordering of children', () => {
230
- const Root = ({children}) => <div>{children}</div>;
231
- const Component = () => <div />;
232
-
233
- const Foo = () => <div>{[<Component key="0" />]}</div>;
234
- const Bar = () => (
235
- <div>{[<Component key="0" />, <Component key="1" />]}</div>
236
- );
237
- const foo = <Foo key="foo" />;
238
- const bar = <Bar key="bar" />;
239
-
240
- const container = document.createElement('div');
241
-
242
- act(() => ReactDOM.render(<Root>{[foo, bar]}</Root>, container));
243
- expect(store).toMatchSnapshot('1: mount');
244
-
245
- act(() => ReactDOM.render(<Root>{[bar, foo]}</Root>, container));
246
- expect(store).toMatchSnapshot('2: reorder children');
247
-
248
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), true));
249
- expect(store).toMatchSnapshot('3: collapse root');
250
-
251
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), false));
252
- expect(store).toMatchSnapshot('4: expand root');
253
- });
254
- });
255
-
256
- describe('collapseNodesByDefault:true', () => {
257
- beforeEach(() => {
258
- store.collapseNodesByDefault = true;
259
- });
260
-
261
- it('should support mount and update operations', () => {
262
- const Parent = ({count}) => (
263
- <div>
264
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
265
- </div>
266
- );
267
- const Child = () => <div>Hi!</div>;
268
-
269
- const container = document.createElement('div');
270
-
271
- act(() =>
272
- ReactDOM.render(
273
- <div>
274
- <Parent count={1} />
275
- <Parent count={3} />
276
- </div>,
277
- container,
278
- ),
279
- );
280
- expect(store).toMatchSnapshot('1: mount');
281
-
282
- act(() =>
283
- ReactDOM.render(
284
- <div>
285
- <Parent count={2} />
286
- <Parent count={1} />
287
- </div>,
288
- container,
289
- ),
290
- );
291
- expect(store).toMatchSnapshot('2: update');
292
-
293
- act(() => ReactDOM.unmountComponentAtNode(container));
294
- expect(store).toMatchSnapshot('3: unmount');
295
- });
296
-
297
- it('should support mount and update operations for multiple roots', () => {
298
- const Parent = ({count}) => (
299
- <div>
300
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
301
- </div>
302
- );
303
- const Child = () => <div>Hi!</div>;
304
-
305
- const containerA = document.createElement('div');
306
- const containerB = document.createElement('div');
307
-
308
- act(() => {
309
- ReactDOM.render(<Parent key="A" count={3} />, containerA);
310
- ReactDOM.render(<Parent key="B" count={2} />, containerB);
311
- });
312
- expect(store).toMatchSnapshot('1: mount');
313
-
314
- act(() => {
315
- ReactDOM.render(<Parent key="A" count={4} />, containerA);
316
- ReactDOM.render(<Parent key="B" count={1} />, containerB);
317
- });
318
- expect(store).toMatchSnapshot('2: update');
319
-
320
- act(() => ReactDOM.unmountComponentAtNode(containerB));
321
- expect(store).toMatchSnapshot('3: unmount B');
322
-
323
- act(() => ReactDOM.unmountComponentAtNode(containerA));
324
- expect(store).toMatchSnapshot('4: unmount A');
325
- });
326
-
327
- it('should not filter DOM nodes from the store tree', () => {
328
- const Grandparent = ({flip}) => (
329
- <div>
330
- <div>
331
- <Parent flip={flip} />
332
- </div>
333
- <Parent flip={flip} />
334
- <Nothing />
335
- </div>
336
- );
337
- const Parent = ({flip}) => (
338
- <div>
339
- {flip ? 'foo' : null}
340
- <Child />
341
- {flip && [null, 'hello', 42]}
342
- {flip ? 'bar' : 'baz'}
343
- </div>
344
- );
345
- const Child = () => <div>Hi!</div>;
346
- const Nothing = () => null;
347
-
348
- const container = document.createElement('div');
349
- act(() =>
350
- ReactDOM.render(<Grandparent count={4} flip={false} />, container),
351
- );
352
- expect(store).toMatchSnapshot('1: mount');
353
-
354
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), false));
355
- expect(store).toMatchSnapshot('2: expand Grandparent');
356
-
357
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(1), false));
358
- expect(store).toMatchSnapshot('3: expand div');
359
-
360
- act(() =>
361
- ReactDOM.render(<Grandparent count={4} flip={true} />, container),
362
- );
363
- expect(store).toMatchSnapshot('4: final update');
364
-
365
- act(() => ReactDOM.unmountComponentAtNode(container));
366
- expect(store).toMatchSnapshot('5: unmount');
367
- });
368
-
369
- it('should support expanding parts of the tree', () => {
370
- const Grandparent = ({count}) => (
371
- <div>
372
- <Parent count={count} />
373
- <Parent count={count} />
374
- </div>
375
- );
376
- const Parent = ({count}) => (
377
- <div>
378
- {new Array(count).fill(true).map((_, index) => <Child key={index} />)}
379
- </div>
380
- );
381
- const Child = () => <div>Hi!</div>;
382
-
383
- act(() =>
384
- ReactDOM.render(
385
- <Grandparent count={2} />,
386
- document.createElement('div'),
387
- ),
388
- );
389
- expect(store).toMatchSnapshot('1: mount');
390
-
391
- const grandparentID = store.getElementIDAtIndex(0);
392
-
393
- act(() => store.toggleIsCollapsed(grandparentID, false));
394
- expect(store).toMatchSnapshot('2: expand Grandparent');
395
-
396
- const parentDivID = store.getElementIDAtIndex(1);
397
- act(() => store.toggleIsCollapsed(parentDivID, false));
398
- expect(store).toMatchSnapshot('3: expand parent div');
399
-
400
- const parentOneID = store.getElementIDAtIndex(2);
401
- const parentTwoID = store.getElementIDAtIndex(3);
402
-
403
- act(() => store.toggleIsCollapsed(parentOneID, false));
404
- expect(store).toMatchSnapshot('4: expand first Parent');
405
-
406
- act(() => store.toggleIsCollapsed(parentTwoID, false));
407
- expect(store).toMatchSnapshot('5: expand second Parent');
408
-
409
- act(() => store.toggleIsCollapsed(parentOneID, true));
410
- expect(store).toMatchSnapshot('6: collapse first Parent');
411
-
412
- act(() => store.toggleIsCollapsed(parentTwoID, true));
413
- expect(store).toMatchSnapshot('7: collapse second Parent');
414
-
415
- act(() => store.toggleIsCollapsed(grandparentID, true));
416
- expect(store).toMatchSnapshot('8: collapse Grandparent');
417
- });
418
-
419
- it('should support expanding deep parts of the tree', () => {
420
- const Wrapper = ({forwardedRef}) => (
421
- <Nested depth={3} forwardedRef={forwardedRef} />
422
- );
423
- const Nested = ({depth, forwardedRef}) =>
424
- depth > 0 ? (
425
- <Nested depth={depth - 1} forwardedRef={forwardedRef} />
426
- ) : (
427
- <div ref={forwardedRef} />
428
- );
429
-
430
- let ref = null;
431
- const refSetter = value => {
432
- ref = value;
433
- };
434
-
435
- act(() =>
436
- ReactDOM.render(
437
- <Wrapper forwardedRef={refSetter} />,
438
- document.createElement('div'),
439
- ),
440
- );
441
- expect(store).toMatchSnapshot('1: mount');
442
-
443
- const deepestedNodeID = global.agent.getIDForNode(ref);
444
-
445
- act(() => store.toggleIsCollapsed(deepestedNodeID, false));
446
- expect(store).toMatchSnapshot('2: expand deepest node');
447
-
448
- const rootID = store.getElementIDAtIndex(0);
449
-
450
- act(() => store.toggleIsCollapsed(rootID, true));
451
- expect(store).toMatchSnapshot('3: collapse root');
452
-
453
- act(() => store.toggleIsCollapsed(rootID, false));
454
- expect(store).toMatchSnapshot('4: expand root');
455
-
456
- const id = store.getElementIDAtIndex(1);
457
-
458
- act(() => store.toggleIsCollapsed(id, true));
459
- expect(store).toMatchSnapshot('5: collapse middle node');
460
-
461
- act(() => store.toggleIsCollapsed(id, false));
462
- expect(store).toMatchSnapshot('6: expand middle node');
463
- });
464
-
465
- it('should support reordering of children', () => {
466
- const Root = ({children}) => <div>{children}</div>;
467
- const Component = () => <div />;
468
-
469
- const Foo = () => <div>{[<Component key="0" />]}</div>;
470
- const Bar = () => (
471
- <div>{[<Component key="0" />, <Component key="1" />]}</div>
472
- );
473
- const foo = <Foo key="foo" />;
474
- const bar = <Bar key="bar" />;
475
-
476
- const container = document.createElement('div');
477
-
478
- act(() => ReactDOM.render(<Root>{[foo, bar]}</Root>, container));
479
- expect(store).toMatchSnapshot('1: mount');
480
-
481
- act(() => ReactDOM.render(<Root>{[bar, foo]}</Root>, container));
482
- expect(store).toMatchSnapshot('2: reorder children');
483
-
484
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), false));
485
- expect(store).toMatchSnapshot('3: expand root');
486
-
487
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(1), false));
488
- expect(store).toMatchSnapshot('4: expand div');
489
-
490
- act(() => {
491
- store.toggleIsCollapsed(store.getElementIDAtIndex(3), false);
492
- store.toggleIsCollapsed(store.getElementIDAtIndex(2), false);
493
- });
494
- expect(store).toMatchSnapshot('4: expand leaves');
495
-
496
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), true));
497
- expect(store).toMatchSnapshot('5: collapse root');
498
- });
499
- });
500
-});
packages/react-devtools-shared/src/__tests__/ownersListContext-test.js
deleted
-209
@@ -1,209 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import typeof ReactTestRenderer from 'react-test-renderer';
11
-import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types';
12
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
13
-import type Store from 'react-devtools-shared/src/devtools/store';
14
-
15
-describe('OwnersListContext', () => {
16
- let React;
17
- let ReactDOM;
18
- let TestRenderer: ReactTestRenderer;
19
- let bridge: FrontendBridge;
20
- let store: Store;
21
- let utils;
22
-
23
- let BridgeContext;
24
- let OwnersListContext;
25
- let OwnersListContextController;
26
- let StoreContext;
27
- let TreeContextController;
28
-
29
- beforeEach(() => {
30
- utils = require('./utils');
31
- utils.beforeEachProfiling();
32
-
33
- bridge = global.bridge;
34
- store = global.store;
35
- store.collapseNodesByDefault = false;
36
-
37
- React = require('react');
38
- ReactDOM = require('react-dom');
39
- TestRenderer = utils.requireTestRenderer();
40
-
41
- BridgeContext = require('react-devtools-shared/src/devtools/views/context')
42
- .BridgeContext;
43
- OwnersListContext = require('react-devtools-shared/src/devtools/views/Components/OwnersListContext')
44
- .OwnersListContext;
45
- OwnersListContextController = require('react-devtools-shared/src/devtools/views/Components/OwnersListContext')
46
- .OwnersListContextController;
47
- StoreContext = require('react-devtools-shared/src/devtools/views/context')
48
- .StoreContext;
49
- TreeContextController = require('react-devtools-shared/src/devtools/views/Components/TreeContext')
50
- .TreeContextController;
51
- });
52
-
53
- const Contexts = ({children, defaultOwnerID = null}) => (
54
- <BridgeContext.Provider value={bridge}>
55
- <StoreContext.Provider value={store}>
56
- <TreeContextController defaultOwnerID={defaultOwnerID}>
57
- <OwnersListContextController>{children}</OwnersListContextController>
58
- </TreeContextController>
59
- </StoreContext.Provider>
60
- </BridgeContext.Provider>
61
- );
62
-
63
- it('should fetch the owners list for the selected element', async done => {
64
- const Grandparent = () => <Parent />;
65
- const Parent = () => {
66
- return (
67
- <React.Fragment>
68
- <Child />
69
- <Child />
70
- </React.Fragment>
71
- );
72
- };
73
- const Child = () => null;
74
-
75
- utils.act(() =>
76
- ReactDOM.render(<Grandparent />, document.createElement('div')),
77
- );
78
-
79
- expect(store).toMatchSnapshot('mount');
80
-
81
- const parent = ((store.getElementAtIndex(1): any): Element);
82
- const firstChild = ((store.getElementAtIndex(2): any): Element);
83
-
84
- let didFinish = false;
85
-
86
- function Suspender({owner}) {
87
- const read = React.useContext(OwnersListContext);
88
- const owners = read(owner.id);
89
- expect(owners).toMatchSnapshot(
90
- `owners for "${(owner && owner.displayName) || ''}"`,
91
- );
92
- didFinish = true;
93
- return null;
94
- }
95
-
96
- await utils.actAsync(() =>
97
- TestRenderer.create(
98
- <Contexts defaultOwnerID={parent.id}>
99
- <React.Suspense fallback={null}>
100
- <Suspender owner={parent} />
101
- </React.Suspense>
102
- </Contexts>,
103
- ),
104
- );
105
- expect(didFinish).toBe(true);
106
-
107
- didFinish = false;
108
- await utils.actAsync(() =>
109
- TestRenderer.create(
110
- <Contexts defaultOwnerID={firstChild.id}>
111
- <React.Suspense fallback={null}>
112
- <Suspender owner={firstChild} />
113
- </React.Suspense>
114
- </Contexts>,
115
- ),
116
- );
117
- expect(didFinish).toBe(true);
118
-
119
- done();
120
- });
121
-
122
- it('should fetch the owners list for the selected element that includes filtered components', async done => {
123
- store.componentFilters = [utils.createDisplayNameFilter('^Parent$')];
124
-
125
- const Grandparent = () => <Parent />;
126
- const Parent = () => {
127
- return (
128
- <React.Fragment>
129
- <Child />
130
- <Child />
131
- </React.Fragment>
132
- );
133
- };
134
- const Child = () => null;
135
-
136
- utils.act(() =>
137
- ReactDOM.render(<Grandparent />, document.createElement('div')),
138
- );
139
-
140
- expect(store).toMatchSnapshot('mount');
141
-
142
- const firstChild = ((store.getElementAtIndex(1): any): Element);
143
-
144
- let didFinish = false;
145
-
146
- function Suspender({owner}) {
147
- const read = React.useContext(OwnersListContext);
148
- const owners = read(owner.id);
149
- expect(owners).toMatchSnapshot(
150
- `owners for "${(owner && owner.displayName) || ''}"`,
151
- );
152
- didFinish = true;
153
- return null;
154
- }
155
-
156
- await utils.actAsync(() =>
157
- TestRenderer.create(
158
- <Contexts defaultOwnerID={firstChild.id}>
159
- <React.Suspense fallback={null}>
160
- <Suspender owner={firstChild} />
161
- </React.Suspense>
162
- </Contexts>,
163
- ),
164
- );
165
- expect(didFinish).toBe(true);
166
-
167
- done();
168
- });
169
-
170
- it('should include the current element even if there are no other owners', async done => {
171
- store.componentFilters = [utils.createDisplayNameFilter('^Parent$')];
172
-
173
- const Grandparent = () => <Parent />;
174
- const Parent = () => null;
175
-
176
- utils.act(() =>
177
- ReactDOM.render(<Grandparent />, document.createElement('div')),
178
- );
179
-
180
- expect(store).toMatchSnapshot('mount');
181
-
182
- const grandparent = ((store.getElementAtIndex(0): any): Element);
183
-
184
- let didFinish = false;
185
-
186
- function Suspender({owner}) {
187
- const read = React.useContext(OwnersListContext);
188
- const owners = read(owner.id);
189
- expect(owners).toMatchSnapshot(
190
- `owners for "${(owner && owner.displayName) || ''}"`,
191
- );
192
- didFinish = true;
193
- return null;
194
- }
195
-
196
- await utils.actAsync(() =>
197
- TestRenderer.create(
198
- <Contexts defaultOwnerID={grandparent.id}>
199
- <React.Suspense fallback={null}>
200
- <Suspender owner={grandparent} />
201
- </React.Suspense>
202
- </Contexts>,
203
- ),
204
- );
205
- expect(didFinish).toBe(true);
206
-
207
- done();
208
- });
209
-});
packages/react-devtools-shared/src/__tests__/profilerContext-test.js
deleted
-354
@@ -1,354 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import typeof ReactTestRenderer from 'react-test-renderer';
11
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
12
-import type {Context} from 'react-devtools-shared/src/devtools/views/Profiler/ProfilerContext';
13
-import type {DispatcherContext} from 'react-devtools-shared/src/devtools/views/Components/TreeContext';
14
-import type Store from 'react-devtools-shared/src/devtools/store';
15
-
16
-describe('ProfilerContext', () => {
17
- let React;
18
- let ReactDOM;
19
- let TestRenderer: ReactTestRenderer;
20
- let bridge: FrontendBridge;
21
- let store: Store;
22
- let utils;
23
-
24
- let BridgeContext;
25
- let ProfilerContext;
26
- let ProfilerContextController;
27
- let StoreContext;
28
- let TreeContextController;
29
- let TreeDispatcherContext;
30
- let TreeStateContext;
31
-
32
- beforeEach(() => {
33
- utils = require('./utils');
34
- utils.beforeEachProfiling();
35
-
36
- bridge = global.bridge;
37
- store = global.store;
38
- store.collapseNodesByDefault = false;
39
- store.recordChangeDescriptions = true;
40
-
41
- React = require('react');
42
- ReactDOM = require('react-dom');
43
- TestRenderer = utils.requireTestRenderer();
44
-
45
- BridgeContext = require('react-devtools-shared/src/devtools/views/context')
46
- .BridgeContext;
47
- ProfilerContext = require('react-devtools-shared/src/devtools/views/Profiler/ProfilerContext')
48
- .ProfilerContext;
49
- ProfilerContextController = require('react-devtools-shared/src/devtools/views/Profiler/ProfilerContext')
50
- .ProfilerContextController;
51
- StoreContext = require('react-devtools-shared/src/devtools/views/context')
52
- .StoreContext;
53
- TreeContextController = require('react-devtools-shared/src/devtools/views/Components/TreeContext')
54
- .TreeContextController;
55
- TreeDispatcherContext = require('react-devtools-shared/src/devtools/views/Components/TreeContext')
56
- .TreeDispatcherContext;
57
- TreeStateContext = require('react-devtools-shared/src/devtools/views/Components/TreeContext')
58
- .TreeStateContext;
59
- });
60
-
61
- const Contexts = ({
62
- children = null,
63
- defaultSelectedElementID = null,
64
- defaultSelectedElementIndex = null,
65
- }: any) => (
66
- <BridgeContext.Provider value={bridge}>
67
- <StoreContext.Provider value={store}>
68
- <TreeContextController
69
- defaultSelectedElementID={defaultSelectedElementID}
70
- defaultSelectedElementIndex={defaultSelectedElementIndex}>
71
- <ProfilerContextController>{children}</ProfilerContextController>
72
- </TreeContextController>
73
- </StoreContext.Provider>
74
- </BridgeContext.Provider>
75
- );
76
-
77
- it('updates updates profiling support based on the attached roots', async done => {
78
- const Component = () => null;
79
-
80
- let context: Context = ((null: any): Context);
81
-
82
- function ContextReader() {
83
- context = React.useContext(ProfilerContext);
84
- return null;
85
- }
86
- await utils.actAsync(() => {
87
- TestRenderer.create(
88
- <Contexts>
89
- <ContextReader />
90
- </Contexts>,
91
- );
92
- });
93
-
94
- expect(context.supportsProfiling).toBe(false);
95
-
96
- const containerA = document.createElement('div');
97
- const containerB = document.createElement('div');
98
-
99
- await utils.actAsync(() => ReactDOM.render(<Component />, containerA));
100
- expect(context.supportsProfiling).toBe(true);
101
-
102
- await utils.actAsync(() => ReactDOM.render(<Component />, containerB));
103
- await utils.actAsync(() => ReactDOM.unmountComponentAtNode(containerA));
104
- expect(context.supportsProfiling).toBe(true);
105
-
106
- await utils.actAsync(() => ReactDOM.unmountComponentAtNode(containerB));
107
- expect(context.supportsProfiling).toBe(false);
108
-
109
- done();
110
- });
111
-
112
- it('should gracefully handle an empty profiling session (with no recorded commits)', async done => {
113
- const Example = () => null;
114
-
115
- utils.act(() =>
116
- ReactDOM.render(<Example />, document.createElement('div')),
117
- );
118
-
119
- let context: Context = ((null: any): Context);
120
-
121
- function ContextReader() {
122
- context = React.useContext(ProfilerContext);
123
- return null;
124
- }
125
-
126
- // Profile but don't record any updates.
127
- await utils.actAsync(() => store.profilerStore.startProfiling());
128
- await utils.actAsync(() => {
129
- TestRenderer.create(
130
- <Contexts>
131
- <ContextReader />
132
- </Contexts>,
133
- );
134
- });
135
- expect(context).not.toBeNull();
136
- expect(context.didRecordCommits).toBe(false);
137
- expect(context.isProcessingData).toBe(false);
138
- expect(context.isProfiling).toBe(true);
139
- expect(context.profilingData).toBe(null);
140
- await utils.actAsync(() => store.profilerStore.stopProfiling());
141
-
142
- expect(context).not.toBeNull();
143
- expect(context.didRecordCommits).toBe(false);
144
- expect(context.isProcessingData).toBe(false);
145
- expect(context.isProfiling).toBe(false);
146
- expect(context.profilingData).toBe(null);
147
-
148
- done();
149
- });
150
-
151
- it('should auto-select the root ID matching the Components tab selection if it has profiling data', async done => {
152
- const Parent = () => <Child />;
153
- const Child = () => null;
154
-
155
- const containerOne = document.createElement('div');
156
- const containerTwo = document.createElement('div');
157
- utils.act(() => ReactDOM.render(<Parent />, containerOne));
158
- utils.act(() => ReactDOM.render(<Parent />, containerTwo));
159
- expect(store).toMatchSnapshot('mounted');
160
-
161
- // Profile and record updates to both roots.
162
- await utils.actAsync(() => store.profilerStore.startProfiling());
163
- await utils.actAsync(() => ReactDOM.render(<Parent />, containerOne));
164
- await utils.actAsync(() => ReactDOM.render(<Parent />, containerTwo));
165
- await utils.actAsync(() => store.profilerStore.stopProfiling());
166
-
167
- let context: Context = ((null: any): Context);
168
- function ContextReader() {
169
- context = React.useContext(ProfilerContext);
170
- return null;
171
- }
172
-
173
- // Select an element within the second root.
174
- await utils.actAsync(() =>
175
- TestRenderer.create(
176
- <Contexts
177
- defaultSelectedElementID={store.getElementIDAtIndex(3)}
178
- defaultSelectedElementIndex={3}>
179
- <ContextReader />
180
- </Contexts>,
181
- ),
182
- );
183
-
184
- expect(context).not.toBeNull();
185
- expect(context.rootID).toBe(
186
- store.getRootIDForElement(((store.getElementIDAtIndex(3): any): number)),
187
- );
188
-
189
- done();
190
- });
191
-
192
- it('should not select the root ID matching the Components tab selection if it has no profiling data', async done => {
193
- const Parent = () => <Child />;
194
- const Child = () => null;
195
-
196
- const containerOne = document.createElement('div');
197
- const containerTwo = document.createElement('div');
198
- utils.act(() => ReactDOM.render(<Parent />, containerOne));
199
- utils.act(() => ReactDOM.render(<Parent />, containerTwo));
200
- expect(store).toMatchSnapshot('mounted');
201
-
202
- // Profile and record updates to only the first root.
203
- await utils.actAsync(() => store.profilerStore.startProfiling());
204
- await utils.actAsync(() => ReactDOM.render(<Parent />, containerOne));
205
- await utils.actAsync(() => store.profilerStore.stopProfiling());
206
-
207
- let context: Context = ((null: any): Context);
208
- function ContextReader() {
209
- context = React.useContext(ProfilerContext);
210
- return null;
211
- }
212
-
213
- // Select an element within the second root.
214
- await utils.actAsync(() =>
215
- TestRenderer.create(
216
- <Contexts
217
- defaultSelectedElementID={store.getElementIDAtIndex(3)}
218
- defaultSelectedElementIndex={3}>
219
- <ContextReader />
220
- </Contexts>,
221
- ),
222
- );
223
-
224
- // Verify the default profiling root is the first one.
225
- expect(context).not.toBeNull();
226
- expect(context.rootID).toBe(
227
- store.getRootIDForElement(((store.getElementIDAtIndex(0): any): number)),
228
- );
229
-
230
- done();
231
- });
232
-
233
- it('should maintain root selection between profiling sessions so long as there is data for that root', async done => {
234
- const Parent = () => <Child />;
235
- const Child = () => null;
236
-
237
- const containerA = document.createElement('div');
238
- const containerB = document.createElement('div');
239
- utils.act(() => ReactDOM.render(<Parent />, containerA));
240
- utils.act(() => ReactDOM.render(<Parent />, containerB));
241
- expect(store).toMatchSnapshot('mounted');
242
-
243
- // Profile and record updates.
244
- await utils.actAsync(() => store.profilerStore.startProfiling());
245
- await utils.actAsync(() => ReactDOM.render(<Parent />, containerA));
246
- await utils.actAsync(() => ReactDOM.render(<Parent />, containerB));
247
- await utils.actAsync(() => store.profilerStore.stopProfiling());
248
-
249
- let context: Context = ((null: any): Context);
250
- let dispatch: DispatcherContext = ((null: any): DispatcherContext);
251
- let selectedElementID = null;
252
- function ContextReader() {
253
- context = React.useContext(ProfilerContext);
254
- dispatch = React.useContext(TreeDispatcherContext);
255
- selectedElementID = React.useContext(TreeStateContext).selectedElementID;
256
- return null;
257
- }
258
-
259
- const id = ((store.getElementIDAtIndex(3): any): number);
260
-
261
- // Select an element within the second root.
262
- await utils.actAsync(() =>
263
- TestRenderer.create(
264
- <Contexts defaultSelectedElementID={id} defaultSelectedElementIndex={3}>
265
- <ContextReader />
266
- </Contexts>,
267
- ),
268
- );
269
-
270
- expect(selectedElementID).toBe(id);
271
-
272
- // Profile and record more updates to both roots
273
- await utils.actAsync(() => store.profilerStore.startProfiling());
274
- await utils.actAsync(() => ReactDOM.render(<Parent />, containerA));
275
- await utils.actAsync(() => ReactDOM.render(<Parent />, containerB));
276
- await utils.actAsync(() => store.profilerStore.stopProfiling());
277
-
278
- const otherID = ((store.getElementIDAtIndex(0): any): number);
279
-
280
- // Change the selected element within a the Components tab.
281
- utils.act(() => dispatch({type: 'SELECT_ELEMENT_AT_INDEX', payload: 0}));
282
-
283
- // Verify that the initial Profiler root selection is maintained.
284
- expect(selectedElementID).toBe(otherID);
285
- expect(context).not.toBeNull();
286
- expect(context.rootID).toBe(store.getRootIDForElement(id));
287
-
288
- done();
289
- });
290
-
291
- it('should sync selected element in the Components tab too, provided the element is a match', async done => {
292
- const GrandParent = ({includeChild}) => (
293
- <Parent includeChild={includeChild} />
294
- );
295
- const Parent = ({includeChild}) => (includeChild ? <Child /> : null);
296
- const Child = () => null;
297
-
298
- const container = document.createElement('div');
299
- utils.act(() =>
300
- ReactDOM.render(<GrandParent includeChild={true} />, container),
301
- );
302
- expect(store).toMatchSnapshot('mounted');
303
-
304
- const parentID = ((store.getElementIDAtIndex(1): any): number);
305
- const childID = ((store.getElementIDAtIndex(2): any): number);
306
-
307
- // Profile and record updates.
308
- await utils.actAsync(() => store.profilerStore.startProfiling());
309
- await utils.actAsync(() =>
310
- ReactDOM.render(<GrandParent includeChild={true} />, container),
311
- );
312
- await utils.actAsync(() =>
313
- ReactDOM.render(<GrandParent includeChild={false} />, container),
314
- );
315
- await utils.actAsync(() => store.profilerStore.stopProfiling());
316
-
317
- expect(store).toMatchSnapshot('updated');
318
-
319
- let context: Context = ((null: any): Context);
320
- let selectedElementID = null;
321
- function ContextReader() {
322
- context = React.useContext(ProfilerContext);
323
- selectedElementID = React.useContext(TreeStateContext).selectedElementID;
324
- return null;
325
- }
326
-
327
- await utils.actAsync(() =>
328
- TestRenderer.create(
329
- <Contexts>
330
- <ContextReader />
331
- </Contexts>,
332
- ),
333
- );
334
- expect(selectedElementID).toBeNull();
335
-
336
- // Select an element in the Profiler tab and verify that the selection is synced to the Components tab.
337
- await utils.actAsync(() => context.selectFiber(parentID, 'Parent'));
338
- expect(selectedElementID).toBe(parentID);
339
-
340
- // We expect a "no element found" warning.
341
- // Let's hide it from the test console though.
342
- spyOn(console, 'warn');
343
-
344
- // Select an unmounted element and verify no Components tab selection doesn't change.
345
- await utils.actAsync(() => context.selectFiber(childID, 'Child'));
346
- expect(selectedElementID).toBe(parentID);
347
-
348
- expect(console.warn).toHaveBeenCalledWith(
349
- `No element found with id "${childID}"`,
350
- );
351
-
352
- done();
353
- });
354
-});
packages/react-devtools-shared/src/__tests__/profilerStore-test.js
deleted
-82
@@ -1,82 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type Store from 'react-devtools-shared/src/devtools/store';
11
-
12
-describe('ProfilerStore', () => {
13
- let React;
14
- let ReactDOM;
15
- let store: Store;
16
- let utils;
17
-
18
- beforeEach(() => {
19
- utils = require('./utils');
20
- utils.beforeEachProfiling();
21
-
22
- store = global.store;
23
- store.collapseNodesByDefault = false;
24
- store.recordChangeDescriptions = true;
25
-
26
- React = require('react');
27
- ReactDOM = require('react-dom');
28
- });
29
-
30
- it('should not remove profiling data when roots are unmounted', async () => {
31
- const Parent = ({count}) =>
32
- new Array(count)
33
- .fill(true)
34
- .map((_, index) => <Child key={index} duration={index} />);
35
- const Child = () => <div>Hi!</div>;
36
-
37
- const containerA = document.createElement('div');
38
- const containerB = document.createElement('div');
39
-
40
- utils.act(() => {
41
- ReactDOM.render(<Parent key="A" count={3} />, containerA);
42
- ReactDOM.render(<Parent key="B" count={2} />, containerB);
43
- });
44
-
45
- utils.act(() => store.profilerStore.startProfiling());
46
-
47
- utils.act(() => {
48
- ReactDOM.render(<Parent key="A" count={4} />, containerA);
49
- ReactDOM.render(<Parent key="B" count={1} />, containerB);
50
- });
51
-
52
- utils.act(() => store.profilerStore.stopProfiling());
53
-
54
- const rootA = store.roots[0];
55
- const rootB = store.roots[1];
56
-
57
- utils.act(() => ReactDOM.unmountComponentAtNode(containerB));
58
-
59
- expect(store.profilerStore.getDataForRoot(rootA)).not.toBeNull();
60
-
61
- utils.act(() => ReactDOM.unmountComponentAtNode(containerA));
62
-
63
- expect(store.profilerStore.getDataForRoot(rootB)).not.toBeNull();
64
- });
65
-
66
- it('should not allow new/saved profiling data to be set while profiling is in progress', () => {
67
- utils.act(() => store.profilerStore.startProfiling());
68
- const fauxProfilingData = {
69
- dataForRoots: new Map(),
70
- };
71
- spyOn(console, 'warn');
72
- store.profilerStore.profilingData = fauxProfilingData;
73
- expect(store.profilerStore.profilingData).not.toBe(fauxProfilingData);
74
- expect(console.warn).toHaveBeenCalledTimes(1);
75
- expect(console.warn).toHaveBeenCalledWith(
76
- 'Profiling data cannot be updated while profiling is in progress.',
77
- );
78
- utils.act(() => store.profilerStore.stopProfiling());
79
- store.profilerStore.profilingData = fauxProfilingData;
80
- expect(store.profilerStore.profilingData).toBe(fauxProfilingData);
81
- });
82
-});
packages/react-devtools-shared/src/__tests__/profilingCache-test.js
deleted
-575
@@ -1,575 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import typeof ReactTestRenderer from 'react-test-renderer';
11
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
12
-import type Store from 'react-devtools-shared/src/devtools/store';
13
-
14
-describe('ProfilingCache', () => {
15
- let PropTypes;
16
- let React;
17
- let ReactDOM;
18
- let Scheduler;
19
- let SchedulerTracing;
20
- let TestRenderer: ReactTestRenderer;
21
- let bridge: FrontendBridge;
22
- let store: Store;
23
- let utils;
24
-
25
- beforeEach(() => {
26
- utils = require('./utils');
27
- utils.beforeEachProfiling();
28
-
29
- bridge = global.bridge;
30
- store = global.store;
31
- store.collapseNodesByDefault = false;
32
- store.recordChangeDescriptions = true;
33
-
34
- PropTypes = require('prop-types');
35
- React = require('react');
36
- ReactDOM = require('react-dom');
37
- Scheduler = require('scheduler');
38
- SchedulerTracing = require('scheduler/tracing');
39
- TestRenderer = utils.requireTestRenderer();
40
- });
41
-
42
- it('should collect data for each root (including ones added or mounted after profiling started)', () => {
43
- const Parent = ({count}) => {
44
- Scheduler.unstable_advanceTime(10);
45
- const children = new Array(count)
46
- .fill(true)
47
- .map((_, index) => <Child key={index} duration={index} />);
48
- return (
49
- <React.Fragment>
50
- {children}
51
- <MemoizedChild duration={1} />
52
- </React.Fragment>
53
- );
54
- };
55
- const Child = ({duration}) => {
56
- Scheduler.unstable_advanceTime(duration);
57
- return null;
58
- };
59
- const MemoizedChild = React.memo(Child);
60
-
61
- const containerA = document.createElement('div');
62
- const containerB = document.createElement('div');
63
- const containerC = document.createElement('div');
64
-
65
- utils.act(() => ReactDOM.render(<Parent count={2} />, containerA));
66
- utils.act(() => ReactDOM.render(<Parent count={1} />, containerB));
67
- utils.act(() => store.profilerStore.startProfiling());
68
- utils.act(() => ReactDOM.render(<Parent count={3} />, containerA));
69
- utils.act(() => ReactDOM.render(<Parent count={1} />, containerC));
70
- utils.act(() => ReactDOM.render(<Parent count={1} />, containerA));
71
- utils.act(() => ReactDOM.unmountComponentAtNode(containerB));
72
- utils.act(() => ReactDOM.render(<Parent count={0} />, containerA));
73
- utils.act(() => store.profilerStore.stopProfiling());
74
-
75
- let allProfilingDataForRoots = [];
76
-
77
- function Validator({previousProfilingDataForRoot, rootID}) {
78
- const profilingDataForRoot = store.profilerStore.getDataForRoot(rootID);
79
- if (previousProfilingDataForRoot != null) {
80
- expect(profilingDataForRoot).toEqual(previousProfilingDataForRoot);
81
- } else {
82
- expect(profilingDataForRoot).toMatchSnapshot(
83
- `Data for root ${profilingDataForRoot.displayName}`,
84
- );
85
- }
86
- allProfilingDataForRoots.push(profilingDataForRoot);
87
- return null;
88
- }
89
-
90
- const dataForRoots =
91
- store.profilerStore.profilingData !== null
92
- ? store.profilerStore.profilingData.dataForRoots
93
- : null;
94
-
95
- expect(dataForRoots).not.toBeNull();
96
-
97
- if (dataForRoots !== null) {
98
- dataForRoots.forEach(dataForRoot => {
99
- utils.act(() =>
100
- TestRenderer.create(
101
- <Validator
102
- previousProfilingDataForRoot={null}
103
- rootID={dataForRoot.rootID}
104
- />,
105
- ),
106
- );
107
- });
108
- }
109
-
110
- expect(allProfilingDataForRoots).toHaveLength(3);
111
-
112
- utils.exportImportHelper(bridge, store);
113
-
114
- allProfilingDataForRoots.forEach(profilingDataForRoot => {
115
- utils.act(() =>
116
- TestRenderer.create(
117
- <Validator
118
- previousProfilingDataForRoot={profilingDataForRoot}
119
- rootID={profilingDataForRoot.rootID}
120
- />,
121
- ),
122
- );
123
- });
124
- });
125
-
126
- it('should collect data for each commit', () => {
127
- const Parent = ({count}) => {
128
- Scheduler.unstable_advanceTime(10);
129
- const children = new Array(count)
130
- .fill(true)
131
- .map((_, index) => <Child key={index} duration={index} />);
132
- return (
133
- <React.Fragment>
134
- {children}
135
- <MemoizedChild duration={1} />
136
- </React.Fragment>
137
- );
138
- };
139
- const Child = ({duration}) => {
140
- Scheduler.unstable_advanceTime(duration);
141
- return null;
142
- };
143
- const MemoizedChild = React.memo(Child);
144
-
145
- const container = document.createElement('div');
146
-
147
- utils.act(() => store.profilerStore.startProfiling());
148
- utils.act(() => ReactDOM.render(<Parent count={2} />, container));
149
- utils.act(() => ReactDOM.render(<Parent count={3} />, container));
150
- utils.act(() => ReactDOM.render(<Parent count={1} />, container));
151
- utils.act(() => ReactDOM.render(<Parent count={0} />, container));
152
- utils.act(() => store.profilerStore.stopProfiling());
153
-
154
- const allCommitData = [];
155
-
156
- function Validator({commitIndex, previousCommitDetails, rootID}) {
157
- const commitData = store.profilerStore.getCommitData(rootID, commitIndex);
158
- if (previousCommitDetails != null) {
159
- expect(commitData).toEqual(previousCommitDetails);
160
- } else {
161
- allCommitData.push(commitData);
162
- expect(commitData).toMatchSnapshot(
163
- `CommitDetails commitIndex: ${commitIndex}`,
164
- );
165
- }
166
- return null;
167
- }
168
-
169
- const rootID = store.roots[0];
170
-
171
- for (let commitIndex = 0; commitIndex < 4; commitIndex++) {
172
- utils.act(() => {
173
- TestRenderer.create(
174
- <Validator
175
- commitIndex={commitIndex}
176
- previousCommitDetails={null}
177
- rootID={rootID}
178
- />,
179
- );
180
- });
181
- }
182
-
183
- expect(allCommitData).toHaveLength(4);
184
-
185
- utils.exportImportHelper(bridge, store);
186
-
187
- for (let commitIndex = 0; commitIndex < 4; commitIndex++) {
188
- utils.act(() => {
189
- TestRenderer.create(
190
- <Validator
191
- commitIndex={commitIndex}
192
- previousCommitDetails={allCommitData[commitIndex]}
193
- rootID={rootID}
194
- />,
195
- );
196
- });
197
- }
198
- });
199
-
200
- it('should record changed props/state/context/hooks', () => {
201
- let instance = null;
202
-
203
- const ModernContext = React.createContext(0);
204
-
205
- class LegacyContextProvider extends React.Component<
206
- any,
207
- {|count: number|},
208
- > {
209
- static childContextTypes = {
210
- count: PropTypes.number,
211
- };
212
- state = {count: 0};
213
- getChildContext() {
214
- return this.state;
215
- }
216
- render() {
217
- instance = this;
218
- return (
219
- <ModernContext.Provider value={this.state.count}>
220
- <React.Fragment>
221
- <ModernContextConsumer />
222
- <LegacyContextConsumer />
223
- </React.Fragment>
224
- </ModernContext.Provider>
225
- );
226
- }
227
- }
228
-
229
- const FunctionComponentWithHooks = ({count}) => {
230
- React.useMemo(() => count, [count]);
231
- return null;
232
- };
233
-
234
- class ModernContextConsumer extends React.Component<any> {
235
- static contextType = ModernContext;
236
- render() {
237
- return <FunctionComponentWithHooks count={this.context} />;
238
- }
239
- }
240
-
241
- class LegacyContextConsumer extends React.Component<any> {
242
- static contextTypes = {
243
- count: PropTypes.number,
244
- };
245
- render() {
246
- return <FunctionComponentWithHooks count={this.context.count} />;
247
- }
248
- }
249
-
250
- const container = document.createElement('div');
251
-
252
- utils.act(() => store.profilerStore.startProfiling());
253
- utils.act(() => ReactDOM.render(<LegacyContextProvider />, container));
254
- expect(instance).not.toBeNull();
255
- utils.act(() => (instance: any).setState({count: 1}));
256
- utils.act(() =>
257
- ReactDOM.render(<LegacyContextProvider foo={123} />, container),
258
- );
259
- utils.act(() =>
260
- ReactDOM.render(<LegacyContextProvider bar="abc" />, container),
261
- );
262
- utils.act(() => ReactDOM.render(<LegacyContextProvider />, container));
263
- utils.act(() => store.profilerStore.stopProfiling());
264
-
265
- const allCommitData = [];
266
-
267
- function Validator({commitIndex, previousCommitDetails, rootID}) {
268
- const commitData = store.profilerStore.getCommitData(rootID, commitIndex);
269
- if (previousCommitDetails != null) {
270
- expect(commitData).toEqual(previousCommitDetails);
271
- } else {
272
- allCommitData.push(commitData);
273
- expect(commitData).toMatchSnapshot(
274
- `CommitDetails commitIndex: ${commitIndex}`,
275
- );
276
- }
277
- return null;
278
- }
279
-
280
- const rootID = store.roots[0];
281
-
282
- for (let commitIndex = 0; commitIndex < 5; commitIndex++) {
283
- utils.act(() => {
284
- TestRenderer.create(
285
- <Validator
286
- commitIndex={commitIndex}
287
- previousCommitDetails={null}
288
- rootID={rootID}
289
- />,
290
- );
291
- });
292
- }
293
-
294
- expect(allCommitData).toHaveLength(5);
295
-
296
- utils.exportImportHelper(bridge, store);
297
-
298
- for (let commitIndex = 0; commitIndex < 5; commitIndex++) {
299
- utils.act(() => {
300
- TestRenderer.create(
301
- <Validator
302
- commitIndex={commitIndex}
303
- previousCommitDetails={allCommitData[commitIndex]}
304
- rootID={rootID}
305
- />,
306
- );
307
- });
308
- }
309
- });
310
-
311
- it('should calculate a self duration based on actual children (not filtered children)', () => {
312
- store.componentFilters = [utils.createDisplayNameFilter('^Parent$')];
313
-
314
- const Grandparent = () => {
315
- Scheduler.unstable_advanceTime(10);
316
- return (
317
- <React.Fragment>
318
- <Parent key="one" />
319
- <Parent key="two" />
320
- </React.Fragment>
321
- );
322
- };
323
- const Parent = () => {
324
- Scheduler.unstable_advanceTime(2);
325
- return <Child />;
326
- };
327
- const Child = () => {
328
- Scheduler.unstable_advanceTime(1);
329
- return null;
330
- };
331
-
332
- utils.act(() => store.profilerStore.startProfiling());
333
- utils.act(() =>
334
- ReactDOM.render(<Grandparent />, document.createElement('div')),
335
- );
336
- utils.act(() => store.profilerStore.stopProfiling());
337
-
338
- let commitData = null;
339
-
340
- function Validator({commitIndex, rootID}) {
341
- commitData = store.profilerStore.getCommitData(rootID, commitIndex);
342
- expect(commitData).toMatchSnapshot(
343
- `CommitDetails with filtered self durations`,
344
- );
345
- return null;
346
- }
347
-
348
- const rootID = store.roots[0];
349
-
350
- utils.act(() => {
351
- TestRenderer.create(<Validator commitIndex={0} rootID={rootID} />);
352
- });
353
-
354
- expect(commitData).not.toBeNull();
355
- });
356
-
357
- it('should calculate self duration correctly for suspended views', async done => {
358
- let data;
359
- const getData = () => {
360
- if (data) {
361
- return data;
362
- } else {
363
- throw new Promise(resolve => {
364
- data = 'abc';
365
- resolve(data);
366
- });
367
- }
368
- };
369
-
370
- const Parent = () => {
371
- Scheduler.unstable_advanceTime(10);
372
- return (
373
- <React.Suspense fallback={<Fallback />}>
374
- <Async />
375
- </React.Suspense>
376
- );
377
- };
378
- const Fallback = () => {
379
- Scheduler.unstable_advanceTime(2);
380
- return 'Fallback...';
381
- };
382
- const Async = () => {
383
- Scheduler.unstable_advanceTime(3);
384
- return getData();
385
- };
386
-
387
- utils.act(() => store.profilerStore.startProfiling());
388
- await utils.actAsync(() =>
389
- ReactDOM.render(<Parent />, document.createElement('div')),
390
- );
391
- utils.act(() => store.profilerStore.stopProfiling());
392
-
393
- const allCommitData = [];
394
-
395
- function Validator({commitIndex, rootID}) {
396
- const commitData = store.profilerStore.getCommitData(rootID, commitIndex);
397
- allCommitData.push(commitData);
398
- expect(commitData).toMatchSnapshot(
399
- `CommitDetails with filtered self durations`,
400
- );
401
- return null;
402
- }
403
-
404
- const rootID = store.roots[0];
405
-
406
- for (let commitIndex = 0; commitIndex < 2; commitIndex++) {
407
- utils.act(() => {
408
- TestRenderer.create(
409
- <Validator commitIndex={commitIndex} rootID={rootID} />,
410
- );
411
- });
412
- }
413
-
414
- expect(allCommitData).toHaveLength(2);
415
-
416
- done();
417
- });
418
-
419
- it('should collect data for each rendered fiber', () => {
420
- const Parent = ({count}) => {
421
- Scheduler.unstable_advanceTime(10);
422
- const children = new Array(count)
423
- .fill(true)
424
- .map((_, index) => <Child key={index} duration={index} />);
425
- return (
426
- <React.Fragment>
427
- {children}
428
- <MemoizedChild duration={1} />
429
- </React.Fragment>
430
- );
431
- };
432
- const Child = ({duration}) => {
433
- Scheduler.unstable_advanceTime(duration);
434
- return null;
435
- };
436
- const MemoizedChild = React.memo(Child);
437
-
438
- const container = document.createElement('div');
439
-
440
- utils.act(() => store.profilerStore.startProfiling());
441
- utils.act(() => ReactDOM.render(<Parent count={1} />, container));
442
- utils.act(() => ReactDOM.render(<Parent count={2} />, container));
443
- utils.act(() => ReactDOM.render(<Parent count={3} />, container));
444
- utils.act(() => store.profilerStore.stopProfiling());
445
-
446
- const allFiberCommits = [];
447
-
448
- function Validator({fiberID, previousFiberCommits, rootID}) {
449
- const fiberCommits = store.profilerStore.profilingCache.getFiberCommits({
450
- fiberID,
451
- rootID,
452
- });
453
- if (previousFiberCommits != null) {
454
- expect(fiberCommits).toEqual(previousFiberCommits);
455
- } else {
456
- allFiberCommits.push(fiberCommits);
457
- expect(fiberCommits).toMatchSnapshot(
458
- `FiberCommits: element ${fiberID}`,
459
- );
460
- }
461
- return null;
462
- }
463
-
464
- const rootID = store.roots[0];
465
-
466
- for (let index = 0; index < store.numElements; index++) {
467
- utils.act(() => {
468
- const fiberID = store.getElementIDAtIndex(index);
469
- if (fiberID == null) {
470
- throw Error(`Unexpected null ID for element at index ${index}`);
471
- }
472
- TestRenderer.create(
473
- <Validator
474
- fiberID={fiberID}
475
- previousFiberCommits={null}
476
- rootID={rootID}
477
- />,
478
- );
479
- });
480
- }
481
-
482
- expect(allFiberCommits).toHaveLength(store.numElements);
483
-
484
- utils.exportImportHelper(bridge, store);
485
-
486
- for (let index = 0; index < store.numElements; index++) {
487
- utils.act(() => {
488
- const fiberID = store.getElementIDAtIndex(index);
489
- if (fiberID == null) {
490
- throw Error(`Unexpected null ID for element at index ${index}`);
491
- }
492
- TestRenderer.create(
493
- <Validator
494
- fiberID={fiberID}
495
- previousFiberCommits={allFiberCommits[index]}
496
- rootID={rootID}
497
- />,
498
- );
499
- });
500
- }
501
- });
502
-
503
- it('should report every traced interaction', () => {
504
- const Parent = ({count}) => {
505
- Scheduler.unstable_advanceTime(10);
506
- const children = new Array(count)
507
- .fill(true)
508
- .map((_, index) => <Child key={index} duration={index} />);
509
- return (
510
- <React.Fragment>
511
- {children}
512
- <MemoizedChild duration={1} />
513
- </React.Fragment>
514
- );
515
- };
516
- const Child = ({duration}) => {
517
- Scheduler.unstable_advanceTime(duration);
518
- return null;
519
- };
520
- const MemoizedChild = React.memo(Child);
521
-
522
- const container = document.createElement('div');
523
-
524
- utils.act(() => store.profilerStore.startProfiling());
525
- utils.act(() =>
526
- SchedulerTracing.unstable_trace(
527
- 'mount: one child',
528
- Scheduler.unstable_now(),
529
- () => ReactDOM.render(<Parent count={1} />, container),
530
- ),
531
- );
532
- utils.act(() =>
533
- SchedulerTracing.unstable_trace(
534
- 'update: two children',
535
- Scheduler.unstable_now(),
536
- () => ReactDOM.render(<Parent count={2} />, container),
537
- ),
538
- );
539
- utils.act(() => store.profilerStore.stopProfiling());
540
-
541
- let interactions = null;
542
-
543
- function Validator({previousInteractions, rootID}) {
544
- interactions = store.profilerStore.profilingCache.getInteractionsChartData(
545
- {
546
- rootID,
547
- },
548
- ).interactions;
549
- if (previousInteractions != null) {
550
- expect(interactions).toEqual(previousInteractions);
551
- } else {
552
- expect(interactions).toMatchSnapshot('Interactions');
553
- }
554
- return null;
555
- }
556
-
557
- const rootID = store.roots[0];
558
-
559
- utils.act(() =>
560
- TestRenderer.create(
561
- <Validator previousInteractions={null} rootID={rootID} />,
562
- ),
563
- );
564
-
565
- expect(interactions).not.toBeNull();
566
-
567
- utils.exportImportHelper(bridge, store);
568
-
569
- utils.act(() =>
570
- TestRenderer.create(
571
- <Validator previousInteractions={interactions} rootID={rootID} />,
572
- ),
573
- );
574
- });
575
-});
packages/react-devtools-shared/src/__tests__/profilingCharts-test.js
deleted
-249
@@ -1,249 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import typeof TestRendererType from 'react-test-renderer';
11
-import type Store from 'react-devtools-shared/src/devtools/store';
12
-
13
-describe('profiling charts', () => {
14
- let React;
15
- let ReactDOM;
16
- let Scheduler;
17
- let SchedulerTracing;
18
- let TestRenderer: TestRendererType;
19
- let store: Store;
20
- let utils;
21
-
22
- beforeEach(() => {
23
- utils = require('./utils');
24
- utils.beforeEachProfiling();
25
-
26
- store = global.store;
27
- store.collapseNodesByDefault = false;
28
- store.recordChangeDescriptions = true;
29
-
30
- React = require('react');
31
- ReactDOM = require('react-dom');
32
- Scheduler = require('scheduler');
33
- SchedulerTracing = require('scheduler/tracing');
34
- TestRenderer = utils.requireTestRenderer();
35
- });
36
-
37
- describe('flamegraph chart', () => {
38
- it('should contain valid data', () => {
39
- const Parent = (_: {||}) => {
40
- Scheduler.unstable_advanceTime(10);
41
- return (
42
- <React.Fragment>
43
- <Child key="first" duration={3} />
44
- <Child key="second" duration={2} />
45
- <Child key="third" duration={0} />
46
- </React.Fragment>
47
- );
48
- };
49
-
50
- // Memoize children to verify that chart doesn't include in the update.
51
- const Child = React.memo(function Child({duration}) {
52
- Scheduler.unstable_advanceTime(duration);
53
- return null;
54
- });
55
-
56
- const container = document.createElement('div');
57
-
58
- utils.act(() => store.profilerStore.startProfiling());
59
- utils.act(() =>
60
- SchedulerTracing.unstable_trace('mount', Scheduler.unstable_now(), () =>
61
- ReactDOM.render(<Parent />, container),
62
- ),
63
- );
64
- utils.act(() =>
65
- SchedulerTracing.unstable_trace(
66
- 'update',
67
- Scheduler.unstable_now(),
68
- () => ReactDOM.render(<Parent />, container),
69
- ),
70
- );
71
- utils.act(() => store.profilerStore.stopProfiling());
72
-
73
- let renderFinished = false;
74
-
75
- function Validator({commitIndex, rootID}) {
76
- const commitTree = store.profilerStore.profilingCache.getCommitTree({
77
- commitIndex,
78
- rootID,
79
- });
80
- const chartData = store.profilerStore.profilingCache.getFlamegraphChartData(
81
- {
82
- commitIndex,
83
- commitTree,
84
- rootID,
85
- },
86
- );
87
- expect(commitTree).toMatchSnapshot(`${commitIndex}: CommitTree`);
88
- expect(chartData).toMatchSnapshot(
89
- `${commitIndex}: FlamegraphChartData`,
90
- );
91
- renderFinished = true;
92
- return null;
93
- }
94
-
95
- const rootID = store.roots[0];
96
-
97
- for (let commitIndex = 0; commitIndex < 2; commitIndex++) {
98
- renderFinished = false;
99
-
100
- utils.act(() => {
101
- TestRenderer.create(
102
- <Validator commitIndex={commitIndex} rootID={rootID} />,
103
- );
104
- });
105
-
106
- expect(renderFinished).toBe(true);
107
- }
108
-
109
- expect(renderFinished).toBe(true);
110
- });
111
- });
112
-
113
- describe('ranked chart', () => {
114
- it('should contain valid data', () => {
115
- const Parent = (_: {||}) => {
116
- Scheduler.unstable_advanceTime(10);
117
- return (
118
- <React.Fragment>
119
- <Child key="first" duration={3} />
120
- <Child key="second" duration={2} />
121
- <Child key="third" duration={0} />
122
- </React.Fragment>
123
- );
124
- };
125
-
126
- // Memoize children to verify that chart doesn't include in the update.
127
- const Child = React.memo(function Child({duration}) {
128
- Scheduler.unstable_advanceTime(duration);
129
- return null;
130
- });
131
-
132
- const container = document.createElement('div');
133
-
134
- utils.act(() => store.profilerStore.startProfiling());
135
- utils.act(() =>
136
- SchedulerTracing.unstable_trace('mount', Scheduler.unstable_now(), () =>
137
- ReactDOM.render(<Parent />, container),
138
- ),
139
- );
140
- utils.act(() =>
141
- SchedulerTracing.unstable_trace(
142
- 'update',
143
- Scheduler.unstable_now(),
144
- () => ReactDOM.render(<Parent />, container),
145
- ),
146
- );
147
- utils.act(() => store.profilerStore.stopProfiling());
148
-
149
- let renderFinished = false;
150
-
151
- function Validator({commitIndex, rootID}) {
152
- const commitTree = store.profilerStore.profilingCache.getCommitTree({
153
- commitIndex,
154
- rootID,
155
- });
156
- const chartData = store.profilerStore.profilingCache.getRankedChartData(
157
- {
158
- commitIndex,
159
- commitTree,
160
- rootID,
161
- },
162
- );
163
- expect(commitTree).toMatchSnapshot(`${commitIndex}: CommitTree`);
164
- expect(chartData).toMatchSnapshot(`${commitIndex}: RankedChartData`);
165
- renderFinished = true;
166
- return null;
167
- }
168
-
169
- const rootID = store.roots[0];
170
-
171
- for (let commitIndex = 0; commitIndex < 2; commitIndex++) {
172
- renderFinished = false;
173
-
174
- utils.act(() => {
175
- TestRenderer.create(
176
- <Validator commitIndex={commitIndex} rootID={rootID} />,
177
- );
178
- });
179
-
180
- expect(renderFinished).toBe(true);
181
- }
182
- });
183
- });
184
-
185
- describe('interactions', () => {
186
- it('should contain valid data', () => {
187
- const Parent = (_: {||}) => {
188
- Scheduler.unstable_advanceTime(10);
189
- return (
190
- <React.Fragment>
191
- <Child key="first" duration={3} />
192
- <Child key="second" duration={2} />
193
- <Child key="third" duration={0} />
194
- </React.Fragment>
195
- );
196
- };
197
-
198
- // Memoize children to verify that chart doesn't include in the update.
199
- const Child = React.memo(function Child({duration}) {
200
- Scheduler.unstable_advanceTime(duration);
201
- return null;
202
- });
203
-
204
- const container = document.createElement('div');
205
-
206
- utils.act(() => store.profilerStore.startProfiling());
207
- utils.act(() =>
208
- SchedulerTracing.unstable_trace('mount', Scheduler.unstable_now(), () =>
209
- ReactDOM.render(<Parent />, container),
210
- ),
211
- );
212
- utils.act(() =>
213
- SchedulerTracing.unstable_trace(
214
- 'update',
215
- Scheduler.unstable_now(),
216
- () => ReactDOM.render(<Parent />, container),
217
- ),
218
- );
219
- utils.act(() => store.profilerStore.stopProfiling());
220
-
221
- let renderFinished = false;
222
-
223
- function Validator({commitIndex, rootID}) {
224
- const chartData = store.profilerStore.profilingCache.getInteractionsChartData(
225
- {
226
- rootID,
227
- },
228
- );
229
- expect(chartData).toMatchSnapshot('Interactions');
230
- renderFinished = true;
231
- return null;
232
- }
233
-
234
- const rootID = store.roots[0];
235
-
236
- for (let commitIndex = 0; commitIndex < 2; commitIndex++) {
237
- renderFinished = false;
238
-
239
- utils.act(() => {
240
- TestRenderer.create(
241
- <Validator commitIndex={commitIndex} rootID={rootID} />,
242
- );
243
- });
244
-
245
- expect(renderFinished).toBe(true);
246
- }
247
- });
248
- });
249
-});
packages/react-devtools-shared/src/__tests__/profilingCommitTreeBuilder-test.js
deleted
-82
@@ -1,82 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import typeof TestRendererType from 'react-test-renderer';
11
-import type Store from 'react-devtools-shared/src/devtools/store';
12
-
13
-describe('commit tree', () => {
14
- let React;
15
- let ReactDOM;
16
- let Scheduler;
17
- let TestRenderer: TestRendererType;
18
- let store: Store;
19
- let utils;
20
-
21
- beforeEach(() => {
22
- utils = require('./utils');
23
- utils.beforeEachProfiling();
24
-
25
- store = global.store;
26
- store.collapseNodesByDefault = false;
27
- store.recordChangeDescriptions = true;
28
-
29
- React = require('react');
30
- ReactDOM = require('react-dom');
31
- Scheduler = require('scheduler');
32
- TestRenderer = utils.requireTestRenderer();
33
- });
34
-
35
- it('should be able to rebuild the store tree for each commit', () => {
36
- const Parent = ({count}) => {
37
- Scheduler.unstable_advanceTime(10);
38
- return new Array(count)
39
- .fill(true)
40
- .map((_, index) => <Child key={index} />);
41
- };
42
- const Child = React.memo(function Child() {
43
- Scheduler.unstable_advanceTime(2);
44
- return null;
45
- });
46
-
47
- const container = document.createElement('div');
48
-
49
- utils.act(() => store.profilerStore.startProfiling());
50
- utils.act(() => ReactDOM.render(<Parent count={1} />, container));
51
- utils.act(() => ReactDOM.render(<Parent count={3} />, container));
52
- utils.act(() => ReactDOM.render(<Parent count={2} />, container));
53
- utils.act(() => ReactDOM.render(<Parent count={0} />, container));
54
- utils.act(() => store.profilerStore.stopProfiling());
55
-
56
- let renderFinished = false;
57
-
58
- function Validator({commitIndex, rootID}) {
59
- const commitTree = store.profilerStore.profilingCache.getCommitTree({
60
- commitIndex,
61
- rootID,
62
- });
63
- expect(commitTree).toMatchSnapshot(`${commitIndex}: CommitTree`);
64
- renderFinished = true;
65
- return null;
66
- }
67
-
68
- const rootID = store.roots[0];
69
-
70
- for (let commitIndex = 0; commitIndex < 4; commitIndex++) {
71
- renderFinished = false;
72
-
73
- utils.act(() => {
74
- TestRenderer.create(
75
- <Validator commitIndex={commitIndex} rootID={rootID} />,
76
- );
77
- });
78
-
79
- expect(renderFinished).toBe(true);
80
- }
81
- });
82
-});
packages/react-devtools-shared/src/__tests__/profilingUtils-test.js
deleted
-27
@@ -1,27 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-describe('profiling utils', () => {
11
- let utils;
12
-
13
- beforeEach(() => {
14
- utils = require('react-devtools-shared/src/devtools/views/Profiler/utils');
15
- });
16
-
17
- it('should throw if importing older/unsupported data', () => {
18
- expect(() =>
19
- utils.prepareProfilingDataFrontendFromExport(
20
- ({
21
- version: 0,
22
- dataForRoots: [],
23
- }: any),
24
- ),
25
- ).toThrow('Unsupported profiler export version "0"');
26
- });
27
-});
packages/react-devtools-shared/src/__tests__/setupEnv.js
deleted
-9
@@ -1,9 +0,0 @@
1
-'use strict';
2
-
3
-// DevTools stores preferences between sessions in localStorage
4
-if (!global.hasOwnProperty('localStorage')) {
5
- global.localStorage = require('local-storage-fallback').default;
6
-}
7
-
8
-// Mimic the global we set with Webpack's DefinePlugin
9
-global.__DEV__ = process.env.NODE_ENV !== 'production';
packages/react-devtools-shared/src/__tests__/setupTests.js
deleted
-94
@@ -1,94 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {
11
- BackendBridge,
12
- FrontendBridge,
13
-} from 'react-devtools-shared/src/bridge';
14
-
15
-const env = jasmine.getEnv();
16
-env.beforeEach(() => {
17
- // These files should be required (and re-reuired) before each test,
18
- // rather than imported at the head of the module.
19
- // That's because we reset modules between tests,
20
- // which disconnects the DevTool's cache from the current dispatcher ref.
21
- const Agent = require('react-devtools-shared/src/backend/agent').default;
22
- const {initBackend} = require('react-devtools-shared/src/backend');
23
- const Bridge = require('react-devtools-shared/src/bridge').default;
24
- const Store = require('react-devtools-shared/src/devtools/store').default;
25
- const {installHook} = require('react-devtools-shared/src/hook');
26
- const {
27
- getDefaultComponentFilters,
28
- saveComponentFilters,
29
- } = require('react-devtools-shared/src/utils');
30
-
31
- // Fake timers let us flush Bridge operations between setup and assertions.
32
- jest.useFakeTimers();
33
-
34
- const originalConsoleError = console.error;
35
- // $FlowFixMe
36
- console.error = (...args) => {
37
- const firstArg = args[0];
38
- if (firstArg === 'Warning: React DevTools encountered an error: %s') {
39
- // Rethrow errors from React.
40
- throw args[1];
41
- } else if (
42
- typeof firstArg === 'string' &&
43
- firstArg.startsWith("Warning: It looks like you're using the wrong act()")
44
- ) {
45
- // DevTools intentionally wraps updates with acts from both DOM and test-renderer,
46
- // since test updates are expected to impact both renderers.
47
- return;
48
- }
49
- originalConsoleError.apply(console, args);
50
- };
51
-
52
- // Initialize filters to a known good state.
53
- saveComponentFilters(getDefaultComponentFilters());
54
- global.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = getDefaultComponentFilters();
55
-
56
- installHook(global);
57
-
58
- const bridgeListeners = [];
59
- const bridge = new Bridge({
60
- listen(callback) {
61
- bridgeListeners.push(callback);
62
- return () => {
63
- const index = bridgeListeners.indexOf(callback);
64
- if (index >= 0) {
65
- bridgeListeners.splice(index, 1);
66
- }
67
- };
68
- },
69
- send(event: string, payload: any, transferable?: Array<any>) {
70
- bridgeListeners.forEach(callback => callback({event, payload}));
71
- },
72
- });
73
-
74
- const agent = new Agent(((bridge: any): BackendBridge));
75
-
76
- const hook = global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
77
-
78
- initBackend(hook, agent, global);
79
-
80
- const store = new Store(((bridge: any): FrontendBridge));
81
-
82
- global.agent = agent;
83
- global.bridge = bridge;
84
- global.store = store;
85
-});
86
-env.afterEach(() => {
87
- delete global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
88
-
89
- // It's important to reset modules between test runs;
90
- // Without this, ReactDOM won't re-inject itself into the new hook.
91
- // It's also important to reset after tests, rather than before,
92
- // so that we don't disconnect the ReactCurrentDispatcher ref.
93
- jest.resetModules();
94
-});
packages/react-devtools-shared/src/__tests__/store-test.js
deleted
-807
@@ -1,807 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-describe('Store', () => {
11
- let React;
12
- let ReactDOM;
13
- let agent;
14
- let act;
15
- let getRendererID;
16
- let store;
17
-
18
- beforeEach(() => {
19
- agent = global.agent;
20
- store = global.store;
21
-
22
- React = require('react');
23
- ReactDOM = require('react-dom');
24
-
25
- const utils = require('./utils');
26
- act = utils.act;
27
- getRendererID = utils.getRendererID;
28
- });
29
-
30
- it('should not allow a root node to be collapsed', () => {
31
- const Component = () => <div>Hi</div>;
32
-
33
- act(() =>
34
- ReactDOM.render(<Component count={4} />, document.createElement('div')),
35
- );
36
- expect(store).toMatchSnapshot('1: mount');
37
-
38
- expect(store.roots).toHaveLength(1);
39
-
40
- const rootID = store.roots[0];
41
-
42
- expect(() => store.toggleIsCollapsed(rootID, true)).toThrow(
43
- 'Root nodes cannot be collapsed',
44
- );
45
- });
46
-
47
- it('should properly handle a root with no visible nodes', () => {
48
- const Root = ({children}) => children;
49
-
50
- const container = document.createElement('div');
51
-
52
- act(() => ReactDOM.render(<Root>{null}</Root>, container));
53
- expect(store).toMatchSnapshot('1: mount');
54
-
55
- act(() => ReactDOM.render(<div />, container));
56
- expect(store).toMatchSnapshot('2: add host nodes');
57
- });
58
-
59
- describe('collapseNodesByDefault:false', () => {
60
- beforeEach(() => {
61
- store.collapseNodesByDefault = false;
62
- });
63
-
64
- it('should support mount and update operations', () => {
65
- const Grandparent = ({count}) => (
66
- <React.Fragment>
67
- <Parent count={count} />
68
- <Parent count={count} />
69
- </React.Fragment>
70
- );
71
- const Parent = ({count}) =>
72
- new Array(count).fill(true).map((_, index) => <Child key={index} />);
73
- const Child = () => <div>Hi!</div>;
74
-
75
- const container = document.createElement('div');
76
-
77
- act(() => ReactDOM.render(<Grandparent count={4} />, container));
78
- expect(store).toMatchSnapshot('1: mount');
79
-
80
- act(() => ReactDOM.render(<Grandparent count={2} />, container));
81
- expect(store).toMatchSnapshot('2: update');
82
-
83
- act(() => ReactDOM.unmountComponentAtNode(container));
84
- expect(store).toMatchSnapshot('3: unmount');
85
- });
86
-
87
- it('should support mount and update operations for multiple roots', () => {
88
- const Parent = ({count}) =>
89
- new Array(count).fill(true).map((_, index) => <Child key={index} />);
90
- const Child = () => <div>Hi!</div>;
91
-
92
- const containerA = document.createElement('div');
93
- const containerB = document.createElement('div');
94
-
95
- act(() => {
96
- ReactDOM.render(<Parent key="A" count={3} />, containerA);
97
- ReactDOM.render(<Parent key="B" count={2} />, containerB);
98
- });
99
- expect(store).toMatchSnapshot('1: mount');
100
-
101
- act(() => {
102
- ReactDOM.render(<Parent key="A" count={4} />, containerA);
103
- ReactDOM.render(<Parent key="B" count={1} />, containerB);
104
- });
105
- expect(store).toMatchSnapshot('2: update');
106
-
107
- act(() => ReactDOM.unmountComponentAtNode(containerB));
108
- expect(store).toMatchSnapshot('3: unmount B');
109
-
110
- act(() => ReactDOM.unmountComponentAtNode(containerA));
111
- expect(store).toMatchSnapshot('4: unmount A');
112
- });
113
-
114
- it('should filter DOM nodes from the store tree', () => {
115
- const Grandparent = () => (
116
- <div>
117
- <div>
118
- <Parent />
119
- </div>
120
- <Parent />
121
- </div>
122
- );
123
- const Parent = () => (
124
- <div>
125
- <Child />
126
- </div>
127
- );
128
- const Child = () => <div>Hi!</div>;
129
-
130
- act(() =>
131
- ReactDOM.render(
132
- <Grandparent count={4} />,
133
- document.createElement('div'),
134
- ),
135
- );
136
- expect(store).toMatchSnapshot('1: mount');
137
- });
138
-
139
- it('should display Suspense nodes properly in various states', () => {
140
- const Loading = () => <div>Loading...</div>;
141
- const SuspendingComponent = () => {
142
- throw new Promise(() => {});
143
- };
144
- const Component = () => {
145
- return <div>Hello</div>;
146
- };
147
- const Wrapper = ({shouldSuspense}) => (
148
- <React.Fragment>
149
- <Component key="Outside" />
150
- <React.Suspense fallback={<Loading />}>
151
- {shouldSuspense ? (
152
- <SuspendingComponent />
153
- ) : (
154
- <Component key="Inside" />
155
- )}
156
- </React.Suspense>
157
- </React.Fragment>
158
- );
159
-
160
- const container = document.createElement('div');
161
- act(() => ReactDOM.render(<Wrapper shouldSuspense={true} />, container));
162
- expect(store).toMatchSnapshot('1: loading');
163
-
164
- act(() => {
165
- ReactDOM.render(<Wrapper shouldSuspense={false} />, container);
166
- });
167
- expect(store).toMatchSnapshot('2: resolved');
168
- });
169
-
170
- it('should support nested Suspense nodes', () => {
171
- const Component = () => null;
172
- const Loading = () => <div>Loading...</div>;
173
- const Never = () => {
174
- throw new Promise(() => {});
175
- };
176
-
177
- const Wrapper = ({
178
- suspendFirst = false,
179
- suspendSecond = false,
180
- suspendParent = false,
181
- }) => (
182
- <React.Fragment>
183
- <Component key="Outside" />
184
- <React.Suspense fallback={<Loading key="Parent Fallback" />}>
185
- <Component key="Unrelated at Start" />
186
- <React.Suspense fallback={<Loading key="Suspense 1 Fallback" />}>
187
- {suspendFirst ? (
188
- <Never />
189
- ) : (
190
- <Component key="Suspense 1 Content" />
191
- )}
192
- </React.Suspense>
193
- <React.Suspense fallback={<Loading key="Suspense 2 Fallback" />}>
194
- {suspendSecond ? (
195
- <Never />
196
- ) : (
197
- <Component key="Suspense 2 Content" />
198
- )}
199
- </React.Suspense>
200
- <React.Suspense fallback={<Loading key="Suspense 3 Fallback" />}>
201
- <Never />
202
- </React.Suspense>
203
- {suspendParent && <Never />}
204
- <Component key="Unrelated at End" />
205
- </React.Suspense>
206
- </React.Fragment>
207
- );
208
-
209
- const container = document.createElement('div');
210
- act(() =>
211
- ReactDOM.render(
212
- <Wrapper
213
- suspendParent={false}
214
- suspendFirst={false}
215
- suspendSecond={false}
216
- />,
217
- container,
218
- ),
219
- );
220
- expect(store).toMatchSnapshot('1: third child is suspended');
221
- act(() =>
222
- ReactDOM.render(
223
- <Wrapper
224
- suspendParent={false}
225
- suspendFirst={true}
226
- suspendSecond={false}
227
- />,
228
- container,
229
- ),
230
- );
231
- expect(store).toMatchSnapshot('2: first and third child are suspended');
232
- act(() =>
233
- ReactDOM.render(
234
- <Wrapper
235
- suspendParent={false}
236
- suspendFirst={false}
237
- suspendSecond={true}
238
- />,
239
- container,
240
- ),
241
- );
242
- expect(store).toMatchSnapshot('3: second and third child are suspended');
243
- act(() =>
244
- ReactDOM.render(
245
- <Wrapper
246
- suspendParent={false}
247
- suspendFirst={true}
248
- suspendSecond={false}
249
- />,
250
- container,
251
- ),
252
- );
253
- expect(store).toMatchSnapshot('4: first and third child are suspended');
254
- act(() =>
255
- ReactDOM.render(
256
- <Wrapper
257
- suspendParent={true}
258
- suspendFirst={true}
259
- suspendSecond={false}
260
- />,
261
- container,
262
- ),
263
- );
264
- expect(store).toMatchSnapshot('5: parent is suspended');
265
- act(() =>
266
- ReactDOM.render(
267
- <Wrapper
268
- suspendParent={false}
269
- suspendFirst={true}
270
- suspendSecond={true}
271
- />,
272
- container,
273
- ),
274
- );
275
- expect(store).toMatchSnapshot('6: all children are suspended');
276
- act(() =>
277
- ReactDOM.render(
278
- <Wrapper
279
- suspendParent={false}
280
- suspendFirst={false}
281
- suspendSecond={false}
282
- />,
283
- container,
284
- ),
285
- );
286
- expect(store).toMatchSnapshot('7: only third child is suspended');
287
-
288
- const rendererID = getRendererID();
289
- act(() =>
290
- agent.overrideSuspense({
291
- id: store.getElementIDAtIndex(4),
292
- rendererID,
293
- forceFallback: true,
294
- }),
295
- );
296
- expect(store).toMatchSnapshot('8: first and third child are suspended');
297
- act(() =>
298
- agent.overrideSuspense({
299
- id: store.getElementIDAtIndex(2),
300
- rendererID,
301
- forceFallback: true,
302
- }),
303
- );
304
- expect(store).toMatchSnapshot('9: parent is suspended');
305
- act(() =>
306
- ReactDOM.render(
307
- <Wrapper
308
- suspendParent={false}
309
- suspendFirst={true}
310
- suspendSecond={true}
311
- />,
312
- container,
313
- ),
314
- );
315
- expect(store).toMatchSnapshot('10: parent is suspended');
316
- act(() =>
317
- agent.overrideSuspense({
318
- id: store.getElementIDAtIndex(2),
319
- rendererID,
320
- forceFallback: false,
321
- }),
322
- );
323
- expect(store).toMatchSnapshot('11: all children are suspended');
324
- act(() =>
325
- agent.overrideSuspense({
326
- id: store.getElementIDAtIndex(4),
327
- rendererID,
328
- forceFallback: false,
329
- }),
330
- );
331
- expect(store).toMatchSnapshot('12: all children are suspended');
332
- act(() =>
333
- ReactDOM.render(
334
- <Wrapper
335
- suspendParent={false}
336
- suspendFirst={false}
337
- suspendSecond={false}
338
- />,
339
- container,
340
- ),
341
- );
342
- expect(store).toMatchSnapshot('13: third child is suspended');
343
- });
344
-
345
- it('should support collapsing parts of the tree', () => {
346
- const Grandparent = ({count}) => (
347
- <React.Fragment>
348
- <Parent count={count} />
349
- <Parent count={count} />
350
- </React.Fragment>
351
- );
352
- const Parent = ({count}) =>
353
- new Array(count).fill(true).map((_, index) => <Child key={index} />);
354
- const Child = () => <div>Hi!</div>;
355
-
356
- act(() =>
357
- ReactDOM.render(
358
- <Grandparent count={2} />,
359
- document.createElement('div'),
360
- ),
361
- );
362
- expect(store).toMatchSnapshot('1: mount');
363
-
364
- const grandparentID = store.getElementIDAtIndex(0);
365
- const parentOneID = store.getElementIDAtIndex(1);
366
- const parentTwoID = store.getElementIDAtIndex(4);
367
-
368
- act(() => store.toggleIsCollapsed(parentOneID, true));
369
- expect(store).toMatchSnapshot('2: collapse first Parent');
370
-
371
- act(() => store.toggleIsCollapsed(parentTwoID, true));
372
- expect(store).toMatchSnapshot('3: collapse second Parent');
373
-
374
- act(() => store.toggleIsCollapsed(parentOneID, false));
375
- expect(store).toMatchSnapshot('4: expand first Parent');
376
-
377
- act(() => store.toggleIsCollapsed(grandparentID, true));
378
- expect(store).toMatchSnapshot('5: collapse Grandparent');
379
-
380
- act(() => store.toggleIsCollapsed(grandparentID, false));
381
- expect(store).toMatchSnapshot('6: expand Grandparent');
382
- });
383
-
384
- it('should support reordering of children', () => {
385
- const Root = ({children}) => children;
386
- const Component = () => null;
387
-
388
- const Foo = () => [<Component key="0" />];
389
- const Bar = () => [<Component key="0" />, <Component key="1" />];
390
- const foo = <Foo key="foo" />;
391
- const bar = <Bar key="bar" />;
392
-
393
- const container = document.createElement('div');
394
-
395
- act(() => ReactDOM.render(<Root>{[foo, bar]}</Root>, container));
396
- expect(store).toMatchSnapshot('1: mount');
397
-
398
- act(() => ReactDOM.render(<Root>{[bar, foo]}</Root>, container));
399
- expect(store).toMatchSnapshot('3: reorder children');
400
-
401
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), true));
402
- expect(store).toMatchSnapshot('4: collapse root');
403
-
404
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), false));
405
- expect(store).toMatchSnapshot('5: expand root');
406
- });
407
- });
408
-
409
- describe('collapseNodesByDefault:true', () => {
410
- beforeEach(() => {
411
- store.collapseNodesByDefault = true;
412
- });
413
-
414
- it('should support mount and update operations', () => {
415
- const Parent = ({count}) =>
416
- new Array(count).fill(true).map((_, index) => <Child key={index} />);
417
- const Child = () => <div>Hi!</div>;
418
-
419
- const container = document.createElement('div');
420
-
421
- act(() =>
422
- ReactDOM.render(
423
- <React.Fragment>
424
- <Parent count={1} />
425
- <Parent count={3} />
426
- </React.Fragment>,
427
- container,
428
- ),
429
- );
430
- expect(store).toMatchSnapshot('1: mount');
431
-
432
- act(() =>
433
- ReactDOM.render(
434
- <React.Fragment>
435
- <Parent count={2} />
436
- <Parent count={1} />
437
- </React.Fragment>,
438
- container,
439
- ),
440
- );
441
- expect(store).toMatchSnapshot('2: update');
442
-
443
- act(() => ReactDOM.unmountComponentAtNode(container));
444
- expect(store).toMatchSnapshot('3: unmount');
445
- });
446
-
447
- it('should support mount and update operations for multiple roots', () => {
448
- const Parent = ({count}) =>
449
- new Array(count).fill(true).map((_, index) => <Child key={index} />);
450
- const Child = () => <div>Hi!</div>;
451
-
452
- const containerA = document.createElement('div');
453
- const containerB = document.createElement('div');
454
-
455
- act(() => {
456
- ReactDOM.render(<Parent key="A" count={3} />, containerA);
457
- ReactDOM.render(<Parent key="B" count={2} />, containerB);
458
- });
459
- expect(store).toMatchSnapshot('1: mount');
460
-
461
- act(() => {
462
- ReactDOM.render(<Parent key="A" count={4} />, containerA);
463
- ReactDOM.render(<Parent key="B" count={1} />, containerB);
464
- });
465
- expect(store).toMatchSnapshot('2: update');
466
-
467
- act(() => ReactDOM.unmountComponentAtNode(containerB));
468
- expect(store).toMatchSnapshot('3: unmount B');
469
-
470
- act(() => ReactDOM.unmountComponentAtNode(containerA));
471
- expect(store).toMatchSnapshot('4: unmount A');
472
- });
473
-
474
- it('should filter DOM nodes from the store tree', () => {
475
- const Grandparent = () => (
476
- <div>
477
- <div>
478
- <Parent />
479
- </div>
480
- <Parent />
481
- </div>
482
- );
483
- const Parent = () => (
484
- <div>
485
- <Child />
486
- </div>
487
- );
488
- const Child = () => <div>Hi!</div>;
489
-
490
- act(() =>
491
- ReactDOM.render(
492
- <Grandparent count={4} />,
493
- document.createElement('div'),
494
- ),
495
- );
496
- expect(store).toMatchSnapshot('1: mount');
497
-
498
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), false));
499
- expect(store).toMatchSnapshot('2: expand Grandparent');
500
-
501
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(1), false));
502
- expect(store).toMatchSnapshot('3: expand Parent');
503
- });
504
-
505
- it('should display Suspense nodes properly in various states', () => {
506
- const Loading = () => <div>Loading...</div>;
507
- const SuspendingComponent = () => {
508
- throw new Promise(() => {});
509
- };
510
- const Component = () => {
511
- return <div>Hello</div>;
512
- };
513
- const Wrapper = ({shouldSuspense}) => (
514
- <React.Fragment>
515
- <Component key="Outside" />
516
- <React.Suspense fallback={<Loading />}>
517
- {shouldSuspense ? (
518
- <SuspendingComponent />
519
- ) : (
520
- <Component key="Inside" />
521
- )}
522
- </React.Suspense>
523
- </React.Fragment>
524
- );
525
-
526
- const container = document.createElement('div');
527
- act(() => ReactDOM.render(<Wrapper shouldSuspense={true} />, container));
528
- expect(store).toMatchSnapshot('1: loading');
529
-
530
- // This test isn't meaningful unless we expand the suspended tree
531
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), false));
532
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(2), false));
533
- expect(store).toMatchSnapshot('2: expand Wrapper and Suspense');
534
-
535
- act(() => {
536
- ReactDOM.render(<Wrapper shouldSuspense={false} />, container);
537
- });
538
- expect(store).toMatchSnapshot('2: resolved');
539
- });
540
-
541
- it('should support expanding parts of the tree', () => {
542
- const Grandparent = ({count}) => (
543
- <React.Fragment>
544
- <Parent count={count} />
545
- <Parent count={count} />
546
- </React.Fragment>
547
- );
548
- const Parent = ({count}) =>
549
- new Array(count).fill(true).map((_, index) => <Child key={index} />);
550
- const Child = () => <div>Hi!</div>;
551
-
552
- act(() =>
553
- ReactDOM.render(
554
- <Grandparent count={2} />,
555
- document.createElement('div'),
556
- ),
557
- );
558
- expect(store).toMatchSnapshot('1: mount');
559
-
560
- const grandparentID = store.getElementIDAtIndex(0);
561
-
562
- act(() => store.toggleIsCollapsed(grandparentID, false));
563
- expect(store).toMatchSnapshot('2: expand Grandparent');
564
-
565
- const parentOneID = store.getElementIDAtIndex(1);
566
- const parentTwoID = store.getElementIDAtIndex(2);
567
-
568
- act(() => store.toggleIsCollapsed(parentOneID, false));
569
- expect(store).toMatchSnapshot('3: expand first Parent');
570
-
571
- act(() => store.toggleIsCollapsed(parentTwoID, false));
572
- expect(store).toMatchSnapshot('4: expand second Parent');
573
-
574
- act(() => store.toggleIsCollapsed(parentOneID, true));
575
- expect(store).toMatchSnapshot('5: collapse first Parent');
576
-
577
- act(() => store.toggleIsCollapsed(parentTwoID, true));
578
- expect(store).toMatchSnapshot('6: collapse second Parent');
579
-
580
- act(() => store.toggleIsCollapsed(grandparentID, true));
581
- expect(store).toMatchSnapshot('7: collapse Grandparent');
582
- });
583
-
584
- it('should support expanding deep parts of the tree', () => {
585
- const Wrapper = ({forwardedRef}) => (
586
- <Nested depth={3} forwardedRef={forwardedRef} />
587
- );
588
- const Nested = ({depth, forwardedRef}) =>
589
- depth > 0 ? (
590
- <Nested depth={depth - 1} forwardedRef={forwardedRef} />
591
- ) : (
592
- <div ref={forwardedRef} />
593
- );
594
-
595
- const ref = React.createRef();
596
-
597
- act(() =>
598
- ReactDOM.render(
599
- <Wrapper forwardedRef={ref} />,
600
- document.createElement('div'),
601
- ),
602
- );
603
- expect(store).toMatchSnapshot('1: mount');
604
-
605
- const deepestedNodeID = agent.getIDForNode(ref.current);
606
-
607
- act(() => store.toggleIsCollapsed(deepestedNodeID, false));
608
- expect(store).toMatchSnapshot('2: expand deepest node');
609
-
610
- const rootID = store.getElementIDAtIndex(0);
611
-
612
- act(() => store.toggleIsCollapsed(rootID, true));
613
- expect(store).toMatchSnapshot('3: collapse root');
614
-
615
- act(() => store.toggleIsCollapsed(rootID, false));
616
- expect(store).toMatchSnapshot('4: expand root');
617
-
618
- const id = store.getElementIDAtIndex(1);
619
-
620
- act(() => store.toggleIsCollapsed(id, true));
621
- expect(store).toMatchSnapshot('5: collapse middle node');
622
-
623
- act(() => store.toggleIsCollapsed(id, false));
624
- expect(store).toMatchSnapshot('6: expand middle node');
625
- });
626
-
627
- it('should support reordering of children', () => {
628
- const Root = ({children}) => children;
629
- const Component = () => null;
630
-
631
- const Foo = () => [<Component key="0" />];
632
- const Bar = () => [<Component key="0" />, <Component key="1" />];
633
- const foo = <Foo key="foo" />;
634
- const bar = <Bar key="bar" />;
635
-
636
- const container = document.createElement('div');
637
-
638
- act(() => ReactDOM.render(<Root>{[foo, bar]}</Root>, container));
639
- expect(store).toMatchSnapshot('1: mount');
640
-
641
- act(() => ReactDOM.render(<Root>{[bar, foo]}</Root>, container));
642
- expect(store).toMatchSnapshot('3: reorder children');
643
-
644
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), false));
645
- expect(store).toMatchSnapshot('4: expand root');
646
-
647
- act(() => {
648
- store.toggleIsCollapsed(store.getElementIDAtIndex(2), false);
649
- store.toggleIsCollapsed(store.getElementIDAtIndex(1), false);
650
- });
651
- expect(store).toMatchSnapshot('5: expand leaves');
652
-
653
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), true));
654
- expect(store).toMatchSnapshot('6: collapse root');
655
- });
656
-
657
- it('should not add new nodes when suspense is toggled', () => {
658
- const SuspenseTree = () => {
659
- return (
660
- <React.Suspense fallback={<Fallback>Loading outer</Fallback>}>
661
- <Parent />
662
- </React.Suspense>
663
- );
664
- };
665
-
666
- const Fallback = () => null;
667
- const Parent = () => <Child />;
668
- const Child = () => null;
669
-
670
- act(() =>
671
- ReactDOM.render(<SuspenseTree />, document.createElement('div')),
672
- );
673
- expect(store).toMatchSnapshot('1: mount');
674
-
675
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(0), false));
676
- act(() => store.toggleIsCollapsed(store.getElementIDAtIndex(1), false));
677
- expect(store).toMatchSnapshot('2: expand tree');
678
-
679
- const rendererID = getRendererID();
680
- const suspenseID = store.getElementIDAtIndex(1);
681
-
682
- act(() =>
683
- agent.overrideSuspense({
684
- id: suspenseID,
685
- rendererID,
686
- forceFallback: true,
687
- }),
688
- );
689
- expect(store).toMatchSnapshot('3: toggle fallback on');
690
-
691
- act(() =>
692
- agent.overrideSuspense({
693
- id: suspenseID,
694
- rendererID,
695
- forceFallback: false,
696
- }),
697
- );
698
- expect(store).toMatchSnapshot('4: toggle fallback on');
699
- });
700
- });
701
-
702
- describe('getIndexOfElementID', () => {
703
- beforeEach(() => {
704
- store.collapseNodesByDefault = false;
705
- });
706
-
707
- it('should support a single root with a single child', () => {
708
- const Grandparent = () => (
709
- <React.Fragment>
710
- <Parent />
711
- <Parent />
712
- </React.Fragment>
713
- );
714
- const Parent = () => <Child />;
715
- const Child = () => null;
716
-
717
- act(() =>
718
- ReactDOM.render(<Grandparent />, document.createElement('div')),
719
- );
720
-
721
- for (let i = 0; i < store.numElements; i++) {
722
- expect(store.getIndexOfElementID(store.getElementIDAtIndex(i))).toBe(i);
723
- }
724
- });
725
-
726
- it('should support multiple roots with one children each', () => {
727
- const Grandparent = () => <Parent />;
728
- const Parent = () => <Child />;
729
- const Child = () => null;
730
-
731
- act(() => {
732
- ReactDOM.render(<Grandparent />, document.createElement('div'));
733
- ReactDOM.render(<Grandparent />, document.createElement('div'));
734
- });
735
-
736
- for (let i = 0; i < store.numElements; i++) {
737
- expect(store.getIndexOfElementID(store.getElementIDAtIndex(i))).toBe(i);
738
- }
739
- });
740
-
741
- it('should support a single root with multiple top level children', () => {
742
- const Grandparent = () => <Parent />;
743
- const Parent = () => <Child />;
744
- const Child = () => null;
745
-
746
- act(() =>
747
- ReactDOM.render(
748
- <React.Fragment>
749
- <Grandparent />
750
- <Grandparent />
751
- </React.Fragment>,
752
- document.createElement('div'),
753
- ),
754
- );
755
-
756
- for (let i = 0; i < store.numElements; i++) {
757
- expect(store.getIndexOfElementID(store.getElementIDAtIndex(i))).toBe(i);
758
- }
759
- });
760
-
761
- it('should support multiple roots with multiple top level children', () => {
762
- const Grandparent = () => <Parent />;
763
- const Parent = () => <Child />;
764
- const Child = () => null;
765
-
766
- act(() => {
767
- ReactDOM.render(
768
- <React.Fragment>
769
- <Grandparent />
770
- <Grandparent />
771
- </React.Fragment>,
772
- document.createElement('div'),
773
- );
774
- ReactDOM.render(
775
- <React.Fragment>
776
- <Grandparent />
777
- <Grandparent />
778
- </React.Fragment>,
779
- document.createElement('div'),
780
- );
781
- });
782
-
783
- for (let i = 0; i < store.numElements; i++) {
784
- expect(store.getIndexOfElementID(store.getElementIDAtIndex(i))).toBe(i);
785
- }
786
- });
787
- });
788
-
789
- it('detects and updates profiling support based on the attached roots', () => {
790
- const Component = () => null;
791
-
792
- const containerA = document.createElement('div');
793
- const containerB = document.createElement('div');
794
-
795
- expect(store.supportsProfiling).toBe(false);
796
-
797
- act(() => ReactDOM.render(<Component />, containerA));
798
- expect(store.supportsProfiling).toBe(true);
799
-
800
- act(() => ReactDOM.render(<Component />, containerB));
801
- act(() => ReactDOM.unmountComponentAtNode(containerA));
802
- expect(store.supportsProfiling).toBe(true);
803
-
804
- act(() => ReactDOM.unmountComponentAtNode(containerB));
805
- expect(store.supportsProfiling).toBe(false);
806
- });
807
-});
packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js
deleted
-230
@@ -1,230 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
11
-import type Store from 'react-devtools-shared/src/devtools/store';
12
-
13
-describe('Store component filters', () => {
14
- let React;
15
- let ReactDOM;
16
- let TestUtils;
17
- let Types;
18
- let bridge: FrontendBridge;
19
- let store: Store;
20
- let utils;
21
-
22
- const act = (callback: Function) => {
23
- TestUtils.act(() => {
24
- callback();
25
- });
26
- jest.runAllTimers(); // Flush Bridge operations
27
- };
28
-
29
- beforeEach(() => {
30
- bridge = global.bridge;
31
- store = global.store;
32
- store.collapseNodesByDefault = false;
33
- store.componentFilters = [];
34
- store.recordChangeDescriptions = true;
35
-
36
- React = require('react');
37
- ReactDOM = require('react-dom');
38
- TestUtils = require('react-dom/test-utils');
39
- Types = require('react-devtools-shared/src/types');
40
- utils = require('./utils');
41
- });
42
-
43
- it('should throw if filters are updated while profiling', () => {
44
- act(() => store.profilerStore.startProfiling());
45
- expect(() => (store.componentFilters = [])).toThrow(
46
- 'Cannot modify filter preferences while profiling',
47
- );
48
- });
49
-
50
- it('should support filtering by element type', () => {
51
- class Root extends React.Component<{|children: React$Node|}> {
52
- render() {
53
- return <div>{this.props.children}</div>;
54
- }
55
- }
56
- const Component = () => <div>Hi</div>;
57
-
58
- act(() =>
59
- ReactDOM.render(
60
- <Root>
61
- <Component />
62
- </Root>,
63
- document.createElement('div'),
64
- ),
65
- );
66
- expect(store).toMatchSnapshot('1: mount');
67
-
68
- act(
69
- () =>
70
- (store.componentFilters = [
71
- utils.createElementTypeFilter(Types.ElementTypeHostComponent),
72
- ]),
73
- );
74
-
75
- expect(store).toMatchSnapshot('2: hide host components');
76
-
77
- act(
78
- () =>
79
- (store.componentFilters = [
80
- utils.createElementTypeFilter(Types.ElementTypeClass),
81
- ]),
82
- );
83
-
84
- expect(store).toMatchSnapshot('3: hide class components');
85
-
86
- act(
87
- () =>
88
- (store.componentFilters = [
89
- utils.createElementTypeFilter(Types.ElementTypeClass),
90
- utils.createElementTypeFilter(Types.ElementTypeFunction),
91
- ]),
92
- );
93
-
94
- expect(store).toMatchSnapshot('4: hide class and function components');
95
-
96
- act(
97
- () =>
98
- (store.componentFilters = [
99
- utils.createElementTypeFilter(Types.ElementTypeClass, false),
100
- utils.createElementTypeFilter(Types.ElementTypeFunction, false),
101
- ]),
102
- );
103
-
104
- expect(store).toMatchSnapshot('5: disable all filters');
105
- });
106
-
107
- it('should ignore invalid ElementTypeRoot filter', () => {
108
- const Root = () => <div>Hi</div>;
109
-
110
- act(() => ReactDOM.render(<Root />, document.createElement('div')));
111
- expect(store).toMatchSnapshot('1: mount');
112
-
113
- act(
114
- () =>
115
- (store.componentFilters = [
116
- utils.createElementTypeFilter(Types.ElementTypeRoot),
117
- ]),
118
- );
119
-
120
- expect(store).toMatchSnapshot('2: add invalid filter');
121
- });
122
-
123
- it('should filter by display name', () => {
124
- const Text = ({label}) => label;
125
- const Foo = () => <Text label="foo" />;
126
- const Bar = () => <Text label="bar" />;
127
- const Baz = () => <Text label="baz" />;
128
-
129
- act(() =>
130
- ReactDOM.render(
131
- <React.Fragment>
132
- <Foo />
133
- <Bar />
134
- <Baz />
135
- </React.Fragment>,
136
- document.createElement('div'),
137
- ),
138
- );
139
- expect(store).toMatchSnapshot('1: mount');
140
-
141
- act(
142
- () => (store.componentFilters = [utils.createDisplayNameFilter('Foo')]),
143
- );
144
- expect(store).toMatchSnapshot('2: filter "Foo"');
145
-
146
- act(() => (store.componentFilters = [utils.createDisplayNameFilter('Ba')]));
147
- expect(store).toMatchSnapshot('3: filter "Ba"');
148
-
149
- act(
150
- () => (store.componentFilters = [utils.createDisplayNameFilter('B.z')]),
151
- );
152
- expect(store).toMatchSnapshot('4: filter "B.z"');
153
- });
154
-
155
- it('should filter by path', () => {
156
- const Component = () => <div>Hi</div>;
157
-
158
- act(() => ReactDOM.render(<Component />, document.createElement('div')));
159
- expect(store).toMatchSnapshot('1: mount');
160
-
161
- act(
162
- () =>
163
- (store.componentFilters = [
164
- utils.createLocationFilter(__filename.replace(__dirname, '')),
165
- ]),
166
- );
167
-
168
- expect(store).toMatchSnapshot(
169
- '2: hide all components declared within this test filed',
170
- );
171
-
172
- act(
173
- () =>
174
- (store.componentFilters = [
175
- utils.createLocationFilter('this:is:a:made:up:path'),
176
- ]),
177
- );
178
-
179
- expect(store).toMatchSnapshot('3: hide components in a made up fake path');
180
- });
181
-
182
- it('should filter HOCs', () => {
183
- const Component = () => <div>Hi</div>;
184
- const Foo = () => <Component />;
185
- Foo.displayName = 'Foo(Component)';
186
- const Bar = () => <Foo />;
187
- Bar.displayName = 'Bar(Foo(Component))';
188
-
189
- act(() => ReactDOM.render(<Bar />, document.createElement('div')));
190
- expect(store).toMatchSnapshot('1: mount');
191
-
192
- act(() => (store.componentFilters = [utils.createHOCFilter(true)]));
193
-
194
- expect(store).toMatchSnapshot('2: hide all HOCs');
195
-
196
- act(() => (store.componentFilters = [utils.createHOCFilter(false)]));
197
-
198
- expect(store).toMatchSnapshot('3: disable HOC filter');
199
- });
200
-
201
- it('should not send a bridge update if the set of enabled filters has not changed', () => {
202
- act(() => (store.componentFilters = [utils.createHOCFilter(true)]));
203
-
204
- bridge.addListener('updateComponentFilters', componentFilters => {
205
- throw Error('Unexpected component update');
206
- });
207
-
208
- act(
209
- () =>
210
- (store.componentFilters = [
211
- utils.createHOCFilter(false),
212
- utils.createHOCFilter(true),
213
- ]),
214
- );
215
- act(
216
- () =>
217
- (store.componentFilters = [
218
- utils.createHOCFilter(true),
219
- utils.createLocationFilter('abc', false),
220
- ]),
221
- );
222
- act(
223
- () =>
224
- (store.componentFilters = [
225
- utils.createHOCFilter(true),
226
- utils.createElementTypeFilter(Types.ElementTypeHostComponent, false),
227
- ]),
228
- );
229
- });
230
-});
packages/react-devtools-shared/src/__tests__/storeOwners-test.js
deleted
-171
@@ -1,171 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-const {printOwnersList} = require('../devtools/utils');
11
-
12
-describe('Store owners list', () => {
13
- let React;
14
- let ReactDOM;
15
- let act;
16
- let store;
17
-
18
- beforeEach(() => {
19
- store = global.store;
20
- store.collapseNodesByDefault = false;
21
-
22
- React = require('react');
23
- ReactDOM = require('react-dom');
24
- act = require('./utils').act;
25
- });
26
-
27
- it('should drill through intermediate components', () => {
28
- const Root = () => (
29
- <Intermediate>
30
- <div>
31
- <Leaf />
32
- </div>
33
- </Intermediate>
34
- );
35
- const Wrapper = ({children}) => children;
36
- const Leaf = () => <div>Leaf</div>;
37
- const Intermediate = ({children}) => <Wrapper>{children}</Wrapper>;
38
-
39
- act(() => ReactDOM.render(<Root />, document.createElement('div')));
40
- expect(store).toMatchSnapshot('1: mount');
41
-
42
- const rootID = store.getElementIDAtIndex(0);
43
- expect(
44
- printOwnersList(store.getOwnersListForElement(rootID)),
45
- ).toMatchSnapshot('2: components owned by <Root>');
46
-
47
- const intermediateID = store.getElementIDAtIndex(1);
48
- expect(
49
- printOwnersList(store.getOwnersListForElement(intermediateID)),
50
- ).toMatchSnapshot('3: components owned by <Intermediate>');
51
- });
52
-
53
- it('should drill through interleaved intermediate components', () => {
54
- const Root = () => [
55
- <Intermediate key="intermediate">
56
- <Leaf />
57
- </Intermediate>,
58
- <Leaf key="leaf" />,
59
- ];
60
- const Wrapper = ({children}) => children;
61
- const Leaf = () => <div>Leaf</div>;
62
- const Intermediate = ({children}) => [
63
- <Leaf key="leaf" />,
64
- <Wrapper key="wrapper">{children}</Wrapper>,
65
- ];
66
-
67
- act(() => ReactDOM.render(<Root />, document.createElement('div')));
68
- expect(store).toMatchSnapshot('1: mount');
69
-
70
- const rootID = store.getElementIDAtIndex(0);
71
- expect(
72
- printOwnersList(store.getOwnersListForElement(rootID)),
73
- ).toMatchSnapshot('2: components owned by <Root>');
74
-
75
- const intermediateID = store.getElementIDAtIndex(1);
76
- expect(
77
- printOwnersList(store.getOwnersListForElement(intermediateID)),
78
- ).toMatchSnapshot('3: components owned by <Intermediate>');
79
- });
80
-
81
- it('should show the proper owners list order and contents after insertions and deletions', () => {
82
- const Root = ({includeDirect, includeIndirect}) => (
83
- <div>
84
- {includeDirect ? <Leaf /> : null}
85
- {includeIndirect ? (
86
- <Intermediate>
87
- <Leaf />
88
- </Intermediate>
89
- ) : null}
90
- </div>
91
- );
92
- const Wrapper = ({children}) => children;
93
- const Leaf = () => <div>Leaf</div>;
94
- const Intermediate = ({children}) => <Wrapper>{children}</Wrapper>;
95
-
96
- const container = document.createElement('div');
97
-
98
- act(() =>
99
- ReactDOM.render(
100
- <Root includeDirect={false} includeIndirect={true} />,
101
- container,
102
- ),
103
- );
104
- expect(store).toMatchSnapshot('1: mount');
105
-
106
- const rootID = store.getElementIDAtIndex(0);
107
- expect(
108
- printOwnersList(store.getOwnersListForElement(rootID)),
109
- ).toMatchSnapshot('2: components owned by <Root>');
110
-
111
- act(() =>
112
- ReactDOM.render(
113
- <Root includeDirect={true} includeIndirect={true} />,
114
- container,
115
- ),
116
- );
117
- expect(store).toMatchSnapshot('3: update to add direct');
118
-
119
- expect(
120
- printOwnersList(store.getOwnersListForElement(rootID)),
121
- ).toMatchSnapshot('4: components owned by <Root>');
122
-
123
- act(() =>
124
- ReactDOM.render(
125
- <Root includeDirect={true} includeIndirect={false} />,
126
- container,
127
- ),
128
- );
129
- expect(store).toMatchSnapshot('5: update to remove indirect');
130
-
131
- expect(
132
- printOwnersList(store.getOwnersListForElement(rootID)),
133
- ).toMatchSnapshot('6: components owned by <Root>');
134
-
135
- act(() =>
136
- ReactDOM.render(
137
- <Root includeDirect={false} includeIndirect={false} />,
138
- container,
139
- ),
140
- );
141
- expect(store).toMatchSnapshot('7: update to remove both');
142
-
143
- expect(
144
- printOwnersList(store.getOwnersListForElement(rootID)),
145
- ).toMatchSnapshot('8: components owned by <Root>');
146
- });
147
-
148
- it('should show the proper owners list ordering after reordered children', () => {
149
- const Root = ({ascending}) =>
150
- ascending
151
- ? [<Leaf key="A" />, <Leaf key="B" />, <Leaf key="C" />]
152
- : [<Leaf key="C" />, <Leaf key="B" />, <Leaf key="A" />];
153
- const Leaf = () => <div>Leaf</div>;
154
-
155
- const container = document.createElement('div');
156
- act(() => ReactDOM.render(<Root ascending={true} />, container));
157
- expect(store).toMatchSnapshot('1: mount (ascending)');
158
-
159
- const rootID = store.getElementIDAtIndex(0);
160
- expect(
161
- printOwnersList(store.getOwnersListForElement(rootID)),
162
- ).toMatchSnapshot('2: components owned by <Root>');
163
-
164
- act(() => ReactDOM.render(<Root ascending={false} />, container));
165
- expect(store).toMatchSnapshot('3: update (descending)');
166
-
167
- expect(
168
- printOwnersList(store.getOwnersListForElement(rootID)),
169
- ).toMatchSnapshot('4: components owned by <Root>');
170
- });
171
-});
packages/react-devtools-shared/src/__tests__/storeSerializer.js
deleted
-21
@@ -1,21 +0,0 @@
1
-import {printStore} from 'react-devtools-shared/src/devtools/utils';
2
-
3
-// test() is part of Jest's serializer API
4
-export function test(maybeStore) {
5
- // It's important to lazy-require the Store rather than imported at the head of the module.
6
- // Because we reset modules between tests, different Store implementations will be used for each test.
7
- // Unfortunately Jest does not reset its own serializer modules.
8
- return (
9
- maybeStore instanceof
10
- require('react-devtools-shared/src/devtools/store').default
11
- );
12
-}
13
-
14
-// print() is part of Jest's serializer API
15
-export function print(store, serialize, indent) {
16
- return printStore(store);
17
-}
18
-
19
-// Used for Jest snapshot testing.
20
-// May also be useful for visually debugging the tree, so it lives on the Store.
21
-export {printStore};
packages/react-devtools-shared/src/__tests__/storeStressSync-test.js
deleted
-1100
@@ -1,1100 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-describe('StoreStress (Sync Mode)', () => {
11
- let React;
12
- let ReactDOM;
13
- let act;
14
- let bridge;
15
- let store;
16
- let print;
17
-
18
- beforeEach(() => {
19
- bridge = global.bridge;
20
- store = global.store;
21
- store.collapseNodesByDefault = false;
22
-
23
- React = require('react');
24
- ReactDOM = require('react-dom');
25
- act = require('./utils').act;
26
-
27
- print = require('./storeSerializer').print;
28
- });
29
-
30
- // This is a stress test for the tree mount/update/unmount traversal.
31
- // It renders different trees that should produce the same output.
32
- it('should handle a stress test with different tree operations (Sync Mode)', () => {
33
- let setShowX;
34
- const A = () => 'a';
35
- const B = () => 'b';
36
- const C = () => {
37
- // We'll be manually flipping this component back and forth in the test.
38
- // We only do this for a single node in order to verify that DevTools
39
- // can handle a subtree switching alternates while other subtrees are memoized.
40
- let [showX, _setShowX] = React.useState(false);
41
- setShowX = _setShowX;
42
- return showX ? <X /> : 'c';
43
- };
44
- const D = () => 'd';
45
- const E = () => 'e';
46
- const X = () => 'x';
47
- const a = <A key="a" />;
48
- const b = <B key="b" />;
49
- const c = <C key="c" />;
50
- const d = <D key="d" />;
51
- const e = <E key="e" />;
52
-
53
- function Parent({children}) {
54
- return children;
55
- }
56
-
57
- // 1. Render a normal version of [a, b, c, d, e].
58
- let container = document.createElement('div');
59
- act(() => ReactDOM.render(<Parent>{[a, b, c, d, e]}</Parent>, container));
60
- expect(store).toMatchSnapshot('1: abcde');
61
- expect(container.textContent).toMatch('abcde');
62
- const snapshotForABCDE = print(store);
63
-
64
- // 2. Render a version where <C /> renders an <X /> child instead of 'c'.
65
- // This is how we'll test an update to a single component.
66
- act(() => {
67
- setShowX(true);
68
- });
69
- expect(store).toMatchSnapshot('2: abxde');
70
- expect(container.textContent).toMatch('abxde');
71
- const snapshotForABXDE = print(store);
72
-
73
- // 3. Verify flipping it back produces the original result.
74
- act(() => {
75
- setShowX(false);
76
- });
77
- expect(container.textContent).toMatch('abcde');
78
- expect(print(store)).toBe(snapshotForABCDE);
79
-
80
- // 4. Clean up.
81
- act(() => ReactDOM.unmountComponentAtNode(container));
82
- expect(print(store)).toBe('');
83
-
84
- // Now comes the interesting part.
85
- // All of these cases are equivalent to [a, b, c, d, e] in output.
86
- // We'll verify that DevTools produces the same snapshots for them.
87
- // These cases are picked so that rendering them sequentially in the same
88
- // container results in a combination of mounts, updates, unmounts, and reorders.
89
- // prettier-ignore
90
- let cases = [
91
- [a, b, c, d, e],
92
- [[a], b, c, d, e],
93
- [[a, b], c, d, e],
94
- [[a, b], c, [d, e]],
95
- [[a, b], c, [d, '', e]],
96
- [[a], b, c, d, [e]],
97
- [a, b, [[c]], d, e],
98
- [[a, ''], [b], [c], [d], [e]],
99
- [a, b, [c, [d, ['', e]]]],
100
- [a, b, c, d, e],
101
- [<div key="0">{a}</div>, b, c, d, e],
102
- [<div key="0">{a}{b}</div>, c, d, e],
103
- [<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],
104
- [<div key="1">{a}{b}</div>, c, <div key="0">{d}{e}</div>],
105
- [<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],
106
- [<div key="2">{a}{b}</div>, c, <div key="3">{d}{e}</div>],
107
- [<span key="0">{a}</span>, b, c, d, [e]],
108
- [a, b, <span key="0"><span>{c}</span></span>, d, e],
109
- [<div key="0">{a}</div>, [b], <span key="1">{c}</span>, [d], <div key="2">{e}</div>],
110
- [a, b, [c, <div key="0">{d}<span>{e}</span></div>], ''],
111
- [a, [[]], b, c, [d, [[]], e]],
112
- [[[a, b, c, d], e]],
113
- [a, b, c, d, e],
114
- ];
115
-
116
- // 5. Test fresh mount for each case.
117
- for (let i = 0; i < cases.length; i++) {
118
- // Ensure fresh mount.
119
- container = document.createElement('div');
120
-
121
- // Verify mounting 'abcde'.
122
- act(() => ReactDOM.render(<Parent>{cases[i]}</Parent>, container));
123
- expect(container.textContent).toMatch('abcde');
124
- expect(print(store)).toEqual(snapshotForABCDE);
125
-
126
- // Verify switching to 'abxde'.
127
- act(() => {
128
- setShowX(true);
129
- });
130
- expect(container.textContent).toMatch('abxde');
131
- expect(print(store)).toBe(snapshotForABXDE);
132
-
133
- // Verify switching back to 'abcde'.
134
- act(() => {
135
- setShowX(false);
136
- });
137
- expect(container.textContent).toMatch('abcde');
138
- expect(print(store)).toBe(snapshotForABCDE);
139
-
140
- // Clean up.
141
- act(() => ReactDOM.unmountComponentAtNode(container));
142
- expect(print(store)).toBe('');
143
- }
144
-
145
- // 6. Verify *updates* by reusing the container between iterations.
146
- // There'll be no unmounting until the very end.
147
- container = document.createElement('div');
148
- for (let i = 0; i < cases.length; i++) {
149
- // Verify mounting 'abcde'.
150
- act(() => ReactDOM.render(<Parent>{cases[i]}</Parent>, container));
151
- expect(container.textContent).toMatch('abcde');
152
- expect(print(store)).toEqual(snapshotForABCDE);
153
-
154
- // Verify switching to 'abxde'.
155
- act(() => {
156
- setShowX(true);
157
- });
158
- expect(container.textContent).toMatch('abxde');
159
- expect(print(store)).toBe(snapshotForABXDE);
160
-
161
- // Verify switching back to 'abcde'.
162
- act(() => {
163
- setShowX(false);
164
- });
165
- expect(container.textContent).toMatch('abcde');
166
- expect(print(store)).toBe(snapshotForABCDE);
167
- // Don't unmount. Reuse the container between iterations.
168
- }
169
- act(() => ReactDOM.unmountComponentAtNode(container));
170
- expect(print(store)).toBe('');
171
- });
172
-
173
- it('should handle stress test with reordering (Sync Mode)', () => {
174
- const A = () => 'a';
175
- const B = () => 'b';
176
- const C = () => 'c';
177
- const D = () => 'd';
178
- const E = () => 'e';
179
- const a = <A key="a" />;
180
- const b = <B key="b" />;
181
- const c = <C key="c" />;
182
- const d = <D key="d" />;
183
- const e = <E key="e" />;
184
-
185
- // prettier-ignore
186
- let steps = [
187
- a,
188
- b,
189
- c,
190
- d,
191
- e,
192
- [a],
193
- [b],
194
- [c],
195
- [d],
196
- [e],
197
- [a, b],
198
- [b, a],
199
- [b, c],
200
- [c, b],
201
- [a, c],
202
- [c, a],
203
- ];
204
-
205
- const Root = ({children}) => {
206
- return children;
207
- };
208
-
209
- // 1. Capture the expected render result.
210
- let snapshots = [];
211
- let container = document.createElement('div');
212
- for (let i = 0; i < steps.length; i++) {
213
- act(() => ReactDOM.render(<Root>{steps[i]}</Root>, container));
214
- // We snapshot each step once so it doesn't regress.
215
- expect(store).toMatchSnapshot();
216
- snapshots.push(print(store));
217
- act(() => ReactDOM.unmountComponentAtNode(container));
218
- expect(print(store)).toBe('');
219
- }
220
-
221
- // 2. Verify that we can update from every step to every other step and back.
222
- for (let i = 0; i < steps.length; i++) {
223
- for (let j = 0; j < steps.length; j++) {
224
- container = document.createElement('div');
225
- act(() => ReactDOM.render(<Root>{steps[i]}</Root>, container));
226
- expect(print(store)).toMatch(snapshots[i]);
227
- act(() => ReactDOM.render(<Root>{steps[j]}</Root>, container));
228
- expect(print(store)).toMatch(snapshots[j]);
229
- act(() => ReactDOM.render(<Root>{steps[i]}</Root>, container));
230
- expect(print(store)).toMatch(snapshots[i]);
231
- act(() => ReactDOM.unmountComponentAtNode(container));
232
- expect(print(store)).toBe('');
233
- }
234
- }
235
-
236
- // 3. Same test as above, but this time we wrap children in a host component.
237
- for (let i = 0; i < steps.length; i++) {
238
- for (let j = 0; j < steps.length; j++) {
239
- container = document.createElement('div');
240
- act(() =>
241
- ReactDOM.render(
242
- <Root>
243
- <div>{steps[i]}</div>
244
- </Root>,
245
- container,
246
- ),
247
- );
248
- expect(print(store)).toMatch(snapshots[i]);
249
- act(() =>
250
- ReactDOM.render(
251
- <Root>
252
- <div>{steps[j]}</div>
253
- </Root>,
254
- container,
255
- ),
256
- );
257
- expect(print(store)).toMatch(snapshots[j]);
258
- act(() =>
259
- ReactDOM.render(
260
- <Root>
261
- <div>{steps[i]}</div>
262
- </Root>,
263
- container,
264
- ),
265
- );
266
- expect(print(store)).toMatch(snapshots[i]);
267
- act(() => ReactDOM.unmountComponentAtNode(container));
268
- expect(print(store)).toBe('');
269
- }
270
- }
271
- });
272
-
273
- it('should handle a stress test for Suspense (Sync Mode)', async () => {
274
- const A = () => 'a';
275
- const B = () => 'b';
276
- const C = () => 'c';
277
- const X = () => 'x';
278
- const Y = () => 'y';
279
- const Z = () => 'z';
280
- const a = <A key="a" />;
281
- const b = <B key="b" />;
282
- const c = <C key="c" />;
283
- const z = <Z key="z" />;
284
-
285
- // prettier-ignore
286
- const steps = [
287
- a,
288
- [a],
289
- [a, b, c],
290
- [c, b, a],
291
- [c, null, a],
292
- <React.Fragment>{c}{a}</React.Fragment>,
293
- <div>{c}{a}</div>,
294
- <div><span>{a}</span>{b}</div>,
295
- [[a]],
296
- null,
297
- b,
298
- a,
299
- ];
300
-
301
- const Never = () => {
302
- throw new Promise(() => {});
303
- };
304
-
305
- const Root = ({children}) => {
306
- return children;
307
- };
308
-
309
- // 1. For each step, check Suspense can render them as initial primary content.
310
- // This is the only step where we use Jest snapshots.
311
- let snapshots = [];
312
- let container = document.createElement('div');
313
- for (let i = 0; i < steps.length; i++) {
314
- act(() =>
315
- ReactDOM.render(
316
- <Root>
317
- <X />
318
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
319
- <Y />
320
- </Root>,
321
- container,
322
- ),
323
- );
324
- // We snapshot each step once so it doesn't regress.
325
- expect(store).toMatchSnapshot();
326
- snapshots.push(print(store));
327
- act(() => ReactDOM.unmountComponentAtNode(container));
328
- expect(print(store)).toBe('');
329
- }
330
-
331
- // 2. Verify check Suspense can render same steps as initial fallback content.
332
- for (let i = 0; i < steps.length; i++) {
333
- act(() =>
334
- ReactDOM.render(
335
- <Root>
336
- <X />
337
- <React.Suspense fallback={steps[i]}>
338
- <Z />
339
- <Never />
340
- <Z />
341
- </React.Suspense>
342
- <Y />
343
- </Root>,
344
- container,
345
- ),
346
- );
347
- expect(print(store)).toEqual(snapshots[i]);
348
- act(() => ReactDOM.unmountComponentAtNode(container));
349
- expect(print(store)).toBe('');
350
- }
351
-
352
- // 3. Verify we can update from each step to each step in primary mode.
353
- for (let i = 0; i < steps.length; i++) {
354
- for (let j = 0; j < steps.length; j++) {
355
- // Always start with a fresh container and steps[i].
356
- container = document.createElement('div');
357
- act(() =>
358
- ReactDOM.render(
359
- <Root>
360
- <X />
361
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
362
- <Y />
363
- </Root>,
364
- container,
365
- ),
366
- );
367
- expect(print(store)).toEqual(snapshots[i]);
368
- // Re-render with steps[j].
369
- act(() =>
370
- ReactDOM.render(
371
- <Root>
372
- <X />
373
- <React.Suspense fallback={z}>{steps[j]}</React.Suspense>
374
- <Y />
375
- </Root>,
376
- container,
377
- ),
378
- );
379
- // Verify the successful transition to steps[j].
380
- expect(print(store)).toEqual(snapshots[j]);
381
- // Check that we can transition back again.
382
- act(() =>
383
- ReactDOM.render(
384
- <Root>
385
- <X />
386
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
387
- <Y />
388
- </Root>,
389
- container,
390
- ),
391
- );
392
- expect(print(store)).toEqual(snapshots[i]);
393
- // Clean up after every iteration.
394
- act(() => ReactDOM.unmountComponentAtNode(container));
395
- expect(print(store)).toBe('');
396
- }
397
- }
398
-
399
- // 4. Verify we can update from each step to each step in fallback mode.
400
- for (let i = 0; i < steps.length; i++) {
401
- for (let j = 0; j < steps.length; j++) {
402
- // Always start with a fresh container and steps[i].
403
- container = document.createElement('div');
404
- act(() =>
405
- ReactDOM.render(
406
- <Root>
407
- <X />
408
- <React.Suspense fallback={steps[i]}>
409
- <Z />
410
- <Never />
411
- <Z />
412
- </React.Suspense>
413
- <Y />
414
- </Root>,
415
- container,
416
- ),
417
- );
418
- expect(print(store)).toEqual(snapshots[i]);
419
- // Re-render with steps[j].
420
- act(() =>
421
- ReactDOM.render(
422
- <Root>
423
- <X />
424
- <React.Suspense fallback={steps[j]}>
425
- <Z />
426
- <Never />
427
- <Z />
428
- </React.Suspense>
429
- <Y />
430
- </Root>,
431
- container,
432
- ),
433
- );
434
- // Verify the successful transition to steps[j].
435
- expect(print(store)).toEqual(snapshots[j]);
436
- // Check that we can transition back again.
437
- act(() =>
438
- ReactDOM.render(
439
- <Root>
440
- <X />
441
- <React.Suspense fallback={steps[i]}>
442
- <Z />
443
- <Never />
444
- <Z />
445
- </React.Suspense>
446
- <Y />
447
- </Root>,
448
- container,
449
- ),
450
- );
451
- expect(print(store)).toEqual(snapshots[i]);
452
- // Clean up after every iteration.
453
- act(() => ReactDOM.unmountComponentAtNode(container));
454
- expect(print(store)).toBe('');
455
- }
456
- }
457
-
458
- // 5. Verify we can update from each step to each step when moving primary -> fallback.
459
- for (let i = 0; i < steps.length; i++) {
460
- for (let j = 0; j < steps.length; j++) {
461
- // Always start with a fresh container and steps[i].
462
- container = document.createElement('div');
463
- act(() =>
464
- ReactDOM.render(
465
- <Root>
466
- <X />
467
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
468
- <Y />
469
- </Root>,
470
- container,
471
- ),
472
- );
473
- expect(print(store)).toEqual(snapshots[i]);
474
- // Re-render with steps[j].
475
- act(() =>
476
- ReactDOM.render(
477
- <Root>
478
- <X />
479
- <React.Suspense fallback={steps[j]}>
480
- <Z />
481
- <Never />
482
- <Z />
483
- </React.Suspense>
484
- <Y />
485
- </Root>,
486
- container,
487
- ),
488
- );
489
- // Verify the successful transition to steps[j].
490
- expect(print(store)).toEqual(snapshots[j]);
491
- // Check that we can transition back again.
492
- act(() =>
493
- ReactDOM.render(
494
- <Root>
495
- <X />
496
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
497
- <Y />
498
- </Root>,
499
- container,
500
- ),
501
- );
502
- expect(print(store)).toEqual(snapshots[i]);
503
- // Clean up after every iteration.
504
- act(() => ReactDOM.unmountComponentAtNode(container));
505
- expect(print(store)).toBe('');
506
- }
507
- }
508
-
509
- // 6. Verify we can update from each step to each step when moving fallback -> primary.
510
- for (let i = 0; i < steps.length; i++) {
511
- for (let j = 0; j < steps.length; j++) {
512
- // Always start with a fresh container and steps[i].
513
- container = document.createElement('div');
514
- act(() =>
515
- ReactDOM.render(
516
- <Root>
517
- <X />
518
- <React.Suspense fallback={steps[i]}>
519
- <Z />
520
- <Never />
521
- <Z />
522
- </React.Suspense>
523
- <Y />
524
- </Root>,
525
- container,
526
- ),
527
- );
528
- expect(print(store)).toEqual(snapshots[i]);
529
- // Re-render with steps[j].
530
- act(() =>
531
- ReactDOM.render(
532
- <Root>
533
- <X />
534
- <React.Suspense fallback={z}>{steps[j]}</React.Suspense>
535
- <Y />
536
- </Root>,
537
- container,
538
- ),
539
- );
540
- // Verify the successful transition to steps[j].
541
- expect(print(store)).toEqual(snapshots[j]);
542
- // Check that we can transition back again.
543
- act(() =>
544
- ReactDOM.render(
545
- <Root>
546
- <X />
547
- <React.Suspense fallback={steps[i]}>
548
- <Z />
549
- <Never />
550
- <Z />
551
- </React.Suspense>
552
- <Y />
553
- </Root>,
554
- container,
555
- ),
556
- );
557
- expect(print(store)).toEqual(snapshots[i]);
558
- // Clean up after every iteration.
559
- act(() => ReactDOM.unmountComponentAtNode(container));
560
- expect(print(store)).toBe('');
561
- }
562
- }
563
-
564
- // 7. Verify we can update from each step to each step when toggling Suspense.
565
- for (let i = 0; i < steps.length; i++) {
566
- for (let j = 0; j < steps.length; j++) {
567
- // Always start with a fresh container and steps[i].
568
- container = document.createElement('div');
569
- act(() =>
570
- ReactDOM.render(
571
- <Root>
572
- <X />
573
- <React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>
574
- <Y />
575
- </Root>,
576
- container,
577
- ),
578
- );
579
-
580
- // We get ID from the index in the tree above:
581
- // Root, X, Suspense, ...
582
- // ^ (index is 2)
583
- const suspenseID = store.getElementIDAtIndex(2);
584
-
585
- // Force fallback.
586
- expect(print(store)).toEqual(snapshots[i]);
587
- act(() => {
588
- bridge.send('overrideSuspense', {
589
- id: suspenseID,
590
- rendererID: store.getRendererIDForElement(suspenseID),
591
- forceFallback: true,
592
- });
593
- });
594
- expect(print(store)).toEqual(snapshots[j]);
595
-
596
- // Stop forcing fallback.
597
- act(() => {
598
- bridge.send('overrideSuspense', {
599
- id: suspenseID,
600
- rendererID: store.getRendererIDForElement(suspenseID),
601
- forceFallback: false,
602
- });
603
- });
604
- expect(print(store)).toEqual(snapshots[i]);
605
-
606
- // Trigger actual fallback.
607
- act(() =>
608
- ReactDOM.render(
609
- <Root>
610
- <X />
611
- <React.Suspense fallback={steps[j]}>
612
- <Z />
613
- <Never />
614
- <Z />
615
- </React.Suspense>
616
- <Y />
617
- </Root>,
618
- container,
619
- ),
620
- );
621
- expect(print(store)).toEqual(snapshots[j]);
622
-
623
- // Force fallback while we're in fallback mode.
624
- act(() => {
625
- bridge.send('overrideSuspense', {
626
- id: suspenseID,
627
- rendererID: store.getRendererIDForElement(suspenseID),
628
- forceFallback: true,
629
- });
630
- });
631
- // Keep seeing fallback content.
632
- expect(print(store)).toEqual(snapshots[j]);
633
-
634
- // Switch to primary mode.
635
- act(() =>
636
- ReactDOM.render(
637
- <Root>
638
- <X />
639
- <React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>
640
- <Y />
641
- </Root>,
642
- container,
643
- ),
644
- );
645
- // Fallback is still forced though.
646
- expect(print(store)).toEqual(snapshots[j]);
647
-
648
- // Stop forcing fallback. This reverts to primary content.
649
- act(() => {
650
- bridge.send('overrideSuspense', {
651
- id: suspenseID,
652
- rendererID: store.getRendererIDForElement(suspenseID),
653
- forceFallback: false,
654
- });
655
- });
656
- // Now we see primary content.
657
- expect(print(store)).toEqual(snapshots[i]);
658
-
659
- // Clean up after every iteration.
660
- act(() => ReactDOM.unmountComponentAtNode(container));
661
- expect(print(store)).toBe('');
662
- }
663
- }
664
- });
665
-
666
- it('should handle a stress test for Suspense without type change (Sync Mode)', () => {
667
- const A = () => 'a';
668
- const B = () => 'b';
669
- const C = () => 'c';
670
- const X = () => 'x';
671
- const Y = () => 'y';
672
- const Z = () => 'z';
673
- const a = <A key="a" />;
674
- const b = <B key="b" />;
675
- const c = <C key="c" />;
676
- const z = <Z key="z" />;
677
-
678
- // prettier-ignore
679
- const steps = [
680
- a,
681
- [a],
682
- [a, b, c],
683
- [c, b, a],
684
- [c, null, a],
685
- <React.Fragment>{c}{a}</React.Fragment>,
686
- <div>{c}{a}</div>,
687
- <div><span>{a}</span>{b}</div>,
688
- [[a]],
689
- null,
690
- b,
691
- a,
692
- ];
693
-
694
- const Never = () => {
695
- throw new Promise(() => {});
696
- };
697
-
698
- const MaybeSuspend = ({children, suspend}) => {
699
- if (suspend) {
700
- return (
701
- <div>
702
- {children}
703
- <Never />
704
- <X />
705
- </div>
706
- );
707
- }
708
- return (
709
- <div>
710
- {children}
711
- <Z />
712
- </div>
713
- );
714
- };
715
-
716
- const Root = ({children}) => {
717
- return children;
718
- };
719
-
720
- // 1. For each step, check Suspense can render them as initial primary content.
721
- // This is the only step where we use Jest snapshots.
722
- let snapshots = [];
723
- let container = document.createElement('div');
724
- for (let i = 0; i < steps.length; i++) {
725
- act(() =>
726
- ReactDOM.render(
727
- <Root>
728
- <X />
729
- <React.Suspense fallback={z}>
730
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
731
- </React.Suspense>
732
- <Y />
733
- </Root>,
734
- container,
735
- ),
736
- );
737
- // We snapshot each step once so it doesn't regress.
738
- expect(store).toMatchSnapshot();
739
- snapshots.push(print(store));
740
- act(() => ReactDOM.unmountComponentAtNode(container));
741
- expect(print(store)).toBe('');
742
- }
743
-
744
- // 2. Verify check Suspense can render same steps as initial fallback content.
745
- // We don't actually assert here because the tree includes <MaybeSuspend>
746
- // which is different from the snapshots above. So we take more snapshots.
747
- let fallbackSnapshots = [];
748
- for (let i = 0; i < steps.length; i++) {
749
- act(() =>
750
- ReactDOM.render(
751
- <Root>
752
- <X />
753
- <React.Suspense fallback={steps[i]}>
754
- <Z />
755
- <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>
756
- <Z />
757
- </React.Suspense>
758
- <Y />
759
- </Root>,
760
- container,
761
- ),
762
- );
763
- // We snapshot each step once so it doesn't regress.
764
- expect(store).toMatchSnapshot();
765
- fallbackSnapshots.push(print(store));
766
- act(() => ReactDOM.unmountComponentAtNode(container));
767
- expect(print(store)).toBe('');
768
- }
769
-
770
- // 3. Verify we can update from each step to each step in primary mode.
771
- for (let i = 0; i < steps.length; i++) {
772
- for (let j = 0; j < steps.length; j++) {
773
- // Always start with a fresh container and steps[i].
774
- container = document.createElement('div');
775
- act(() =>
776
- ReactDOM.render(
777
- <Root>
778
- <X />
779
- <React.Suspense fallback={z}>
780
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
781
- </React.Suspense>
782
- <Y />
783
- </Root>,
784
- container,
785
- ),
786
- );
787
- expect(print(store)).toEqual(snapshots[i]);
788
- // Re-render with steps[j].
789
- act(() =>
790
- ReactDOM.render(
791
- <Root>
792
- <X />
793
- <React.Suspense fallback={z}>
794
- <MaybeSuspend suspend={false}>{steps[j]}</MaybeSuspend>
795
- </React.Suspense>
796
- <Y />
797
- </Root>,
798
- container,
799
- ),
800
- );
801
- // Verify the successful transition to steps[j].
802
- expect(print(store)).toEqual(snapshots[j]);
803
- // Check that we can transition back again.
804
- act(() =>
805
- ReactDOM.render(
806
- <Root>
807
- <X />
808
- <React.Suspense fallback={z}>
809
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
810
- </React.Suspense>
811
- <Y />
812
- </Root>,
813
- container,
814
- ),
815
- );
816
- expect(print(store)).toEqual(snapshots[i]);
817
- // Clean up after every iteration.
818
- act(() => ReactDOM.unmountComponentAtNode(container));
819
- expect(print(store)).toBe('');
820
- }
821
- }
822
-
823
- // 4. Verify we can update from each step to each step in fallback mode.
824
- for (let i = 0; i < steps.length; i++) {
825
- for (let j = 0; j < steps.length; j++) {
826
- // Always start with a fresh container and steps[i].
827
- container = document.createElement('div');
828
- act(() =>
829
- ReactDOM.render(
830
- <Root>
831
- <X />
832
- <React.Suspense fallback={steps[i]}>
833
- <Z />
834
- <MaybeSuspend suspend={true}>
835
- <X />
836
- <Y />
837
- </MaybeSuspend>
838
- <Z />
839
- </React.Suspense>
840
- <Y />
841
- </Root>,
842
- container,
843
- ),
844
- );
845
- expect(print(store)).toEqual(fallbackSnapshots[i]);
846
- // Re-render with steps[j].
847
- act(() =>
848
- ReactDOM.render(
849
- <Root>
850
- <X />
851
- <React.Suspense fallback={steps[j]}>
852
- <Z />
853
- <MaybeSuspend suspend={true}>
854
- <Y />
855
- <X />
856
- </MaybeSuspend>
857
- <Z />
858
- </React.Suspense>
859
- <Y />
860
- </Root>,
861
- container,
862
- ),
863
- );
864
- // Verify the successful transition to steps[j].
865
- expect(print(store)).toEqual(fallbackSnapshots[j]);
866
- // Check that we can transition back again.
867
- act(() =>
868
- ReactDOM.render(
869
- <Root>
870
- <X />
871
- <React.Suspense fallback={steps[i]}>
872
- <Z />
873
- <MaybeSuspend suspend={true}>
874
- <X />
875
- <Y />
876
- </MaybeSuspend>
877
- <Z />
878
- </React.Suspense>
879
- <Y />
880
- </Root>,
881
- container,
882
- ),
883
- );
884
- expect(print(store)).toEqual(fallbackSnapshots[i]);
885
- // Clean up after every iteration.
886
- act(() => ReactDOM.unmountComponentAtNode(container));
887
- expect(print(store)).toBe('');
888
- }
889
- }
890
-
891
- // 5. Verify we can update from each step to each step when moving primary -> fallback.
892
- for (let i = 0; i < steps.length; i++) {
893
- for (let j = 0; j < steps.length; j++) {
894
- // Always start with a fresh container and steps[i].
895
- container = document.createElement('div');
896
- act(() =>
897
- ReactDOM.render(
898
- <Root>
899
- <X />
900
- <React.Suspense fallback={z}>
901
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
902
- </React.Suspense>
903
- <Y />
904
- </Root>,
905
- container,
906
- ),
907
- );
908
- expect(print(store)).toEqual(snapshots[i]);
909
- // Re-render with steps[j].
910
- act(() =>
911
- ReactDOM.render(
912
- <Root>
913
- <X />
914
- <React.Suspense fallback={steps[j]}>
915
- <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>
916
- </React.Suspense>
917
- <Y />
918
- </Root>,
919
- container,
920
- ),
921
- );
922
- // Verify the successful transition to steps[j].
923
- expect(print(store)).toEqual(fallbackSnapshots[j]);
924
- // Check that we can transition back again.
925
- act(() =>
926
- ReactDOM.render(
927
- <Root>
928
- <X />
929
- <React.Suspense fallback={z}>
930
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
931
- </React.Suspense>
932
- <Y />
933
- </Root>,
934
- container,
935
- ),
936
- );
937
- expect(print(store)).toEqual(snapshots[i]);
938
- // Clean up after every iteration.
939
- act(() => ReactDOM.unmountComponentAtNode(container));
940
- expect(print(store)).toBe('');
941
- }
942
- }
943
-
944
- // 6. Verify we can update from each step to each step when moving fallback -> primary.
945
- for (let i = 0; i < steps.length; i++) {
946
- for (let j = 0; j < steps.length; j++) {
947
- // Always start with a fresh container and steps[i].
948
- container = document.createElement('div');
949
- act(() =>
950
- ReactDOM.render(
951
- <Root>
952
- <X />
953
- <React.Suspense fallback={steps[i]}>
954
- <MaybeSuspend suspend={true}>{steps[j]}</MaybeSuspend>
955
- </React.Suspense>
956
- <Y />
957
- </Root>,
958
- container,
959
- ),
960
- );
961
- expect(print(store)).toEqual(fallbackSnapshots[i]);
962
- // Re-render with steps[j].
963
- act(() =>
964
- ReactDOM.render(
965
- <Root>
966
- <X />
967
- <React.Suspense fallback={steps[i]}>
968
- <MaybeSuspend suspend={false}>{steps[j]}</MaybeSuspend>
969
- </React.Suspense>
970
- <Y />
971
- </Root>,
972
- container,
973
- ),
974
- );
975
- // Verify the successful transition to steps[j].
976
- expect(print(store)).toEqual(snapshots[j]);
977
- // Check that we can transition back again.
978
- act(() =>
979
- ReactDOM.render(
980
- <Root>
981
- <X />
982
- <React.Suspense fallback={steps[i]}>
983
- <MaybeSuspend suspend={true}>{steps[j]}</MaybeSuspend>
984
- </React.Suspense>
985
- <Y />
986
- </Root>,
987
- container,
988
- ),
989
- );
990
- expect(print(store)).toEqual(fallbackSnapshots[i]);
991
- // Clean up after every iteration.
992
- act(() => ReactDOM.unmountComponentAtNode(container));
993
- expect(print(store)).toBe('');
994
- }
995
- }
996
-
997
- // 7. Verify we can update from each step to each step when toggling Suspense.
998
- for (let i = 0; i < steps.length; i++) {
999
- for (let j = 0; j < steps.length; j++) {
1000
- // Always start with a fresh container and steps[i].
1001
- container = document.createElement('div');
1002
- act(() =>
1003
- ReactDOM.render(
1004
- <Root>
1005
- <X />
1006
- <React.Suspense fallback={steps[j]}>
1007
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
1008
- </React.Suspense>
1009
- <Y />
1010
- </Root>,
1011
- container,
1012
- ),
1013
- );
1014
-
1015
- // We get ID from the index in the tree above:
1016
- // Root, X, Suspense, ...
1017
- // ^ (index is 2)
1018
- const suspenseID = store.getElementIDAtIndex(2);
1019
-
1020
- // Force fallback.
1021
- expect(print(store)).toEqual(snapshots[i]);
1022
- act(() => {
1023
- bridge.send('overrideSuspense', {
1024
- id: suspenseID,
1025
- rendererID: store.getRendererIDForElement(suspenseID),
1026
- forceFallback: true,
1027
- });
1028
- });
1029
- expect(print(store)).toEqual(fallbackSnapshots[j]);
1030
-
1031
- // Stop forcing fallback.
1032
- act(() => {
1033
- bridge.send('overrideSuspense', {
1034
- id: suspenseID,
1035
- rendererID: store.getRendererIDForElement(suspenseID),
1036
- forceFallback: false,
1037
- });
1038
- });
1039
- expect(print(store)).toEqual(snapshots[i]);
1040
-
1041
- // Trigger actual fallback.
1042
- act(() =>
1043
- ReactDOM.render(
1044
- <Root>
1045
- <X />
1046
- <React.Suspense fallback={steps[j]}>
1047
- <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>
1048
- </React.Suspense>
1049
- <Y />
1050
- </Root>,
1051
- container,
1052
- ),
1053
- );
1054
- expect(print(store)).toEqual(fallbackSnapshots[j]);
1055
-
1056
- // Force fallback while we're in fallback mode.
1057
- act(() => {
1058
- bridge.send('overrideSuspense', {
1059
- id: suspenseID,
1060
- rendererID: store.getRendererIDForElement(suspenseID),
1061
- forceFallback: true,
1062
- });
1063
- });
1064
- // Keep seeing fallback content.
1065
- expect(print(store)).toEqual(fallbackSnapshots[j]);
1066
-
1067
- // Switch to primary mode.
1068
- act(() =>
1069
- ReactDOM.render(
1070
- <Root>
1071
- <X />
1072
- <React.Suspense fallback={steps[j]}>
1073
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
1074
- </React.Suspense>
1075
- <Y />
1076
- </Root>,
1077
- container,
1078
- ),
1079
- );
1080
- // Fallback is still forced though.
1081
- expect(print(store)).toEqual(fallbackSnapshots[j]);
1082
-
1083
- // Stop forcing fallback. This reverts to primary content.
1084
- act(() => {
1085
- bridge.send('overrideSuspense', {
1086
- id: suspenseID,
1087
- rendererID: store.getRendererIDForElement(suspenseID),
1088
- forceFallback: false,
1089
- });
1090
- });
1091
- // Now we see primary content.
1092
- expect(print(store)).toEqual(snapshots[i]);
1093
-
1094
- // Clean up after every iteration.
1095
- act(() => ReactDOM.unmountComponentAtNode(container));
1096
- expect(print(store)).toBe('');
1097
- }
1098
- }
1099
- });
1100
-});
packages/react-devtools-shared/src/__tests__/storeStressTestConcurrent-test.js
deleted
-1099
@@ -1,1099 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-describe('StoreStressConcurrent', () => {
11
- let React;
12
- let ReactDOM;
13
- let act;
14
- let bridge;
15
- let store;
16
- let print;
17
-
18
- beforeEach(() => {
19
- bridge = global.bridge;
20
- store = global.store;
21
- store.collapseNodesByDefault = false;
22
-
23
- React = require('react');
24
- ReactDOM = require('react-dom');
25
- act = require('./utils').act;
26
-
27
- print = require('./storeSerializer').print;
28
- });
29
-
30
- // This is a stress test for the tree mount/update/unmount traversal.
31
- // It renders different trees that should produce the same output.
32
- it('should handle a stress test with different tree operations (Concurrent Mode)', () => {
33
- let setShowX;
34
- const A = () => 'a';
35
- const B = () => 'b';
36
- const C = () => {
37
- // We'll be manually flipping this component back and forth in the test.
38
- // We only do this for a single node in order to verify that DevTools
39
- // can handle a subtree switching alternates while other subtrees are memoized.
40
- let [showX, _setShowX] = React.useState(false);
41
- setShowX = _setShowX;
42
- return showX ? <X /> : 'c';
43
- };
44
- const D = () => 'd';
45
- const E = () => 'e';
46
- const X = () => 'x';
47
- const a = <A key="a" />;
48
- const b = <B key="b" />;
49
- const c = <C key="c" />;
50
- const d = <D key="d" />;
51
- const e = <E key="e" />;
52
-
53
- function Parent({children}) {
54
- return children;
55
- }
56
-
57
- // 1. Render a normal version of [a, b, c, d, e].
58
- let container = document.createElement('div');
59
- // $FlowFixMe
60
- let root = ReactDOM.unstable_createRoot(container);
61
- act(() => root.render(<Parent>{[a, b, c, d, e]}</Parent>));
62
- expect(store).toMatchSnapshot('1: abcde');
63
- expect(container.textContent).toMatch('abcde');
64
- const snapshotForABCDE = print(store);
65
-
66
- // 2. Render a version where <C /> renders an <X /> child instead of 'c'.
67
- // This is how we'll test an update to a single component.
68
- act(() => {
69
- setShowX(true);
70
- });
71
- expect(store).toMatchSnapshot('2: abxde');
72
- expect(container.textContent).toMatch('abxde');
73
- const snapshotForABXDE = print(store);
74
-
75
- // 3. Verify flipping it back produces the original result.
76
- act(() => {
77
- setShowX(false);
78
- });
79
- expect(container.textContent).toMatch('abcde');
80
- expect(print(store)).toBe(snapshotForABCDE);
81
-
82
- // 4. Clean up.
83
- act(() => root.unmount());
84
- expect(print(store)).toBe('');
85
-
86
- // Now comes the interesting part.
87
- // All of these cases are equivalent to [a, b, c, d, e] in output.
88
- // We'll verify that DevTools produces the same snapshots for them.
89
- // These cases are picked so that rendering them sequentially in the same
90
- // container results in a combination of mounts, updates, unmounts, and reorders.
91
- // prettier-ignore
92
- let cases = [
93
- [a, b, c, d, e],
94
- [[a], b, c, d, e],
95
- [[a, b], c, d, e],
96
- [[a, b], c, [d, e]],
97
- [[a, b], c, [d, '', e]],
98
- [[a], b, c, d, [e]],
99
- [a, b, [[c]], d, e],
100
- [[a, ''], [b], [c], [d], [e]],
101
- [a, b, [c, [d, ['', e]]]],
102
- [a, b, c, d, e],
103
- [<div key="0">{a}</div>, b, c, d, e],
104
- [<div key="0">{a}{b}</div>, c, d, e],
105
- [<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],
106
- [<div key="1">{a}{b}</div>, c, <div key="0">{d}{e}</div>],
107
- [<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],
108
- [<div key="2">{a}{b}</div>, c, <div key="3">{d}{e}</div>],
109
- [<span key="0">{a}</span>, b, c, d, [e]],
110
- [a, b, <span key="0"><span>{c}</span></span>, d, e],
111
- [<div key="0">{a}</div>, [b], <span key="1">{c}</span>, [d], <div key="2">{e}</div>],
112
- [a, b, [c, <div key="0">{d}<span>{e}</span></div>], ''],
113
- [a, [[]], b, c, [d, [[]], e]],
114
- [[[a, b, c, d], e]],
115
- [a, b, c, d, e],
116
- ];
117
-
118
- // 5. Test fresh mount for each case.
119
- for (let i = 0; i < cases.length; i++) {
120
- // Ensure fresh mount.
121
- container = document.createElement('div');
122
- // $FlowFixMe
123
- root = ReactDOM.unstable_createRoot(container);
124
-
125
- // Verify mounting 'abcde'.
126
- act(() => root.render(<Parent>{cases[i]}</Parent>));
127
- expect(container.textContent).toMatch('abcde');
128
- expect(print(store)).toEqual(snapshotForABCDE);
129
-
130
- // Verify switching to 'abxde'.
131
- act(() => {
132
- setShowX(true);
133
- });
134
- expect(container.textContent).toMatch('abxde');
135
- expect(print(store)).toBe(snapshotForABXDE);
136
-
137
- // Verify switching back to 'abcde'.
138
- act(() => {
139
- setShowX(false);
140
- });
141
- expect(container.textContent).toMatch('abcde');
142
- expect(print(store)).toBe(snapshotForABCDE);
143
-
144
- // Clean up.
145
- act(() => root.unmount());
146
- expect(print(store)).toBe('');
147
- }
148
-
149
- // 6. Verify *updates* by reusing the container between iterations.
150
- // There'll be no unmounting until the very end.
151
- container = document.createElement('div');
152
- // $FlowFixMe
153
- root = ReactDOM.unstable_createRoot(container);
154
- for (let i = 0; i < cases.length; i++) {
155
- // Verify mounting 'abcde'.
156
- act(() => root.render(<Parent>{cases[i]}</Parent>));
157
- expect(container.textContent).toMatch('abcde');
158
- expect(print(store)).toEqual(snapshotForABCDE);
159
-
160
- // Verify switching to 'abxde'.
161
- act(() => {
162
- setShowX(true);
163
- });
164
- expect(container.textContent).toMatch('abxde');
165
- expect(print(store)).toBe(snapshotForABXDE);
166
-
167
- // Verify switching back to 'abcde'.
168
- act(() => {
169
- setShowX(false);
170
- });
171
- expect(container.textContent).toMatch('abcde');
172
- expect(print(store)).toBe(snapshotForABCDE);
173
- // Don't unmount. Reuse the container between iterations.
174
- }
175
- act(() => root.unmount());
176
- expect(print(store)).toBe('');
177
- });
178
-
179
- it('should handle stress test with reordering (Concurrent Mode)', () => {
180
- const A = () => 'a';
181
- const B = () => 'b';
182
- const C = () => 'c';
183
- const D = () => 'd';
184
- const E = () => 'e';
185
- const a = <A key="a" />;
186
- const b = <B key="b" />;
187
- const c = <C key="c" />;
188
- const d = <D key="d" />;
189
- const e = <E key="e" />;
190
-
191
- // prettier-ignore
192
- let steps = [
193
- a,
194
- b,
195
- c,
196
- d,
197
- e,
198
- [a],
199
- [b],
200
- [c],
201
- [d],
202
- [e],
203
- [a, b],
204
- [b, a],
205
- [b, c],
206
- [c, b],
207
- [a, c],
208
- [c, a],
209
- ];
210
-
211
- const Root = ({children}) => {
212
- return children;
213
- };
214
-
215
- // 1. Capture the expected render result.
216
- let snapshots = [];
217
- let container = document.createElement('div');
218
- // $FlowFixMe
219
- let root = ReactDOM.unstable_createRoot(container);
220
- for (let i = 0; i < steps.length; i++) {
221
- act(() => root.render(<Root>{steps[i]}</Root>));
222
- // We snapshot each step once so it doesn't regress.
223
- expect(store).toMatchSnapshot();
224
- snapshots.push(print(store));
225
- act(() => root.unmount());
226
- expect(print(store)).toBe('');
227
- }
228
-
229
- // 2. Verify that we can update from every step to every other step and back.
230
- for (let i = 0; i < steps.length; i++) {
231
- for (let j = 0; j < steps.length; j++) {
232
- container = document.createElement('div');
233
- // $FlowFixMe
234
- root = ReactDOM.unstable_createRoot(container);
235
- act(() => root.render(<Root>{steps[i]}</Root>));
236
- expect(print(store)).toMatch(snapshots[i]);
237
- act(() => root.render(<Root>{steps[j]}</Root>));
238
- expect(print(store)).toMatch(snapshots[j]);
239
- act(() => root.render(<Root>{steps[i]}</Root>));
240
- expect(print(store)).toMatch(snapshots[i]);
241
- act(() => root.unmount());
242
- expect(print(store)).toBe('');
243
- }
244
- }
245
-
246
- // 3. Same test as above, but this time we wrap children in a host component.
247
- for (let i = 0; i < steps.length; i++) {
248
- for (let j = 0; j < steps.length; j++) {
249
- container = document.createElement('div');
250
- // $FlowFixMe
251
- root = ReactDOM.unstable_createRoot(container);
252
- act(() =>
253
- root.render(
254
- <Root>
255
- <div>{steps[i]}</div>
256
- </Root>,
257
- ),
258
- );
259
- expect(print(store)).toMatch(snapshots[i]);
260
- act(() =>
261
- root.render(
262
- <Root>
263
- <div>{steps[j]}</div>
264
- </Root>,
265
- ),
266
- );
267
- expect(print(store)).toMatch(snapshots[j]);
268
- act(() =>
269
- root.render(
270
- <Root>
271
- <div>{steps[i]}</div>
272
- </Root>,
273
- ),
274
- );
275
- expect(print(store)).toMatch(snapshots[i]);
276
- act(() => root.unmount());
277
- expect(print(store)).toBe('');
278
- }
279
- }
280
- });
281
-
282
- it('should handle a stress test for Suspense (Concurrent Mode)', async () => {
283
- const A = () => 'a';
284
- const B = () => 'b';
285
- const C = () => 'c';
286
- const X = () => 'x';
287
- const Y = () => 'y';
288
- const Z = () => 'z';
289
- const a = <A key="a" />;
290
- const b = <B key="b" />;
291
- const c = <C key="c" />;
292
- const z = <Z key="z" />;
293
-
294
- // prettier-ignore
295
- const steps = [
296
- a,
297
- [a],
298
- [a, b, c],
299
- [c, b, a],
300
- [c, null, a],
301
- <React.Fragment>{c}{a}</React.Fragment>,
302
- <div>{c}{a}</div>,
303
- <div><span>{a}</span>{b}</div>,
304
- [[a]],
305
- null,
306
- b,
307
- a,
308
- ];
309
-
310
- const Never = () => {
311
- throw new Promise(() => {});
312
- };
313
-
314
- const Root = ({children}) => {
315
- return children;
316
- };
317
-
318
- // 1. For each step, check Suspense can render them as initial primary content.
319
- // This is the only step where we use Jest snapshots.
320
- let snapshots = [];
321
- let container = document.createElement('div');
322
- // $FlowFixMe
323
- let root = ReactDOM.unstable_createRoot(container);
324
- for (let i = 0; i < steps.length; i++) {
325
- act(() =>
326
- root.render(
327
- <Root>
328
- <X />
329
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
330
- <Y />
331
- </Root>,
332
- ),
333
- );
334
- // We snapshot each step once so it doesn't regress.
335
- expect(store).toMatchSnapshot();
336
- snapshots.push(print(store));
337
- act(() => root.unmount());
338
- expect(print(store)).toBe('');
339
- }
340
-
341
- // 2. Verify check Suspense can render same steps as initial fallback content.
342
- for (let i = 0; i < steps.length; i++) {
343
- act(() =>
344
- root.render(
345
- <Root>
346
- <X />
347
- <React.Suspense fallback={steps[i]}>
348
- <Z />
349
- <Never />
350
- <Z />
351
- </React.Suspense>
352
- <Y />
353
- </Root>,
354
- ),
355
- );
356
- expect(print(store)).toEqual(snapshots[i]);
357
- act(() => root.unmount());
358
- expect(print(store)).toBe('');
359
- }
360
-
361
- // 3. Verify we can update from each step to each step in primary mode.
362
- for (let i = 0; i < steps.length; i++) {
363
- for (let j = 0; j < steps.length; j++) {
364
- // Always start with a fresh container and steps[i].
365
- container = document.createElement('div');
366
- // $FlowFixMe
367
- root = ReactDOM.unstable_createRoot(container);
368
- act(() =>
369
- root.render(
370
- <Root>
371
- <X />
372
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
373
- <Y />
374
- </Root>,
375
- ),
376
- );
377
- expect(print(store)).toEqual(snapshots[i]);
378
- // Re-render with steps[j].
379
- act(() =>
380
- root.render(
381
- <Root>
382
- <X />
383
- <React.Suspense fallback={z}>{steps[j]}</React.Suspense>
384
- <Y />
385
- </Root>,
386
- ),
387
- );
388
- // Verify the successful transition to steps[j].
389
- expect(print(store)).toEqual(snapshots[j]);
390
- // Check that we can transition back again.
391
- act(() =>
392
- root.render(
393
- <Root>
394
- <X />
395
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
396
- <Y />
397
- </Root>,
398
- ),
399
- );
400
- expect(print(store)).toEqual(snapshots[i]);
401
- // Clean up after every iteration.
402
- act(() => root.unmount());
403
- expect(print(store)).toBe('');
404
- }
405
- }
406
-
407
- // 4. Verify we can update from each step to each step in fallback mode.
408
- for (let i = 0; i < steps.length; i++) {
409
- for (let j = 0; j < steps.length; j++) {
410
- // Always start with a fresh container and steps[i].
411
- container = document.createElement('div');
412
- // $FlowFixMe
413
- root = ReactDOM.unstable_createRoot(container);
414
- act(() =>
415
- root.render(
416
- <Root>
417
- <X />
418
- <React.Suspense fallback={steps[i]}>
419
- <Z />
420
- <Never />
421
- <Z />
422
- </React.Suspense>
423
- <Y />
424
- </Root>,
425
- ),
426
- );
427
- expect(print(store)).toEqual(snapshots[i]);
428
- // Re-render with steps[j].
429
- act(() =>
430
- root.render(
431
- <Root>
432
- <X />
433
- <React.Suspense fallback={steps[j]}>
434
- <Z />
435
- <Never />
436
- <Z />
437
- </React.Suspense>
438
- <Y />
439
- </Root>,
440
- ),
441
- );
442
- // Verify the successful transition to steps[j].
443
- expect(print(store)).toEqual(snapshots[j]);
444
- // Check that we can transition back again.
445
- act(() =>
446
- root.render(
447
- <Root>
448
- <X />
449
- <React.Suspense fallback={steps[i]}>
450
- <Z />
451
- <Never />
452
- <Z />
453
- </React.Suspense>
454
- <Y />
455
- </Root>,
456
- ),
457
- );
458
- expect(print(store)).toEqual(snapshots[i]);
459
- // Clean up after every iteration.
460
- act(() => root.unmount());
461
- expect(print(store)).toBe('');
462
- }
463
- }
464
-
465
- // 5. Verify we can update from each step to each step when moving primary -> fallback.
466
- for (let i = 0; i < steps.length; i++) {
467
- for (let j = 0; j < steps.length; j++) {
468
- // Always start with a fresh container and steps[i].
469
- container = document.createElement('div');
470
- // $FlowFixMe
471
- root = ReactDOM.unstable_createRoot(container);
472
- act(() =>
473
- root.render(
474
- <Root>
475
- <X />
476
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
477
- <Y />
478
- </Root>,
479
- ),
480
- );
481
- expect(print(store)).toEqual(snapshots[i]);
482
- // Re-render with steps[j].
483
- act(() =>
484
- root.render(
485
- <Root>
486
- <X />
487
- <React.Suspense fallback={steps[j]}>
488
- <Z />
489
- <Never />
490
- <Z />
491
- </React.Suspense>
492
- <Y />
493
- </Root>,
494
- ),
495
- );
496
- // Verify the successful transition to steps[j].
497
- expect(print(store)).toEqual(snapshots[j]);
498
- // Check that we can transition back again.
499
- act(() =>
500
- root.render(
501
- <Root>
502
- <X />
503
- <React.Suspense fallback={z}>{steps[i]}</React.Suspense>
504
- <Y />
505
- </Root>,
506
- ),
507
- );
508
- expect(print(store)).toEqual(snapshots[i]);
509
- // Clean up after every iteration.
510
- act(() => root.unmount());
511
- expect(print(store)).toBe('');
512
- }
513
- }
514
-
515
- // 6. Verify we can update from each step to each step when moving fallback -> primary.
516
- for (let i = 0; i < steps.length; i++) {
517
- for (let j = 0; j < steps.length; j++) {
518
- // Always start with a fresh container and steps[i].
519
- container = document.createElement('div');
520
- // $FlowFixMe
521
- root = ReactDOM.unstable_createRoot(container);
522
- act(() =>
523
- root.render(
524
- <Root>
525
- <X />
526
- <React.Suspense fallback={steps[i]}>
527
- <Z />
528
- <Never />
529
- <Z />
530
- </React.Suspense>
531
- <Y />
532
- </Root>,
533
- ),
534
- );
535
- expect(print(store)).toEqual(snapshots[i]);
536
- // Re-render with steps[j].
537
- act(() =>
538
- root.render(
539
- <Root>
540
- <X />
541
- <React.Suspense fallback={z}>{steps[j]}</React.Suspense>
542
- <Y />
543
- </Root>,
544
- ),
545
- );
546
- // Verify the successful transition to steps[j].
547
- expect(print(store)).toEqual(snapshots[j]);
548
- // Check that we can transition back again.
549
- act(() =>
550
- root.render(
551
- <Root>
552
- <X />
553
- <React.Suspense fallback={steps[i]}>
554
- <Z />
555
- <Never />
556
- <Z />
557
- </React.Suspense>
558
- <Y />
559
- </Root>,
560
- ),
561
- );
562
- expect(print(store)).toEqual(snapshots[i]);
563
- // Clean up after every iteration.
564
- act(() => root.unmount());
565
- expect(print(store)).toBe('');
566
- }
567
- }
568
-
569
- // 7. Verify we can update from each step to each step when toggling Suspense.
570
- for (let i = 0; i < steps.length; i++) {
571
- for (let j = 0; j < steps.length; j++) {
572
- // Always start with a fresh container and steps[i].
573
- container = document.createElement('div');
574
- // $FlowFixMe
575
- root = ReactDOM.unstable_createRoot(container);
576
- act(() =>
577
- root.render(
578
- <Root>
579
- <X />
580
- <React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>
581
- <Y />
582
- </Root>,
583
- ),
584
- );
585
-
586
- // We get ID from the index in the tree above:
587
- // Root, X, Suspense, ...
588
- // ^ (index is 2)
589
- const suspenseID = store.getElementIDAtIndex(2);
590
-
591
- // Force fallback.
592
- expect(print(store)).toEqual(snapshots[i]);
593
- act(() => {
594
- bridge.send('overrideSuspense', {
595
- id: suspenseID,
596
- rendererID: store.getRendererIDForElement(suspenseID),
597
- forceFallback: true,
598
- });
599
- });
600
- expect(print(store)).toEqual(snapshots[j]);
601
-
602
- // Stop forcing fallback.
603
- act(() => {
604
- bridge.send('overrideSuspense', {
605
- id: suspenseID,
606
- rendererID: store.getRendererIDForElement(suspenseID),
607
- forceFallback: false,
608
- });
609
- });
610
- expect(print(store)).toEqual(snapshots[i]);
611
-
612
- // Trigger actual fallback.
613
- act(() =>
614
- root.render(
615
- <Root>
616
- <X />
617
- <React.Suspense fallback={steps[j]}>
618
- <Z />
619
- <Never />
620
- <Z />
621
- </React.Suspense>
622
- <Y />
623
- </Root>,
624
- ),
625
- );
626
- expect(print(store)).toEqual(snapshots[j]);
627
-
628
- // Force fallback while we're in fallback mode.
629
- act(() => {
630
- bridge.send('overrideSuspense', {
631
- id: suspenseID,
632
- rendererID: store.getRendererIDForElement(suspenseID),
633
- forceFallback: true,
634
- });
635
- });
636
- // Keep seeing fallback content.
637
- expect(print(store)).toEqual(snapshots[j]);
638
-
639
- // Switch to primary mode.
640
- act(() =>
641
- root.render(
642
- <Root>
643
- <X />
644
- <React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>
645
- <Y />
646
- </Root>,
647
- ),
648
- );
649
- // Fallback is still forced though.
650
- expect(print(store)).toEqual(snapshots[j]);
651
-
652
- // Stop forcing fallback. This reverts to primary content.
653
- act(() => {
654
- bridge.send('overrideSuspense', {
655
- id: suspenseID,
656
- rendererID: store.getRendererIDForElement(suspenseID),
657
- forceFallback: false,
658
- });
659
- });
660
- // Now we see primary content.
661
- expect(print(store)).toEqual(snapshots[i]);
662
-
663
- // Clean up after every iteration.
664
- act(() => root.unmount());
665
- expect(print(store)).toBe('');
666
- }
667
- }
668
- });
669
-
670
- it('should handle a stress test for Suspense without type change (Concurrent Mode)', () => {
671
- const A = () => 'a';
672
- const B = () => 'b';
673
- const C = () => 'c';
674
- const X = () => 'x';
675
- const Y = () => 'y';
676
- const Z = () => 'z';
677
- const a = <A key="a" />;
678
- const b = <B key="b" />;
679
- const c = <C key="c" />;
680
- const z = <Z key="z" />;
681
-
682
- // prettier-ignore
683
- const steps = [
684
- a,
685
- [a],
686
- [a, b, c],
687
- [c, b, a],
688
- [c, null, a],
689
- <React.Fragment>{c}{a}</React.Fragment>,
690
- <div>{c}{a}</div>,
691
- <div><span>{a}</span>{b}</div>,
692
- [[a]],
693
- null,
694
- b,
695
- a,
696
- ];
697
-
698
- const Never = () => {
699
- throw new Promise(() => {});
700
- };
701
-
702
- const MaybeSuspend = ({children, suspend}) => {
703
- if (suspend) {
704
- return (
705
- <div>
706
- {children}
707
- <Never />
708
- <X />
709
- </div>
710
- );
711
- }
712
- return (
713
- <div>
714
- {children}
715
- <Z />
716
- </div>
717
- );
718
- };
719
-
720
- const Root = ({children}) => {
721
- return children;
722
- };
723
-
724
- // 1. For each step, check Suspense can render them as initial primary content.
725
- // This is the only step where we use Jest snapshots.
726
- let snapshots = [];
727
- let container = document.createElement('div');
728
- // $FlowFixMe
729
- let root = ReactDOM.unstable_createRoot(container);
730
- for (let i = 0; i < steps.length; i++) {
731
- act(() =>
732
- root.render(
733
- <Root>
734
- <X />
735
- <React.Suspense fallback={z}>
736
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
737
- </React.Suspense>
738
- <Y />
739
- </Root>,
740
- ),
741
- );
742
- // We snapshot each step once so it doesn't regress.
743
- expect(store).toMatchSnapshot();
744
- snapshots.push(print(store));
745
- act(() => root.unmount());
746
- expect(print(store)).toBe('');
747
- }
748
-
749
- // 2. Verify check Suspense can render same steps as initial fallback content.
750
- // We don't actually assert here because the tree includes <MaybeSuspend>
751
- // which is different from the snapshots above. So we take more snapshots.
752
- let fallbackSnapshots = [];
753
- for (let i = 0; i < steps.length; i++) {
754
- act(() =>
755
- root.render(
756
- <Root>
757
- <X />
758
- <React.Suspense fallback={steps[i]}>
759
- <Z />
760
- <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>
761
- <Z />
762
- </React.Suspense>
763
- <Y />
764
- </Root>,
765
- ),
766
- );
767
- // We snapshot each step once so it doesn't regress.
768
- expect(store).toMatchSnapshot();
769
- fallbackSnapshots.push(print(store));
770
- act(() => root.unmount());
771
- expect(print(store)).toBe('');
772
- }
773
-
774
- // 3. Verify we can update from each step to each step in primary mode.
775
- for (let i = 0; i < steps.length; i++) {
776
- for (let j = 0; j < steps.length; j++) {
777
- // Always start with a fresh container and steps[i].
778
- container = document.createElement('div');
779
- // $FlowFixMe
780
- root = ReactDOM.unstable_createRoot(container);
781
- act(() =>
782
- root.render(
783
- <Root>
784
- <X />
785
- <React.Suspense fallback={z}>
786
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
787
- </React.Suspense>
788
- <Y />
789
- </Root>,
790
- ),
791
- );
792
- expect(print(store)).toEqual(snapshots[i]);
793
- // Re-render with steps[j].
794
- act(() =>
795
- root.render(
796
- <Root>
797
- <X />
798
- <React.Suspense fallback={z}>
799
- <MaybeSuspend suspend={false}>{steps[j]}</MaybeSuspend>
800
- </React.Suspense>
801
- <Y />
802
- </Root>,
803
- ),
804
- );
805
- // Verify the successful transition to steps[j].
806
- expect(print(store)).toEqual(snapshots[j]);
807
- // Check that we can transition back again.
808
- act(() =>
809
- root.render(
810
- <Root>
811
- <X />
812
- <React.Suspense fallback={z}>
813
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
814
- </React.Suspense>
815
- <Y />
816
- </Root>,
817
- ),
818
- );
819
- expect(print(store)).toEqual(snapshots[i]);
820
- // Clean up after every iteration.
821
- act(() => root.unmount());
822
- expect(print(store)).toBe('');
823
- }
824
- }
825
-
826
- // 4. Verify we can update from each step to each step in fallback mode.
827
- for (let i = 0; i < steps.length; i++) {
828
- for (let j = 0; j < steps.length; j++) {
829
- // Always start with a fresh container and steps[i].
830
- container = document.createElement('div');
831
- // $FlowFixMe
832
- root = ReactDOM.unstable_createRoot(container);
833
- act(() =>
834
- root.render(
835
- <Root>
836
- <X />
837
- <React.Suspense fallback={steps[i]}>
838
- <Z />
839
- <MaybeSuspend suspend={true}>
840
- <X />
841
- <Y />
842
- </MaybeSuspend>
843
- <Z />
844
- </React.Suspense>
845
- <Y />
846
- </Root>,
847
- ),
848
- );
849
- expect(print(store)).toEqual(fallbackSnapshots[i]);
850
- // Re-render with steps[j].
851
- act(() =>
852
- root.render(
853
- <Root>
854
- <X />
855
- <React.Suspense fallback={steps[j]}>
856
- <Z />
857
- <MaybeSuspend suspend={true}>
858
- <Y />
859
- <X />
860
- </MaybeSuspend>
861
- <Z />
862
- </React.Suspense>
863
- <Y />
864
- </Root>,
865
- ),
866
- );
867
- // Verify the successful transition to steps[j].
868
- expect(print(store)).toEqual(fallbackSnapshots[j]);
869
- // Check that we can transition back again.
870
- act(() =>
871
- root.render(
872
- <Root>
873
- <X />
874
- <React.Suspense fallback={steps[i]}>
875
- <Z />
876
- <MaybeSuspend suspend={true}>
877
- <X />
878
- <Y />
879
- </MaybeSuspend>
880
- <Z />
881
- </React.Suspense>
882
- <Y />
883
- </Root>,
884
- ),
885
- );
886
- expect(print(store)).toEqual(fallbackSnapshots[i]);
887
- // Clean up after every iteration.
888
- act(() => root.unmount());
889
- expect(print(store)).toBe('');
890
- }
891
- }
892
-
893
- // 5. Verify we can update from each step to each step when moving primary -> fallback.
894
- for (let i = 0; i < steps.length; i++) {
895
- for (let j = 0; j < steps.length; j++) {
896
- // Always start with a fresh container and steps[i].
897
- container = document.createElement('div');
898
- // $FlowFixMe
899
- root = ReactDOM.unstable_createRoot(container);
900
- act(() =>
901
- root.render(
902
- <Root>
903
- <X />
904
- <React.Suspense fallback={z}>
905
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
906
- </React.Suspense>
907
- <Y />
908
- </Root>,
909
- ),
910
- );
911
- expect(print(store)).toEqual(snapshots[i]);
912
- // Re-render with steps[j].
913
- act(() =>
914
- root.render(
915
- <Root>
916
- <X />
917
- <React.Suspense fallback={steps[j]}>
918
- <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>
919
- </React.Suspense>
920
- <Y />
921
- </Root>,
922
- ),
923
- );
924
- // Verify the successful transition to steps[j].
925
- expect(print(store)).toEqual(fallbackSnapshots[j]);
926
- // Check that we can transition back again.
927
- act(() =>
928
- root.render(
929
- <Root>
930
- <X />
931
- <React.Suspense fallback={z}>
932
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
933
- </React.Suspense>
934
- <Y />
935
- </Root>,
936
- ),
937
- );
938
- expect(print(store)).toEqual(snapshots[i]);
939
- // Clean up after every iteration.
940
- act(() => root.unmount());
941
- expect(print(store)).toBe('');
942
- }
943
- }
944
-
945
- // 6. Verify we can update from each step to each step when moving fallback -> primary.
946
- for (let i = 0; i < steps.length; i++) {
947
- for (let j = 0; j < steps.length; j++) {
948
- // Always start with a fresh container and steps[i].
949
- container = document.createElement('div');
950
- // $FlowFixMe
951
- root = ReactDOM.unstable_createRoot(container);
952
- act(() =>
953
- root.render(
954
- <Root>
955
- <X />
956
- <React.Suspense fallback={steps[i]}>
957
- <MaybeSuspend suspend={true}>{steps[j]}</MaybeSuspend>
958
- </React.Suspense>
959
- <Y />
960
- </Root>,
961
- ),
962
- );
963
- expect(print(store)).toEqual(fallbackSnapshots[i]);
964
- // Re-render with steps[j].
965
- act(() =>
966
- root.render(
967
- <Root>
968
- <X />
969
- <React.Suspense fallback={steps[i]}>
970
- <MaybeSuspend suspend={false}>{steps[j]}</MaybeSuspend>
971
- </React.Suspense>
972
- <Y />
973
- </Root>,
974
- ),
975
- );
976
- // Verify the successful transition to steps[j].
977
- expect(print(store)).toEqual(snapshots[j]);
978
- // Check that we can transition back again.
979
- act(() =>
980
- root.render(
981
- <Root>
982
- <X />
983
- <React.Suspense fallback={steps[i]}>
984
- <MaybeSuspend suspend={true}>{steps[j]}</MaybeSuspend>
985
- </React.Suspense>
986
- <Y />
987
- </Root>,
988
- ),
989
- );
990
- expect(print(store)).toEqual(fallbackSnapshots[i]);
991
- // Clean up after every iteration.
992
- act(() => root.unmount());
993
- expect(print(store)).toBe('');
994
- }
995
- }
996
-
997
- // 7. Verify we can update from each step to each step when toggling Suspense.
998
- for (let i = 0; i < steps.length; i++) {
999
- for (let j = 0; j < steps.length; j++) {
1000
- // Always start with a fresh container and steps[i].
1001
- container = document.createElement('div');
1002
- // $FlowFixMe
1003
- root = ReactDOM.unstable_createRoot(container);
1004
- act(() =>
1005
- root.render(
1006
- <Root>
1007
- <X />
1008
- <React.Suspense fallback={steps[j]}>
1009
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
1010
- </React.Suspense>
1011
- <Y />
1012
- </Root>,
1013
- ),
1014
- );
1015
-
1016
- // We get ID from the index in the tree above:
1017
- // Root, X, Suspense, ...
1018
- // ^ (index is 2)
1019
- const suspenseID = store.getElementIDAtIndex(2);
1020
-
1021
- // Force fallback.
1022
- expect(print(store)).toEqual(snapshots[i]);
1023
- act(() => {
1024
- bridge.send('overrideSuspense', {
1025
- id: suspenseID,
1026
- rendererID: store.getRendererIDForElement(suspenseID),
1027
- forceFallback: true,
1028
- });
1029
- });
1030
- expect(print(store)).toEqual(fallbackSnapshots[j]);
1031
-
1032
- // Stop forcing fallback.
1033
- act(() => {
1034
- bridge.send('overrideSuspense', {
1035
- id: suspenseID,
1036
- rendererID: store.getRendererIDForElement(suspenseID),
1037
- forceFallback: false,
1038
- });
1039
- });
1040
- expect(print(store)).toEqual(snapshots[i]);
1041
-
1042
- // Trigger actual fallback.
1043
- act(() =>
1044
- root.render(
1045
- <Root>
1046
- <X />
1047
- <React.Suspense fallback={steps[j]}>
1048
- <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>
1049
- </React.Suspense>
1050
- <Y />
1051
- </Root>,
1052
- ),
1053
- );
1054
- expect(print(store)).toEqual(fallbackSnapshots[j]);
1055
-
1056
- // Force fallback while we're in fallback mode.
1057
- act(() => {
1058
- bridge.send('overrideSuspense', {
1059
- id: suspenseID,
1060
- rendererID: store.getRendererIDForElement(suspenseID),
1061
- forceFallback: true,
1062
- });
1063
- });
1064
- // Keep seeing fallback content.
1065
- expect(print(store)).toEqual(fallbackSnapshots[j]);
1066
-
1067
- // Switch to primary mode.
1068
- act(() =>
1069
- root.render(
1070
- <Root>
1071
- <X />
1072
- <React.Suspense fallback={steps[j]}>
1073
- <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>
1074
- </React.Suspense>
1075
- <Y />
1076
- </Root>,
1077
- ),
1078
- );
1079
- // Fallback is still forced though.
1080
- expect(print(store)).toEqual(fallbackSnapshots[j]);
1081
-
1082
- // Stop forcing fallback. This reverts to primary content.
1083
- act(() => {
1084
- bridge.send('overrideSuspense', {
1085
- id: suspenseID,
1086
- rendererID: store.getRendererIDForElement(suspenseID),
1087
- forceFallback: false,
1088
- });
1089
- });
1090
- // Now we see primary content.
1091
- expect(print(store)).toEqual(snapshots[i]);
1092
-
1093
- // Clean up after every iteration.
1094
- act(() => root.unmount());
1095
- expect(print(store)).toBe('');
1096
- }
1097
- }
1098
- });
1099
-});
packages/react-devtools-shared/src/__tests__/treeContext-test.js
deleted
-613
@@ -1,613 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import typeof ReactTestRenderer from 'react-test-renderer';
11
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
12
-import type Store from 'react-devtools-shared/src/devtools/store';
13
-import type {
14
- DispatcherContext,
15
- StateContext,
16
-} from 'react-devtools-shared/src/devtools/views/Components/TreeContext';
17
-
18
-describe('TreeListContext', () => {
19
- let React;
20
- let ReactDOM;
21
- let TestRenderer: ReactTestRenderer;
22
- let bridge: FrontendBridge;
23
- let store: Store;
24
- let utils;
25
-
26
- let BridgeContext;
27
- let StoreContext;
28
- let TreeContext;
29
-
30
- let dispatch: DispatcherContext;
31
- let state: StateContext;
32
-
33
- beforeEach(() => {
34
- utils = require('./utils');
35
- utils.beforeEachProfiling();
36
-
37
- bridge = global.bridge;
38
- store = global.store;
39
- store.collapseNodesByDefault = false;
40
-
41
- React = require('react');
42
- ReactDOM = require('react-dom');
43
- TestRenderer = utils.requireTestRenderer();
44
-
45
- BridgeContext = require('react-devtools-shared/src/devtools/views/context')
46
- .BridgeContext;
47
- StoreContext = require('react-devtools-shared/src/devtools/views/context')
48
- .StoreContext;
49
- TreeContext = require('react-devtools-shared/src/devtools/views/Components/TreeContext');
50
- });
51
-
52
- afterEach(() => {
53
- // Reset between tests
54
- dispatch = ((null: any): DispatcherContext);
55
- state = ((null: any): StateContext);
56
- });
57
-
58
- const Capture = () => {
59
- dispatch = React.useContext(TreeContext.TreeDispatcherContext);
60
- state = React.useContext(TreeContext.TreeStateContext);
61
- return null;
62
- };
63
-
64
- const Contexts = () => {
65
- return (
66
- <BridgeContext.Provider value={bridge}>
67
- <StoreContext.Provider value={store}>
68
- <TreeContext.TreeContextController>
69
- <Capture />
70
- </TreeContext.TreeContextController>
71
- </StoreContext.Provider>
72
- </BridgeContext.Provider>
73
- );
74
- };
75
-
76
- describe('tree state', () => {
77
- it('should select the next and previous elements in the tree', () => {
78
- const Grandparent = () => <Parent />;
79
- const Parent = () => (
80
- <React.Fragment>
81
- <Child />
82
- <Child />
83
- </React.Fragment>
84
- );
85
- const Child = () => null;
86
-
87
- utils.act(() =>
88
- ReactDOM.render(<Grandparent />, document.createElement('div')),
89
- );
90
-
91
- expect(store).toMatchSnapshot('0: mount');
92
-
93
- let renderer;
94
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
95
- expect(state).toMatchSnapshot('1: initial state');
96
-
97
- utils.act(() => dispatch({type: 'SELECT_NEXT_ELEMENT_IN_TREE'}));
98
- utils.act(() => renderer.update(<Contexts />));
99
- expect(state).toMatchSnapshot('2: select first element');
100
-
101
- while (
102
- state.selectedElementIndex !== null &&
103
- state.selectedElementIndex < store.numElements - 1
104
- ) {
105
- const index = ((state.selectedElementIndex: any): number);
106
- utils.act(() => dispatch({type: 'SELECT_NEXT_ELEMENT_IN_TREE'}));
107
- utils.act(() => renderer.update(<Contexts />));
108
- expect(state).toMatchSnapshot(`3: select element after (${index})`);
109
- }
110
-
111
- while (
112
- state.selectedElementIndex !== null &&
113
- state.selectedElementIndex > 0
114
- ) {
115
- const index = ((state.selectedElementIndex: any): number);
116
- utils.act(() => dispatch({type: 'SELECT_PREVIOUS_ELEMENT_IN_TREE'}));
117
- utils.act(() => renderer.update(<Contexts />));
118
- expect(state).toMatchSnapshot(`4: select element before (${index})`);
119
- }
120
-
121
- utils.act(() => dispatch({type: 'SELECT_PREVIOUS_ELEMENT_IN_TREE'}));
122
- utils.act(() => renderer.update(<Contexts />));
123
- expect(state).toMatchSnapshot('5: select previous wraps around to last');
124
-
125
- utils.act(() => dispatch({type: 'SELECT_NEXT_ELEMENT_IN_TREE'}));
126
- utils.act(() => renderer.update(<Contexts />));
127
- expect(state).toMatchSnapshot('6: select next wraps around to first');
128
- });
129
-
130
- it('should select child elements', () => {
131
- const Grandparent = () => (
132
- <React.Fragment>
133
- <Parent />
134
- <Parent />
135
- </React.Fragment>
136
- );
137
- const Parent = () => (
138
- <React.Fragment>
139
- <Child />
140
- <Child />
141
- </React.Fragment>
142
- );
143
- const Child = () => null;
144
-
145
- utils.act(() =>
146
- ReactDOM.render(<Grandparent />, document.createElement('div')),
147
- );
148
-
149
- expect(store).toMatchSnapshot('0: mount');
150
-
151
- let renderer;
152
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
153
- expect(state).toMatchSnapshot('1: initial state');
154
-
155
- utils.act(() => dispatch({type: 'SELECT_ELEMENT_AT_INDEX', payload: 0}));
156
- utils.act(() => renderer.update(<Contexts />));
157
- expect(state).toMatchSnapshot('2: select first element');
158
-
159
- utils.act(() => dispatch({type: 'SELECT_CHILD_ELEMENT_IN_TREE'}));
160
- utils.act(() => renderer.update(<Contexts />));
161
- expect(state).toMatchSnapshot('3: select Parent');
162
-
163
- utils.act(() => dispatch({type: 'SELECT_CHILD_ELEMENT_IN_TREE'}));
164
- utils.act(() => renderer.update(<Contexts />));
165
- expect(state).toMatchSnapshot('4: select Child');
166
-
167
- const previousState = state;
168
-
169
- // There are no more children to select, so this should be a no-op
170
- utils.act(() => dispatch({type: 'SELECT_CHILD_ELEMENT_IN_TREE'}));
171
- utils.act(() => renderer.update(<Contexts />));
172
- expect(state).toEqual(previousState);
173
- });
174
-
175
- it('should select parent elements and then collapse', () => {
176
- const Grandparent = () => (
177
- <React.Fragment>
178
- <Parent />
179
- <Parent />
180
- </React.Fragment>
181
- );
182
- const Parent = () => (
183
- <React.Fragment>
184
- <Child />
185
- <Child />
186
- </React.Fragment>
187
- );
188
- const Child = () => null;
189
-
190
- utils.act(() =>
191
- ReactDOM.render(<Grandparent />, document.createElement('div')),
192
- );
193
-
194
- expect(store).toMatchSnapshot('0: mount');
195
-
196
- let renderer;
197
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
198
- expect(state).toMatchSnapshot('1: initial state');
199
-
200
- const lastChildID = store.getElementIDAtIndex(store.numElements - 1);
201
-
202
- utils.act(() =>
203
- dispatch({type: 'SELECT_ELEMENT_BY_ID', payload: lastChildID}),
204
- );
205
- utils.act(() => renderer.update(<Contexts />));
206
- expect(state).toMatchSnapshot('2: select last child');
207
-
208
- utils.act(() => dispatch({type: 'SELECT_PARENT_ELEMENT_IN_TREE'}));
209
- utils.act(() => renderer.update(<Contexts />));
210
- expect(state).toMatchSnapshot('3: select Parent');
211
-
212
- utils.act(() => dispatch({type: 'SELECT_PARENT_ELEMENT_IN_TREE'}));
213
- utils.act(() => renderer.update(<Contexts />));
214
- expect(state).toMatchSnapshot('4: select Grandparent');
215
-
216
- const previousState = state;
217
-
218
- // There are no more ancestors to select, so this should be a no-op
219
- utils.act(() => dispatch({type: 'SELECT_PARENT_ELEMENT_IN_TREE'}));
220
- utils.act(() => renderer.update(<Contexts />));
221
- expect(state).toEqual(previousState);
222
- });
223
-
224
- it('should clear selection if the selected element is unmounted', async done => {
225
- const Grandparent = props => props.children || null;
226
- const Parent = props => props.children || null;
227
- const Child = () => null;
228
-
229
- const container = document.createElement('div');
230
- utils.act(() =>
231
- ReactDOM.render(
232
- <Grandparent>
233
- <Parent>
234
- <Child />
235
- <Child />
236
- </Parent>
237
- </Grandparent>,
238
- container,
239
- ),
240
- );
241
-
242
- expect(store).toMatchSnapshot('0: mount');
243
-
244
- let renderer;
245
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
246
- expect(state).toMatchSnapshot('1: initial state');
247
-
248
- utils.act(() => dispatch({type: 'SELECT_ELEMENT_AT_INDEX', payload: 3}));
249
- utils.act(() => renderer.update(<Contexts />));
250
- expect(state).toMatchSnapshot('2: select second child');
251
-
252
- await utils.actAsync(() =>
253
- ReactDOM.render(
254
- <Grandparent>
255
- <Parent />
256
- </Grandparent>,
257
- container,
258
- ),
259
- );
260
- expect(state).toMatchSnapshot(
261
- '3: remove children (parent should now be selected)',
262
- );
263
-
264
- await utils.actAsync(() => ReactDOM.unmountComponentAtNode(container));
265
- expect(state).toMatchSnapshot(
266
- '4: unmount root (nothing should be selected)',
267
- );
268
-
269
- done();
270
- });
271
- });
272
-
273
- describe('search state', () => {
274
- it('should find elements matching search text', () => {
275
- const Foo = () => null;
276
- const Bar = () => null;
277
- const Baz = () => null;
278
- const Qux = () => null;
279
-
280
- Qux.displayName = `withHOC(${Qux.name})`;
281
-
282
- utils.act(() =>
283
- ReactDOM.render(
284
- <React.Fragment>
285
- <Foo />
286
- <Bar />
287
- <Baz />
288
- <Qux />
289
- </React.Fragment>,
290
- document.createElement('div'),
291
- ),
292
- );
293
-
294
- expect(store).toMatchSnapshot('0: mount');
295
-
296
- let renderer;
297
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
298
- expect(state).toMatchSnapshot('1: initial state');
299
-
300
- // NOTE: multi-match
301
- utils.act(() => dispatch({type: 'SET_SEARCH_TEXT', payload: 'ba'}));
302
- utils.act(() => renderer.update(<Contexts />));
303
- expect(state).toMatchSnapshot('2: search for "ba"');
304
-
305
- // NOTE: single match
306
- utils.act(() => dispatch({type: 'SET_SEARCH_TEXT', payload: 'f'}));
307
- utils.act(() => renderer.update(<Contexts />));
308
- expect(state).toMatchSnapshot('3: search for "f"');
309
-
310
- // NOTE: no match
311
- utils.act(() => dispatch({type: 'SET_SEARCH_TEXT', payload: 'y'}));
312
- utils.act(() => renderer.update(<Contexts />));
313
- expect(state).toMatchSnapshot('4: search for "y"');
314
-
315
- // NOTE: HOC match
316
- utils.act(() => dispatch({type: 'SET_SEARCH_TEXT', payload: 'w'}));
317
- utils.act(() => renderer.update(<Contexts />));
318
- expect(state).toMatchSnapshot('5: search for "w"');
319
- });
320
-
321
- it('should select the next and previous items within the search results', () => {
322
- const Foo = () => null;
323
- const Bar = () => null;
324
- const Baz = () => null;
325
-
326
- utils.act(() =>
327
- ReactDOM.render(
328
- <React.Fragment>
329
- <Foo />
330
- <Baz />
331
- <Bar />
332
- <Baz />
333
- </React.Fragment>,
334
- document.createElement('div'),
335
- ),
336
- );
337
-
338
- expect(store).toMatchSnapshot('0: mount');
339
-
340
- let renderer;
341
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
342
- expect(state).toMatchSnapshot('1: initial state');
343
-
344
- utils.act(() => dispatch({type: 'SET_SEARCH_TEXT', payload: 'ba'}));
345
- utils.act(() => renderer.update(<Contexts />));
346
- expect(state).toMatchSnapshot('2: search for "ba"');
347
-
348
- utils.act(() => dispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'}));
349
- utils.act(() => renderer.update(<Contexts />));
350
- expect(state).toMatchSnapshot('3: go to second result');
351
-
352
- utils.act(() => dispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'}));
353
- utils.act(() => renderer.update(<Contexts />));
354
- expect(state).toMatchSnapshot('4: go to third result');
355
-
356
- utils.act(() => dispatch({type: 'GO_TO_PREVIOUS_SEARCH_RESULT'}));
357
- utils.act(() => renderer.update(<Contexts />));
358
- expect(state).toMatchSnapshot('5: go to second result');
359
-
360
- utils.act(() => dispatch({type: 'GO_TO_PREVIOUS_SEARCH_RESULT'}));
361
- utils.act(() => renderer.update(<Contexts />));
362
- expect(state).toMatchSnapshot('6: go to first result');
363
-
364
- utils.act(() => dispatch({type: 'GO_TO_PREVIOUS_SEARCH_RESULT'}));
365
- utils.act(() => renderer.update(<Contexts />));
366
- expect(state).toMatchSnapshot('7: wrap to last result');
367
-
368
- utils.act(() => dispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'}));
369
- utils.act(() => renderer.update(<Contexts />));
370
- expect(state).toMatchSnapshot('8: wrap to first result');
371
- });
372
-
373
- it('should add newly mounted elements to the search results set if they match the current text', async done => {
374
- const Foo = () => null;
375
- const Bar = () => null;
376
- const Baz = () => null;
377
-
378
- const container = document.createElement('div');
379
-
380
- utils.act(() =>
381
- ReactDOM.render(
382
- <React.Fragment>
383
- <Foo />
384
- <Bar />
385
- </React.Fragment>,
386
- container,
387
- ),
388
- );
389
-
390
- expect(store).toMatchSnapshot('0: mount');
391
-
392
- let renderer;
393
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
394
- expect(state).toMatchSnapshot('1: initial state');
395
-
396
- utils.act(() => dispatch({type: 'SET_SEARCH_TEXT', payload: 'ba'}));
397
- utils.act(() => renderer.update(<Contexts />));
398
- expect(state).toMatchSnapshot('2: search for "ba"');
399
-
400
- await utils.actAsync(() =>
401
- ReactDOM.render(
402
- <React.Fragment>
403
- <Foo />
404
- <Bar />
405
- <Baz />
406
- </React.Fragment>,
407
- container,
408
- ),
409
- );
410
- utils.act(() => renderer.update(<Contexts />));
411
- expect(state).toMatchSnapshot('3: mount Baz');
412
-
413
- done();
414
- });
415
-
416
- it('should remove unmounted elements from the search results set', async done => {
417
- const Foo = () => null;
418
- const Bar = () => null;
419
- const Baz = () => null;
420
-
421
- const container = document.createElement('div');
422
-
423
- utils.act(() =>
424
- ReactDOM.render(
425
- <React.Fragment>
426
- <Foo />
427
- <Bar />
428
- <Baz />
429
- </React.Fragment>,
430
- container,
431
- ),
432
- );
433
-
434
- expect(store).toMatchSnapshot('0: mount');
435
-
436
- let renderer;
437
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
438
- expect(state).toMatchSnapshot('1: initial state');
439
-
440
- utils.act(() => dispatch({type: 'SET_SEARCH_TEXT', payload: 'ba'}));
441
- utils.act(() => renderer.update(<Contexts />));
442
- expect(state).toMatchSnapshot('2: search for "ba"');
443
-
444
- utils.act(() => dispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'}));
445
- utils.act(() => renderer.update(<Contexts />));
446
- expect(state).toMatchSnapshot('3: go to second result');
447
-
448
- await utils.actAsync(() =>
449
- ReactDOM.render(
450
- <React.Fragment>
451
- <Foo />
452
- <Bar />
453
- </React.Fragment>,
454
- container,
455
- ),
456
- );
457
- utils.act(() => renderer.update(<Contexts />));
458
- expect(state).toMatchSnapshot('4: unmount Baz');
459
-
460
- done();
461
- });
462
- });
463
-
464
- describe('owners state', () => {
465
- it('should support entering and existing the owners tree view', () => {
466
- const Grandparent = () => <Parent />;
467
- const Parent = () => (
468
- <React.Fragment>
469
- <Child />
470
- <Child />
471
- </React.Fragment>
472
- );
473
- const Child = () => null;
474
-
475
- utils.act(() =>
476
- ReactDOM.render(<Grandparent />, document.createElement('div')),
477
- );
478
-
479
- expect(store).toMatchSnapshot('0: mount');
480
-
481
- let renderer;
482
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
483
- expect(state).toMatchSnapshot('1: initial state');
484
-
485
- let parentID = ((store.getElementIDAtIndex(1): any): number);
486
- utils.act(() => dispatch({type: 'SELECT_OWNER', payload: parentID}));
487
- utils.act(() => renderer.update(<Contexts />));
488
- expect(state).toMatchSnapshot('2: parent owners tree');
489
-
490
- utils.act(() => dispatch({type: 'RESET_OWNER_STACK'}));
491
- utils.act(() => renderer.update(<Contexts />));
492
- expect(state).toMatchSnapshot('3: final state');
493
- });
494
-
495
- it('should remove an element from the owners list if it is unmounted', async done => {
496
- const Grandparent = ({count}) => <Parent count={count} />;
497
- const Parent = ({count}) =>
498
- new Array(count).fill(true).map((_, index) => <Child key={index} />);
499
- const Child = () => null;
500
-
501
- const container = document.createElement('div');
502
- utils.act(() => ReactDOM.render(<Grandparent count={2} />, container));
503
-
504
- expect(store).toMatchSnapshot('0: mount');
505
-
506
- let renderer;
507
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
508
- expect(state).toMatchSnapshot('1: initial state');
509
-
510
- let parentID = ((store.getElementIDAtIndex(1): any): number);
511
- utils.act(() => dispatch({type: 'SELECT_OWNER', payload: parentID}));
512
- utils.act(() => renderer.update(<Contexts />));
513
- expect(state).toMatchSnapshot('2: parent owners tree');
514
-
515
- await utils.actAsync(() =>
516
- ReactDOM.render(<Grandparent count={1} />, container),
517
- );
518
- expect(state).toMatchSnapshot('3: remove second child');
519
-
520
- await utils.actAsync(() =>
521
- ReactDOM.render(<Grandparent count={0} />, container),
522
- );
523
- expect(state).toMatchSnapshot('4: remove first child');
524
-
525
- done();
526
- });
527
-
528
- it('should exit the owners list if the current owner is unmounted', async done => {
529
- const Parent = props => props.children || null;
530
- const Child = () => null;
531
-
532
- const container = document.createElement('div');
533
- utils.act(() =>
534
- ReactDOM.render(
535
- <Parent>
536
- <Child />
537
- </Parent>,
538
- container,
539
- ),
540
- );
541
-
542
- expect(store).toMatchSnapshot('0: mount');
543
-
544
- let renderer;
545
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
546
- expect(state).toMatchSnapshot('1: initial state');
547
-
548
- let childID = ((store.getElementIDAtIndex(1): any): number);
549
- utils.act(() => dispatch({type: 'SELECT_OWNER', payload: childID}));
550
- utils.act(() => renderer.update(<Contexts />));
551
- expect(state).toMatchSnapshot('2: child owners tree');
552
-
553
- await utils.actAsync(() => ReactDOM.render(<Parent />, container));
554
- expect(state).toMatchSnapshot('3: remove child');
555
-
556
- let parentID = ((store.getElementIDAtIndex(0): any): number);
557
- utils.act(() => dispatch({type: 'SELECT_OWNER', payload: parentID}));
558
- utils.act(() => renderer.update(<Contexts />));
559
- expect(state).toMatchSnapshot('4: parent owners tree');
560
-
561
- await utils.actAsync(() => ReactDOM.unmountComponentAtNode(container));
562
- expect(state).toMatchSnapshot('5: unmount root');
563
-
564
- done();
565
- });
566
-
567
- // This tests ensures support for toggling Suspense boundaries outside of the active owners list.
568
- it('should exit the owners list if an element outside the list is selected', () => {
569
- const Grandchild = () => null;
570
- const Child = () => (
571
- <React.Suspense fallback="Loading">
572
- <Grandchild />
573
- </React.Suspense>
574
- );
575
- const Parent = () => (
576
- <React.Suspense fallback="Loading">
577
- <Child />
578
- </React.Suspense>
579
- );
580
-
581
- const container = document.createElement('div');
582
- utils.act(() => ReactDOM.render(<Parent />, container));
583
-
584
- expect(store).toMatchSnapshot('0: mount');
585
-
586
- let renderer;
587
- utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
588
- expect(state).toMatchSnapshot('1: initial state');
589
-
590
- const outerSuspenseID = ((store.getElementIDAtIndex(1): any): number);
591
- const childID = ((store.getElementIDAtIndex(2): any): number);
592
- const innerSuspenseID = ((store.getElementIDAtIndex(3): any): number);
593
-
594
- utils.act(() => dispatch({type: 'SELECT_OWNER', payload: childID}));
595
- utils.act(() => renderer.update(<Contexts />));
596
- expect(state).toMatchSnapshot('2: child owners tree');
597
-
598
- // Toggling a Suspense boundary inside of the flat list should update selected index
599
- utils.act(() =>
600
- dispatch({type: 'SELECT_ELEMENT_BY_ID', payload: innerSuspenseID}),
601
- );
602
- utils.act(() => renderer.update(<Contexts />));
603
- expect(state).toMatchSnapshot('3: child owners tree');
604
-
605
- // Toggling a Suspense boundary outside of the flat list should exit owners list and update index
606
- utils.act(() =>
607
- dispatch({type: 'SELECT_ELEMENT_BY_ID', payload: outerSuspenseID}),
608
- );
609
- utils.act(() => renderer.update(<Contexts />));
610
- expect(state).toMatchSnapshot('4: main tree');
611
- });
612
- });
613
-});
packages/react-devtools-shared/src/__tests__/utils.js
deleted
-212
@@ -1,212 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import typeof ReactTestRenderer from 'react-test-renderer';
11
-
12
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
13
-import type Store from 'react-devtools-shared/src/devtools/store';
14
-import type {ProfilingDataFrontend} from 'react-devtools-shared/src/devtools/views/Profiler/types';
15
-import type {ElementType} from 'react-devtools-shared/src/types';
16
-
17
-export function act(callback: Function): void {
18
- const {act: actTestRenderer} = require('react-test-renderer');
19
- const {act: actDOM} = require('react-dom/test-utils');
20
-
21
- actDOM(() => {
22
- actTestRenderer(() => {
23
- callback();
24
- });
25
- });
26
-
27
- // Flush Bridge operations
28
- while (global.mockGetTimersCount() > 0) {
29
- actDOM(() => {
30
- actTestRenderer(() => {
31
- jest.runAllTimers();
32
- });
33
- });
34
- }
35
-}
36
-
37
-export async function actAsync(
38
- cb: () => *,
39
- recursivelyFlush: boolean = true,
40
-): Promise<void> {
41
- const {act: actTestRenderer} = require('react-test-renderer');
42
- const {act: actDOM} = require('react-dom/test-utils');
43
-
44
- // $FlowFixMe Flow doens't know about "await act()" yet
45
- await actDOM(async () => {
46
- await actTestRenderer(async () => {
47
- await cb();
48
- });
49
- });
50
-
51
- if (recursivelyFlush) {
52
- // TODO (Jest v24) Replace with jest.getTimerCount() after we upgrade Jest
53
- while (global.mockGetTimersCount() > 0) {
54
- // $FlowFixMe Flow doens't know about "await act()" yet
55
- await actDOM(async () => {
56
- await actTestRenderer(async () => {
57
- jest.runAllTimers();
58
- });
59
- });
60
- }
61
- } else {
62
- // $FlowFixMe Flow doesn't know about "await act()" yet
63
- await actDOM(async () => {
64
- await actTestRenderer(async () => {
65
- jest.runOnlyPendingTimers();
66
- });
67
- });
68
- }
69
-}
70
-
71
-export function beforeEachProfiling(): void {
72
- // Mock React's timing information so that test runs are predictable.
73
- jest.mock('scheduler', () => jest.requireActual('scheduler/unstable_mock'));
74
-
75
- // DevTools itself uses performance.now() to offset commit times
76
- // so they appear relative to when profiling was started in the UI.
77
- jest
78
- .spyOn(performance, 'now')
79
- .mockImplementation(
80
- jest.requireActual('scheduler/unstable_mock').unstable_now,
81
- );
82
-}
83
-
84
-export function createDisplayNameFilter(
85
- source: string,
86
- isEnabled: boolean = true,
87
-) {
88
- const Types = require('react-devtools-shared/src/types');
89
- let isValid = true;
90
- try {
91
- new RegExp(source); // eslint-disable-line no-new
92
- } catch (error) {
93
- isValid = false;
94
- }
95
- return {
96
- type: Types.ComponentFilterDisplayName,
97
- isEnabled,
98
- isValid,
99
- value: source,
100
- };
101
-}
102
-
103
-export function createHOCFilter(isEnabled: boolean = true) {
104
- const Types = require('react-devtools-shared/src/types');
105
- return {
106
- type: Types.ComponentFilterHOC,
107
- isEnabled,
108
- isValid: true,
109
- };
110
-}
111
-
112
-export function createElementTypeFilter(
113
- elementType: ElementType,
114
- isEnabled: boolean = true,
115
-) {
116
- const Types = require('react-devtools-shared/src/types');
117
- return {
118
- type: Types.ComponentFilterElementType,
119
- isEnabled,
120
- value: elementType,
121
- };
122
-}
123
-
124
-export function createLocationFilter(
125
- source: string,
126
- isEnabled: boolean = true,
127
-) {
128
- const Types = require('react-devtools-shared/src/types');
129
- let isValid = true;
130
- try {
131
- new RegExp(source); // eslint-disable-line no-new
132
- } catch (error) {
133
- isValid = false;
134
- }
135
- return {
136
- type: Types.ComponentFilterLocation,
137
- isEnabled,
138
- isValid,
139
- value: source,
140
- };
141
-}
142
-
143
-export function getRendererID(): number {
144
- if (global.agent == null) {
145
- throw Error('Agent unavailable.');
146
- }
147
- const ids = Object.keys(global.agent._rendererInterfaces);
148
-
149
- const id = ids.find(innerID => {
150
- const rendererInterface = global.agent._rendererInterfaces[innerID];
151
- return rendererInterface.renderer.rendererPackageName === 'react-dom';
152
- });
153
-
154
- if (ids == null) {
155
- throw Error('Could not find renderer.');
156
- }
157
-
158
- return parseInt(id, 10);
159
-}
160
-
161
-export function requireTestRenderer(): ReactTestRenderer {
162
- let hook;
163
- try {
164
- // Hide the hook before requiring TestRenderer, so we don't end up with a loop.
165
- hook = global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
166
- delete global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
167
-
168
- return require('react-test-renderer');
169
- } finally {
170
- global.__REACT_DEVTOOLS_GLOBAL_HOOK__ = hook;
171
- }
172
-}
173
-
174
-export function exportImportHelper(bridge: FrontendBridge, store: Store): void {
175
- const {
176
- prepareProfilingDataExport,
177
- prepareProfilingDataFrontendFromExport,
178
- } = require('react-devtools-shared/src/devtools/views/Profiler/utils');
179
-
180
- const {profilerStore} = store;
181
-
182
- expect(profilerStore.profilingData).not.toBeNull();
183
-
184
- const profilingDataFrontendInitial = ((profilerStore.profilingData: any): ProfilingDataFrontend);
185
-
186
- const profilingDataExport = prepareProfilingDataExport(
187
- profilingDataFrontendInitial,
188
- );
189
-
190
- // Simulate writing/reading to disk.
191
- const serializedProfilingDataExport = JSON.stringify(
192
- profilingDataExport,
193
- null,
194
- 2,
195
- );
196
- const parsedProfilingDataExport = JSON.parse(serializedProfilingDataExport);
197
-
198
- const profilingDataFrontend = prepareProfilingDataFrontendFromExport(
199
- (parsedProfilingDataExport: any),
200
- );
201
-
202
- // Sanity check that profiling snapshots are serialized correctly.
203
- expect(profilingDataFrontendInitial).toEqual(profilingDataFrontend);
204
-
205
- // Snapshot the JSON-parsed object, rather than the raw string, because Jest formats the diff nicer.
206
- expect(parsedProfilingDataExport).toMatchSnapshot('imported data');
207
-
208
- act(() => {
209
- // Apply the new exported-then-reimported data so tests can re-run assertions.
210
- profilerStore.profilingData = profilingDataFrontend;
211
- });
212
-}
packages/react-devtools-shared/src/backend/NativeStyleEditor/resolveBoxStyle.js
deleted
-93
@@ -1,93 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {BoxStyle} from './types';
11
-
12
-/**
13
- * This mirrors react-native/Libraries/Inspector/resolveBoxStyle.js (but without RTL support).
14
- *
15
- * Resolve a style property into it's component parts, e.g.
16
- *
17
- * resolveBoxStyle('margin', {margin: 5, marginBottom: 10})
18
- * -> {top: 5, left: 5, right: 5, bottom: 10}
19
- */
20
-export default function resolveBoxStyle(
21
- prefix: string,
22
- style: Object,
23
-): BoxStyle | null {
24
- let hasParts = false;
25
- const result = {
26
- bottom: 0,
27
- left: 0,
28
- right: 0,
29
- top: 0,
30
- };
31
-
32
- const styleForAll = style[prefix];
33
- if (styleForAll != null) {
34
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
35
- for (const key of Object.keys(result)) {
36
- result[key] = styleForAll;
37
- }
38
- hasParts = true;
39
- }
40
-
41
- const styleForHorizontal = style[prefix + 'Horizontal'];
42
- if (styleForHorizontal != null) {
43
- result.left = styleForHorizontal;
44
- result.right = styleForHorizontal;
45
- hasParts = true;
46
- } else {
47
- const styleForLeft = style[prefix + 'Left'];
48
- if (styleForLeft != null) {
49
- result.left = styleForLeft;
50
- hasParts = true;
51
- }
52
-
53
- const styleForRight = style[prefix + 'Right'];
54
- if (styleForRight != null) {
55
- result.right = styleForRight;
56
- hasParts = true;
57
- }
58
-
59
- const styleForEnd = style[prefix + 'End'];
60
- if (styleForEnd != null) {
61
- // TODO RTL support
62
- result.right = styleForEnd;
63
- hasParts = true;
64
- }
65
- const styleForStart = style[prefix + 'Start'];
66
- if (styleForStart != null) {
67
- // TODO RTL support
68
- result.left = styleForStart;
69
- hasParts = true;
70
- }
71
- }
72
-
73
- const styleForVertical = style[prefix + 'Vertical'];
74
- if (styleForVertical != null) {
75
- result.bottom = styleForVertical;
76
- result.top = styleForVertical;
77
- hasParts = true;
78
- } else {
79
- const styleForBottom = style[prefix + 'Bottom'];
80
- if (styleForBottom != null) {
81
- result.bottom = styleForBottom;
82
- hasParts = true;
83
- }
84
-
85
- const styleForTop = style[prefix + 'Top'];
86
- if (styleForTop != null) {
87
- result.top = styleForTop;
88
- hasParts = true;
89
- }
90
- }
91
-
92
- return hasParts ? result : null;
93
-}
packages/react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor.js
deleted
-325
@@ -1,325 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import Agent from 'react-devtools-shared/src/backend/agent';
11
-import resolveBoxStyle from './resolveBoxStyle';
12
-
13
-import type {BackendBridge} from 'react-devtools-shared/src/bridge';
14
-import type {RendererID} from '../types';
15
-import type {StyleAndLayout} from './types';
16
-
17
-export type ResolveNativeStyle = (stylesheetID: any) => ?Object;
18
-
19
-export default function setupNativeStyleEditor(
20
- bridge: BackendBridge,
21
- agent: Agent,
22
- resolveNativeStyle: ResolveNativeStyle,
23
- validAttributes?: $ReadOnlyArray<string> | null,
24
-) {
25
- bridge.addListener(
26
- 'NativeStyleEditor_measure',
27
- ({id, rendererID}: {|id: number, rendererID: RendererID|}) => {
28
- measureStyle(agent, bridge, resolveNativeStyle, id, rendererID);
29
- },
30
- );
31
-
32
- bridge.addListener(
33
- 'NativeStyleEditor_renameAttribute',
34
- ({
35
- id,
36
- rendererID,
37
- oldName,
38
- newName,
39
- value,
40
- }: {|
41
- id: number,
42
- rendererID: RendererID,
43
- oldName: string,
44
- newName: string,
45
- value: string,
46
- |}) => {
47
- renameStyle(agent, id, rendererID, oldName, newName, value);
48
- setTimeout(() =>
49
- measureStyle(agent, bridge, resolveNativeStyle, id, rendererID),
50
- );
51
- },
52
- );
53
-
54
- bridge.addListener(
55
- 'NativeStyleEditor_setValue',
56
- ({
57
- id,
58
- rendererID,
59
- name,
60
- value,
61
- }: {|
62
- id: number,
63
- rendererID: number,
64
- name: string,
65
- value: string,
66
- |}) => {
67
- setStyle(agent, id, rendererID, name, value);
68
- setTimeout(() =>
69
- measureStyle(agent, bridge, resolveNativeStyle, id, rendererID),
70
- );
71
- },
72
- );
73
-
74
- bridge.send('isNativeStyleEditorSupported', {
75
- isSupported: true,
76
- validAttributes,
77
- });
78
-}
79
-
80
-const EMPTY_BOX_STYLE = {
81
- top: 0,
82
- left: 0,
83
- right: 0,
84
- bottom: 0,
85
-};
86
-
87
-const componentIDToStyleOverrides: Map<number, Object> = new Map();
88
-
89
-function measureStyle(
90
- agent: Agent,
91
- bridge: BackendBridge,
92
- resolveNativeStyle: ResolveNativeStyle,
93
- id: number,
94
- rendererID: RendererID,
95
-) {
96
- const data = agent.getInstanceAndStyle({id, rendererID});
97
- if (!data || !data.style) {
98
- bridge.send(
99
- 'NativeStyleEditor_styleAndLayout',
100
- ({
101
- id,
102
- layout: null,
103
- style: null,
104
- }: StyleAndLayout),
105
- );
106
- return;
107
- }
108
-
109
- const {instance, style} = data;
110
-
111
- let resolvedStyle = resolveNativeStyle(style);
112
-
113
- // If it's a host component we edited before, amend styles.
114
- const styleOverrides = componentIDToStyleOverrides.get(id);
115
- if (styleOverrides != null) {
116
- resolvedStyle = Object.assign({}, resolvedStyle, styleOverrides);
117
- }
118
-
119
- if (!instance || typeof instance.measure !== 'function') {
120
- bridge.send(
121
- 'NativeStyleEditor_styleAndLayout',
122
- ({
123
- id,
124
- layout: null,
125
- style: resolvedStyle || null,
126
- }: StyleAndLayout),
127
- );
128
- return;
129
- }
130
-
131
- // $FlowFixMe the parameter types of an unknown function are unknown
132
- instance.measure((x, y, width, height, left, top) => {
133
- // RN Android sometimes returns undefined here. Don't send measurements in this case.
134
- // https://github.com/jhen0409/react-native-debugger/issues/84#issuecomment-304611817
135
- if (typeof x !== 'number') {
136
- bridge.send(
137
- 'NativeStyleEditor_styleAndLayout',
138
- ({
139
- id,
140
- layout: null,
141
- style: resolvedStyle || null,
142
- }: StyleAndLayout),
143
- );
144
- return;
145
- }
146
- const margin =
147
- (resolvedStyle != null && resolveBoxStyle('margin', resolvedStyle)) ||
148
- EMPTY_BOX_STYLE;
149
- const padding =
150
- (resolvedStyle != null && resolveBoxStyle('padding', resolvedStyle)) ||
151
- EMPTY_BOX_STYLE;
152
- bridge.send(
153
- 'NativeStyleEditor_styleAndLayout',
154
- ({
155
- id,
156
- layout: {
157
- x,
158
- y,
159
- width,
160
- height,
161
- left,
162
- top,
163
- margin,
164
- padding,
165
- },
166
- style: resolvedStyle || null,
167
- }: StyleAndLayout),
168
- );
169
- });
170
-}
171
-
172
-function shallowClone(object: Object): Object {
173
- const cloned = {};
174
- for (let n in object) {
175
- cloned[n] = object[n];
176
- }
177
- return cloned;
178
-}
179
-
180
-function renameStyle(
181
- agent: Agent,
182
- id: number,
183
- rendererID: RendererID,
184
- oldName: string,
185
- newName: string,
186
- value: string,
187
-): void {
188
- const data = agent.getInstanceAndStyle({id, rendererID});
189
- if (!data || !data.style) {
190
- return;
191
- }
192
-
193
- const {instance, style} = data;
194
-
195
- const newStyle = newName
196
- ? {[oldName]: undefined, [newName]: value}
197
- : {[oldName]: undefined};
198
-
199
- let customStyle;
200
-
201
- // TODO It would be nice if the renderer interface abstracted this away somehow.
202
- if (instance !== null && typeof instance.setNativeProps === 'function') {
203
- // In the case of a host component, we need to use setNativeProps().
204
- // Remember to "correct" resolved styles when we read them next time.
205
- const styleOverrides = componentIDToStyleOverrides.get(id);
206
- if (!styleOverrides) {
207
- componentIDToStyleOverrides.set(id, newStyle);
208
- } else {
209
- Object.assign(styleOverrides, newStyle);
210
- }
211
- // TODO Fabric does not support setNativeProps; chat with Sebastian or Eli
212
- instance.setNativeProps({style: newStyle});
213
- } else if (Array.isArray(style)) {
214
- const lastIndex = style.length - 1;
215
- if (
216
- typeof style[lastIndex] === 'object' &&
217
- !Array.isArray(style[lastIndex])
218
- ) {
219
- customStyle = shallowClone(style[lastIndex]);
220
- delete customStyle[oldName];
221
- if (newName) {
222
- customStyle[newName] = value;
223
- } else {
224
- customStyle[oldName] = undefined;
225
- }
226
-
227
- agent.overrideProps({
228
- id,
229
- rendererID,
230
- path: ['style', lastIndex],
231
- value: customStyle,
232
- });
233
- } else {
234
- agent.overrideProps({
235
- id,
236
- rendererID,
237
- path: ['style'],
238
- value: style.concat([newStyle]),
239
- });
240
- }
241
- } else if (typeof style === 'object') {
242
- customStyle = shallowClone(style);
243
- delete customStyle[oldName];
244
- if (newName) {
245
- customStyle[newName] = value;
246
- } else {
247
- customStyle[oldName] = undefined;
248
- }
249
-
250
- agent.overrideProps({
251
- id,
252
- rendererID,
253
- path: ['style'],
254
- value: customStyle,
255
- });
256
- } else {
257
- agent.overrideProps({
258
- id,
259
- rendererID,
260
- path: ['style'],
261
- value: [style, newStyle],
262
- });
263
- }
264
-
265
- agent.emit('hideNativeHighlight');
266
-}
267
-
268
-function setStyle(
269
- agent: Agent,
270
- id: number,
271
- rendererID: RendererID,
272
- name: string,
273
- value: string,
274
-) {
275
- const data = agent.getInstanceAndStyle({id, rendererID});
276
- if (!data || !data.style) {
277
- return;
278
- }
279
-
280
- const {instance, style} = data;
281
- const newStyle = {[name]: value};
282
-
283
- // TODO It would be nice if the renderer interface abstracted this away somehow.
284
- if (instance !== null && typeof instance.setNativeProps === 'function') {
285
- // In the case of a host component, we need to use setNativeProps().
286
- // Remember to "correct" resolved styles when we read them next time.
287
- const styleOverrides = componentIDToStyleOverrides.get(id);
288
- if (!styleOverrides) {
289
- componentIDToStyleOverrides.set(id, newStyle);
290
- } else {
291
- Object.assign(styleOverrides, newStyle);
292
- }
293
- // TODO Fabric does not support setNativeProps; chat with Sebastian or Eli
294
- instance.setNativeProps({style: newStyle});
295
- } else if (Array.isArray(style)) {
296
- const lastLength = style.length - 1;
297
- if (
298
- typeof style[lastLength] === 'object' &&
299
- !Array.isArray(style[lastLength])
300
- ) {
301
- agent.overrideProps({
302
- id,
303
- rendererID,
304
- path: ['style', lastLength, name],
305
- value,
306
- });
307
- } else {
308
- agent.overrideProps({
309
- id,
310
- rendererID,
311
- path: ['style'],
312
- value: style.concat([newStyle]),
313
- });
314
- }
315
- } else {
316
- agent.overrideProps({
317
- id,
318
- rendererID,
319
- path: ['style'],
320
- value: [style, newStyle],
321
- });
322
- }
323
-
324
- agent.emit('hideNativeHighlight');
325
-}
packages/react-devtools-shared/src/backend/NativeStyleEditor/types.js
deleted
-34
@@ -1,34 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-export type BoxStyle = $ReadOnly<{|
11
- bottom: number,
12
- left: number,
13
- right: number,
14
- top: number,
15
-|}>;
16
-
17
-export type Layout = {|
18
- x: number,
19
- y: number,
20
- width: number,
21
- height: number,
22
- left: number,
23
- top: number,
24
- margin: BoxStyle,
25
- padding: BoxStyle,
26
-|};
27
-
28
-export type Style = Object;
29
-
30
-export type StyleAndLayout = {|
31
- id: number,
32
- style: Style | null,
33
- layout: Layout | null,
34
-|};
packages/react-devtools-shared/src/backend/agent.js
deleted
-492
@@ -1,492 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import EventEmitter from 'events';
11
-import throttle from 'lodash.throttle';
12
-import {
13
- SESSION_STORAGE_LAST_SELECTION_KEY,
14
- SESSION_STORAGE_RELOAD_AND_PROFILE_KEY,
15
- SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
16
- __DEBUG__,
17
-} from '../constants';
18
-import {
19
- sessionStorageGetItem,
20
- sessionStorageRemoveItem,
21
- sessionStorageSetItem,
22
-} from 'react-devtools-shared/src/storage';
23
-import setupHighlighter from './views/Highlighter';
24
-import {patch as patchConsole, unpatch as unpatchConsole} from './console';
25
-
26
-import type {BackendBridge} from 'react-devtools-shared/src/bridge';
27
-import type {
28
- InstanceAndStyle,
29
- NativeType,
30
- OwnersList,
31
- PathFrame,
32
- PathMatch,
33
- RendererID,
34
- RendererInterface,
35
-} from './types';
36
-import type {ComponentFilter} from '../types';
37
-
38
-const debug = (methodName, ...args) => {
39
- if (__DEBUG__) {
40
- console.log(
41
- `%cAgent %c${methodName}`,
42
- 'color: purple; font-weight: bold;',
43
- 'font-weight: bold;',
44
- ...args,
45
- );
46
- }
47
-};
48
-
49
-type ElementAndRendererID = {|
50
- id: number,
51
- rendererID: number,
52
-|};
53
-
54
-type InspectElementParams = {|
55
- id: number,
56
- path?: Array<string | number>,
57
- rendererID: number,
58
-|};
59
-
60
-type OverrideHookParams = {|
61
- id: number,
62
- hookID: number,
63
- path: Array<string | number>,
64
- rendererID: number,
65
- value: any,
66
-|};
67
-
68
-type SetInParams = {|
69
- id: number,
70
- path: Array<string | number>,
71
- rendererID: number,
72
- value: any,
73
-|};
74
-
75
-type OverrideSuspenseParams = {|
76
- id: number,
77
- rendererID: number,
78
- forceFallback: boolean,
79
-|};
80
-
81
-type PersistedSelection = {|
82
- rendererID: number,
83
- path: Array<PathFrame>,
84
-|};
85
-
86
-export default class Agent extends EventEmitter<{|
87
- hideNativeHighlight: [],
88
- showNativeHighlight: [NativeType],
89
- shutdown: [],
90
-|}> {
91
- _bridge: BackendBridge;
92
- _isProfiling: boolean = false;
93
- _recordChangeDescriptions: boolean = false;
94
- _rendererInterfaces: {[key: RendererID]: RendererInterface} = {};
95
- _persistedSelection: PersistedSelection | null = null;
96
- _persistedSelectionMatch: PathMatch | null = null;
97
-
98
- constructor(bridge: BackendBridge) {
99
- super();
100
-
101
- if (
102
- sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true'
103
- ) {
104
- this._recordChangeDescriptions =
105
- sessionStorageGetItem(
106
- SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
107
- ) === 'true';
108
- this._isProfiling = true;
109
-
110
- sessionStorageRemoveItem(SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY);
111
- sessionStorageRemoveItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY);
112
- }
113
-
114
- const persistedSelectionString = sessionStorageGetItem(
115
- SESSION_STORAGE_LAST_SELECTION_KEY,
116
- );
117
- if (persistedSelectionString != null) {
118
- this._persistedSelection = JSON.parse(persistedSelectionString);
119
- }
120
-
121
- this._bridge = bridge;
122
-
123
- bridge.addListener('getProfilingData', this.getProfilingData);
124
- bridge.addListener('getProfilingStatus', this.getProfilingStatus);
125
- bridge.addListener('getOwnersList', this.getOwnersList);
126
- bridge.addListener('inspectElement', this.inspectElement);
127
- bridge.addListener('logElementToConsole', this.logElementToConsole);
128
- bridge.addListener('overrideContext', this.overrideContext);
129
- bridge.addListener('overrideHookState', this.overrideHookState);
130
- bridge.addListener('overrideProps', this.overrideProps);
131
- bridge.addListener('overrideState', this.overrideState);
132
- bridge.addListener('overrideSuspense', this.overrideSuspense);
133
- bridge.addListener('reloadAndProfile', this.reloadAndProfile);
134
- bridge.addListener('startProfiling', this.startProfiling);
135
- bridge.addListener('stopProfiling', this.stopProfiling);
136
- bridge.addListener(
137
- 'syncSelectionFromNativeElementsPanel',
138
- this.syncSelectionFromNativeElementsPanel,
139
- );
140
- bridge.addListener('shutdown', this.shutdown);
141
- bridge.addListener(
142
- 'updateAppendComponentStack',
143
- this.updateAppendComponentStack,
144
- );
145
- bridge.addListener('updateComponentFilters', this.updateComponentFilters);
146
- bridge.addListener('viewElementSource', this.viewElementSource);
147
-
148
- if (this._isProfiling) {
149
- bridge.send('profilingStatus', true);
150
- }
151
-
152
- // Notify the frontend if the backend supports the Storage API (e.g. localStorage).
153
- // If not, features like reload-and-profile will not work correctly and must be disabled.
154
- let isBackendStorageAPISupported = false;
155
- try {
156
- localStorage.getItem('test');
157
- isBackendStorageAPISupported = true;
158
- } catch (error) {}
159
- bridge.send('isBackendStorageAPISupported', isBackendStorageAPISupported);
160
-
161
- setupHighlighter(bridge, this);
162
- }
163
-
164
- get rendererInterfaces(): {[key: RendererID]: RendererInterface} {
165
- return this._rendererInterfaces;
166
- }
167
-
168
- getInstanceAndStyle({
169
- id,
170
- rendererID,
171
- }: ElementAndRendererID): InstanceAndStyle | null {
172
- const renderer = this._rendererInterfaces[rendererID];
173
- if (renderer == null) {
174
- console.warn(`Invalid renderer id "${rendererID}"`);
175
- return null;
176
- }
177
- return renderer.getInstanceAndStyle(id);
178
- }
179
-
180
- getIDForNode(node: Object): number | null {
181
- for (let rendererID in this._rendererInterfaces) {
182
- const renderer = ((this._rendererInterfaces[
183
- (rendererID: any)
184
- ]: any): RendererInterface);
185
-
186
- try {
187
- const id = renderer.getFiberIDForNative(node, true);
188
- if (id !== null) {
189
- return id;
190
- }
191
- } catch (error) {
192
- // Some old React versions might throw if they can't find a match.
193
- // If so we should ignore it...
194
- }
195
- }
196
- return null;
197
- }
198
-
199
- getProfilingData = ({rendererID}: {|rendererID: RendererID|}) => {
200
- const renderer = this._rendererInterfaces[rendererID];
201
- if (renderer == null) {
202
- console.warn(`Invalid renderer id "${rendererID}"`);
203
- }
204
-
205
- this._bridge.send('profilingData', renderer.getProfilingData());
206
- };
207
-
208
- getProfilingStatus = () => {
209
- this._bridge.send('profilingStatus', this._isProfiling);
210
- };
211
-
212
- getOwnersList = ({id, rendererID}: ElementAndRendererID) => {
213
- const renderer = this._rendererInterfaces[rendererID];
214
- if (renderer == null) {
215
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
216
- } else {
217
- const owners = renderer.getOwnersList(id);
218
- this._bridge.send('ownersList', ({id, owners}: OwnersList));
219
- }
220
- };
221
-
222
- inspectElement = ({id, path, rendererID}: InspectElementParams) => {
223
- const renderer = this._rendererInterfaces[rendererID];
224
- if (renderer == null) {
225
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
226
- } else {
227
- this._bridge.send('inspectedElement', renderer.inspectElement(id, path));
228
-
229
- // When user selects an element, stop trying to restore the selection,
230
- // and instead remember the current selection for the next reload.
231
- if (
232
- this._persistedSelectionMatch === null ||
233
- this._persistedSelectionMatch.id !== id
234
- ) {
235
- this._persistedSelection = null;
236
- this._persistedSelectionMatch = null;
237
- renderer.setTrackedPath(null);
238
- this._throttledPersistSelection(rendererID, id);
239
- }
240
-
241
- // TODO: If there was a way to change the selected DOM element
242
- // in native Elements tab without forcing a switch to it, we'd do it here.
243
- // For now, it doesn't seem like there is a way to do that:
244
- // https://github.com/bvaughn/react-devtools-experimental/issues/102
245
- // (Setting $0 doesn't work, and calling inspect() switches the tab.)
246
- }
247
- };
248
-
249
- logElementToConsole = ({id, rendererID}: ElementAndRendererID) => {
250
- const renderer = this._rendererInterfaces[rendererID];
251
- if (renderer == null) {
252
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
253
- } else {
254
- renderer.logElementToConsole(id);
255
- }
256
- };
257
-
258
- reloadAndProfile = (recordChangeDescriptions: boolean) => {
259
- sessionStorageSetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY, 'true');
260
- sessionStorageSetItem(
261
- SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
262
- recordChangeDescriptions ? 'true' : 'false',
263
- );
264
-
265
- // This code path should only be hit if the shell has explicitly told the Store that it supports profiling.
266
- // In that case, the shell must also listen for this specific message to know when it needs to reload the app.
267
- // The agent can't do this in a way that is renderer agnostic.
268
- this._bridge.send('reloadAppForProfiling');
269
- };
270
-
271
- overrideContext = ({id, path, rendererID, value}: SetInParams) => {
272
- const renderer = this._rendererInterfaces[rendererID];
273
- if (renderer == null) {
274
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
275
- } else {
276
- renderer.setInContext(id, path, value);
277
- }
278
- };
279
-
280
- overrideHookState = ({
281
- id,
282
- hookID,
283
- path,
284
- rendererID,
285
- value,
286
- }: OverrideHookParams) => {
287
- const renderer = this._rendererInterfaces[rendererID];
288
- if (renderer == null) {
289
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
290
- } else {
291
- renderer.setInHook(id, hookID, path, value);
292
- }
293
- };
294
-
295
- overrideProps = ({id, path, rendererID, value}: SetInParams) => {
296
- const renderer = this._rendererInterfaces[rendererID];
297
- if (renderer == null) {
298
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
299
- } else {
300
- renderer.setInProps(id, path, value);
301
- }
302
- };
303
-
304
- overrideState = ({id, path, rendererID, value}: SetInParams) => {
305
- const renderer = this._rendererInterfaces[rendererID];
306
- if (renderer == null) {
307
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
308
- } else {
309
- renderer.setInState(id, path, value);
310
- }
311
- };
312
-
313
- overrideSuspense = ({
314
- id,
315
- rendererID,
316
- forceFallback,
317
- }: OverrideSuspenseParams) => {
318
- const renderer = this._rendererInterfaces[rendererID];
319
- if (renderer == null) {
320
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
321
- } else {
322
- renderer.overrideSuspense(id, forceFallback);
323
- }
324
- };
325
-
326
- selectNode(target: Object): void {
327
- const id = this.getIDForNode(target);
328
- if (id !== null) {
329
- this._bridge.send('selectFiber', id);
330
- }
331
- }
332
-
333
- setRendererInterface(
334
- rendererID: RendererID,
335
- rendererInterface: RendererInterface,
336
- ) {
337
- this._rendererInterfaces[rendererID] = rendererInterface;
338
-
339
- if (this._isProfiling) {
340
- rendererInterface.startProfiling(this._recordChangeDescriptions);
341
- }
342
-
343
- // When the renderer is attached, we need to tell it whether
344
- // we remember the previous selection that we'd like to restore.
345
- // It'll start tracking mounts for matches to the last selection path.
346
- const selection = this._persistedSelection;
347
- if (selection !== null && selection.rendererID === rendererID) {
348
- rendererInterface.setTrackedPath(selection.path);
349
- }
350
- }
351
-
352
- syncSelectionFromNativeElementsPanel = () => {
353
- const target = window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0;
354
- if (target == null) {
355
- return;
356
- }
357
- this.selectNode(target);
358
- };
359
-
360
- shutdown = () => {
361
- // Clean up the overlay if visible, and associated events.
362
- this.emit('shutdown');
363
- };
364
-
365
- startProfiling = (recordChangeDescriptions: boolean) => {
366
- this._recordChangeDescriptions = recordChangeDescriptions;
367
- this._isProfiling = true;
368
- for (let rendererID in this._rendererInterfaces) {
369
- const renderer = ((this._rendererInterfaces[
370
- (rendererID: any)
371
- ]: any): RendererInterface);
372
- renderer.startProfiling(recordChangeDescriptions);
373
- }
374
- this._bridge.send('profilingStatus', this._isProfiling);
375
- };
376
-
377
- stopProfiling = () => {
378
- this._isProfiling = false;
379
- this._recordChangeDescriptions = false;
380
- for (let rendererID in this._rendererInterfaces) {
381
- const renderer = ((this._rendererInterfaces[
382
- (rendererID: any)
383
- ]: any): RendererInterface);
384
- renderer.stopProfiling();
385
- }
386
- this._bridge.send('profilingStatus', this._isProfiling);
387
- };
388
-
389
- updateAppendComponentStack = (appendComponentStack: boolean) => {
390
- // If the frontend preference has change,
391
- // or in the case of React Native- if the backend is just finding out the preference-
392
- // then install or uninstall the console overrides.
393
- // It's safe to call these methods multiple times, so we don't need to worry about that.
394
- if (appendComponentStack) {
395
- patchConsole();
396
- } else {
397
- unpatchConsole();
398
- }
399
- };
400
-
401
- updateComponentFilters = (componentFilters: Array<ComponentFilter>) => {
402
- for (let rendererID in this._rendererInterfaces) {
403
- const renderer = ((this._rendererInterfaces[
404
- (rendererID: any)
405
- ]: any): RendererInterface);
406
- renderer.updateComponentFilters(componentFilters);
407
- }
408
- };
409
-
410
- viewElementSource = ({id, rendererID}: ElementAndRendererID) => {
411
- const renderer = this._rendererInterfaces[rendererID];
412
- if (renderer == null) {
413
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
414
- } else {
415
- renderer.prepareViewElementSource(id);
416
- }
417
- };
418
-
419
- onHookOperations = (operations: Array<number>) => {
420
- if (__DEBUG__) {
421
- debug('onHookOperations', operations);
422
- }
423
-
424
- // TODO:
425
- // The chrome.runtime does not currently support transferables; it forces JSON serialization.
426
- // See bug https://bugs.chromium.org/p/chromium/issues/detail?id=927134
427
- //
428
- // Regarding transferables, the postMessage doc states:
429
- // If the ownership of an object is transferred, it becomes unusable (neutered)
430
- // in the context it was sent from and becomes available only to the worker it was sent to.
431
- //
432
- // Even though Chrome is eventually JSON serializing the array buffer,
433
- // using the transferable approach also sometimes causes it to throw:
434
- // DOMException: Failed to execute 'postMessage' on 'Window': ArrayBuffer at index 0 is already neutered.
435
- //
436
- // See bug https://github.com/bvaughn/react-devtools-experimental/issues/25
437
- //
438
- // The Store has a fallback in place that parses the message as JSON if the type isn't an array.
439
- // For now the simplest fix seems to be to not transfer the array.
440
- // This will negatively impact performance on Firefox so it's unfortunate,
441
- // but until we're able to fix the Chrome error mentioned above, it seems necessary.
442
- //
443
- // this._bridge.send('operations', operations, [operations.buffer]);
444
- this._bridge.send('operations', operations);
445
-
446
- if (this._persistedSelection !== null) {
447
- const rendererID = operations[0];
448
- if (this._persistedSelection.rendererID === rendererID) {
449
- // Check if we can select a deeper match for the persisted selection.
450
- const renderer = this._rendererInterfaces[rendererID];
451
- if (renderer == null) {
452
- console.warn(`Invalid renderer id "${rendererID}"`);
453
- } else {
454
- const prevMatch = this._persistedSelectionMatch;
455
- const nextMatch = renderer.getBestMatchForTrackedPath();
456
- this._persistedSelectionMatch = nextMatch;
457
- const prevMatchID = prevMatch !== null ? prevMatch.id : null;
458
- const nextMatchID = nextMatch !== null ? nextMatch.id : null;
459
- if (prevMatchID !== nextMatchID) {
460
- if (nextMatchID !== null) {
461
- // We moved forward, unlocking a deeper node.
462
- this._bridge.send('selectFiber', nextMatchID);
463
- }
464
- }
465
- if (nextMatch !== null && nextMatch.isFullMatch) {
466
- // We've just unlocked the innermost selected node.
467
- // There's no point tracking it further.
468
- this._persistedSelection = null;
469
- this._persistedSelectionMatch = null;
470
- renderer.setTrackedPath(null);
471
- }
472
- }
473
- }
474
- }
475
- };
476
-
477
- _throttledPersistSelection = throttle((rendererID: number, id: number) => {
478
- // This is throttled, so both renderer and selected ID
479
- // might not be available by the time we read them.
480
- // This is why we need the defensive checks here.
481
- const renderer = this._rendererInterfaces[rendererID];
482
- const path = renderer != null ? renderer.getPathForElement(id) : null;
483
- if (path !== null) {
484
- sessionStorageSetItem(
485
- SESSION_STORAGE_LAST_SELECTION_KEY,
486
- JSON.stringify(({rendererID, path}: PersistedSelection)),
487
- );
488
- } else {
489
- sessionStorageRemoveItem(SESSION_STORAGE_LAST_SELECTION_KEY);
490
- }
491
- }, 1000);
492
-}
packages/react-devtools-shared/src/backend/console.js
deleted
-152
@@ -1,152 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {getInternalReactConstants} from './renderer';
11
-import describeComponentFrame from './describeComponentFrame';
12
-
13
-import type {Fiber} from 'react-reconciler/src/ReactFiber';
14
-import type {ReactRenderer} from './types';
15
-
16
-const APPEND_STACK_TO_METHODS = ['error', 'trace', 'warn'];
17
-
18
-const FRAME_REGEX = /\n {4}in /;
19
-
20
-const injectedRenderers: Map<
21
- ReactRenderer,
22
- {|
23
- getCurrentFiber: () => Fiber | null,
24
- getDisplayNameForFiber: (fiber: Fiber) => string | null,
25
- |},
26
-> = new Map();
27
-
28
-let targetConsole: Object = console;
29
-let targetConsoleMethods = {};
30
-for (let method in console) {
31
- targetConsoleMethods[method] = console[method];
32
-}
33
-
34
-let unpatchFn: null | (() => void) = null;
35
-
36
-// Enables e.g. Jest tests to inject a mock console object.
37
-export function dangerous_setTargetConsoleForTesting(
38
- targetConsoleForTesting: Object,
39
-): void {
40
- targetConsole = targetConsoleForTesting;
41
-
42
- targetConsoleMethods = {};
43
- for (let method in targetConsole) {
44
- targetConsoleMethods[method] = console[method];
45
- }
46
-}
47
-
48
-// v16 renderers should use this method to inject internals necessary to generate a component stack.
49
-// These internals will be used if the console is patched.
50
-// Injecting them separately allows the console to easily be patched or unpacted later (at runtime).
51
-export function registerRenderer(renderer: ReactRenderer): void {
52
- const {getCurrentFiber, findFiberByHostInstance, version} = renderer;
53
-
54
- // Ignore React v15 and older because they don't expose a component stack anyway.
55
- if (typeof findFiberByHostInstance !== 'function') {
56
- return;
57
- }
58
-
59
- if (typeof getCurrentFiber === 'function') {
60
- const {getDisplayNameForFiber} = getInternalReactConstants(version);
61
-
62
- injectedRenderers.set(renderer, {
63
- getCurrentFiber,
64
- getDisplayNameForFiber,
65
- });
66
- }
67
-}
68
-
69
-// Patches whitelisted console methods to append component stack for the current fiber.
70
-// Call unpatch() to remove the injected behavior.
71
-export function patch(): void {
72
- if (unpatchFn !== null) {
73
- // Don't patch twice.
74
- return;
75
- }
76
-
77
- const originalConsoleMethods = {};
78
-
79
- unpatchFn = () => {
80
- for (let method in originalConsoleMethods) {
81
- try {
82
- // $FlowFixMe property error|warn is not writable.
83
- targetConsole[method] = originalConsoleMethods[method];
84
- } catch (error) {}
85
- }
86
- };
87
-
88
- APPEND_STACK_TO_METHODS.forEach(method => {
89
- try {
90
- const originalMethod = (originalConsoleMethods[method] =
91
- targetConsole[method]);
92
-
93
- const overrideMethod = (...args) => {
94
- try {
95
- // If we are ever called with a string that already has a component stack, e.g. a React error/warning,
96
- // don't append a second stack.
97
- const alreadyHasComponentStack =
98
- args.length > 0 && FRAME_REGEX.exec(args[args.length - 1]);
99
-
100
- if (!alreadyHasComponentStack) {
101
- // If there's a component stack for at least one of the injected renderers, append it.
102
- // We don't handle the edge case of stacks for more than one (e.g. interleaved renderers?)
103
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
104
- for (let {
105
- getCurrentFiber,
106
- getDisplayNameForFiber,
107
- } of injectedRenderers.values()) {
108
- let current: ?Fiber = getCurrentFiber();
109
- let ownerStack: string = '';
110
- while (current != null) {
111
- const name = getDisplayNameForFiber(current);
112
- const owner = current._debugOwner;
113
- const ownerName =
114
- owner != null ? getDisplayNameForFiber(owner) : null;
115
-
116
- ownerStack += describeComponentFrame(
117
- name,
118
- current._debugSource,
119
- ownerName,
120
- );
121
-
122
- current = owner;
123
- }
124
-
125
- if (ownerStack !== '') {
126
- args.push(ownerStack);
127
- break;
128
- }
129
- }
130
- }
131
- } catch (error) {
132
- // Don't let a DevTools or React internal error interfere with logging.
133
- }
134
-
135
- originalMethod(...args);
136
- };
137
-
138
- overrideMethod.__REACT_DEVTOOLS_ORIGINAL_METHOD__ = originalMethod;
139
-
140
- // $FlowFixMe property error|warn is not writable.
141
- targetConsole[method] = overrideMethod;
142
- } catch (error) {}
143
- });
144
-}
145
-
146
-// Removed component stack patch from whitelisted console methods.
147
-export function unpatch(): void {
148
- if (unpatchFn !== null) {
149
- unpatchFn();
150
- unpatchFn = null;
151
- }
152
-}
packages/react-devtools-shared/src/backend/describeComponentFrame.js
deleted
-48
@@ -1,48 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-// This file was forked from the React GitHub repo:
11
-// https://raw.githubusercontent.com/facebook/react/master/packages/shared/describeComponentFrame.js
12
-//
13
-// It has been modified sligthly to add a zero width space as commented below.
14
-
15
-const BEFORE_SLASH_RE = /^(.*)[\\/]/;
16
-
17
-export default function describeComponentFrame(
18
- name: null | string,
19
- source: any,
20
- ownerName: null | string,
21
-) {
22
- let sourceInfo = '';
23
- if (source) {
24
- let path = source.fileName;
25
- let fileName = path.replace(BEFORE_SLASH_RE, '');
26
- if (__DEV__) {
27
- // In DEV, include code for a common special case:
28
- // prefer "folder/index.js" instead of just "index.js".
29
- if (/^index\./.test(fileName)) {
30
- const match = path.match(BEFORE_SLASH_RE);
31
- if (match) {
32
- const pathBeforeSlash = match[1];
33
- if (pathBeforeSlash) {
34
- const folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
35
- // Note the below string contains a zero width space after the "/" character.
36
- // This is to prevent browsers like Chrome from formatting the file name as a link.
37
- // (Since this is a source link, it would not work to open the source file anyway.)
38
- fileName = folderName + '/' + fileName;
39
- }
40
- }
41
- }
42
- }
43
- sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
44
- } else if (ownerName) {
45
- sourceInfo = ' (created by ' + ownerName + ')';
46
- }
47
- return '\n in ' + (name || 'Unknown') + sourceInfo;
48
-}
packages/react-devtools-shared/src/backend/index.js
deleted
-102
@@ -1,102 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import Agent from './agent';
11
-
12
-import {attach} from './renderer';
13
-import {attach as attachLegacy} from './legacy/renderer';
14
-
15
-import type {DevToolsHook, ReactRenderer, RendererInterface} from './types';
16
-
17
-export function initBackend(
18
- hook: DevToolsHook,
19
- agent: Agent,
20
- global: Object,
21
-): () => void {
22
- const subs = [
23
- hook.sub(
24
- 'renderer-attached',
25
- ({
26
- id,
27
- renderer,
28
- rendererInterface,
29
- }: {
30
- id: number,
31
- renderer: ReactRenderer,
32
- rendererInterface: RendererInterface,
33
- }) => {
34
- agent.setRendererInterface(id, rendererInterface);
35
-
36
- // Now that the Store and the renderer interface are connected,
37
- // it's time to flush the pending operation codes to the frontend.
38
- rendererInterface.flushInitialOperations();
39
- },
40
- ),
41
-
42
- hook.sub('operations', agent.onHookOperations),
43
-
44
- // TODO Add additional subscriptions required for profiling mode
45
- ];
46
-
47
- const attachRenderer = (id: number, renderer: ReactRenderer) => {
48
- let rendererInterface = hook.rendererInterfaces.get(id);
49
-
50
- // Inject any not-yet-injected renderers (if we didn't reload-and-profile)
51
- if (!rendererInterface) {
52
- if (typeof renderer.findFiberByHostInstance === 'function') {
53
- rendererInterface = attach(hook, id, renderer, global);
54
- } else {
55
- rendererInterface = attachLegacy(hook, id, renderer, global);
56
- }
57
-
58
- hook.rendererInterfaces.set(id, rendererInterface);
59
- }
60
-
61
- // Notify the DevTools frontend about new renderers.
62
- // This includes any that were attached early (via __REACT_DEVTOOLS_ATTACH__).
63
- hook.emit('renderer-attached', {
64
- id,
65
- renderer,
66
- rendererInterface,
67
- });
68
- };
69
-
70
- // Connect renderers that have already injected themselves.
71
- hook.renderers.forEach((renderer, id) => {
72
- attachRenderer(id, renderer);
73
- });
74
-
75
- // Connect any new renderers that injected themselves.
76
- subs.push(
77
- hook.sub(
78
- 'renderer',
79
- ({id, renderer}: {id: number, renderer: ReactRenderer}) => {
80
- attachRenderer(id, renderer);
81
- },
82
- ),
83
- );
84
-
85
- hook.emit('react-devtools', agent);
86
- hook.reactDevtoolsAgent = agent;
87
- const onAgentShutdown = () => {
88
- subs.forEach(fn => fn());
89
- hook.rendererInterfaces.forEach(rendererInterface => {
90
- rendererInterface.cleanup();
91
- });
92
- hook.reactDevtoolsAgent = null;
93
- };
94
- agent.addListener('shutdown', onAgentShutdown);
95
- subs.push(() => {
96
- agent.removeListener('shutdown', onAgentShutdown);
97
- });
98
-
99
- return () => {
100
- subs.forEach(fn => fn());
101
- };
102
-}
packages/react-devtools-shared/src/backend/legacy/renderer.js
deleted
-950
@@ -1,950 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {
11
- ElementTypeClass,
12
- ElementTypeFunction,
13
- ElementTypeRoot,
14
- ElementTypeHostComponent,
15
- ElementTypeOtherOrUnknown,
16
-} from 'react-devtools-shared/src/types';
17
-import {getUID, utfEncodeString, printOperationsArray} from '../../utils';
18
-import {cleanForBridge, copyWithSet} from '../utils';
19
-import {getDisplayName} from 'react-devtools-shared/src/utils';
20
-import {
21
- __DEBUG__,
22
- TREE_OPERATION_ADD,
23
- TREE_OPERATION_REMOVE,
24
- TREE_OPERATION_REORDER_CHILDREN,
25
-} from '../../constants';
26
-import {decorateMany, forceUpdate, restoreMany} from './utils';
27
-
28
-import type {
29
- DevToolsHook,
30
- GetFiberIDForNative,
31
- InspectedElementPayload,
32
- InstanceAndStyle,
33
- NativeType,
34
- PathFrame,
35
- PathMatch,
36
- RendererInterface,
37
-} from '../types';
38
-import type {
39
- ComponentFilter,
40
- ElementType,
41
-} from 'react-devtools-shared/src/types';
42
-import type {Owner, InspectedElement} from '../types';
43
-
44
-export type InternalInstance = Object;
45
-type LegacyRenderer = Object;
46
-
47
-function getData(internalInstance: InternalInstance) {
48
- let displayName = null;
49
- let key = null;
50
-
51
- // != used deliberately here to catch undefined and null
52
- if (internalInstance._currentElement != null) {
53
- if (internalInstance._currentElement.key) {
54
- key = '' + internalInstance._currentElement.key;
55
- }
56
-
57
- const elementType = internalInstance._currentElement.type;
58
- if (typeof elementType === 'string') {
59
- displayName = elementType;
60
- } else if (typeof elementType === 'function') {
61
- displayName = getDisplayName(elementType);
62
- }
63
- }
64
-
65
- return {
66
- displayName,
67
- key,
68
- };
69
-}
70
-
71
-function getElementType(internalInstance: InternalInstance): ElementType {
72
- // != used deliberately here to catch undefined and null
73
- if (internalInstance._currentElement != null) {
74
- const elementType = internalInstance._currentElement.type;
75
- if (typeof elementType === 'function') {
76
- const publicInstance = internalInstance.getPublicInstance();
77
- if (publicInstance !== null) {
78
- return ElementTypeClass;
79
- } else {
80
- return ElementTypeFunction;
81
- }
82
- } else if (typeof elementType === 'string') {
83
- return ElementTypeHostComponent;
84
- }
85
- }
86
- return ElementTypeOtherOrUnknown;
87
-}
88
-
89
-function getChildren(internalInstance: Object): Array<any> {
90
- let children = [];
91
-
92
- // If the parent is a native node without rendered children, but with
93
- // multiple string children, then the `element` that gets passed in here is
94
- // a plain value -- a string or number.
95
- if (typeof internalInstance !== 'object') {
96
- // No children
97
- } else if (
98
- internalInstance._currentElement === null ||
99
- internalInstance._currentElement === false
100
- ) {
101
- // No children
102
- } else if (internalInstance._renderedComponent) {
103
- const child = internalInstance._renderedComponent;
104
- if (getElementType(child) !== ElementTypeOtherOrUnknown) {
105
- children.push(child);
106
- }
107
- } else if (internalInstance._renderedChildren) {
108
- const renderedChildren = internalInstance._renderedChildren;
109
- for (let name in renderedChildren) {
110
- const child = renderedChildren[name];
111
- if (getElementType(child) !== ElementTypeOtherOrUnknown) {
112
- children.push(child);
113
- }
114
- }
115
- }
116
- // Note: we skip the case where children are just strings or numbers
117
- // because the new DevTools skips over host text nodes anyway.
118
- return children;
119
-}
120
-
121
-export function attach(
122
- hook: DevToolsHook,
123
- rendererID: number,
124
- renderer: LegacyRenderer,
125
- global: Object,
126
-): RendererInterface {
127
- const idToInternalInstanceMap: Map<number, InternalInstance> = new Map();
128
- const internalInstanceToIDMap: WeakMap<
129
- InternalInstance,
130
- number,
131
- > = new WeakMap();
132
- const internalInstanceToRootIDMap: WeakMap<
133
- InternalInstance,
134
- number,
135
- > = new WeakMap();
136
-
137
- let getInternalIDForNative: GetFiberIDForNative = ((null: any): GetFiberIDForNative);
138
- let findNativeNodeForInternalID: (id: number) => ?NativeType;
139
-
140
- if (renderer.ComponentTree) {
141
- getInternalIDForNative = (node, findNearestUnfilteredAncestor) => {
142
- const internalInstance = renderer.ComponentTree.getClosestInstanceFromNode(
143
- node,
144
- );
145
- return internalInstanceToIDMap.get(internalInstance) || null;
146
- };
147
- findNativeNodeForInternalID = (id: number) => {
148
- const internalInstance = idToInternalInstanceMap.get(id);
149
- return renderer.ComponentTree.getNodeFromInstance(internalInstance);
150
- };
151
- } else if (renderer.Mount.getID && renderer.Mount.getNode) {
152
- getInternalIDForNative = (node, findNearestUnfilteredAncestor) => {
153
- // Not implemented.
154
- return null;
155
- };
156
- findNativeNodeForInternalID = (id: number) => {
157
- // Not implemented.
158
- return null;
159
- };
160
- }
161
-
162
- function getID(internalInstance: InternalInstance): number {
163
- if (typeof internalInstance !== 'object') {
164
- throw new Error('Invalid internal instance: ' + internalInstance);
165
- }
166
- if (!internalInstanceToIDMap.has(internalInstance)) {
167
- const id = getUID();
168
- internalInstanceToIDMap.set(internalInstance, id);
169
- idToInternalInstanceMap.set(id, internalInstance);
170
- }
171
- return ((internalInstanceToIDMap.get(internalInstance): any): number);
172
- }
173
-
174
- function areEqualArrays(a, b) {
175
- if (a.length !== b.length) {
176
- return false;
177
- }
178
- for (let i = 0; i < a.length; i++) {
179
- if (a[i] !== b[i]) {
180
- return false;
181
- }
182
- }
183
- return true;
184
- }
185
-
186
- // This is shared mutable state that lets us keep track of where we are.
187
- let parentIDStack = [];
188
-
189
- let oldReconcilerMethods = null;
190
- if (renderer.Reconciler) {
191
- // React 15
192
- oldReconcilerMethods = decorateMany(renderer.Reconciler, {
193
- mountComponent(fn, args) {
194
- const internalInstance = args[0];
195
- const hostContainerInfo = args[3];
196
- if (getElementType(internalInstance) === ElementTypeOtherOrUnknown) {
197
- return fn.apply(this, args);
198
- }
199
- if (hostContainerInfo._topLevelWrapper === undefined) {
200
- // SSR
201
- return fn.apply(this, args);
202
- }
203
-
204
- const id = getID(internalInstance);
205
- // Push the operation.
206
- const parentID =
207
- parentIDStack.length > 0
208
- ? parentIDStack[parentIDStack.length - 1]
209
- : 0;
210
- recordMount(internalInstance, id, parentID);
211
- parentIDStack.push(id);
212
-
213
- // Remember the root.
214
- internalInstanceToRootIDMap.set(
215
- internalInstance,
216
- getID(hostContainerInfo._topLevelWrapper),
217
- );
218
-
219
- try {
220
- const result = fn.apply(this, args);
221
- parentIDStack.pop();
222
- return result;
223
- } catch (err) {
224
- parentIDStack = [];
225
- throw err;
226
- } finally {
227
- if (parentIDStack.length === 0) {
228
- const rootID = internalInstanceToRootIDMap.get(internalInstance);
229
- if (rootID === undefined) {
230
- throw new Error('Expected to find root ID.');
231
- }
232
- flushPendingEvents(rootID);
233
- }
234
- }
235
- },
236
- performUpdateIfNecessary(fn, args) {
237
- const internalInstance = args[0];
238
- if (getElementType(internalInstance) === ElementTypeOtherOrUnknown) {
239
- return fn.apply(this, args);
240
- }
241
-
242
- const id = getID(internalInstance);
243
- parentIDStack.push(id);
244
-
245
- const prevChildren = getChildren(internalInstance);
246
- try {
247
- const result = fn.apply(this, args);
248
-
249
- const nextChildren = getChildren(internalInstance);
250
- if (!areEqualArrays(prevChildren, nextChildren)) {
251
- // Push the operation
252
- recordReorder(internalInstance, id, nextChildren);
253
- }
254
-
255
- parentIDStack.pop();
256
- return result;
257
- } catch (err) {
258
- parentIDStack = [];
259
- throw err;
260
- } finally {
261
- if (parentIDStack.length === 0) {
262
- const rootID = internalInstanceToRootIDMap.get(internalInstance);
263
- if (rootID === undefined) {
264
- throw new Error('Expected to find root ID.');
265
- }
266
- flushPendingEvents(rootID);
267
- }
268
- }
269
- },
270
- receiveComponent(fn, args) {
271
- const internalInstance = args[0];
272
- if (getElementType(internalInstance) === ElementTypeOtherOrUnknown) {
273
- return fn.apply(this, args);
274
- }
275
-
276
- const id = getID(internalInstance);
277
- parentIDStack.push(id);
278
-
279
- const prevChildren = getChildren(internalInstance);
280
- try {
281
- const result = fn.apply(this, args);
282
-
283
- const nextChildren = getChildren(internalInstance);
284
- if (!areEqualArrays(prevChildren, nextChildren)) {
285
- // Push the operation
286
- recordReorder(internalInstance, id, nextChildren);
287
- }
288
-
289
- parentIDStack.pop();
290
- return result;
291
- } catch (err) {
292
- parentIDStack = [];
293
- throw err;
294
- } finally {
295
- if (parentIDStack.length === 0) {
296
- const rootID = internalInstanceToRootIDMap.get(internalInstance);
297
- if (rootID === undefined) {
298
- throw new Error('Expected to find root ID.');
299
- }
300
- flushPendingEvents(rootID);
301
- }
302
- }
303
- },
304
- unmountComponent(fn, args) {
305
- const internalInstance = args[0];
306
- if (getElementType(internalInstance) === ElementTypeOtherOrUnknown) {
307
- return fn.apply(this, args);
308
- }
309
-
310
- const id = getID(internalInstance);
311
- parentIDStack.push(id);
312
- try {
313
- const result = fn.apply(this, args);
314
- parentIDStack.pop();
315
-
316
- // Push the operation.
317
- recordUnmount(internalInstance, id);
318
-
319
- return result;
320
- } catch (err) {
321
- parentIDStack = [];
322
- throw err;
323
- } finally {
324
- if (parentIDStack.length === 0) {
325
- const rootID = internalInstanceToRootIDMap.get(internalInstance);
326
- if (rootID === undefined) {
327
- throw new Error('Expected to find root ID.');
328
- }
329
- flushPendingEvents(rootID);
330
- }
331
- }
332
- },
333
- });
334
- }
335
-
336
- function cleanup() {
337
- if (oldReconcilerMethods !== null) {
338
- if (renderer.Component) {
339
- restoreMany(renderer.Component.Mixin, oldReconcilerMethods);
340
- } else {
341
- restoreMany(renderer.Reconciler, oldReconcilerMethods);
342
- }
343
- }
344
- oldReconcilerMethods = null;
345
- }
346
-
347
- function recordMount(
348
- internalInstance: InternalInstance,
349
- id: number,
350
- parentID: number,
351
- ) {
352
- const isRoot = parentID === 0;
353
-
354
- if (__DEBUG__) {
355
- console.log(
356
- '%crecordMount()',
357
- 'color: green; font-weight: bold;',
358
- id,
359
- getData(internalInstance).displayName,
360
- );
361
- }
362
-
363
- if (isRoot) {
364
- // TODO Is this right? For all versions?
365
- const hasOwnerMetadata =
366
- internalInstance._currentElement != null &&
367
- internalInstance._currentElement._owner != null;
368
-
369
- pushOperation(TREE_OPERATION_ADD);
370
- pushOperation(id);
371
- pushOperation(ElementTypeRoot);
372
- pushOperation(0); // isProfilingSupported?
373
- pushOperation(hasOwnerMetadata ? 1 : 0);
374
- } else {
375
- const type = getElementType(internalInstance);
376
- const {displayName, key} = getData(internalInstance);
377
-
378
- const ownerID =
379
- internalInstance._currentElement != null &&
380
- internalInstance._currentElement._owner != null
381
- ? getID(internalInstance._currentElement._owner)
382
- : 0;
383
-
384
- let displayNameStringID = getStringID(displayName);
385
- let keyStringID = getStringID(key);
386
- pushOperation(TREE_OPERATION_ADD);
387
- pushOperation(id);
388
- pushOperation(type);
389
- pushOperation(parentID);
390
- pushOperation(ownerID);
391
- pushOperation(displayNameStringID);
392
- pushOperation(keyStringID);
393
- }
394
- }
395
-
396
- function recordReorder(
397
- internalInstance: InternalInstance,
398
- id: number,
399
- nextChildren: Array<InternalInstance>,
400
- ) {
401
- pushOperation(TREE_OPERATION_REORDER_CHILDREN);
402
- pushOperation(id);
403
- const nextChildIDs = nextChildren.map(getID);
404
- pushOperation(nextChildIDs.length);
405
- for (let i = 0; i < nextChildIDs.length; i++) {
406
- pushOperation(nextChildIDs[i]);
407
- }
408
- }
409
-
410
- function recordUnmount(internalInstance: InternalInstance, id: number) {
411
- pendingUnmountedIDs.push(id);
412
- idToInternalInstanceMap.delete(id);
413
- }
414
-
415
- function crawlAndRecordInitialMounts(
416
- id: number,
417
- parentID: number,
418
- rootID: number,
419
- ) {
420
- if (__DEBUG__) {
421
- console.group('crawlAndRecordInitialMounts() id:', id);
422
- }
423
-
424
- const internalInstance = idToInternalInstanceMap.get(id);
425
- if (internalInstance != null) {
426
- internalInstanceToRootIDMap.set(internalInstance, rootID);
427
- recordMount(internalInstance, id, parentID);
428
- getChildren(internalInstance).forEach(child =>
429
- crawlAndRecordInitialMounts(getID(child), id, rootID),
430
- );
431
- }
432
-
433
- if (__DEBUG__) {
434
- console.groupEnd();
435
- }
436
- }
437
-
438
- function flushInitialOperations() {
439
- // Crawl roots though and register any nodes that mounted before we were injected.
440
-
441
- const roots =
442
- renderer.Mount._instancesByReactRootID ||
443
- renderer.Mount._instancesByContainerID;
444
-
445
- for (let key in roots) {
446
- const internalInstance = roots[key];
447
- const id = getID(internalInstance);
448
- crawlAndRecordInitialMounts(id, 0, id);
449
- flushPendingEvents(id);
450
- }
451
- }
452
-
453
- let pendingOperations: Array<number> = [];
454
- let pendingStringTable: Map<string, number> = new Map();
455
- let pendingUnmountedIDs: Array<number> = [];
456
- let pendingStringTableLength: number = 0;
457
- let pendingUnmountedRootID: number | null = null;
458
-
459
- function flushPendingEvents(rootID: number) {
460
- if (
461
- pendingOperations.length === 0 &&
462
- pendingUnmountedIDs.length === 0 &&
463
- pendingUnmountedRootID === null
464
- ) {
465
- return;
466
- }
467
-
468
- const numUnmountIDs =
469
- pendingUnmountedIDs.length + (pendingUnmountedRootID === null ? 0 : 1);
470
-
471
- const operations = new Array(
472
- // Identify which renderer this update is coming from.
473
- 2 + // [rendererID, rootFiberID]
474
- // How big is the string table?
475
- 1 + // [stringTableLength]
476
- // Then goes the actual string table.
477
- pendingStringTableLength +
478
- // All unmounts are batched in a single message.
479
- // [TREE_OPERATION_REMOVE, removedIDLength, ...ids]
480
- (numUnmountIDs > 0 ? 2 + numUnmountIDs : 0) +
481
- // Mount operations
482
- pendingOperations.length,
483
- );
484
-
485
- // Identify which renderer this update is coming from.
486
- // This enables roots to be mapped to renderers,
487
- // Which in turn enables fiber properations, states, and hooks to be inspected.
488
- let i = 0;
489
- operations[i++] = rendererID;
490
- operations[i++] = rootID;
491
-
492
- // Now fill in the string table.
493
- // [stringTableLength, str1Length, ...str1, str2Length, ...str2, ...]
494
- operations[i++] = pendingStringTableLength;
495
- pendingStringTable.forEach((value, key) => {
496
- operations[i++] = key.length;
497
- const encodedKey = utfEncodeString(key);
498
- for (let j = 0; j < encodedKey.length; j++) {
499
- operations[i + j] = encodedKey[j];
500
- }
501
- i += key.length;
502
- });
503
-
504
- if (numUnmountIDs > 0) {
505
- // All unmounts except roots are batched in a single message.
506
- operations[i++] = TREE_OPERATION_REMOVE;
507
- // The first number is how many unmounted IDs we're gonna send.
508
- operations[i++] = numUnmountIDs;
509
- // Fill in the unmounts
510
- for (let j = 0; j < pendingUnmountedIDs.length; j++) {
511
- operations[i++] = pendingUnmountedIDs[j];
512
- }
513
- // The root ID should always be unmounted last.
514
- if (pendingUnmountedRootID !== null) {
515
- operations[i] = pendingUnmountedRootID;
516
- i++;
517
- }
518
- }
519
-
520
- // Fill in the rest of the operations.
521
- for (let j = 0; j < pendingOperations.length; j++) {
522
- operations[i + j] = pendingOperations[j];
523
- }
524
- i += pendingOperations.length;
525
-
526
- if (__DEBUG__) {
527
- printOperationsArray(operations);
528
- }
529
-
530
- // If we've already connected to the frontend, just pass the operations through.
531
- hook.emit('operations', operations);
532
-
533
- pendingOperations.length = 0;
534
- pendingUnmountedIDs = [];
535
- pendingUnmountedRootID = null;
536
- pendingStringTable.clear();
537
- pendingStringTableLength = 0;
538
- }
539
-
540
- function pushOperation(op: number): void {
541
- if (__DEV__) {
542
- if (!Number.isInteger(op)) {
543
- console.error(
544
- 'pushOperation() was called but the value is not an integer.',
545
- op,
546
- );
547
- }
548
- }
549
- pendingOperations.push(op);
550
- }
551
-
552
- function getStringID(str: string | null): number {
553
- if (str === null) {
554
- return 0;
555
- }
556
- const existingID = pendingStringTable.get(str);
557
- if (existingID !== undefined) {
558
- return existingID;
559
- }
560
- const stringID = pendingStringTable.size + 1;
561
- pendingStringTable.set(str, stringID);
562
- // The string table total length needs to account
563
- // both for the string length, and for the array item
564
- // that contains the length itself. Hence + 1.
565
- pendingStringTableLength += str.length + 1;
566
- return stringID;
567
- }
568
-
569
- let currentlyInspectedElementID: number | null = null;
570
- let currentlyInspectedPaths: Object = {};
571
-
572
- // Track the intersection of currently inspected paths,
573
- // so that we can send their data along if the element is re-rendered.
574
- function mergeInspectedPaths(path: Array<string | number>) {
575
- let current = currentlyInspectedPaths;
576
- path.forEach(key => {
577
- if (!current[key]) {
578
- current[key] = {};
579
- }
580
- current = current[key];
581
- });
582
- }
583
-
584
- function createIsPathWhitelisted(key: string) {
585
- // This function helps prevent previously-inspected paths from being dehydrated in updates.
586
- // This is important to avoid a bad user experience where expanded toggles collapse on update.
587
- return function isPathWhitelisted(path: Array<string | number>): boolean {
588
- let current = currentlyInspectedPaths[key];
589
- if (!current) {
590
- return false;
591
- }
592
- for (let i = 0; i < path.length; i++) {
593
- current = current[path[i]];
594
- if (!current) {
595
- return false;
596
- }
597
- }
598
- return true;
599
- };
600
- }
601
-
602
- // Fast path props lookup for React Native style editor.
603
- function getInstanceAndStyle(id: number): InstanceAndStyle {
604
- let instance = null;
605
- let style = null;
606
-
607
- const internalInstance = idToInternalInstanceMap.get(id);
608
- if (internalInstance != null) {
609
- instance = internalInstance._instance || null;
610
-
611
- const element = internalInstance._currentElement;
612
- if (element != null && element.props != null) {
613
- style = element.props.style || null;
614
- }
615
- }
616
-
617
- return {
618
- instance,
619
- style,
620
- };
621
- }
622
-
623
- function updateSelectedElement(id: number): void {
624
- const internalInstance = idToInternalInstanceMap.get(id);
625
- if (internalInstance == null) {
626
- console.warn(`Could not find instance with id "${id}"`);
627
- return;
628
- }
629
-
630
- switch (getElementType(internalInstance)) {
631
- case ElementTypeClass:
632
- global.$r = internalInstance._instance;
633
- break;
634
- case ElementTypeFunction:
635
- const element = internalInstance._currentElement;
636
- if (element == null) {
637
- console.warn(`Could not find element with id "${id}"`);
638
- return;
639
- }
640
-
641
- global.$r = {
642
- props: element.props,
643
- type: element.type,
644
- };
645
- break;
646
- default:
647
- global.$r = null;
648
- break;
649
- }
650
- }
651
-
652
- function inspectElement(
653
- id: number,
654
- path?: Array<string | number>,
655
- ): InspectedElementPayload {
656
- if (currentlyInspectedElementID !== id) {
657
- currentlyInspectedElementID = id;
658
- currentlyInspectedPaths = {};
659
- }
660
-
661
- const inspectedElement = inspectElementRaw(id);
662
- if (inspectedElement === null) {
663
- return {
664
- id,
665
- type: 'not-found',
666
- };
667
- }
668
-
669
- if (path != null) {
670
- mergeInspectedPaths(path);
671
- }
672
-
673
- // Any time an inspected element has an update,
674
- // we should update the selected $r value as wel.
675
- // Do this before dehyration (cleanForBridge).
676
- updateSelectedElement(id);
677
-
678
- inspectedElement.context = cleanForBridge(
679
- inspectedElement.context,
680
- createIsPathWhitelisted('context'),
681
- );
682
- inspectedElement.props = cleanForBridge(
683
- inspectedElement.props,
684
- createIsPathWhitelisted('props'),
685
- );
686
- inspectedElement.state = cleanForBridge(
687
- inspectedElement.state,
688
- createIsPathWhitelisted('state'),
689
- );
690
-
691
- return {
692
- id,
693
- type: 'full-data',
694
- value: inspectedElement,
695
- };
696
- }
697
-
698
- function inspectElementRaw(id: number): InspectedElement | null {
699
- const internalInstance = idToInternalInstanceMap.get(id);
700
-
701
- if (internalInstance == null) {
702
- return null;
703
- }
704
-
705
- const {displayName} = getData(internalInstance);
706
- const type = getElementType(internalInstance);
707
-
708
- let context = null;
709
- let owners = null;
710
- let props = null;
711
- let state = null;
712
- let source = null;
713
-
714
- const element = internalInstance._currentElement;
715
- if (element !== null) {
716
- props = element.props;
717
- source = element._source != null ? element._source : null;
718
-
719
- let owner = element._owner;
720
- if (owner) {
721
- owners = [];
722
- while (owner != null) {
723
- owners.push({
724
- displayName: getData(owner).displayName || 'Unknown',
725
- id: getID(owner),
726
- type: getElementType(owner),
727
- });
728
- if (owner._currentElement) {
729
- owner = owner._currentElement._owner;
730
- }
731
- }
732
- }
733
- }
734
-
735
- const publicInstance = internalInstance._instance;
736
- if (publicInstance != null) {
737
- context = publicInstance.context || null;
738
- state = publicInstance.state || null;
739
- }
740
-
741
- return {
742
- id,
743
-
744
- // Hooks did not exist in legacy versions
745
- canEditHooks: false,
746
-
747
- // Does the current renderer support editable function props?
748
- canEditFunctionProps: true,
749
-
750
- // Suspense did not exist in legacy versions
751
- canToggleSuspense: false,
752
-
753
- // Can view component source location.
754
- canViewSource: type === ElementTypeClass || type === ElementTypeFunction,
755
-
756
- displayName: displayName,
757
-
758
- type: type,
759
-
760
- // Inspectable properties.
761
- context,
762
- hooks: null,
763
- props,
764
- state,
765
-
766
- // List of owners
767
- owners,
768
-
769
- // Location of component in source coude.
770
- source,
771
- };
772
- }
773
-
774
- function logElementToConsole(id: number): void {
775
- const result = inspectElementRaw(id);
776
- if (result === null) {
777
- console.warn(`Could not find element with id "${id}"`);
778
- return;
779
- }
780
-
781
- const supportsGroup = typeof console.groupCollapsed === 'function';
782
- if (supportsGroup) {
783
- console.groupCollapsed(
784
- `[Click to expand] %c<${result.displayName || 'Component'} />`,
785
- // --dom-tag-name-color is the CSS variable Chrome styles HTML elements with in the console.
786
- 'color: var(--dom-tag-name-color); font-weight: normal;',
787
- );
788
- }
789
- if (result.props !== null) {
790
- console.log('Props:', result.props);
791
- }
792
- if (result.state !== null) {
793
- console.log('State:', result.state);
794
- }
795
- if (result.context !== null) {
796
- console.log('Context:', result.context);
797
- }
798
- const nativeNode = findNativeNodeForInternalID(id);
799
- if (nativeNode !== null) {
800
- console.log('Node:', nativeNode);
801
- }
802
- if (window.chrome || /firefox/i.test(navigator.userAgent)) {
803
- console.log(
804
- 'Right-click any value to save it as a global variable for further inspection.',
805
- );
806
- }
807
- if (supportsGroup) {
808
- console.groupEnd();
809
- }
810
- }
811
-
812
- function prepareViewElementSource(id: number): void {
813
- const internalInstance = idToInternalInstanceMap.get(id);
814
- if (internalInstance == null) {
815
- console.warn(`Could not find instance with id "${id}"`);
816
- return;
817
- }
818
-
819
- const element = internalInstance._currentElement;
820
- if (element == null) {
821
- console.warn(`Could not find element with id "${id}"`);
822
- return;
823
- }
824
-
825
- global.$type = element.type;
826
- }
827
-
828
- function setInProps(id: number, path: Array<string | number>, value: any) {
829
- const internalInstance = idToInternalInstanceMap.get(id);
830
- if (internalInstance != null) {
831
- const element = internalInstance._currentElement;
832
- internalInstance._currentElement = {
833
- ...element,
834
- props: copyWithSet(element.props, path, value),
835
- };
836
- forceUpdate(internalInstance._instance);
837
- }
838
- }
839
-
840
- function setInState(id: number, path: Array<string | number>, value: any) {
841
- const internalInstance = idToInternalInstanceMap.get(id);
842
- if (internalInstance != null) {
843
- const publicInstance = internalInstance._instance;
844
- if (publicInstance != null) {
845
- setIn(publicInstance.state, path, value);
846
- forceUpdate(publicInstance);
847
- }
848
- }
849
- }
850
-
851
- function setInContext(id: number, path: Array<string | number>, value: any) {
852
- const internalInstance = idToInternalInstanceMap.get(id);
853
- if (internalInstance != null) {
854
- const publicInstance = internalInstance._instance;
855
- if (publicInstance != null) {
856
- setIn(publicInstance.context, path, value);
857
- forceUpdate(publicInstance);
858
- }
859
- }
860
- }
861
-
862
- function setIn(obj: Object, path: Array<string | number>, value: any) {
863
- const last = path.pop();
864
- const parent = path.reduce(
865
- // $FlowFixMe
866
- (reduced, attr) => (reduced ? reduced[attr] : null),
867
- obj,
868
- );
869
- if (parent) {
870
- // $FlowFixMe
871
- parent[last] = value;
872
- }
873
- }
874
-
875
- // v16+ only features
876
- const getProfilingData = () => {
877
- throw new Error('getProfilingData not supported by this renderer');
878
- };
879
- const handleCommitFiberRoot = () => {
880
- throw new Error('handleCommitFiberRoot not supported by this renderer');
881
- };
882
- const handleCommitFiberUnmount = () => {
883
- throw new Error('handleCommitFiberUnmount not supported by this renderer');
884
- };
885
- const overrideSuspense = () => {
886
- throw new Error('overrideSuspense not supported by this renderer');
887
- };
888
- const setInHook = () => {
889
- throw new Error('setInHook not supported by this renderer');
890
- };
891
- const startProfiling = () => {
892
- // Do not throw, since this would break a multi-root scenario where v15 and v16 were both present.
893
- };
894
- const stopProfiling = () => {
895
- // Do not throw, since this would break a multi-root scenario where v15 and v16 were both present.
896
- };
897
-
898
- function getBestMatchForTrackedPath(): PathMatch | null {
899
- // Not implemented.
900
- return null;
901
- }
902
-
903
- function getPathForElement(id: number): Array<PathFrame> | null {
904
- // Not implemented.
905
- return null;
906
- }
907
-
908
- function updateComponentFilters(componentFilters: Array<ComponentFilter>) {
909
- // Not implemented.
910
- }
911
-
912
- function setTrackedPath(path: Array<PathFrame> | null) {
913
- // Not implemented.
914
- }
915
-
916
- function getOwnersList(id: number): Array<Owner> | null {
917
- // Not implemented.
918
- return null;
919
- }
920
-
921
- return {
922
- cleanup,
923
- flushInitialOperations,
924
- getBestMatchForTrackedPath,
925
- getFiberIDForNative: getInternalIDForNative,
926
- getInstanceAndStyle,
927
- findNativeNodesForFiberID: (id: number) => {
928
- const nativeNode = findNativeNodeForInternalID(id);
929
- return nativeNode == null ? null : [nativeNode];
930
- },
931
- getOwnersList,
932
- getPathForElement,
933
- getProfilingData,
934
- handleCommitFiberRoot,
935
- handleCommitFiberUnmount,
936
- inspectElement,
937
- logElementToConsole,
938
- overrideSuspense,
939
- prepareViewElementSource,
940
- renderer,
941
- setInContext,
942
- setInHook,
943
- setInProps,
944
- setInState,
945
- setTrackedPath,
946
- startProfiling,
947
- stopProfiling,
948
- updateComponentFilters,
949
- };
950
-}
packages/react-devtools-shared/src/backend/legacy/utils.js
deleted
-46
@@ -1,46 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {InternalInstance} from './renderer';
11
-
12
-export function decorate(object: Object, attr: string, fn: Function): Function {
13
- const old = object[attr];
14
- object[attr] = function(instance: InternalInstance) {
15
- return fn.call(this, old, arguments);
16
- };
17
- return old;
18
-}
19
-
20
-export function decorateMany(
21
- source: Object,
22
- fns: {[attr: string]: Function},
23
-): Object {
24
- const olds = {};
25
- for (const name in fns) {
26
- olds[name] = decorate(source, name, fns[name]);
27
- }
28
- return olds;
29
-}
30
-
31
-export function restoreMany(source: Object, olds: Object): void {
32
- for (let name in olds) {
33
- source[name] = olds[name];
34
- }
35
-}
36
-
37
-export function forceUpdate(instance: InternalInstance): void {
38
- if (typeof instance.forceUpdate === 'function') {
39
- instance.forceUpdate();
40
- } else if (
41
- instance.updater != null &&
42
- typeof instance.updater.enqueueForceUpdate === 'function'
43
- ) {
44
- instance.updater.enqueueForceUpdate(this, () => {}, 'forceUpdate');
45
- }
46
-}
packages/react-devtools-shared/src/backend/renderer.js
deleted
-3032
@@ -1,3032 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {gte} from 'semver';
11
-import {
12
- ComponentFilterDisplayName,
13
- ComponentFilterElementType,
14
- ComponentFilterHOC,
15
- ComponentFilterLocation,
16
- ElementTypeClass,
17
- ElementTypeContext,
18
- ElementTypeFunction,
19
- ElementTypeForwardRef,
20
- ElementTypeHostComponent,
21
- ElementTypeMemo,
22
- ElementTypeOtherOrUnknown,
23
- ElementTypeProfiler,
24
- ElementTypeRoot,
25
- ElementTypeSuspense,
26
-} from 'react-devtools-shared/src/types';
27
-import {
28
- getDisplayName,
29
- getDefaultComponentFilters,
30
- getInObject,
31
- getUID,
32
- setInObject,
33
- utfEncodeString,
34
-} from 'react-devtools-shared/src/utils';
35
-import {sessionStorageGetItem} from 'react-devtools-shared/src/storage';
36
-import {cleanForBridge, copyWithSet} from './utils';
37
-import {
38
- __DEBUG__,
39
- SESSION_STORAGE_RELOAD_AND_PROFILE_KEY,
40
- SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
41
- TREE_OPERATION_ADD,
42
- TREE_OPERATION_REMOVE,
43
- TREE_OPERATION_REORDER_CHILDREN,
44
- TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
45
-} from '../constants';
46
-import {inspectHooksOfFiber} from 'react-debug-tools';
47
-import {
48
- patch as patchConsole,
49
- registerRenderer as registerRendererWithConsole,
50
-} from './console';
51
-
52
-import type {Fiber} from 'react-reconciler/src/ReactFiber';
53
-import type {
54
- ChangeDescription,
55
- CommitDataBackend,
56
- DevToolsHook,
57
- InspectedElement,
58
- InspectedElementPayload,
59
- InstanceAndStyle,
60
- Owner,
61
- PathFrame,
62
- PathMatch,
63
- ProfilingDataBackend,
64
- ProfilingDataForRootBackend,
65
- ReactRenderer,
66
- RendererInterface,
67
-} from './types';
68
-import type {Interaction} from 'react-devtools-shared/src/devtools/views/Profiler/types';
69
-import type {
70
- ComponentFilter,
71
- ElementType,
72
-} from 'react-devtools-shared/src/types';
73
-
74
-type getDisplayNameForFiberType = (fiber: Fiber) => string | null;
75
-type getTypeSymbolType = (type: any) => Symbol | number;
76
-
77
-type ReactSymbolsType = {
78
- CONCURRENT_MODE_NUMBER: number,
79
- CONCURRENT_MODE_SYMBOL_STRING: string,
80
- DEPRECATED_ASYNC_MODE_SYMBOL_STRING: string,
81
- CONTEXT_CONSUMER_NUMBER: number,
82
- CONTEXT_CONSUMER_SYMBOL_STRING: string,
83
- CONTEXT_PROVIDER_NUMBER: number,
84
- CONTEXT_PROVIDER_SYMBOL_STRING: string,
85
- EVENT_COMPONENT_NUMBER: number,
86
- EVENT_COMPONENT_STRING: string,
87
- EVENT_TARGET_NUMBER: number,
88
- EVENT_TARGET_STRING: string,
89
- EVENT_TARGET_TOUCH_HIT_NUMBER: number,
90
- EVENT_TARGET_TOUCH_HIT_STRING: string,
91
- FORWARD_REF_NUMBER: number,
92
- FORWARD_REF_SYMBOL_STRING: string,
93
- MEMO_NUMBER: number,
94
- MEMO_SYMBOL_STRING: string,
95
- PROFILER_NUMBER: number,
96
- PROFILER_SYMBOL_STRING: string,
97
- STRICT_MODE_NUMBER: number,
98
- STRICT_MODE_SYMBOL_STRING: string,
99
- SUSPENSE_NUMBER: number,
100
- SUSPENSE_SYMBOL_STRING: string,
101
- DEPRECATED_PLACEHOLDER_SYMBOL_STRING: string,
102
-};
103
-
104
-type ReactPriorityLevelsType = {|
105
- ImmediatePriority: number,
106
- UserBlockingPriority: number,
107
- NormalPriority: number,
108
- LowPriority: number,
109
- IdlePriority: number,
110
- NoPriority: number,
111
-|};
112
-
113
-type ReactTypeOfWorkType = {|
114
- ClassComponent: number,
115
- ContextConsumer: number,
116
- ContextProvider: number,
117
- CoroutineComponent: number,
118
- CoroutineHandlerPhase: number,
119
- DehydratedSuspenseComponent: number,
120
- ForwardRef: number,
121
- Fragment: number,
122
- FunctionComponent: number,
123
- HostComponent: number,
124
- HostPortal: number,
125
- HostRoot: number,
126
- HostText: number,
127
- IncompleteClassComponent: number,
128
- IndeterminateComponent: number,
129
- LazyComponent: number,
130
- MemoComponent: number,
131
- Mode: number,
132
- Profiler: number,
133
- SimpleMemoComponent: number,
134
- SuspenseComponent: number,
135
- YieldComponent: number,
136
-|};
137
-
138
-type ReactTypeOfSideEffectType = {|
139
- NoEffect: number,
140
- PerformedWork: number,
141
- Placement: number,
142
-|};
143
-
144
-// Some environments (e.g. React Native / Hermes) don't support the performace API yet.
145
-const getCurrentTime =
146
- typeof performance === 'object' && typeof performance.now === 'function'
147
- ? () => performance.now()
148
- : () => Date.now();
149
-
150
-export function getInternalReactConstants(
151
- version: string,
152
-): {|
153
- getDisplayNameForFiber: getDisplayNameForFiberType,
154
- getTypeSymbol: getTypeSymbolType,
155
- ReactPriorityLevels: ReactPriorityLevelsType,
156
- ReactSymbols: ReactSymbolsType,
157
- ReactTypeOfSideEffect: ReactTypeOfSideEffectType,
158
- ReactTypeOfWork: ReactTypeOfWorkType,
159
-|} {
160
- const ReactSymbols: ReactSymbolsType = {
161
- CONCURRENT_MODE_NUMBER: 0xeacf,
162
- CONCURRENT_MODE_SYMBOL_STRING: 'Symbol(react.concurrent_mode)',
163
- DEPRECATED_ASYNC_MODE_SYMBOL_STRING: 'Symbol(react.async_mode)',
164
- CONTEXT_CONSUMER_NUMBER: 0xeace,
165
- CONTEXT_CONSUMER_SYMBOL_STRING: 'Symbol(react.context)',
166
- CONTEXT_PROVIDER_NUMBER: 0xeacd,
167
- CONTEXT_PROVIDER_SYMBOL_STRING: 'Symbol(react.provider)',
168
- EVENT_COMPONENT_NUMBER: 0xead5,
169
- EVENT_COMPONENT_STRING: 'Symbol(react.event_component)',
170
- EVENT_TARGET_NUMBER: 0xead6,
171
- EVENT_TARGET_STRING: 'Symbol(react.event_target)',
172
- EVENT_TARGET_TOUCH_HIT_NUMBER: 0xead7,
173
- EVENT_TARGET_TOUCH_HIT_STRING: 'Symbol(react.event_target.touch_hit)',
174
- FORWARD_REF_NUMBER: 0xead0,
175
- FORWARD_REF_SYMBOL_STRING: 'Symbol(react.forward_ref)',
176
- MEMO_NUMBER: 0xead3,
177
- MEMO_SYMBOL_STRING: 'Symbol(react.memo)',
178
- PROFILER_NUMBER: 0xead2,
179
- PROFILER_SYMBOL_STRING: 'Symbol(react.profiler)',
180
- STRICT_MODE_NUMBER: 0xeacc,
181
- STRICT_MODE_SYMBOL_STRING: 'Symbol(react.strict_mode)',
182
- SUSPENSE_NUMBER: 0xead1,
183
- SUSPENSE_SYMBOL_STRING: 'Symbol(react.suspense)',
184
- DEPRECATED_PLACEHOLDER_SYMBOL_STRING: 'Symbol(react.placeholder)',
185
- };
186
-
187
- const ReactTypeOfSideEffect: ReactTypeOfSideEffectType = {
188
- NoEffect: 0b00,
189
- PerformedWork: 0b01,
190
- Placement: 0b10,
191
- };
192
-
193
- // **********************************************************
194
- // The section below is copied from files in React repo.
195
- // Keep it in sync, and add version guards if it changes.
196
- //
197
- // Technically these priority levels are invalid for versions before 16.9,
198
- // but 16.9 is the first version to report priority level to DevTools,
199
- // so we can avoid checking for earlier versions and support pre-16.9 canary releases in the process.
200
- const ReactPriorityLevels: ReactPriorityLevelsType = {
201
- ImmediatePriority: 99,
202
- UserBlockingPriority: 98,
203
- NormalPriority: 97,
204
- LowPriority: 96,
205
- IdlePriority: 95,
206
- NoPriority: 90,
207
- };
208
-
209
- let ReactTypeOfWork: ReactTypeOfWorkType = ((null: any): ReactTypeOfWorkType);
210
-
211
- // **********************************************************
212
- // The section below is copied from files in React repo.
213
- // Keep it in sync, and add version guards if it changes.
214
- if (gte(version, '16.6.0-beta.0')) {
215
- ReactTypeOfWork = {
216
- ClassComponent: 1,
217
- ContextConsumer: 9,
218
- ContextProvider: 10,
219
- CoroutineComponent: -1, // Removed
220
- CoroutineHandlerPhase: -1, // Removed
221
- DehydratedSuspenseComponent: 18, // Behind a flag
222
- ForwardRef: 11,
223
- Fragment: 7,
224
- FunctionComponent: 0,
225
- HostComponent: 5,
226
- HostPortal: 4,
227
- HostRoot: 3,
228
- HostText: 6,
229
- IncompleteClassComponent: 17,
230
- IndeterminateComponent: 2,
231
- LazyComponent: 16,
232
- MemoComponent: 14,
233
- Mode: 8,
234
- Profiler: 12,
235
- SimpleMemoComponent: 15,
236
- SuspenseComponent: 13,
237
- YieldComponent: -1, // Removed
238
- };
239
- } else if (gte(version, '16.4.3-alpha')) {
240
- ReactTypeOfWork = {
241
- ClassComponent: 2,
242
- ContextConsumer: 11,
243
- ContextProvider: 12,
244
- CoroutineComponent: -1, // Removed
245
- CoroutineHandlerPhase: -1, // Removed
246
- DehydratedSuspenseComponent: -1, // Doesn't exist yet
247
- ForwardRef: 13,
248
- Fragment: 9,
249
- FunctionComponent: 0,
250
- HostComponent: 7,
251
- HostPortal: 6,
252
- HostRoot: 5,
253
- HostText: 8,
254
- IncompleteClassComponent: -1, // Doesn't exist yet
255
- IndeterminateComponent: 4,
256
- LazyComponent: -1, // Doesn't exist yet
257
- MemoComponent: -1, // Doesn't exist yet
258
- Mode: 10,
259
- Profiler: 15,
260
- SimpleMemoComponent: -1, // Doesn't exist yet
261
- SuspenseComponent: 16,
262
- YieldComponent: -1, // Removed
263
- };
264
- } else {
265
- ReactTypeOfWork = {
266
- ClassComponent: 2,
267
- ContextConsumer: 12,
268
- ContextProvider: 13,
269
- CoroutineComponent: 7,
270
- CoroutineHandlerPhase: 8,
271
- DehydratedSuspenseComponent: -1, // Doesn't exist yet
272
- ForwardRef: 14,
273
- Fragment: 10,
274
- FunctionComponent: 1,
275
- HostComponent: 5,
276
- HostPortal: 4,
277
- HostRoot: 3,
278
- HostText: 6,
279
- IncompleteClassComponent: -1, // Doesn't exist yet
280
- IndeterminateComponent: 0,
281
- LazyComponent: -1, // Doesn't exist yet
282
- MemoComponent: -1, // Doesn't exist yet
283
- Mode: 11,
284
- Profiler: 15,
285
- SimpleMemoComponent: -1, // Doesn't exist yet
286
- SuspenseComponent: 16,
287
- YieldComponent: 9,
288
- };
289
- }
290
- // **********************************************************
291
- // End of copied code.
292
- // **********************************************************
293
-
294
- function getTypeSymbol(type: any): Symbol | number {
295
- const symbolOrNumber =
296
- typeof type === 'object' && type !== null ? type.$$typeof : type;
297
-
298
- // $FlowFixMe Flow doesn't know about typeof "symbol"
299
- return typeof symbolOrNumber === 'symbol'
300
- ? symbolOrNumber.toString()
301
- : symbolOrNumber;
302
- }
303
-
304
- const {
305
- ClassComponent,
306
- IncompleteClassComponent,
307
- FunctionComponent,
308
- IndeterminateComponent,
309
- ForwardRef,
310
- HostRoot,
311
- HostComponent,
312
- HostPortal,
313
- HostText,
314
- Fragment,
315
- MemoComponent,
316
- SimpleMemoComponent,
317
- } = ReactTypeOfWork;
318
-
319
- const {
320
- CONCURRENT_MODE_NUMBER,
321
- CONCURRENT_MODE_SYMBOL_STRING,
322
- DEPRECATED_ASYNC_MODE_SYMBOL_STRING,
323
- CONTEXT_PROVIDER_NUMBER,
324
- CONTEXT_PROVIDER_SYMBOL_STRING,
325
- CONTEXT_CONSUMER_NUMBER,
326
- CONTEXT_CONSUMER_SYMBOL_STRING,
327
- STRICT_MODE_NUMBER,
328
- STRICT_MODE_SYMBOL_STRING,
329
- SUSPENSE_NUMBER,
330
- SUSPENSE_SYMBOL_STRING,
331
- DEPRECATED_PLACEHOLDER_SYMBOL_STRING,
332
- PROFILER_NUMBER,
333
- PROFILER_SYMBOL_STRING,
334
- } = ReactSymbols;
335
-
336
- // NOTICE Keep in sync with shouldFilterFiber() and other get*ForFiber methods
337
- function getDisplayNameForFiber(fiber: Fiber): string | null {
338
- const {elementType, type, tag} = fiber;
339
-
340
- // This is to support lazy components with a Promise as the type.
341
- // see https://github.com/facebook/react/pull/13397
342
- let resolvedType = type;
343
- if (typeof type === 'object' && type !== null) {
344
- if (typeof type.then === 'function') {
345
- resolvedType = type._reactResult;
346
- }
347
- }
348
-
349
- let resolvedContext: any = null;
350
-
351
- switch (tag) {
352
- case ClassComponent:
353
- case IncompleteClassComponent:
354
- return getDisplayName(resolvedType);
355
- case FunctionComponent:
356
- case IndeterminateComponent:
357
- return getDisplayName(resolvedType);
358
- case ForwardRef:
359
- return (
360
- resolvedType.displayName ||
361
- getDisplayName(resolvedType.render, 'Anonymous')
362
- );
363
- case HostRoot:
364
- return null;
365
- case HostComponent:
366
- return type;
367
- case HostPortal:
368
- case HostText:
369
- case Fragment:
370
- return null;
371
- case MemoComponent:
372
- case SimpleMemoComponent:
373
- if (elementType.displayName) {
374
- return elementType.displayName;
375
- } else {
376
- return getDisplayName(type, 'Anonymous');
377
- }
378
- default:
379
- const typeSymbol = getTypeSymbol(type);
380
-
381
- switch (typeSymbol) {
382
- case CONCURRENT_MODE_NUMBER:
383
- case CONCURRENT_MODE_SYMBOL_STRING:
384
- case DEPRECATED_ASYNC_MODE_SYMBOL_STRING:
385
- return null;
386
- case CONTEXT_PROVIDER_NUMBER:
387
- case CONTEXT_PROVIDER_SYMBOL_STRING:
388
- // 16.3.0 exposed the context object as "context"
389
- // PR #12501 changed it to "_context" for 16.3.1+
390
- // NOTE Keep in sync with inspectElementRaw()
391
- resolvedContext = fiber.type._context || fiber.type.context;
392
- return `${resolvedContext.displayName || 'Context'}.Provider`;
393
- case CONTEXT_CONSUMER_NUMBER:
394
- case CONTEXT_CONSUMER_SYMBOL_STRING:
395
- // 16.3-16.5 read from "type" because the Consumer is the actual context object.
396
- // 16.6+ should read from "type._context" because Consumer can be different (in DEV).
397
- // NOTE Keep in sync with inspectElementRaw()
398
- resolvedContext = fiber.type._context || fiber.type;
399
-
400
- // NOTE: TraceUpdatesBackendManager depends on the name ending in '.Consumer'
401
- // If you change the name, figure out a more resilient way to detect it.
402
- return `${resolvedContext.displayName || 'Context'}.Consumer`;
403
- case STRICT_MODE_NUMBER:
404
- case STRICT_MODE_SYMBOL_STRING:
405
- return null;
406
- case SUSPENSE_NUMBER:
407
- case SUSPENSE_SYMBOL_STRING:
408
- case DEPRECATED_PLACEHOLDER_SYMBOL_STRING:
409
- return 'Suspense';
410
- case PROFILER_NUMBER:
411
- case PROFILER_SYMBOL_STRING:
412
- return `Profiler(${fiber.memoizedProps.id})`;
413
- default:
414
- // Unknown element type.
415
- // This may mean a new element type that has not yet been added to DevTools.
416
- return null;
417
- }
418
- }
419
- }
420
-
421
- return {
422
- getDisplayNameForFiber,
423
- getTypeSymbol,
424
- ReactPriorityLevels,
425
- ReactTypeOfWork,
426
- ReactSymbols,
427
- ReactTypeOfSideEffect,
428
- };
429
-}
430
-
431
-export function attach(
432
- hook: DevToolsHook,
433
- rendererID: number,
434
- renderer: ReactRenderer,
435
- global: Object,
436
-): RendererInterface {
437
- const {
438
- getDisplayNameForFiber,
439
- getTypeSymbol,
440
- ReactPriorityLevels,
441
- ReactTypeOfWork,
442
- ReactSymbols,
443
- ReactTypeOfSideEffect,
444
- } = getInternalReactConstants(renderer.version);
445
- const {NoEffect, PerformedWork, Placement} = ReactTypeOfSideEffect;
446
- const {
447
- FunctionComponent,
448
- ClassComponent,
449
- ContextConsumer,
450
- DehydratedSuspenseComponent,
451
- Fragment,
452
- ForwardRef,
453
- HostRoot,
454
- HostPortal,
455
- HostComponent,
456
- HostText,
457
- IncompleteClassComponent,
458
- IndeterminateComponent,
459
- MemoComponent,
460
- SimpleMemoComponent,
461
- SuspenseComponent,
462
- } = ReactTypeOfWork;
463
- const {
464
- ImmediatePriority,
465
- UserBlockingPriority,
466
- NormalPriority,
467
- LowPriority,
468
- IdlePriority,
469
- NoPriority,
470
- } = ReactPriorityLevels;
471
- const {
472
- CONCURRENT_MODE_NUMBER,
473
- CONCURRENT_MODE_SYMBOL_STRING,
474
- DEPRECATED_ASYNC_MODE_SYMBOL_STRING,
475
- CONTEXT_CONSUMER_NUMBER,
476
- CONTEXT_CONSUMER_SYMBOL_STRING,
477
- CONTEXT_PROVIDER_NUMBER,
478
- CONTEXT_PROVIDER_SYMBOL_STRING,
479
- PROFILER_NUMBER,
480
- PROFILER_SYMBOL_STRING,
481
- STRICT_MODE_NUMBER,
482
- STRICT_MODE_SYMBOL_STRING,
483
- SUSPENSE_NUMBER,
484
- SUSPENSE_SYMBOL_STRING,
485
- DEPRECATED_PLACEHOLDER_SYMBOL_STRING,
486
- } = ReactSymbols;
487
-
488
- const {
489
- overrideHookState,
490
- overrideProps,
491
- setSuspenseHandler,
492
- scheduleUpdate,
493
- } = renderer;
494
- const supportsTogglingSuspense =
495
- typeof setSuspenseHandler === 'function' &&
496
- typeof scheduleUpdate === 'function';
497
-
498
- // Patching the console enables DevTools to do a few useful things:
499
- // * Append component stacks to warnings and error messages
500
- // * Disable logging during re-renders to inspect hooks (see inspectHooksOfFiber)
501
- //
502
- // Don't patch in test environments because we don't want to interfere with Jest's own console overrides.
503
- if (process.env.NODE_ENV !== 'test') {
504
- registerRendererWithConsole(renderer);
505
-
506
- // The renderer interface can't read this preference directly,
507
- // because it is stored in localStorage within the context of the extension.
508
- // It relies on the extension to pass the preference through via the global.
509
- if (window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ !== false) {
510
- patchConsole();
511
- }
512
- }
513
-
514
- const debug = (name: string, fiber: Fiber, parentFiber: ?Fiber): void => {
515
- if (__DEBUG__) {
516
- const displayName = getDisplayNameForFiber(fiber) || 'null';
517
- const parentDisplayName =
518
- (parentFiber != null && getDisplayNameForFiber(parentFiber)) || 'null';
519
- // NOTE: calling getFiberID or getPrimaryFiber is unsafe here
520
- // because it will put them in the map. For now, we'll omit them.
521
- // TODO: better debugging story for this.
522
- console.log(
523
- `[renderer] %c${name} %c${displayName} %c${
524
- parentFiber ? parentDisplayName : ''
525
- }`,
526
- 'color: red; font-weight: bold;',
527
- 'color: blue;',
528
- 'color: purple;',
529
- );
530
- }
531
- };
532
-
533
- // Configurable Components tree filters.
534
- const hideElementsWithDisplayNames: Set<RegExp> = new Set();
535
- const hideElementsWithPaths: Set<RegExp> = new Set();
536
- const hideElementsWithTypes: Set<ElementType> = new Set();
537
-
538
- function applyComponentFilters(componentFilters: Array<ComponentFilter>) {
539
- hideElementsWithTypes.clear();
540
- hideElementsWithDisplayNames.clear();
541
- hideElementsWithPaths.clear();
542
-
543
- componentFilters.forEach(componentFilter => {
544
- if (!componentFilter.isEnabled) {
545
- return;
546
- }
547
-
548
- switch (componentFilter.type) {
549
- case ComponentFilterDisplayName:
550
- if (componentFilter.isValid && componentFilter.value !== '') {
551
- hideElementsWithDisplayNames.add(
552
- new RegExp(componentFilter.value, 'i'),
553
- );
554
- }
555
- break;
556
- case ComponentFilterElementType:
557
- hideElementsWithTypes.add(componentFilter.value);
558
- break;
559
- case ComponentFilterLocation:
560
- if (componentFilter.isValid && componentFilter.value !== '') {
561
- hideElementsWithPaths.add(new RegExp(componentFilter.value, 'i'));
562
- }
563
- break;
564
- case ComponentFilterHOC:
565
- hideElementsWithDisplayNames.add(new RegExp('\\('));
566
- break;
567
- default:
568
- console.warn(
569
- `Invalid component filter type "${componentFilter.type}"`,
570
- );
571
- break;
572
- }
573
- });
574
- }
575
-
576
- // The renderer interface can't read saved component filters directly,
577
- // because they are stored in localStorage within the context of the extension.
578
- // Instead it relies on the extension to pass filters through.
579
- if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ != null) {
580
- applyComponentFilters(window.__REACT_DEVTOOLS_COMPONENT_FILTERS__);
581
- } else {
582
- // Unfortunately this feature is not expected to work for React Native for now.
583
- // It would be annoying for us to spam YellowBox warnings with unactionable stuff,
584
- // so for now just skip this message...
585
- //console.warn('⚛️ DevTools: Could not locate saved component filters');
586
-
587
- // Fallback to assuming the default filters in this case.
588
- applyComponentFilters(getDefaultComponentFilters());
589
- }
590
-
591
- // If necessary, we can revisit optimizing this operation.
592
- // For example, we could add a new recursive unmount tree operation.
593
- // The unmount operations are already significantly smaller than mount opreations though.
594
- // This is something to keep in mind for later.
595
- function updateComponentFilters(componentFilters: Array<ComponentFilter>) {
596
- if (isProfiling) {
597
- // Re-mounting a tree while profiling is in progress might break a lot of assumptions.
598
- // If necessary, we could support this- but it doesn't seem like a necessary use case.
599
- throw Error('Cannot modify filter preferences while profiling');
600
- }
601
-
602
- // Recursively unmount all roots.
603
- hook.getFiberRoots(rendererID).forEach(root => {
604
- currentRootID = getFiberID(getPrimaryFiber(root.current));
605
- unmountFiberChildrenRecursively(root.current);
606
- recordUnmount(root.current, false);
607
- currentRootID = -1;
608
- });
609
-
610
- applyComponentFilters(componentFilters);
611
-
612
- // Reset psuedo counters so that new path selections will be persisted.
613
- rootDisplayNameCounter.clear();
614
-
615
- // Recursively re-mount all roots with new filter criteria applied.
616
- hook.getFiberRoots(rendererID).forEach(root => {
617
- currentRootID = getFiberID(getPrimaryFiber(root.current));
618
- setRootPseudoKey(currentRootID, root.current);
619
- mountFiberRecursively(root.current, null);
620
- flushPendingEvents(root);
621
- currentRootID = -1;
622
- });
623
- }
624
-
625
- // NOTICE Keep in sync with get*ForFiber methods
626
- function shouldFilterFiber(fiber: Fiber): boolean {
627
- const {_debugSource, tag, type} = fiber;
628
-
629
- switch (tag) {
630
- case DehydratedSuspenseComponent:
631
- // TODO: ideally we would show dehydrated Suspense immediately.
632
- // However, it has some special behavior (like disconnecting
633
- // an alternate and turning into real Suspense) which breaks DevTools.
634
- // For now, ignore it, and only show it once it gets hydrated.
635
- // https://github.com/bvaughn/react-devtools-experimental/issues/197
636
- return true;
637
- case HostPortal:
638
- case HostText:
639
- case Fragment:
640
- return true;
641
- case HostRoot:
642
- // It is never valid to filter the root element.
643
- return false;
644
- default:
645
- const typeSymbol = getTypeSymbol(type);
646
-
647
- switch (typeSymbol) {
648
- case CONCURRENT_MODE_NUMBER:
649
- case CONCURRENT_MODE_SYMBOL_STRING:
650
- case DEPRECATED_ASYNC_MODE_SYMBOL_STRING:
651
- case STRICT_MODE_NUMBER:
652
- case STRICT_MODE_SYMBOL_STRING:
653
- return true;
654
- default:
655
- break;
656
- }
657
- }
658
-
659
- const elementType = getElementTypeForFiber(fiber);
660
- if (hideElementsWithTypes.has(elementType)) {
661
- return true;
662
- }
663
-
664
- if (hideElementsWithDisplayNames.size > 0) {
665
- const displayName = getDisplayNameForFiber(fiber);
666
- if (displayName != null) {
667
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
668
- for (let displayNameRegExp of hideElementsWithDisplayNames) {
669
- if (displayNameRegExp.test(displayName)) {
670
- return true;
671
- }
672
- }
673
- }
674
- }
675
-
676
- if (_debugSource != null && hideElementsWithPaths.size > 0) {
677
- const {fileName} = _debugSource;
678
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
679
- for (let pathRegExp of hideElementsWithPaths) {
680
- if (pathRegExp.test(fileName)) {
681
- return true;
682
- }
683
- }
684
- }
685
-
686
- return false;
687
- }
688
- // NOTICE Keep in sync with shouldFilterFiber() and other get*ForFiber methods
689
- function getElementTypeForFiber(fiber: Fiber): ElementType {
690
- const {type, tag} = fiber;
691
-
692
- switch (tag) {
693
- case ClassComponent:
694
- case IncompleteClassComponent:
695
- return ElementTypeClass;
696
- case FunctionComponent:
697
- case IndeterminateComponent:
698
- return ElementTypeFunction;
699
- case ForwardRef:
700
- return ElementTypeForwardRef;
701
- case HostRoot:
702
- return ElementTypeRoot;
703
- case HostComponent:
704
- return ElementTypeHostComponent;
705
- case HostPortal:
706
- case HostText:
707
- case Fragment:
708
- return ElementTypeOtherOrUnknown;
709
- case MemoComponent:
710
- case SimpleMemoComponent:
711
- return ElementTypeMemo;
712
- default:
713
- const typeSymbol = getTypeSymbol(type);
714
-
715
- switch (typeSymbol) {
716
- case CONCURRENT_MODE_NUMBER:
717
- case CONCURRENT_MODE_SYMBOL_STRING:
718
- case DEPRECATED_ASYNC_MODE_SYMBOL_STRING:
719
- return ElementTypeOtherOrUnknown;
720
- case CONTEXT_PROVIDER_NUMBER:
721
- case CONTEXT_PROVIDER_SYMBOL_STRING:
722
- return ElementTypeContext;
723
- case CONTEXT_CONSUMER_NUMBER:
724
- case CONTEXT_CONSUMER_SYMBOL_STRING:
725
- return ElementTypeContext;
726
- case STRICT_MODE_NUMBER:
727
- case STRICT_MODE_SYMBOL_STRING:
728
- return ElementTypeOtherOrUnknown;
729
- case SUSPENSE_NUMBER:
730
- case SUSPENSE_SYMBOL_STRING:
731
- case DEPRECATED_PLACEHOLDER_SYMBOL_STRING:
732
- return ElementTypeSuspense;
733
- case PROFILER_NUMBER:
734
- case PROFILER_SYMBOL_STRING:
735
- return ElementTypeProfiler;
736
- default:
737
- return ElementTypeOtherOrUnknown;
738
- }
739
- }
740
- }
741
-
742
- // This is a slightly annoying indirection.
743
- // It is currently necessary because DevTools wants to use unique objects as keys for instances.
744
- // However fibers have two versions.
745
- // We use this set to remember first encountered fiber for each conceptual instance.
746
- function getPrimaryFiber(fiber: Fiber): Fiber {
747
- if (primaryFibers.has(fiber)) {
748
- return fiber;
749
- }
750
- const {alternate} = fiber;
751
- if (alternate != null && primaryFibers.has(alternate)) {
752
- return alternate;
753
- }
754
- primaryFibers.add(fiber);
755
- return fiber;
756
- }
757
-
758
- const fiberToIDMap: Map<Fiber, number> = new Map();
759
- const idToFiberMap: Map<number, Fiber> = new Map();
760
- const primaryFibers: Set<Fiber> = new Set();
761
-
762
- // When profiling is supported, we store the latest tree base durations for each Fiber.
763
- // This is so that we can quickly capture a snapshot of those values if profiling starts.
764
- // If we didn't store these values, we'd have to crawl the tree when profiling started,
765
- // and use a slow path to find each of the current Fibers.
766
- const idToTreeBaseDurationMap: Map<number, number> = new Map();
767
-
768
- // When profiling is supported, we store the latest tree base durations for each Fiber.
769
- // This map enables us to filter these times by root when sending them to the frontend.
770
- const idToRootMap: Map<number, number> = new Map();
771
-
772
- // When a mount or update is in progress, this value tracks the root that is being operated on.
773
- let currentRootID: number = -1;
774
-
775
- function getFiberID(primaryFiber: Fiber): number {
776
- if (!fiberToIDMap.has(primaryFiber)) {
777
- const id = getUID();
778
- fiberToIDMap.set(primaryFiber, id);
779
- idToFiberMap.set(id, primaryFiber);
780
- }
781
- return ((fiberToIDMap.get(primaryFiber): any): number);
782
- }
783
-
784
- function getChangeDescription(
785
- prevFiber: Fiber | null,
786
- nextFiber: Fiber,
787
- ): ChangeDescription | null {
788
- switch (getElementTypeForFiber(nextFiber)) {
789
- case ElementTypeClass:
790
- case ElementTypeFunction:
791
- case ElementTypeMemo:
792
- case ElementTypeForwardRef:
793
- if (prevFiber === null) {
794
- return {
795
- context: null,
796
- didHooksChange: false,
797
- isFirstMount: true,
798
- props: null,
799
- state: null,
800
- };
801
- } else {
802
- return {
803
- context: getContextChangedKeys(nextFiber),
804
- didHooksChange: didHooksChange(
805
- prevFiber.memoizedState,
806
- nextFiber.memoizedState,
807
- ),
808
- isFirstMount: false,
809
- props: getChangedKeys(
810
- prevFiber.memoizedProps,
811
- nextFiber.memoizedProps,
812
- ),
813
- state: getChangedKeys(
814
- prevFiber.memoizedState,
815
- nextFiber.memoizedState,
816
- ),
817
- };
818
- }
819
- default:
820
- return null;
821
- }
822
- }
823
-
824
- function updateContextsForFiber(fiber: Fiber) {
825
- switch (getElementTypeForFiber(fiber)) {
826
- case ElementTypeClass:
827
- if (idToContextsMap !== null) {
828
- const id = getFiberID(getPrimaryFiber(fiber));
829
- const contexts = getContextsForFiber(fiber);
830
- if (contexts !== null) {
831
- idToContextsMap.set(id, contexts);
832
- }
833
- }
834
- break;
835
- default:
836
- break;
837
- }
838
- }
839
-
840
- // Differentiates between a null context value and no context.
841
- const NO_CONTEXT = {};
842
-
843
- function getContextsForFiber(fiber: Fiber): [Object, any] | null {
844
- switch (getElementTypeForFiber(fiber)) {
845
- case ElementTypeClass:
846
- const instance = fiber.stateNode;
847
- let legacyContext = NO_CONTEXT;
848
- let modernContext = NO_CONTEXT;
849
- if (instance != null) {
850
- if (
851
- instance.constructor &&
852
- instance.constructor.contextType != null
853
- ) {
854
- modernContext = instance.context;
855
- } else {
856
- legacyContext = instance.context;
857
- if (legacyContext && Object.keys(legacyContext).length === 0) {
858
- legacyContext = NO_CONTEXT;
859
- }
860
- }
861
- }
862
- return [legacyContext, modernContext];
863
- default:
864
- return null;
865
- }
866
- }
867
-
868
- // Record all contexts at the time profiling is started.
869
- // Fibers only store the current context value,
870
- // so we need to track them separatenly in order to determine changed keys.
871
- function crawlToInitializeContextsMap(fiber: Fiber) {
872
- updateContextsForFiber(fiber);
873
- let current = fiber.child;
874
- while (current !== null) {
875
- crawlToInitializeContextsMap(current);
876
- current = current.sibling;
877
- }
878
- }
879
-
880
- function getContextChangedKeys(fiber: Fiber): null | boolean | Array<string> {
881
- switch (getElementTypeForFiber(fiber)) {
882
- case ElementTypeClass:
883
- if (idToContextsMap !== null) {
884
- const id = getFiberID(getPrimaryFiber(fiber));
885
- const prevContexts = idToContextsMap.has(id)
886
- ? idToContextsMap.get(id)
887
- : null;
888
- const nextContexts = getContextsForFiber(fiber);
889
-
890
- if (prevContexts == null || nextContexts == null) {
891
- return null;
892
- }
893
-
894
- const [prevLegacyContext, prevModernContext] = prevContexts;
895
- const [nextLegacyContext, nextModernContext] = nextContexts;
896
-
897
- if (nextLegacyContext !== NO_CONTEXT) {
898
- return getChangedKeys(prevLegacyContext, nextLegacyContext);
899
- } else if (nextModernContext !== NO_CONTEXT) {
900
- return prevModernContext !== nextModernContext;
901
- }
902
- }
903
- break;
904
- default:
905
- break;
906
- }
907
- return null;
908
- }
909
-
910
- function didHooksChange(prev: any, next: any): boolean {
911
- if (next == null) {
912
- return false;
913
- }
914
-
915
- // We can't report anything meaningful for hooks changes.
916
- if (
917
- next.hasOwnProperty('baseState') &&
918
- next.hasOwnProperty('memoizedState') &&
919
- next.hasOwnProperty('next') &&
920
- next.hasOwnProperty('queue')
921
- ) {
922
- while (next !== null) {
923
- if (next.memoizedState !== prev.memoizedState) {
924
- return true;
925
- } else {
926
- next = next.next;
927
- prev = prev.next;
928
- }
929
- }
930
- }
931
-
932
- return false;
933
- }
934
-
935
- function getChangedKeys(prev: any, next: any): null | Array<string> {
936
- if (prev == null || next == null) {
937
- return null;
938
- }
939
-
940
- // We can't report anything meaningful for hooks changes.
941
- if (
942
- next.hasOwnProperty('baseState') &&
943
- next.hasOwnProperty('memoizedState') &&
944
- next.hasOwnProperty('next') &&
945
- next.hasOwnProperty('queue')
946
- ) {
947
- return null;
948
- }
949
-
950
- const keys = new Set([...Object.keys(prev), ...Object.keys(next)]);
951
- const changedKeys = [];
952
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
953
- for (let key of keys) {
954
- if (prev[key] !== next[key]) {
955
- changedKeys.push(key);
956
- }
957
- }
958
-
959
- return changedKeys;
960
- }
961
-
962
- // eslint-disable-next-line no-unused-vars
963
- function didFiberRender(prevFiber: Fiber, nextFiber: Fiber): boolean {
964
- switch (nextFiber.tag) {
965
- case ClassComponent:
966
- case FunctionComponent:
967
- case ContextConsumer:
968
- case MemoComponent:
969
- case SimpleMemoComponent:
970
- // For types that execute user code, we check PerformedWork effect.
971
- // We don't reflect bailouts (either referential or sCU) in DevTools.
972
- // eslint-disable-next-line no-bitwise
973
- return (nextFiber.effectTag & PerformedWork) === PerformedWork;
974
- // Note: ContextConsumer only gets PerformedWork effect in 16.3.3+
975
- // so it won't get highlighted with React 16.3.0 to 16.3.2.
976
- default:
977
- // For host components and other types, we compare inputs
978
- // to determine whether something is an update.
979
- return (
980
- prevFiber.memoizedProps !== nextFiber.memoizedProps ||
981
- prevFiber.memoizedState !== nextFiber.memoizedState ||
982
- prevFiber.ref !== nextFiber.ref
983
- );
984
- }
985
- }
986
-
987
- let pendingOperations: Array<number> = [];
988
- let pendingRealUnmountedIDs: Array<number> = [];
989
- let pendingSimulatedUnmountedIDs: Array<number> = [];
990
- let pendingOperationsQueue: Array<Array<number>> | null = [];
991
- let pendingStringTable: Map<string, number> = new Map();
992
- let pendingStringTableLength: number = 0;
993
- let pendingUnmountedRootID: number | null = null;
994
-
995
- function pushOperation(op: number): void {
996
- if (__DEV__) {
997
- if (!Number.isInteger(op)) {
998
- console.error(
999
- 'pushOperation() was called but the value is not an integer.',
1000
- op,
1001
- );
1002
- }
1003
- }
1004
- pendingOperations.push(op);
1005
- }
1006
-
1007
- function flushPendingEvents(root: Object): void {
1008
- if (
1009
- pendingOperations.length === 0 &&
1010
- pendingRealUnmountedIDs.length === 0 &&
1011
- pendingSimulatedUnmountedIDs.length === 0 &&
1012
- pendingUnmountedRootID === null
1013
- ) {
1014
- // If we're currently profiling, send an "operations" method even if there are no mutations to the tree.
1015
- // The frontend needs this no-op info to know how to reconstruct the tree for each commit,
1016
- // even if a particular commit didn't change the shape of the tree.
1017
- if (!isProfiling) {
1018
- return;
1019
- }
1020
- }
1021
-
1022
- const numUnmountIDs =
1023
- pendingRealUnmountedIDs.length +
1024
- pendingSimulatedUnmountedIDs.length +
1025
- (pendingUnmountedRootID === null ? 0 : 1);
1026
-
1027
- const operations = new Array(
1028
- // Identify which renderer this update is coming from.
1029
- 2 + // [rendererID, rootFiberID]
1030
- // How big is the string table?
1031
- 1 + // [stringTableLength]
1032
- // Then goes the actual string table.
1033
- pendingStringTableLength +
1034
- // All unmounts are batched in a single message.
1035
- // [TREE_OPERATION_REMOVE, removedIDLength, ...ids]
1036
- (numUnmountIDs > 0 ? 2 + numUnmountIDs : 0) +
1037
- // Regular operations
1038
- pendingOperations.length,
1039
- );
1040
-
1041
- // Identify which renderer this update is coming from.
1042
- // This enables roots to be mapped to renderers,
1043
- // Which in turn enables fiber props, states, and hooks to be inspected.
1044
- let i = 0;
1045
- operations[i++] = rendererID;
1046
- operations[i++] = currentRootID; // Use this ID in case the root was unmounted!
1047
-
1048
- // Now fill in the string table.
1049
- // [stringTableLength, str1Length, ...str1, str2Length, ...str2, ...]
1050
- operations[i++] = pendingStringTableLength;
1051
- pendingStringTable.forEach((value, key) => {
1052
- operations[i++] = key.length;
1053
- const encodedKey = utfEncodeString(key);
1054
- for (let j = 0; j < encodedKey.length; j++) {
1055
- operations[i + j] = encodedKey[j];
1056
- }
1057
- i += key.length;
1058
- });
1059
-
1060
- if (numUnmountIDs > 0) {
1061
- // All unmounts except roots are batched in a single message.
1062
- operations[i++] = TREE_OPERATION_REMOVE;
1063
- // The first number is how many unmounted IDs we're gonna send.
1064
- operations[i++] = numUnmountIDs;
1065
- // Fill in the real unmounts in the reverse order.
1066
- // They were inserted parents-first by React, but we want children-first.
1067
- // So we traverse our array backwards.
1068
- for (let j = pendingRealUnmountedIDs.length - 1; j >= 0; j--) {
1069
- operations[i++] = pendingRealUnmountedIDs[j];
1070
- }
1071
- // Fill in the simulated unmounts (hidden Suspense subtrees) in their order.
1072
- // (We want children to go before parents.)
1073
- // They go *after* the real unmounts because we know for sure they won't be
1074
- // children of already pushed "real" IDs. If they were, we wouldn't be able
1075
- // to discover them during the traversal, as they would have been deleted.
1076
- for (let j = 0; j < pendingSimulatedUnmountedIDs.length; j++) {
1077
- operations[i + j] = pendingSimulatedUnmountedIDs[j];
1078
- }
1079
- i += pendingSimulatedUnmountedIDs.length;
1080
- // The root ID should always be unmounted last.
1081
- if (pendingUnmountedRootID !== null) {
1082
- operations[i] = pendingUnmountedRootID;
1083
- i++;
1084
- }
1085
- }
1086
- // Fill in the rest of the operations.
1087
- for (let j = 0; j < pendingOperations.length; j++) {
1088
- operations[i + j] = pendingOperations[j];
1089
- }
1090
- i += pendingOperations.length;
1091
-
1092
- // Let the frontend know about tree operations.
1093
- // The first value in this array will identify which root it corresponds to,
1094
- // so we do no longer need to dispatch a separate root-committed event.
1095
- if (pendingOperationsQueue !== null) {
1096
- // Until the frontend has been connected, store the tree operations.
1097
- // This will let us avoid walking the tree later when the frontend connects,
1098
- // and it enables the Profiler's reload-and-profile functionality to work as well.
1099
- pendingOperationsQueue.push(operations);
1100
- } else {
1101
- // If we've already connected to the frontend, just pass the operations through.
1102
- hook.emit('operations', operations);
1103
- }
1104
-
1105
- pendingOperations.length = 0;
1106
- pendingRealUnmountedIDs.length = 0;
1107
- pendingSimulatedUnmountedIDs.length = 0;
1108
- pendingUnmountedRootID = null;
1109
- pendingStringTable.clear();
1110
- pendingStringTableLength = 0;
1111
- }
1112
-
1113
- function getStringID(str: string | null): number {
1114
- if (str === null) {
1115
- return 0;
1116
- }
1117
- const existingID = pendingStringTable.get(str);
1118
- if (existingID !== undefined) {
1119
- return existingID;
1120
- }
1121
- const stringID = pendingStringTable.size + 1;
1122
- pendingStringTable.set(str, stringID);
1123
- // The string table total length needs to account
1124
- // both for the string length, and for the array item
1125
- // that contains the length itself. Hence + 1.
1126
- pendingStringTableLength += str.length + 1;
1127
- return stringID;
1128
- }
1129
-
1130
- function recordMount(fiber: Fiber, parentFiber: Fiber | null) {
1131
- const isRoot = fiber.tag === HostRoot;
1132
- const id = getFiberID(getPrimaryFiber(fiber));
1133
-
1134
- const hasOwnerMetadata = fiber.hasOwnProperty('_debugOwner');
1135
- const isProfilingSupported = fiber.hasOwnProperty('treeBaseDuration');
1136
-
1137
- if (isRoot) {
1138
- pushOperation(TREE_OPERATION_ADD);
1139
- pushOperation(id);
1140
- pushOperation(ElementTypeRoot);
1141
- pushOperation(isProfilingSupported ? 1 : 0);
1142
- pushOperation(hasOwnerMetadata ? 1 : 0);
1143
-
1144
- if (isProfiling) {
1145
- if (displayNamesByRootID !== null) {
1146
- displayNamesByRootID.set(id, getDisplayNameForRoot(fiber));
1147
- }
1148
- }
1149
- } else {
1150
- const {key} = fiber;
1151
- const displayName = getDisplayNameForFiber(fiber);
1152
- const elementType = getElementTypeForFiber(fiber);
1153
- const {_debugOwner} = fiber;
1154
-
1155
- const ownerID =
1156
- _debugOwner != null ? getFiberID(getPrimaryFiber(_debugOwner)) : 0;
1157
- const parentID = parentFiber
1158
- ? getFiberID(getPrimaryFiber(parentFiber))
1159
- : 0;
1160
-
1161
- let displayNameStringID = getStringID(displayName);
1162
- let keyStringID = getStringID(key);
1163
- pushOperation(TREE_OPERATION_ADD);
1164
- pushOperation(id);
1165
- pushOperation(elementType);
1166
- pushOperation(parentID);
1167
- pushOperation(ownerID);
1168
- pushOperation(displayNameStringID);
1169
- pushOperation(keyStringID);
1170
- }
1171
-
1172
- if (isProfilingSupported) {
1173
- idToRootMap.set(id, currentRootID);
1174
-
1175
- recordProfilingDurations(fiber);
1176
- }
1177
- }
1178
-
1179
- function recordUnmount(fiber: Fiber, isSimulated: boolean) {
1180
- if (trackedPathMatchFiber !== null) {
1181
- // We're in the process of trying to restore previous selection.
1182
- // If this fiber matched but is being unmounted, there's no use trying.
1183
- // Reset the state so we don't keep holding onto it.
1184
- if (
1185
- fiber === trackedPathMatchFiber ||
1186
- fiber === trackedPathMatchFiber.alternate
1187
- ) {
1188
- setTrackedPath(null);
1189
- }
1190
- }
1191
-
1192
- const isRoot = fiber.tag === HostRoot;
1193
- const primaryFiber = getPrimaryFiber(fiber);
1194
- if (!fiberToIDMap.has(primaryFiber)) {
1195
- // If we've never seen this Fiber, it might be because
1196
- // it is inside a non-current Suspense fragment tree,
1197
- // and so the store is not even aware of it.
1198
- // In that case we can just ignore it, or otherwise
1199
- // there will be errors later on.
1200
- primaryFibers.delete(primaryFiber);
1201
- // TODO: this is fragile and can obscure actual bugs.
1202
- return;
1203
- }
1204
- const id = getFiberID(primaryFiber);
1205
- if (isRoot) {
1206
- // Roots must be removed only after all children (pending and simultated) have been removed.
1207
- // So we track it separately.
1208
- pendingUnmountedRootID = id;
1209
- } else if (!shouldFilterFiber(fiber)) {
1210
- // To maintain child-first ordering,
1211
- // we'll push it into one of these queues,
1212
- // and later arrange them in the correct order.
1213
- if (isSimulated) {
1214
- pendingSimulatedUnmountedIDs.push(id);
1215
- } else {
1216
- pendingRealUnmountedIDs.push(id);
1217
- }
1218
- }
1219
- fiberToIDMap.delete(primaryFiber);
1220
- idToFiberMap.delete(id);
1221
- primaryFibers.delete(primaryFiber);
1222
-
1223
- const isProfilingSupported = fiber.hasOwnProperty('treeBaseDuration');
1224
- if (isProfilingSupported) {
1225
- idToRootMap.delete(id);
1226
- idToTreeBaseDurationMap.delete(id);
1227
- }
1228
- }
1229
-
1230
- function mountFiberRecursively(
1231
- fiber: Fiber,
1232
- parentFiber: Fiber | null,
1233
- traverseSiblings = false,
1234
- ) {
1235
- if (__DEBUG__) {
1236
- debug('mountFiberRecursively()', fiber, parentFiber);
1237
- }
1238
-
1239
- // If we have the tree selection from previous reload, try to match this Fiber.
1240
- // Also remember whether to do the same for siblings.
1241
- const mightSiblingsBeOnTrackedPath = updateTrackedPathStateBeforeMount(
1242
- fiber,
1243
- );
1244
-
1245
- const shouldIncludeInTree = !shouldFilterFiber(fiber);
1246
- if (shouldIncludeInTree) {
1247
- recordMount(fiber, parentFiber);
1248
- }
1249
-
1250
- const isTimedOutSuspense =
1251
- fiber.tag === ReactTypeOfWork.SuspenseComponent &&
1252
- fiber.memoizedState !== null;
1253
-
1254
- if (isTimedOutSuspense) {
1255
- // Special case: if Suspense mounts in a timed-out state,
1256
- // get the fallback child from the inner fragment and mount
1257
- // it as if it was our own child. Updates handle this too.
1258
- const primaryChildFragment = fiber.child;
1259
- const fallbackChildFragment = primaryChildFragment
1260
- ? primaryChildFragment.sibling
1261
- : null;
1262
- const fallbackChild = fallbackChildFragment
1263
- ? fallbackChildFragment.child
1264
- : null;
1265
- if (fallbackChild !== null) {
1266
- mountFiberRecursively(
1267
- fallbackChild,
1268
- shouldIncludeInTree ? fiber : parentFiber,
1269
- true,
1270
- );
1271
- }
1272
- } else {
1273
- if (fiber.child !== null) {
1274
- mountFiberRecursively(
1275
- fiber.child,
1276
- shouldIncludeInTree ? fiber : parentFiber,
1277
- true,
1278
- );
1279
- }
1280
- }
1281
-
1282
- // We're exiting this Fiber now, and entering its siblings.
1283
- // If we have selection to restore, we might need to re-activate tracking.
1284
- updateTrackedPathStateAfterMount(mightSiblingsBeOnTrackedPath);
1285
-
1286
- if (traverseSiblings && fiber.sibling !== null) {
1287
- mountFiberRecursively(fiber.sibling, parentFiber, true);
1288
- }
1289
- }
1290
-
1291
- // We use this to simulate unmounting for Suspense trees
1292
- // when we switch from primary to fallback.
1293
- function unmountFiberChildrenRecursively(fiber: Fiber) {
1294
- if (__DEBUG__) {
1295
- debug('unmountFiberChildrenRecursively()', fiber);
1296
- }
1297
-
1298
- // We might meet a nested Suspense on our way.
1299
- const isTimedOutSuspense =
1300
- fiber.tag === ReactTypeOfWork.SuspenseComponent &&
1301
- fiber.memoizedState !== null;
1302
-
1303
- let child = fiber.child;
1304
- if (isTimedOutSuspense) {
1305
- // If it's showing fallback tree, let's traverse it instead.
1306
- const primaryChildFragment = fiber.child;
1307
- const fallbackChildFragment = primaryChildFragment
1308
- ? primaryChildFragment.sibling
1309
- : null;
1310
- // Skip over to the real Fiber child.
1311
- child = fallbackChildFragment ? fallbackChildFragment.child : null;
1312
- }
1313
-
1314
- while (child !== null) {
1315
- // Record simulated unmounts children-first.
1316
- // We skip nodes without return because those are real unmounts.
1317
- if (child.return !== null) {
1318
- unmountFiberChildrenRecursively(child);
1319
- recordUnmount(child, true);
1320
- }
1321
- child = child.sibling;
1322
- }
1323
- }
1324
-
1325
- function recordProfilingDurations(fiber: Fiber) {
1326
- const id = getFiberID(getPrimaryFiber(fiber));
1327
- const {actualDuration, treeBaseDuration} = fiber;
1328
-
1329
- idToTreeBaseDurationMap.set(id, treeBaseDuration || 0);
1330
-
1331
- if (isProfiling) {
1332
- const {alternate} = fiber;
1333
-
1334
- if (
1335
- alternate == null ||
1336
- treeBaseDuration !== alternate.treeBaseDuration
1337
- ) {
1338
- // Tree base duration updates are included in the operations typed array.
1339
- // So we have to convert them from milliseconds to microseconds so we can send them as ints.
1340
- const convertedTreeBaseDuration = Math.floor(
1341
- (treeBaseDuration || 0) * 1000,
1342
- );
1343
- pushOperation(TREE_OPERATION_UPDATE_TREE_BASE_DURATION);
1344
- pushOperation(id);
1345
- pushOperation(convertedTreeBaseDuration);
1346
- }
1347
-
1348
- if (alternate == null || didFiberRender(alternate, fiber)) {
1349
- if (actualDuration != null) {
1350
- // The actual duration reported by React includes time spent working on children.
1351
- // This is useful information, but it's also useful to be able to exclude child durations.
1352
- // The frontend can't compute this, since the immediate children may have been filtered out.
1353
- // So we need to do this on the backend.
1354
- // Note that this calculated self duration is not the same thing as the base duration.
1355
- // The two are calculated differently (tree duration does not accumulate).
1356
- let selfDuration = actualDuration;
1357
- let child = fiber.child;
1358
- while (child !== null) {
1359
- selfDuration -= child.actualDuration || 0;
1360
- child = child.sibling;
1361
- }
1362
-
1363
- // If profiling is active, store durations for elements that were rendered during the commit.
1364
- // Note that we should do this for any fiber we performed work on, regardless of its actualDuration value.
1365
- // In some cases actualDuration might be 0 for fibers we worked on (particularly if we're using Date.now)
1366
- // In other cases (e.g. Memo) actualDuration might be greater than 0 even if we "bailed out".
1367
- const metadata = ((currentCommitProfilingMetadata: any): CommitProfilingData);
1368
- metadata.durations.push(id, actualDuration, selfDuration);
1369
- metadata.maxActualDuration = Math.max(
1370
- metadata.maxActualDuration,
1371
- actualDuration,
1372
- );
1373
-
1374
- if (recordChangeDescriptions) {
1375
- const changeDescription = getChangeDescription(alternate, fiber);
1376
- if (changeDescription !== null) {
1377
- if (metadata.changeDescriptions !== null) {
1378
- metadata.changeDescriptions.set(id, changeDescription);
1379
- }
1380
- }
1381
-
1382
- updateContextsForFiber(fiber);
1383
- }
1384
- }
1385
- }
1386
- }
1387
- }
1388
-
1389
- function recordResetChildren(fiber: Fiber, childSet: Fiber) {
1390
- // The frontend only really cares about the displayName, key, and children.
1391
- // The first two don't really change, so we are only concerned with the order of children here.
1392
- // This is trickier than a simple comparison though, since certain types of fibers are filtered.
1393
- const nextChildren: Array<number> = [];
1394
-
1395
- // This is a naive implimentation that shallowly recurses children.
1396
- // We might want to revisit this if it proves to be too inefficient.
1397
- let child = childSet;
1398
- while (child !== null) {
1399
- findReorderedChildrenRecursively(child, nextChildren);
1400
- child = child.sibling;
1401
- }
1402
-
1403
- const numChildren = nextChildren.length;
1404
- if (numChildren < 2) {
1405
- // No need to reorder.
1406
- return;
1407
- }
1408
- pushOperation(TREE_OPERATION_REORDER_CHILDREN);
1409
- pushOperation(getFiberID(getPrimaryFiber(fiber)));
1410
- pushOperation(numChildren);
1411
- for (let i = 0; i < nextChildren.length; i++) {
1412
- pushOperation(nextChildren[i]);
1413
- }
1414
- }
1415
-
1416
- function findReorderedChildrenRecursively(
1417
- fiber: Fiber,
1418
- nextChildren: Array<number>,
1419
- ) {
1420
- if (!shouldFilterFiber(fiber)) {
1421
- nextChildren.push(getFiberID(getPrimaryFiber(fiber)));
1422
- } else {
1423
- let child = fiber.child;
1424
- while (child !== null) {
1425
- findReorderedChildrenRecursively(child, nextChildren);
1426
- child = child.sibling;
1427
- }
1428
- }
1429
- }
1430
-
1431
- // Returns whether closest unfiltered fiber parent needs to reset its child list.
1432
- function updateFiberRecursively(
1433
- nextFiber: Fiber,
1434
- prevFiber: Fiber,
1435
- parentFiber: Fiber | null,
1436
- ): boolean {
1437
- if (__DEBUG__) {
1438
- debug('updateFiberRecursively()', nextFiber, parentFiber);
1439
- }
1440
-
1441
- if (
1442
- mostRecentlyInspectedElement !== null &&
1443
- mostRecentlyInspectedElement.id ===
1444
- getFiberID(getPrimaryFiber(nextFiber)) &&
1445
- didFiberRender(prevFiber, nextFiber)
1446
- ) {
1447
- // If this Fiber has updated, clear cached inspected data.
1448
- // If it is inspected again, it may need to be re-run to obtain updated hooks values.
1449
- hasElementUpdatedSinceLastInspected = true;
1450
- }
1451
-
1452
- const shouldIncludeInTree = !shouldFilterFiber(nextFiber);
1453
- const isSuspense = nextFiber.tag === SuspenseComponent;
1454
- let shouldResetChildren = false;
1455
- // The behavior of timed-out Suspense trees is unique.
1456
- // Rather than unmount the timed out content (and possibly lose important state),
1457
- // React re-parents this content within a hidden Fragment while the fallback is showing.
1458
- // This behavior doesn't need to be observable in the DevTools though.
1459
- // It might even result in a bad user experience for e.g. node selection in the Elements panel.
1460
- // The easiest fix is to strip out the intermediate Fragment fibers,
1461
- // so the Elements panel and Profiler don't need to special case them.
1462
- // Suspense components only have a non-null memoizedState if they're timed-out.
1463
- const prevDidTimeout = isSuspense && prevFiber.memoizedState !== null;
1464
- const nextDidTimeOut = isSuspense && nextFiber.memoizedState !== null;
1465
- // The logic below is inspired by the codepaths in updateSuspenseComponent()
1466
- // inside ReactFiberBeginWork in the React source code.
1467
- if (prevDidTimeout && nextDidTimeOut) {
1468
- // Fallback -> Fallback:
1469
- // 1. Reconcile fallback set.
1470
- const nextFiberChild = nextFiber.child;
1471
- const nextFallbackChildSet = nextFiberChild
1472
- ? nextFiberChild.sibling
1473
- : null;
1474
- // Note: We can't use nextFiber.child.sibling.alternate
1475
- // because the set is special and alternate may not exist.
1476
- const prevFiberChild = prevFiber.child;
1477
- const prevFallbackChildSet = prevFiberChild
1478
- ? prevFiberChild.sibling
1479
- : null;
1480
- if (
1481
- nextFallbackChildSet != null &&
1482
- prevFallbackChildSet != null &&
1483
- updateFiberRecursively(
1484
- nextFallbackChildSet,
1485
- prevFallbackChildSet,
1486
- nextFiber,
1487
- )
1488
- ) {
1489
- shouldResetChildren = true;
1490
- }
1491
- } else if (prevDidTimeout && !nextDidTimeOut) {
1492
- // Fallback -> Primary:
1493
- // 1. Unmount fallback set
1494
- // Note: don't emulate fallback unmount because React actually did it.
1495
- // 2. Mount primary set
1496
- const nextPrimaryChildSet = nextFiber.child;
1497
- if (nextPrimaryChildSet !== null) {
1498
- mountFiberRecursively(nextPrimaryChildSet, nextFiber, true);
1499
- }
1500
- shouldResetChildren = true;
1501
- } else if (!prevDidTimeout && nextDidTimeOut) {
1502
- // Primary -> Fallback:
1503
- // 1. Hide primary set
1504
- // This is not a real unmount, so it won't get reported by React.
1505
- // We need to manually walk the previous tree and record unmounts.
1506
- unmountFiberChildrenRecursively(prevFiber);
1507
- // 2. Mount fallback set
1508
- const nextFiberChild = nextFiber.child;
1509
- const nextFallbackChildSet = nextFiberChild
1510
- ? nextFiberChild.sibling
1511
- : null;
1512
- if (nextFallbackChildSet != null) {
1513
- mountFiberRecursively(nextFallbackChildSet, nextFiber, true);
1514
- shouldResetChildren = true;
1515
- }
1516
- } else {
1517
- // Common case: Primary -> Primary.
1518
- // This is the same codepath as for non-Suspense fibers.
1519
- if (nextFiber.child !== prevFiber.child) {
1520
- // If the first child is different, we need to traverse them.
1521
- // Each next child will be either a new child (mount) or an alternate (update).
1522
- let nextChild = nextFiber.child;
1523
- let prevChildAtSameIndex = prevFiber.child;
1524
- while (nextChild) {
1525
- // We already know children will be referentially different because
1526
- // they are either new mounts or alternates of previous children.
1527
- // Schedule updates and mounts depending on whether alternates exist.
1528
- // We don't track deletions here because they are reported separately.
1529
- if (nextChild.alternate) {
1530
- const prevChild = nextChild.alternate;
1531
- if (
1532
- updateFiberRecursively(
1533
- nextChild,
1534
- prevChild,
1535
- shouldIncludeInTree ? nextFiber : parentFiber,
1536
- )
1537
- ) {
1538
- // If a nested tree child order changed but it can't handle its own
1539
- // child order invalidation (e.g. because it's filtered out like host nodes),
1540
- // propagate the need to reset child order upwards to this Fiber.
1541
- shouldResetChildren = true;
1542
- }
1543
- // However we also keep track if the order of the children matches
1544
- // the previous order. They are always different referentially, but
1545
- // if the instances line up conceptually we'll want to know that.
1546
- if (prevChild !== prevChildAtSameIndex) {
1547
- shouldResetChildren = true;
1548
- }
1549
- } else {
1550
- mountFiberRecursively(
1551
- nextChild,
1552
- shouldIncludeInTree ? nextFiber : parentFiber,
1553
- );
1554
- shouldResetChildren = true;
1555
- }
1556
- // Try the next child.
1557
- nextChild = nextChild.sibling;
1558
- // Advance the pointer in the previous list so that we can
1559
- // keep comparing if they line up.
1560
- if (!shouldResetChildren && prevChildAtSameIndex !== null) {
1561
- prevChildAtSameIndex = prevChildAtSameIndex.sibling;
1562
- }
1563
- }
1564
- // If we have no more children, but used to, they don't line up.
1565
- if (prevChildAtSameIndex !== null) {
1566
- shouldResetChildren = true;
1567
- }
1568
- }
1569
- }
1570
- if (shouldIncludeInTree) {
1571
- const isProfilingSupported = nextFiber.hasOwnProperty('treeBaseDuration');
1572
- if (isProfilingSupported) {
1573
- recordProfilingDurations(nextFiber);
1574
- }
1575
- }
1576
- if (shouldResetChildren) {
1577
- // We need to crawl the subtree for closest non-filtered Fibers
1578
- // so that we can display them in a flat children set.
1579
- if (shouldIncludeInTree) {
1580
- // Normally, search for children from the rendered child.
1581
- let nextChildSet = nextFiber.child;
1582
- if (nextDidTimeOut) {
1583
- // Special case: timed-out Suspense renders the fallback set.
1584
- const nextFiberChild = nextFiber.child;
1585
- nextChildSet = nextFiberChild ? nextFiberChild.sibling : null;
1586
- }
1587
- if (nextChildSet != null) {
1588
- recordResetChildren(nextFiber, nextChildSet);
1589
- }
1590
- // We've handled the child order change for this Fiber.
1591
- // Since it's included, there's no need to invalidate parent child order.
1592
- return false;
1593
- } else {
1594
- // Let the closest unfiltered parent Fiber reset its child order instead.
1595
- return true;
1596
- }
1597
- } else {
1598
- return false;
1599
- }
1600
- }
1601
-
1602
- function cleanup() {
1603
- // We don't patch any methods so there is no cleanup.
1604
- }
1605
-
1606
- function flushInitialOperations() {
1607
- const localPendingOperationsQueue = pendingOperationsQueue;
1608
-
1609
- pendingOperationsQueue = null;
1610
-
1611
- if (
1612
- localPendingOperationsQueue !== null &&
1613
- localPendingOperationsQueue.length > 0
1614
- ) {
1615
- // We may have already queued up some operations before the frontend connected
1616
- // If so, let the frontend know about them.
1617
- localPendingOperationsQueue.forEach(operations => {
1618
- hook.emit('operations', operations);
1619
- });
1620
- } else {
1621
- // Before the traversals, remember to start tracking
1622
- // our path in case we have selection to restore.
1623
- if (trackedPath !== null) {
1624
- mightBeOnTrackedPath = true;
1625
- }
1626
- // If we have not been profiling, then we can just walk the tree and build up its current state as-is.
1627
- hook.getFiberRoots(rendererID).forEach(root => {
1628
- currentRootID = getFiberID(getPrimaryFiber(root.current));
1629
- setRootPseudoKey(currentRootID, root.current);
1630
-
1631
- // Checking root.memoizedInteractions handles multi-renderer edge-case-
1632
- // where some v16 renderers support profiling and others don't.
1633
- if (isProfiling && root.memoizedInteractions != null) {
1634
- // If profiling is active, store commit time and duration, and the current interactions.
1635
- // The frontend may request this information after profiling has stopped.
1636
- currentCommitProfilingMetadata = {
1637
- changeDescriptions: recordChangeDescriptions ? new Map() : null,
1638
- durations: [],
1639
- commitTime: getCurrentTime() - profilingStartTime,
1640
- interactions: Array.from(root.memoizedInteractions).map(
1641
- (interaction: Interaction) => ({
1642
- ...interaction,
1643
- timestamp: interaction.timestamp - profilingStartTime,
1644
- }),
1645
- ),
1646
- maxActualDuration: 0,
1647
- priorityLevel: null,
1648
- };
1649
- }
1650
-
1651
- mountFiberRecursively(root.current, null);
1652
- flushPendingEvents(root);
1653
- currentRootID = -1;
1654
- });
1655
- }
1656
- }
1657
-
1658
- function handleCommitFiberUnmount(fiber) {
1659
- // This is not recursive.
1660
- // We can't traverse fibers after unmounting so instead
1661
- // we rely on React telling us about each unmount.
1662
- recordUnmount(fiber, false);
1663
- }
1664
-
1665
- function handleCommitFiberRoot(root, priorityLevel) {
1666
- const current = root.current;
1667
- const alternate = current.alternate;
1668
-
1669
- currentRootID = getFiberID(getPrimaryFiber(current));
1670
-
1671
- // Before the traversals, remember to start tracking
1672
- // our path in case we have selection to restore.
1673
- if (trackedPath !== null) {
1674
- mightBeOnTrackedPath = true;
1675
- }
1676
-
1677
- // Checking root.memoizedInteractions handles multi-renderer edge-case-
1678
- // where some v16 renderers support profiling and others don't.
1679
- const isProfilingSupported = root.memoizedInteractions != null;
1680
-
1681
- if (isProfiling && isProfilingSupported) {
1682
- // If profiling is active, store commit time and duration, and the current interactions.
1683
- // The frontend may request this information after profiling has stopped.
1684
- currentCommitProfilingMetadata = {
1685
- changeDescriptions: recordChangeDescriptions ? new Map() : null,
1686
- durations: [],
1687
- commitTime: getCurrentTime() - profilingStartTime,
1688
- interactions: Array.from(root.memoizedInteractions).map(
1689
- (interaction: Interaction) => ({
1690
- ...interaction,
1691
- timestamp: interaction.timestamp - profilingStartTime,
1692
- }),
1693
- ),
1694
- maxActualDuration: 0,
1695
- priorityLevel:
1696
- priorityLevel == null ? null : formatPriorityLevel(priorityLevel),
1697
- };
1698
- }
1699
-
1700
- if (alternate) {
1701
- // TODO: relying on this seems a bit fishy.
1702
- const wasMounted =
1703
- alternate.memoizedState != null &&
1704
- alternate.memoizedState.element != null;
1705
- const isMounted =
1706
- current.memoizedState != null && current.memoizedState.element != null;
1707
- if (!wasMounted && isMounted) {
1708
- // Mount a new root.
1709
- setRootPseudoKey(currentRootID, current);
1710
- mountFiberRecursively(current, null);
1711
- } else if (wasMounted && isMounted) {
1712
- // Update an existing root.
1713
- updateFiberRecursively(current, alternate, null);
1714
- } else if (wasMounted && !isMounted) {
1715
- // Unmount an existing root.
1716
- removeRootPseudoKey(currentRootID);
1717
- recordUnmount(current, false);
1718
- }
1719
- } else {
1720
- // Mount a new root.
1721
- setRootPseudoKey(currentRootID, current);
1722
- mountFiberRecursively(current, null);
1723
- }
1724
-
1725
- if (isProfiling && isProfilingSupported) {
1726
- const commitProfilingMetadata = ((rootToCommitProfilingMetadataMap: any): CommitProfilingMetadataMap).get(
1727
- currentRootID,
1728
- );
1729
- if (commitProfilingMetadata != null) {
1730
- commitProfilingMetadata.push(
1731
- ((currentCommitProfilingMetadata: any): CommitProfilingData),
1732
- );
1733
- } else {
1734
- ((rootToCommitProfilingMetadataMap: any): CommitProfilingMetadataMap).set(
1735
- currentRootID,
1736
- [((currentCommitProfilingMetadata: any): CommitProfilingData)],
1737
- );
1738
- }
1739
- }
1740
-
1741
- // We're done here.
1742
- flushPendingEvents(root);
1743
-
1744
- currentRootID = -1;
1745
- }
1746
-
1747
- function findAllCurrentHostFibers(id: number): $ReadOnlyArray<Fiber> {
1748
- const fibers = [];
1749
- const fiber = findCurrentFiberUsingSlowPathById(id);
1750
- if (!fiber) {
1751
- return fibers;
1752
- }
1753
-
1754
- // Next we'll drill down this component to find all HostComponent/Text.
1755
- let node: Fiber = fiber;
1756
- while (true) {
1757
- if (node.tag === HostComponent || node.tag === HostText) {
1758
- fibers.push(node);
1759
- } else if (node.child) {
1760
- node.child.return = node;
1761
- node = node.child;
1762
- continue;
1763
- }
1764
- if (node === fiber) {
1765
- return fibers;
1766
- }
1767
- while (!node.sibling) {
1768
- if (!node.return || node.return === fiber) {
1769
- return fibers;
1770
- }
1771
- node = node.return;
1772
- }
1773
- node.sibling.return = node.return;
1774
- node = node.sibling;
1775
- }
1776
- // Flow needs the return here, but ESLint complains about it.
1777
- // eslint-disable-next-line no-unreachable
1778
- return fibers;
1779
- }
1780
-
1781
- function findNativeNodesForFiberID(id: number) {
1782
- try {
1783
- let fiber = findCurrentFiberUsingSlowPathById(id);
1784
- if (fiber === null) {
1785
- return null;
1786
- }
1787
- // Special case for a timed-out Suspense.
1788
- const isTimedOutSuspense =
1789
- fiber.tag === SuspenseComponent && fiber.memoizedState !== null;
1790
- if (isTimedOutSuspense) {
1791
- // A timed-out Suspense's findDOMNode is useless.
1792
- // Try our best to find the fallback directly.
1793
- const maybeFallbackFiber = fiber.child && fiber.child.sibling;
1794
- if (maybeFallbackFiber != null) {
1795
- fiber = maybeFallbackFiber;
1796
- }
1797
- }
1798
- const hostFibers = findAllCurrentHostFibers(id);
1799
- return hostFibers.map(hostFiber => hostFiber.stateNode).filter(Boolean);
1800
- } catch (err) {
1801
- // The fiber might have unmounted by now.
1802
- return null;
1803
- }
1804
- }
1805
-
1806
- function getFiberIDForNative(
1807
- hostInstance,
1808
- findNearestUnfilteredAncestor = false,
1809
- ) {
1810
- let fiber = renderer.findFiberByHostInstance(hostInstance);
1811
- if (fiber != null) {
1812
- if (findNearestUnfilteredAncestor) {
1813
- while (fiber !== null && shouldFilterFiber(fiber)) {
1814
- fiber = fiber.return;
1815
- }
1816
- }
1817
- return getFiberID(getPrimaryFiber(((fiber: any): Fiber)));
1818
- }
1819
- return null;
1820
- }
1821
-
1822
- const MOUNTING = 1;
1823
- const MOUNTED = 2;
1824
- const UNMOUNTED = 3;
1825
-
1826
- // This function is copied from React and should be kept in sync:
1827
- // https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberTreeReflection.js
1828
- function isFiberMountedImpl(fiber: Fiber): number {
1829
- let node = fiber;
1830
- if (!fiber.alternate) {
1831
- // If there is no alternate, this might be a new tree that isn't inserted
1832
- // yet. If it is, then it will have a pending insertion effect on it.
1833
- if ((node.effectTag & Placement) !== NoEffect) {
1834
- return MOUNTING;
1835
- }
1836
- while (node.return) {
1837
- node = node.return;
1838
- if ((node.effectTag & Placement) !== NoEffect) {
1839
- return MOUNTING;
1840
- }
1841
- }
1842
- } else {
1843
- while (node.return) {
1844
- node = node.return;
1845
- }
1846
- }
1847
- if (node.tag === HostRoot) {
1848
- // TODO: Check if this was a nested HostRoot when used with
1849
- // renderContainerIntoSubtree.
1850
- return MOUNTED;
1851
- }
1852
- // If we didn't hit the root, that means that we're in an disconnected tree
1853
- // that has been unmounted.
1854
- return UNMOUNTED;
1855
- }
1856
-
1857
- // This function is copied from React and should be kept in sync:
1858
- // https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberTreeReflection.js
1859
- // It would be nice if we updated React to inject this function directly (vs just indirectly via findDOMNode).
1860
- // BEGIN copied code
1861
- function findCurrentFiberUsingSlowPathById(id: number): Fiber | null {
1862
- const fiber = idToFiberMap.get(id);
1863
- if (fiber == null) {
1864
- console.warn(`Could not find Fiber with id "${id}"`);
1865
- return null;
1866
- }
1867
-
1868
- let alternate = fiber.alternate;
1869
- if (!alternate) {
1870
- // If there is no alternate, then we only need to check if it is mounted.
1871
- const state = isFiberMountedImpl(fiber);
1872
- if (state === UNMOUNTED) {
1873
- throw Error('Unable to find node on an unmounted component.');
1874
- }
1875
- if (state === MOUNTING) {
1876
- return null;
1877
- }
1878
- return fiber;
1879
- }
1880
- // If we have two possible branches, we'll walk backwards up to the root
1881
- // to see what path the root points to. On the way we may hit one of the
1882
- // special cases and we'll deal with them.
1883
- let a: Fiber = fiber;
1884
- let b: Fiber = alternate;
1885
- while (true) {
1886
- let parentA = a.return;
1887
- if (parentA === null) {
1888
- // We're at the root.
1889
- break;
1890
- }
1891
- let parentB = parentA.alternate;
1892
- if (parentB === null) {
1893
- // There is no alternate. This is an unusual case. Currently, it only
1894
- // happens when a Suspense component is hidden. An extra fragment fiber
1895
- // is inserted in between the Suspense fiber and its children. Skip
1896
- // over this extra fragment fiber and proceed to the next parent.
1897
- const nextParent = parentA.return;
1898
- if (nextParent !== null) {
1899
- a = b = nextParent;
1900
- continue;
1901
- }
1902
- // If there's no parent, we're at the root.
1903
- break;
1904
- }
1905
-
1906
- // If both copies of the parent fiber point to the same child, we can
1907
- // assume that the child is current. This happens when we bailout on low
1908
- // priority: the bailed out fiber's child reuses the current child.
1909
- if (parentA.child === parentB.child) {
1910
- let child = parentA.child;
1911
- while (child) {
1912
- if (child === a) {
1913
- // We've determined that A is the current branch.
1914
- if (isFiberMountedImpl(parentA) !== MOUNTED) {
1915
- throw Error('Unable to find node on an unmounted component.');
1916
- }
1917
- return fiber;
1918
- }
1919
- if (child === b) {
1920
- // We've determined that B is the current branch.
1921
- if (isFiberMountedImpl(parentA) !== MOUNTED) {
1922
- throw Error('Unable to find node on an unmounted component.');
1923
- }
1924
- return alternate;
1925
- }
1926
- child = child.sibling;
1927
- }
1928
- // We should never have an alternate for any mounting node. So the only
1929
- // way this could possibly happen is if this was unmounted, if at all.
1930
- throw Error('Unable to find node on an unmounted component.');
1931
- }
1932
-
1933
- if (a.return !== b.return) {
1934
- // The return pointer of A and the return pointer of B point to different
1935
- // fibers. We assume that return pointers never criss-cross, so A must
1936
- // belong to the child set of A.return, and B must belong to the child
1937
- // set of B.return.
1938
- a = parentA;
1939
- b = parentB;
1940
- } else {
1941
- // The return pointers point to the same fiber. We'll have to use the
1942
- // default, slow path: scan the child sets of each parent alternate to see
1943
- // which child belongs to which set.
1944
- //
1945
- // Search parent A's child set
1946
- let didFindChild = false;
1947
- let child = parentA.child;
1948
- while (child) {
1949
- if (child === a) {
1950
- didFindChild = true;
1951
- a = parentA;
1952
- b = parentB;
1953
- break;
1954
- }
1955
- if (child === b) {
1956
- didFindChild = true;
1957
- b = parentA;
1958
- a = parentB;
1959
- break;
1960
- }
1961
- child = child.sibling;
1962
- }
1963
- if (!didFindChild) {
1964
- // Search parent B's child set
1965
- child = parentB.child;
1966
- while (child) {
1967
- if (child === a) {
1968
- didFindChild = true;
1969
- a = parentB;
1970
- b = parentA;
1971
- break;
1972
- }
1973
- if (child === b) {
1974
- didFindChild = true;
1975
- b = parentB;
1976
- a = parentA;
1977
- break;
1978
- }
1979
- child = child.sibling;
1980
- }
1981
- if (!didFindChild) {
1982
- throw Error(
1983
- 'Child was not found in either parent set. This indicates a bug ' +
1984
- 'in React related to the return pointer. Please file an issue.',
1985
- );
1986
- }
1987
- }
1988
- }
1989
-
1990
- if (a.alternate !== b) {
1991
- throw Error(
1992
- "Return fibers should always be each others' alternates. " +
1993
- 'This error is likely caused by a bug in React. Please file an issue.',
1994
- );
1995
- }
1996
- }
1997
- // If the root is not a host container, we're in a disconnected tree. I.e.
1998
- // unmounted.
1999
- if (a.tag !== HostRoot) {
2000
- throw Error('Unable to find node on an unmounted component.');
2001
- }
2002
- if (a.stateNode.current === a) {
2003
- // We've determined that A is the current branch.
2004
- return fiber;
2005
- }
2006
- // Otherwise B has to be current branch.
2007
- return alternate;
2008
- }
2009
- // END copied code
2010
-
2011
- function prepareViewElementSource(id: number): void {
2012
- let fiber = idToFiberMap.get(id);
2013
- if (fiber == null) {
2014
- console.warn(`Could not find Fiber with id "${id}"`);
2015
- return;
2016
- }
2017
-
2018
- const {elementType, tag, type} = fiber;
2019
-
2020
- switch (tag) {
2021
- case ClassComponent:
2022
- case IncompleteClassComponent:
2023
- case IndeterminateComponent:
2024
- case FunctionComponent:
2025
- global.$type = type;
2026
- break;
2027
- case ForwardRef:
2028
- global.$type = type.render;
2029
- break;
2030
- case MemoComponent:
2031
- case SimpleMemoComponent:
2032
- global.$type =
2033
- elementType != null && elementType.type != null
2034
- ? elementType.type
2035
- : type;
2036
- break;
2037
- default:
2038
- global.$type = null;
2039
- break;
2040
- }
2041
- }
2042
-
2043
- function getOwnersList(id: number): Array<Owner> | null {
2044
- let fiber = findCurrentFiberUsingSlowPathById(id);
2045
- if (fiber == null) {
2046
- return null;
2047
- }
2048
-
2049
- const {_debugOwner} = fiber;
2050
-
2051
- const owners = [
2052
- {
2053
- displayName: getDisplayNameForFiber(fiber) || 'Anonymous',
2054
- id,
2055
- type: getElementTypeForFiber(fiber),
2056
- },
2057
- ];
2058
-
2059
- if (_debugOwner) {
2060
- let owner = _debugOwner;
2061
- while (owner !== null) {
2062
- owners.unshift({
2063
- displayName: getDisplayNameForFiber(owner) || 'Anonymous',
2064
- id: getFiberID(getPrimaryFiber(owner)),
2065
- type: getElementTypeForFiber(owner),
2066
- });
2067
- owner = owner._debugOwner || null;
2068
- }
2069
- }
2070
-
2071
- return owners;
2072
- }
2073
-
2074
- // Fast path props lookup for React Native style editor.
2075
- // Could use inspectElementRaw() but that would require shallow rendering hooks components,
2076
- // and could also mess with memoization.
2077
- function getInstanceAndStyle(id: number): InstanceAndStyle {
2078
- let instance = null;
2079
- let style = null;
2080
-
2081
- let fiber = findCurrentFiberUsingSlowPathById(id);
2082
- if (fiber !== null) {
2083
- instance = fiber.stateNode;
2084
-
2085
- if (fiber.memoizedProps !== null) {
2086
- style = fiber.memoizedProps.style;
2087
- }
2088
- }
2089
-
2090
- return {instance, style};
2091
- }
2092
-
2093
- function inspectElementRaw(id: number): InspectedElement | null {
2094
- let fiber = findCurrentFiberUsingSlowPathById(id);
2095
- if (fiber == null) {
2096
- return null;
2097
- }
2098
-
2099
- const {
2100
- _debugOwner,
2101
- _debugSource,
2102
- dependencies,
2103
- stateNode,
2104
- memoizedProps,
2105
- memoizedState,
2106
- tag,
2107
- type,
2108
- } = fiber;
2109
-
2110
- const usesHooks =
2111
- (tag === FunctionComponent ||
2112
- tag === SimpleMemoComponent ||
2113
- tag === ForwardRef) &&
2114
- (!!memoizedState || !!dependencies);
2115
-
2116
- const typeSymbol = getTypeSymbol(type);
2117
-
2118
- let canViewSource = false;
2119
- let context = null;
2120
- if (
2121
- tag === ClassComponent ||
2122
- tag === FunctionComponent ||
2123
- tag === IncompleteClassComponent ||
2124
- tag === IndeterminateComponent ||
2125
- tag === MemoComponent ||
2126
- tag === ForwardRef ||
2127
- tag === SimpleMemoComponent
2128
- ) {
2129
- canViewSource = true;
2130
- if (stateNode && stateNode.context != null) {
2131
- context = stateNode.context;
2132
- }
2133
- } else if (
2134
- typeSymbol === CONTEXT_CONSUMER_NUMBER ||
2135
- typeSymbol === CONTEXT_CONSUMER_SYMBOL_STRING
2136
- ) {
2137
- // 16.3-16.5 read from "type" because the Consumer is the actual context object.
2138
- // 16.6+ should read from "type._context" because Consumer can be different (in DEV).
2139
- // NOTE Keep in sync with getDisplayNameForFiber()
2140
- const consumerResolvedContext = type._context || type;
2141
-
2142
- // Global context value.
2143
- context = consumerResolvedContext._currentValue || null;
2144
-
2145
- // Look for overridden value.
2146
- let current = ((fiber: any): Fiber).return;
2147
- while (current !== null) {
2148
- const currentType = current.type;
2149
- const currentTypeSymbol = getTypeSymbol(currentType);
2150
- if (
2151
- currentTypeSymbol === CONTEXT_PROVIDER_NUMBER ||
2152
- currentTypeSymbol === CONTEXT_PROVIDER_SYMBOL_STRING
2153
- ) {
2154
- // 16.3.0 exposed the context object as "context"
2155
- // PR #12501 changed it to "_context" for 16.3.1+
2156
- // NOTE Keep in sync with getDisplayNameForFiber()
2157
- const providerResolvedContext =
2158
- currentType._context || currentType.context;
2159
- if (providerResolvedContext === consumerResolvedContext) {
2160
- context = current.memoizedProps.value;
2161
- break;
2162
- }
2163
- }
2164
-
2165
- current = current.return;
2166
- }
2167
- }
2168
-
2169
- if (context !== null) {
2170
- // To simplify hydration and display logic for context, wrap in a value object.
2171
- // Otherwise simple values (e.g. strings, booleans) become harder to handle.
2172
- context = {value: context};
2173
- }
2174
-
2175
- let owners = null;
2176
- if (_debugOwner) {
2177
- owners = [];
2178
- let owner = _debugOwner;
2179
- while (owner !== null) {
2180
- owners.push({
2181
- displayName: getDisplayNameForFiber(owner) || 'Anonymous',
2182
- id: getFiberID(getPrimaryFiber(owner)),
2183
- type: getElementTypeForFiber(owner),
2184
- });
2185
- owner = owner._debugOwner || null;
2186
- }
2187
- }
2188
-
2189
- const isTimedOutSuspense =
2190
- tag === SuspenseComponent && memoizedState !== null;
2191
-
2192
- let hooks = null;
2193
- if (usesHooks) {
2194
- const originalConsoleMethods = {};
2195
-
2196
- // Temporarily disable all console logging before re-running the hook.
2197
- for (let method in console) {
2198
- try {
2199
- originalConsoleMethods[method] = console[method];
2200
- // $FlowFixMe property error|warn is not writable.
2201
- console[method] = () => {};
2202
- } catch (error) {}
2203
- }
2204
-
2205
- try {
2206
- hooks = inspectHooksOfFiber(
2207
- fiber,
2208
- (renderer.currentDispatcherRef: any),
2209
- );
2210
- } finally {
2211
- // Restore original console functionality.
2212
- for (let method in originalConsoleMethods) {
2213
- try {
2214
- // $FlowFixMe property error|warn is not writable.
2215
- console[method] = originalConsoleMethods[method];
2216
- } catch (error) {}
2217
- }
2218
- }
2219
- }
2220
-
2221
- return {
2222
- id,
2223
-
2224
- // Does the current renderer support editable hooks?
2225
- canEditHooks: typeof overrideHookState === 'function',
2226
-
2227
- // Does the current renderer support editable function props?
2228
- canEditFunctionProps: typeof overrideProps === 'function',
2229
-
2230
- canToggleSuspense:
2231
- supportsTogglingSuspense &&
2232
- // If it's showing the real content, we can always flip fallback.
2233
- (!isTimedOutSuspense ||
2234
- // If it's showing fallback because we previously forced it to,
2235
- // allow toggling it back to remove the fallback override.
2236
- forceFallbackForSuspenseIDs.has(id)),
2237
-
2238
- // Can view component source location.
2239
- canViewSource,
2240
-
2241
- displayName: getDisplayNameForFiber(fiber),
2242
- type: getElementTypeForFiber(fiber),
2243
-
2244
- // Inspectable properties.
2245
- // TODO Review sanitization approach for the below inspectable values.
2246
- context,
2247
- hooks,
2248
- props: memoizedProps,
2249
- state: usesHooks ? null : memoizedState,
2250
-
2251
- // List of owners
2252
- owners,
2253
-
2254
- // Location of component in source coude.
2255
- source: _debugSource || null,
2256
- };
2257
- }
2258
-
2259
- let mostRecentlyInspectedElement: InspectedElement | null = null;
2260
- let hasElementUpdatedSinceLastInspected: boolean = false;
2261
- let currentlyInspectedPaths: Object = {};
2262
-
2263
- function isMostRecentlyInspectedElementCurrent(id: number): boolean {
2264
- return (
2265
- mostRecentlyInspectedElement !== null &&
2266
- mostRecentlyInspectedElement.id === id &&
2267
- !hasElementUpdatedSinceLastInspected
2268
- );
2269
- }
2270
-
2271
- // Track the intersection of currently inspected paths,
2272
- // so that we can send their data along if the element is re-rendered.
2273
- function mergeInspectedPaths(path: Array<string | number>) {
2274
- let current = currentlyInspectedPaths;
2275
- path.forEach(key => {
2276
- if (!current[key]) {
2277
- current[key] = {};
2278
- }
2279
- current = current[key];
2280
- });
2281
- }
2282
-
2283
- function createIsPathWhitelisted(
2284
- key: string | null,
2285
- secondaryCategory: 'hooks' | null,
2286
- ) {
2287
- // This function helps prevent previously-inspected paths from being dehydrated in updates.
2288
- // This is important to avoid a bad user experience where expanded toggles collapse on update.
2289
- return function isPathWhitelisted(path: Array<string | number>): boolean {
2290
- switch (secondaryCategory) {
2291
- case 'hooks':
2292
- if (path.length === 1) {
2293
- // Never dehydrate the "hooks" object at the top levels.
2294
- return true;
2295
- }
2296
- if (
2297
- path[path.length - 1] === 'subHooks' ||
2298
- path[path.length - 2] === 'subHooks'
2299
- ) {
2300
- // Dehydrating the 'subHooks' property makes the HooksTree UI a lot more complicated,
2301
- // so it's easiest for now if we just don't break on this boundary.
2302
- // We can always dehydrate a level deeper (in the value object).
2303
- return true;
2304
- }
2305
- break;
2306
- default:
2307
- break;
2308
- }
2309
-
2310
- let current =
2311
- key === null ? currentlyInspectedPaths : currentlyInspectedPaths[key];
2312
- if (!current) {
2313
- return false;
2314
- }
2315
- for (let i = 0; i < path.length; i++) {
2316
- current = current[path[i]];
2317
- if (!current) {
2318
- return false;
2319
- }
2320
- }
2321
- return true;
2322
- };
2323
- }
2324
-
2325
- function updateSelectedElement(inspectedElement: InspectedElement): void {
2326
- const {hooks, id, props} = inspectedElement;
2327
-
2328
- let fiber = idToFiberMap.get(id);
2329
- if (fiber == null) {
2330
- console.warn(`Could not find Fiber with id "${id}"`);
2331
- return;
2332
- }
2333
-
2334
- const {elementType, stateNode, tag, type} = fiber;
2335
-
2336
- switch (tag) {
2337
- case ClassComponent:
2338
- case IncompleteClassComponent:
2339
- case IndeterminateComponent:
2340
- global.$r = stateNode;
2341
- break;
2342
- case FunctionComponent:
2343
- global.$r = {
2344
- hooks,
2345
- props,
2346
- type,
2347
- };
2348
- break;
2349
- case ForwardRef:
2350
- global.$r = {
2351
- props,
2352
- type: type.render,
2353
- };
2354
- break;
2355
- case MemoComponent:
2356
- case SimpleMemoComponent:
2357
- global.$r = {
2358
- props,
2359
- type:
2360
- elementType != null && elementType.type != null
2361
- ? elementType.type
2362
- : type,
2363
- };
2364
- break;
2365
- default:
2366
- global.$r = null;
2367
- break;
2368
- }
2369
- }
2370
-
2371
- function inspectElement(
2372
- id: number,
2373
- path?: Array<string | number>,
2374
- ): InspectedElementPayload {
2375
- const isCurrent = isMostRecentlyInspectedElementCurrent(id);
2376
-
2377
- if (isCurrent) {
2378
- if (path != null) {
2379
- mergeInspectedPaths(path);
2380
-
2381
- let secondaryCategory = null;
2382
- if (path[0] === 'hooks') {
2383
- secondaryCategory = 'hooks';
2384
- }
2385
-
2386
- // If this element has not been updated since it was last inspected,
2387
- // we can just return the subset of data in the newly-inspected path.
2388
- return {
2389
- id,
2390
- type: 'hydrated-path',
2391
- path,
2392
- value: cleanForBridge(
2393
- getInObject(
2394
- ((mostRecentlyInspectedElement: any): InspectedElement),
2395
- path,
2396
- ),
2397
- createIsPathWhitelisted(null, secondaryCategory),
2398
- path,
2399
- ),
2400
- };
2401
- } else {
2402
- // If this element has not been updated since it was last inspected, we don't need to re-run it.
2403
- // Instead we can just return the ID to indicate that it has not changed.
2404
- return {
2405
- id,
2406
- type: 'no-change',
2407
- };
2408
- }
2409
- } else {
2410
- hasElementUpdatedSinceLastInspected = false;
2411
-
2412
- if (
2413
- mostRecentlyInspectedElement === null ||
2414
- mostRecentlyInspectedElement.id !== id
2415
- ) {
2416
- currentlyInspectedPaths = {};
2417
- }
2418
-
2419
- mostRecentlyInspectedElement = inspectElementRaw(id);
2420
- if (mostRecentlyInspectedElement === null) {
2421
- return {
2422
- id,
2423
- type: 'not-found',
2424
- };
2425
- }
2426
-
2427
- if (path != null) {
2428
- mergeInspectedPaths(path);
2429
- }
2430
-
2431
- // Any time an inspected element has an update,
2432
- // we should update the selected $r value as wel.
2433
- // Do this before dehyration (cleanForBridge).
2434
- updateSelectedElement(mostRecentlyInspectedElement);
2435
-
2436
- // Clone before cleaning so that we preserve the full data.
2437
- // This will enable us to send patches without re-inspecting if hydrated paths are requested.
2438
- // (Reducing how often we shallow-render is a better DX for function components that use hooks.)
2439
- const cleanedInspectedElement = {...mostRecentlyInspectedElement};
2440
- cleanedInspectedElement.context = cleanForBridge(
2441
- cleanedInspectedElement.context,
2442
- createIsPathWhitelisted('context', null),
2443
- );
2444
- cleanedInspectedElement.hooks = cleanForBridge(
2445
- cleanedInspectedElement.hooks,
2446
- createIsPathWhitelisted('hooks', 'hooks'),
2447
- );
2448
- cleanedInspectedElement.props = cleanForBridge(
2449
- cleanedInspectedElement.props,
2450
- createIsPathWhitelisted('props', null),
2451
- );
2452
- cleanedInspectedElement.state = cleanForBridge(
2453
- cleanedInspectedElement.state,
2454
- createIsPathWhitelisted('state', null),
2455
- );
2456
-
2457
- return {
2458
- id,
2459
- type: 'full-data',
2460
- value: cleanedInspectedElement,
2461
- };
2462
- }
2463
- }
2464
-
2465
- function logElementToConsole(id) {
2466
- const result = isMostRecentlyInspectedElementCurrent(id)
2467
- ? mostRecentlyInspectedElement
2468
- : inspectElementRaw(id);
2469
- if (result === null) {
2470
- console.warn(`Could not find Fiber with id "${id}"`);
2471
- return;
2472
- }
2473
-
2474
- const supportsGroup = typeof console.groupCollapsed === 'function';
2475
- if (supportsGroup) {
2476
- console.groupCollapsed(
2477
- `[Click to expand] %c<${result.displayName || 'Component'} />`,
2478
- // --dom-tag-name-color is the CSS variable Chrome styles HTML elements with in the console.
2479
- 'color: var(--dom-tag-name-color); font-weight: normal;',
2480
- );
2481
- }
2482
- if (result.props !== null) {
2483
- console.log('Props:', result.props);
2484
- }
2485
- if (result.state !== null) {
2486
- console.log('State:', result.state);
2487
- }
2488
- if (result.hooks !== null) {
2489
- console.log('Hooks:', result.hooks);
2490
- }
2491
- const nativeNodes = findNativeNodesForFiberID(id);
2492
- if (nativeNodes !== null) {
2493
- console.log('Nodes:', nativeNodes);
2494
- }
2495
- if (result.source !== null) {
2496
- console.log('Location:', result.source);
2497
- }
2498
- if (window.chrome || /firefox/i.test(navigator.userAgent)) {
2499
- console.log(
2500
- 'Right-click any value to save it as a global variable for further inspection.',
2501
- );
2502
- }
2503
- if (supportsGroup) {
2504
- console.groupEnd();
2505
- }
2506
- }
2507
-
2508
- function setInHook(
2509
- id: number,
2510
- index: number,
2511
- path: Array<string | number>,
2512
- value: any,
2513
- ) {
2514
- const fiber = findCurrentFiberUsingSlowPathById(id);
2515
- if (fiber !== null) {
2516
- if (typeof overrideHookState === 'function') {
2517
- overrideHookState(fiber, index, path, value);
2518
- }
2519
- }
2520
- }
2521
-
2522
- function setInProps(id: number, path: Array<string | number>, value: any) {
2523
- const fiber = findCurrentFiberUsingSlowPathById(id);
2524
- if (fiber !== null) {
2525
- const instance = fiber.stateNode;
2526
- if (instance === null) {
2527
- if (typeof overrideProps === 'function') {
2528
- overrideProps(fiber, path, value);
2529
- }
2530
- } else {
2531
- fiber.pendingProps = copyWithSet(instance.props, path, value);
2532
- instance.forceUpdate();
2533
- }
2534
- }
2535
- }
2536
-
2537
- function setInState(id: number, path: Array<string | number>, value: any) {
2538
- const fiber = findCurrentFiberUsingSlowPathById(id);
2539
- if (fiber !== null) {
2540
- const instance = fiber.stateNode;
2541
- setInObject(instance.state, path, value);
2542
- instance.forceUpdate();
2543
- }
2544
- }
2545
-
2546
- function setInContext(id: number, path: Array<string | number>, value: any) {
2547
- // To simplify hydration and display of primative context values (e.g. number, string)
2548
- // the inspectElement() method wraps context in a {value: ...} object.
2549
- // We need to remove the first part of the path (the "value") before continuing.
2550
- path = path.slice(1);
2551
-
2552
- const fiber = findCurrentFiberUsingSlowPathById(id);
2553
- if (fiber !== null) {
2554
- const instance = fiber.stateNode;
2555
- if (path.length === 0) {
2556
- // Simple context value
2557
- instance.context = value;
2558
- } else {
2559
- setInObject(instance.context, path, value);
2560
- }
2561
- instance.forceUpdate();
2562
- }
2563
- }
2564
-
2565
- type CommitProfilingData = {|
2566
- changeDescriptions: Map<number, ChangeDescription> | null,
2567
- commitTime: number,
2568
- durations: Array<number>,
2569
- interactions: Array<Interaction>,
2570
- maxActualDuration: number,
2571
- priorityLevel: string | null,
2572
- |};
2573
-
2574
- type CommitProfilingMetadataMap = Map<number, Array<CommitProfilingData>>;
2575
- type DisplayNamesByRootID = Map<number, string>;
2576
-
2577
- let currentCommitProfilingMetadata: CommitProfilingData | null = null;
2578
- let displayNamesByRootID: DisplayNamesByRootID | null = null;
2579
- let idToContextsMap: Map<number, any> | null = null;
2580
- let initialTreeBaseDurationsMap: Map<number, number> | null = null;
2581
- let initialIDToRootMap: Map<number, number> | null = null;
2582
- let isProfiling: boolean = false;
2583
- let profilingStartTime: number = 0;
2584
- let recordChangeDescriptions: boolean = false;
2585
- let rootToCommitProfilingMetadataMap: CommitProfilingMetadataMap | null = null;
2586
-
2587
- function getProfilingData(): ProfilingDataBackend {
2588
- const dataForRoots: Array<ProfilingDataForRootBackend> = [];
2589
-
2590
- if (rootToCommitProfilingMetadataMap === null) {
2591
- throw Error(
2592
- 'getProfilingData() called before any profiling data was recorded',
2593
- );
2594
- }
2595
-
2596
- rootToCommitProfilingMetadataMap.forEach(
2597
- (commitProfilingMetadata, rootID) => {
2598
- const commitData: Array<CommitDataBackend> = [];
2599
- const initialTreeBaseDurations: Array<[number, number]> = [];
2600
- const allInteractions: Map<number, Interaction> = new Map();
2601
- const interactionCommits: Map<number, Array<number>> = new Map();
2602
-
2603
- const displayName =
2604
- (displayNamesByRootID !== null && displayNamesByRootID.get(rootID)) ||
2605
- 'Unknown';
2606
-
2607
- if (initialTreeBaseDurationsMap != null) {
2608
- initialTreeBaseDurationsMap.forEach((treeBaseDuration, id) => {
2609
- if (
2610
- initialIDToRootMap != null &&
2611
- initialIDToRootMap.get(id) === rootID
2612
- ) {
2613
- // We don't need to convert milliseconds to microseconds in this case,
2614
- // because the profiling summary is JSON serialized.
2615
- initialTreeBaseDurations.push([id, treeBaseDuration]);
2616
- }
2617
- });
2618
- }
2619
-
2620
- commitProfilingMetadata.forEach((commitProfilingData, commitIndex) => {
2621
- const {
2622
- changeDescriptions,
2623
- durations,
2624
- interactions,
2625
- maxActualDuration,
2626
- priorityLevel,
2627
- commitTime,
2628
- } = commitProfilingData;
2629
-
2630
- const interactionIDs: Array<number> = [];
2631
-
2632
- interactions.forEach(interaction => {
2633
- if (!allInteractions.has(interaction.id)) {
2634
- allInteractions.set(interaction.id, interaction);
2635
- }
2636
-
2637
- interactionIDs.push(interaction.id);
2638
-
2639
- const commitIndices = interactionCommits.get(interaction.id);
2640
- if (commitIndices != null) {
2641
- commitIndices.push(commitIndex);
2642
- } else {
2643
- interactionCommits.set(interaction.id, [commitIndex]);
2644
- }
2645
- });
2646
-
2647
- const fiberActualDurations: Array<[number, number]> = [];
2648
- const fiberSelfDurations: Array<[number, number]> = [];
2649
- for (let i = 0; i < durations.length; i += 3) {
2650
- const fiberID = durations[i];
2651
- fiberActualDurations.push([fiberID, durations[i + 1]]);
2652
- fiberSelfDurations.push([fiberID, durations[i + 2]]);
2653
- }
2654
-
2655
- commitData.push({
2656
- changeDescriptions:
2657
- changeDescriptions !== null
2658
- ? Array.from(changeDescriptions.entries())
2659
- : null,
2660
- duration: maxActualDuration,
2661
- fiberActualDurations,
2662
- fiberSelfDurations,
2663
- interactionIDs,
2664
- priorityLevel,
2665
- timestamp: commitTime,
2666
- });
2667
- });
2668
-
2669
- dataForRoots.push({
2670
- commitData,
2671
- displayName,
2672
- initialTreeBaseDurations,
2673
- interactionCommits: Array.from(interactionCommits.entries()),
2674
- interactions: Array.from(allInteractions.entries()),
2675
- rootID,
2676
- });
2677
- },
2678
- );
2679
-
2680
- return {
2681
- dataForRoots,
2682
- rendererID,
2683
- };
2684
- }
2685
-
2686
- function startProfiling(shouldRecordChangeDescriptions: boolean) {
2687
- if (isProfiling) {
2688
- return;
2689
- }
2690
-
2691
- recordChangeDescriptions = shouldRecordChangeDescriptions;
2692
-
2693
- // Capture initial values as of the time profiling starts.
2694
- // It's important we snapshot both the durations and the id-to-root map,
2695
- // since either of these may change during the profiling session
2696
- // (e.g. when a fiber is re-rendered or when a fiber gets removed).
2697
- displayNamesByRootID = new Map();
2698
- initialTreeBaseDurationsMap = new Map(idToTreeBaseDurationMap);
2699
- initialIDToRootMap = new Map(idToRootMap);
2700
- idToContextsMap = new Map();
2701
-
2702
- hook.getFiberRoots(rendererID).forEach(root => {
2703
- const rootID = getFiberID(getPrimaryFiber(root.current));
2704
- ((displayNamesByRootID: any): DisplayNamesByRootID).set(
2705
- rootID,
2706
- getDisplayNameForRoot(root.current),
2707
- );
2708
-
2709
- if (shouldRecordChangeDescriptions) {
2710
- // Record all contexts at the time profiling is started.
2711
- // Fibers only store the current context value,
2712
- // so we need to track them separatenly in order to determine changed keys.
2713
- crawlToInitializeContextsMap(root.current);
2714
- }
2715
- });
2716
-
2717
- isProfiling = true;
2718
- profilingStartTime = getCurrentTime();
2719
- rootToCommitProfilingMetadataMap = new Map();
2720
- }
2721
-
2722
- function stopProfiling() {
2723
- isProfiling = false;
2724
- recordChangeDescriptions = false;
2725
- }
2726
-
2727
- // Automatically start profiling so that we don't miss timing info from initial "mount".
2728
- if (
2729
- sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true'
2730
- ) {
2731
- startProfiling(
2732
- sessionStorageGetItem(SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY) ===
2733
- 'true',
2734
- );
2735
- }
2736
-
2737
- // React will switch between these implementations depending on whether
2738
- // we have any manually suspended Fibers or not.
2739
-
2740
- function shouldSuspendFiberAlwaysFalse() {
2741
- return false;
2742
- }
2743
-
2744
- let forceFallbackForSuspenseIDs = new Set();
2745
- function shouldSuspendFiberAccordingToSet(fiber) {
2746
- const id = getFiberID(getPrimaryFiber(((fiber: any): Fiber)));
2747
- return forceFallbackForSuspenseIDs.has(id);
2748
- }
2749
-
2750
- function overrideSuspense(id, forceFallback) {
2751
- if (
2752
- typeof setSuspenseHandler !== 'function' ||
2753
- typeof scheduleUpdate !== 'function'
2754
- ) {
2755
- throw new Error(
2756
- 'Expected overrideSuspense() to not get called for earlier React versions.',
2757
- );
2758
- }
2759
- if (forceFallback) {
2760
- forceFallbackForSuspenseIDs.add(id);
2761
- if (forceFallbackForSuspenseIDs.size === 1) {
2762
- // First override is added. Switch React to slower path.
2763
- setSuspenseHandler(shouldSuspendFiberAccordingToSet);
2764
- }
2765
- } else {
2766
- forceFallbackForSuspenseIDs.delete(id);
2767
- if (forceFallbackForSuspenseIDs.size === 0) {
2768
- // Last override is gone. Switch React back to fast path.
2769
- setSuspenseHandler(shouldSuspendFiberAlwaysFalse);
2770
- }
2771
- }
2772
- const fiber = idToFiberMap.get(id);
2773
- if (fiber != null) {
2774
- scheduleUpdate(fiber);
2775
- }
2776
- }
2777
-
2778
- // Remember if we're trying to restore the selection after reload.
2779
- // In that case, we'll do some extra checks for matching mounts.
2780
- let trackedPath: Array<PathFrame> | null = null;
2781
- let trackedPathMatchFiber: Fiber | null = null;
2782
- let trackedPathMatchDepth = -1;
2783
- let mightBeOnTrackedPath = false;
2784
-
2785
- function setTrackedPath(path: Array<PathFrame> | null) {
2786
- if (path === null) {
2787
- trackedPathMatchFiber = null;
2788
- trackedPathMatchDepth = -1;
2789
- mightBeOnTrackedPath = false;
2790
- }
2791
- trackedPath = path;
2792
- }
2793
-
2794
- // We call this before traversing a new mount.
2795
- // It remembers whether this Fiber is the next best match for tracked path.
2796
- // The return value signals whether we should keep matching siblings or not.
2797
- function updateTrackedPathStateBeforeMount(fiber: Fiber): boolean {
2798
- if (trackedPath === null || !mightBeOnTrackedPath) {
2799
- // Fast path: there's nothing to track so do nothing and ignore siblings.
2800
- return false;
2801
- }
2802
- const returnFiber = fiber.return;
2803
- const returnAlternate = returnFiber !== null ? returnFiber.alternate : null;
2804
- // By now we know there's some selection to restore, and this is a new Fiber.
2805
- // Is this newly mounted Fiber a direct child of the current best match?
2806
- // (This will also be true for new roots if we haven't matched anything yet.)
2807
- if (
2808
- trackedPathMatchFiber === returnFiber ||
2809
- (trackedPathMatchFiber === returnAlternate && returnAlternate !== null)
2810
- ) {
2811
- // Is this the next Fiber we should select? Let's compare the frames.
2812
- const actualFrame = getPathFrame(fiber);
2813
- const expectedFrame = trackedPath[trackedPathMatchDepth + 1];
2814
- if (expectedFrame === undefined) {
2815
- throw new Error('Expected to see a frame at the next depth.');
2816
- }
2817
- if (
2818
- actualFrame.index === expectedFrame.index &&
2819
- actualFrame.key === expectedFrame.key &&
2820
- actualFrame.displayName === expectedFrame.displayName
2821
- ) {
2822
- // We have our next match.
2823
- trackedPathMatchFiber = fiber;
2824
- trackedPathMatchDepth++;
2825
- // Are we out of frames to match?
2826
- if (trackedPathMatchDepth === trackedPath.length - 1) {
2827
- // There's nothing that can possibly match afterwards.
2828
- // Don't check the children.
2829
- mightBeOnTrackedPath = false;
2830
- } else {
2831
- // Check the children, as they might reveal the next match.
2832
- mightBeOnTrackedPath = true;
2833
- }
2834
- // In either case, since we have a match, we don't need
2835
- // to check the siblings. They'll never match.
2836
- return false;
2837
- }
2838
- }
2839
- // This Fiber's parent is on the path, but this Fiber itself isn't.
2840
- // There's no need to check its children--they won't be on the path either.
2841
- mightBeOnTrackedPath = false;
2842
- // However, one of its siblings may be on the path so keep searching.
2843
- return true;
2844
- }
2845
-
2846
- function updateTrackedPathStateAfterMount(mightSiblingsBeOnTrackedPath) {
2847
- // updateTrackedPathStateBeforeMount() told us whether to match siblings.
2848
- // Now that we're entering siblings, let's use that information.
2849
- mightBeOnTrackedPath = mightSiblingsBeOnTrackedPath;
2850
- }
2851
-
2852
- // Roots don't have a real persistent identity.
2853
- // A root's "pseudo key" is "childDisplayName:indexWithThatName".
2854
- // For example, "App:0" or, in case of similar roots, "Story:0", "Story:1", etc.
2855
- // We will use this to try to disambiguate roots when restoring selection between reloads.
2856
- const rootPseudoKeys: Map<number, string> = new Map();
2857
- const rootDisplayNameCounter: Map<string, number> = new Map();
2858
-
2859
- function setRootPseudoKey(id: number, fiber: Fiber) {
2860
- const name = getDisplayNameForRoot(fiber);
2861
- const counter = rootDisplayNameCounter.get(name) || 0;
2862
- rootDisplayNameCounter.set(name, counter + 1);
2863
- const pseudoKey = `${name}:${counter}`;
2864
- rootPseudoKeys.set(id, pseudoKey);
2865
- }
2866
-
2867
- function removeRootPseudoKey(id: number) {
2868
- const pseudoKey = rootPseudoKeys.get(id);
2869
- if (pseudoKey === undefined) {
2870
- throw new Error('Expected root pseudo key to be known.');
2871
- }
2872
- const name = pseudoKey.substring(0, pseudoKey.lastIndexOf(':'));
2873
- const counter = rootDisplayNameCounter.get(name);
2874
- if (counter === undefined) {
2875
- throw new Error('Expected counter to be known.');
2876
- }
2877
- if (counter > 1) {
2878
- rootDisplayNameCounter.set(name, counter - 1);
2879
- } else {
2880
- rootDisplayNameCounter.delete(name);
2881
- }
2882
- rootPseudoKeys.delete(id);
2883
- }
2884
-
2885
- function getDisplayNameForRoot(fiber: Fiber): string {
2886
- let preferredDisplayName = null;
2887
- let fallbackDisplayName = null;
2888
- let child = fiber.child;
2889
- // Go at most three levels deep into direct children
2890
- // while searching for a child that has a displayName.
2891
- for (let i = 0; i < 3; i++) {
2892
- if (child === null) {
2893
- break;
2894
- }
2895
- const displayName = getDisplayNameForFiber(child);
2896
- if (displayName !== null) {
2897
- // Prefer display names that we get from user-defined components.
2898
- // We want to avoid using e.g. 'Suspense' unless we find nothing else.
2899
- if (typeof child.type === 'function') {
2900
- // There's a few user-defined tags, but we'll prefer the ones
2901
- // that are usually explicitly named (function or class components).
2902
- preferredDisplayName = displayName;
2903
- } else if (fallbackDisplayName === null) {
2904
- fallbackDisplayName = displayName;
2905
- }
2906
- }
2907
- if (preferredDisplayName !== null) {
2908
- break;
2909
- }
2910
- child = child.child;
2911
- }
2912
- return preferredDisplayName || fallbackDisplayName || 'Anonymous';
2913
- }
2914
-
2915
- function getPathFrame(fiber: Fiber): PathFrame {
2916
- const {key} = fiber;
2917
- let displayName = getDisplayNameForFiber(fiber);
2918
- const index = fiber.index;
2919
- switch (fiber.tag) {
2920
- case HostRoot:
2921
- // Roots don't have a real displayName, index, or key.
2922
- // Instead, we'll use the pseudo key (childDisplayName:indexWithThatName).
2923
- const id = getFiberID(getPrimaryFiber(fiber));
2924
- const pseudoKey = rootPseudoKeys.get(id);
2925
- if (pseudoKey === undefined) {
2926
- throw new Error('Expected mounted root to have known pseudo key.');
2927
- }
2928
- displayName = pseudoKey;
2929
- break;
2930
- case HostComponent:
2931
- displayName = fiber.type;
2932
- break;
2933
- default:
2934
- break;
2935
- }
2936
- return {
2937
- displayName,
2938
- key,
2939
- index,
2940
- };
2941
- }
2942
-
2943
- // Produces a serializable representation that does a best effort
2944
- // of identifying a particular Fiber between page reloads.
2945
- // The return path will contain Fibers that are "invisible" to the store
2946
- // because their keys and indexes are important to restoring the selection.
2947
- function getPathForElement(id: number): Array<PathFrame> | null {
2948
- let fiber = idToFiberMap.get(id);
2949
- if (fiber == null) {
2950
- return null;
2951
- }
2952
- const keyPath = [];
2953
- while (fiber !== null) {
2954
- keyPath.push(getPathFrame(fiber));
2955
- fiber = fiber.return;
2956
- }
2957
- keyPath.reverse();
2958
- return keyPath;
2959
- }
2960
-
2961
- function getBestMatchForTrackedPath(): PathMatch | null {
2962
- if (trackedPath === null) {
2963
- // Nothing to match.
2964
- return null;
2965
- }
2966
- if (trackedPathMatchFiber === null) {
2967
- // We didn't find anything.
2968
- return null;
2969
- }
2970
- // Find the closest Fiber store is aware of.
2971
- let fiber = trackedPathMatchFiber;
2972
- while (fiber !== null && shouldFilterFiber(fiber)) {
2973
- fiber = fiber.return;
2974
- }
2975
- if (fiber === null) {
2976
- return null;
2977
- }
2978
- return {
2979
- id: getFiberID(getPrimaryFiber(fiber)),
2980
- isFullMatch: trackedPathMatchDepth === trackedPath.length - 1,
2981
- };
2982
- }
2983
-
2984
- const formatPriorityLevel = (priorityLevel: ?number) => {
2985
- if (priorityLevel == null) {
2986
- return 'Unknown';
2987
- }
2988
-
2989
- switch (priorityLevel) {
2990
- case ImmediatePriority:
2991
- return 'Immediate';
2992
- case UserBlockingPriority:
2993
- return 'User-Blocking';
2994
- case NormalPriority:
2995
- return 'Normal';
2996
- case LowPriority:
2997
- return 'Low';
2998
- case IdlePriority:
2999
- return 'Idle';
3000
- case NoPriority:
3001
- default:
3002
- return 'Unknown';
3003
- }
3004
- };
3005
-
3006
- return {
3007
- cleanup,
3008
- findNativeNodesForFiberID,
3009
- flushInitialOperations,
3010
- getBestMatchForTrackedPath,
3011
- getFiberIDForNative,
3012
- getInstanceAndStyle,
3013
- getOwnersList,
3014
- getPathForElement,
3015
- getProfilingData,
3016
- handleCommitFiberRoot,
3017
- handleCommitFiberUnmount,
3018
- inspectElement,
3019
- logElementToConsole,
3020
- prepareViewElementSource,
3021
- overrideSuspense,
3022
- renderer,
3023
- setInContext,
3024
- setInHook,
3025
- setInProps,
3026
- setInState,
3027
- setTrackedPath,
3028
- startProfiling,
3029
- stopProfiling,
3030
- updateComponentFilters,
3031
- };
3032
-}
packages/react-devtools-shared/src/backend/types.js
deleted
-282
@@ -1,282 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {ReactContext} from 'shared/ReactTypes';
11
-import type {Source} from 'shared/ReactElementType';
12
-import type {Fiber} from 'react-reconciler/src/ReactFiber';
13
-import type {
14
- ComponentFilter,
15
- ElementType,
16
-} from 'react-devtools-shared/src/types';
17
-import type {Interaction} from 'react-devtools-shared/src/devtools/views/Profiler/types';
18
-import type {ResolveNativeStyle} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
19
-
20
-type BundleType =
21
- | 0 // PROD
22
- | 1; // DEV
23
-
24
-export type WorkTag = number;
25
-export type SideEffectTag = number;
26
-export type ExpirationTime = number;
27
-
28
-// TODO: If it's useful for the frontend to know which types of data an Element has
29
-// (e.g. props, state, context, hooks) then we could add a bitmask field for this
30
-// to keep the number of attributes small.
31
-export type FiberData = {|
32
- key: string | null,
33
- displayName: string | null,
34
- type: ElementType,
35
-|};
36
-
37
-export type NativeType = Object;
38
-export type RendererID = number;
39
-
40
-type Dispatcher = any;
41
-
42
-export type GetFiberIDForNative = (
43
- component: NativeType,
44
- findNearestUnfilteredAncestor?: boolean,
45
-) => number | null;
46
-export type FindNativeNodesForFiberID = (id: number) => ?Array<NativeType>;
47
-
48
-export type ReactProviderType<T> = {
49
- $$typeof: Symbol | number,
50
- _context: ReactContext<T>,
51
-};
52
-
53
-export type ReactRenderer = {
54
- findFiberByHostInstance: (hostInstance: NativeType) => ?Fiber,
55
- version: string,
56
- bundleType: BundleType,
57
-
58
- // 16.9+
59
- overrideHookState?: ?(
60
- fiber: Object,
61
- id: number,
62
- path: Array<string | number>,
63
- value: any,
64
- ) => void,
65
-
66
- // 16.7+
67
- overrideProps?: ?(
68
- fiber: Object,
69
- path: Array<string | number>,
70
- value: any,
71
- ) => void,
72
-
73
- // 16.9+
74
- scheduleUpdate?: ?(fiber: Object) => void,
75
- setSuspenseHandler?: ?(shouldSuspend: (fiber: Object) => boolean) => void,
76
-
77
- // Only injected by React v16.8+ in order to support hooks inspection.
78
- currentDispatcherRef?: {|current: null | Dispatcher|},
79
-
80
- // Only injected by React v16.9+ in DEV mode.
81
- // Enables DevTools to append owners-only component stack to error messages.
82
- getCurrentFiber?: () => Fiber | null,
83
-
84
- // <= 15
85
- Mount?: any,
86
-};
87
-
88
-export type ChangeDescription = {|
89
- context: Array<string> | boolean | null,
90
- didHooksChange: boolean,
91
- isFirstMount: boolean,
92
- props: Array<string> | null,
93
- state: Array<string> | null,
94
-|};
95
-
96
-export type CommitDataBackend = {|
97
- // Tuple of fiber ID and change description
98
- changeDescriptions: Array<[number, ChangeDescription]> | null,
99
- duration: number,
100
- // Tuple of fiber ID and actual duration
101
- fiberActualDurations: Array<[number, number]>,
102
- // Tuple of fiber ID and computed "self" duration
103
- fiberSelfDurations: Array<[number, number]>,
104
- interactionIDs: Array<number>,
105
- priorityLevel: string | null,
106
- timestamp: number,
107
-|};
108
-
109
-export type ProfilingDataForRootBackend = {|
110
- commitData: Array<CommitDataBackend>,
111
- displayName: string,
112
- // Tuple of Fiber ID and base duration
113
- initialTreeBaseDurations: Array<[number, number]>,
114
- // Tuple of Interaction ID and commit indices
115
- interactionCommits: Array<[number, Array<number>]>,
116
- interactions: Array<[number, Interaction]>,
117
- rootID: number,
118
-|};
119
-
120
-// Profiling data collected by the renderer interface.
121
-// This information will be passed to the frontend and combined with info it collects.
122
-export type ProfilingDataBackend = {|
123
- dataForRoots: Array<ProfilingDataForRootBackend>,
124
- rendererID: number,
125
-|};
126
-
127
-export type PathFrame = {|
128
- key: string | null,
129
- index: number,
130
- displayName: string | null,
131
-|};
132
-
133
-export type PathMatch = {|
134
- id: number,
135
- isFullMatch: boolean,
136
-|};
137
-
138
-export type Owner = {|
139
- displayName: string | null,
140
- id: number,
141
- type: ElementType,
142
-|};
143
-
144
-export type OwnersList = {|
145
- id: number,
146
- owners: Array<Owner> | null,
147
-|};
148
-
149
-export type InspectedElement = {|
150
- id: number,
151
-
152
- displayName: string | null,
153
-
154
- // Does the current renderer support editable hooks?
155
- canEditHooks: boolean,
156
-
157
- // Does the current renderer support editable function props?
158
- canEditFunctionProps: boolean,
159
-
160
- // Is this Suspense, and can its value be overriden now?
161
- canToggleSuspense: boolean,
162
-
163
- // Can view component source location.
164
- canViewSource: boolean,
165
-
166
- // Inspectable properties.
167
- context: Object | null,
168
- hooks: Object | null,
169
- props: Object | null,
170
- state: Object | null,
171
-
172
- // List of owners
173
- owners: Array<Owner> | null,
174
-
175
- // Location of component in source coude.
176
- source: Source | null,
177
-
178
- type: ElementType,
179
-|};
180
-
181
-export const InspectElementFullDataType = 'full-data';
182
-export const InspectElementNoChangeType = 'no-change';
183
-export const InspectElementNotFoundType = 'not-found';
184
-export const InspectElementHydratedPathType = 'hydrated-path';
185
-
186
-type InspectElementFullData = {|
187
- id: number,
188
- type: 'full-data',
189
- value: InspectedElement,
190
-|};
191
-
192
-type InspectElementHydratedPath = {|
193
- id: number,
194
- type: 'hydrated-path',
195
- path: Array<string | number>,
196
- value: any,
197
-|};
198
-
199
-type InspectElementNoChange = {|
200
- id: number,
201
- type: 'no-change',
202
-|};
203
-
204
-type InspectElementNotFound = {|
205
- id: number,
206
- type: 'not-found',
207
-|};
208
-
209
-export type InspectedElementPayload =
210
- | InspectElementFullData
211
- | InspectElementHydratedPath
212
- | InspectElementNoChange
213
- | InspectElementNotFound;
214
-
215
-export type InstanceAndStyle = {|
216
- instance: Object | null,
217
- style: Object | null,
218
-|};
219
-
220
-export type RendererInterface = {
221
- cleanup: () => void,
222
- findNativeNodesForFiberID: FindNativeNodesForFiberID,
223
- flushInitialOperations: () => void,
224
- getBestMatchForTrackedPath: () => PathMatch | null,
225
- getFiberIDForNative: GetFiberIDForNative,
226
- getInstanceAndStyle(id: number): InstanceAndStyle,
227
- getProfilingData(): ProfilingDataBackend,
228
- getOwnersList: (id: number) => Array<Owner> | null,
229
- getPathForElement: (id: number) => Array<PathFrame> | null,
230
- handleCommitFiberRoot: (fiber: Object, commitPriority?: number) => void,
231
- handleCommitFiberUnmount: (fiber: Object) => void,
232
- inspectElement: (
233
- id: number,
234
- path?: Array<string | number>,
235
- ) => InspectedElementPayload,
236
- logElementToConsole: (id: number) => void,
237
- overrideSuspense: (id: number, forceFallback: boolean) => void,
238
- prepareViewElementSource: (id: number) => void,
239
- renderer: ReactRenderer | null,
240
- setInContext: (id: number, path: Array<string | number>, value: any) => void,
241
- setInHook: (
242
- id: number,
243
- index: number,
244
- path: Array<string | number>,
245
- value: any,
246
- ) => void,
247
- setInProps: (id: number, path: Array<string | number>, value: any) => void,
248
- setInState: (id: number, path: Array<string | number>, value: any) => void,
249
- setTrackedPath: (path: Array<PathFrame> | null) => void,
250
- startProfiling: (recordChangeDescriptions: boolean) => void,
251
- stopProfiling: () => void,
252
- updateComponentFilters: (somponentFilters: Array<ComponentFilter>) => void,
253
-};
254
-
255
-export type Handler = (data: any) => void;
256
-
257
-export type DevToolsHook = {
258
- listeners: {[key: string]: Array<Handler>},
259
- rendererInterfaces: Map<RendererID, RendererInterface>,
260
- renderers: Map<RendererID, ReactRenderer>,
261
-
262
- emit: (event: string, data: any) => void,
263
- getFiberRoots: (rendererID: RendererID) => Set<Object>,
264
- inject: (renderer: ReactRenderer) => number | null,
265
- on: (event: string, handler: Handler) => void,
266
- off: (event: string, handler: Handler) => void,
267
- reactDevtoolsAgent?: ?Object,
268
- sub: (event: string, handler: Handler) => () => void,
269
-
270
- // Used by react-native-web and Flipper/Inspector
271
- resolveRNStyle?: ResolveNativeStyle,
272
- nativeStyleEditorValidAttributes?: $ReadOnlyArray<string>,
273
-
274
- // React uses these methods.
275
- checkDCE: (fn: Function) => void,
276
- onCommitFiberUnmount: (rendererID: RendererID, fiber: Object) => void,
277
- onCommitFiberRoot: (
278
- rendererID: RendererID,
279
- fiber: Object,
280
- commitPriority?: number,
281
- ) => void,
282
-};
packages/react-devtools-shared/src/backend/utils.js
deleted
-55
@@ -1,55 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {dehydrate} from '../hydration';
11
-
12
-import type {DehydratedData} from 'react-devtools-shared/src/devtools/views/Components/types';
13
-
14
-export function cleanForBridge(
15
- data: Object | null,
16
- isPathWhitelisted: (path: Array<string | number>) => boolean,
17
- path?: Array<string | number> = [],
18
-): DehydratedData | null {
19
- if (data !== null) {
20
- const cleanedPaths = [];
21
- const unserializablePaths = [];
22
- const cleanedData = dehydrate(
23
- data,
24
- cleanedPaths,
25
- unserializablePaths,
26
- path,
27
- isPathWhitelisted,
28
- );
29
-
30
- return {
31
- data: cleanedData,
32
- cleaned: cleanedPaths,
33
- unserializable: unserializablePaths,
34
- };
35
- } else {
36
- return null;
37
- }
38
-}
39
-
40
-export function copyWithSet(
41
- obj: Object | Array<any>,
42
- path: Array<string | number>,
43
- value: any,
44
- index: number = 0,
45
-): Object | Array<any> {
46
- console.log('[utils] copyWithSet()', obj, path, index, value);
47
- if (index >= path.length) {
48
- return value;
49
- }
50
- const key = path[index];
51
- const updated = Array.isArray(obj) ? obj.slice() : {...obj};
52
- // $FlowFixMe number or string is fine here
53
- updated[key] = copyWithSet(obj[key], path, value, index + 1);
54
- return updated;
55
-}
packages/react-devtools-shared/src/backend/views/Highlighter/Highlighter.js
deleted
-53
@@ -1,53 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import Overlay from './Overlay';
11
-
12
-const SHOW_DURATION = 2000;
13
-
14
-let timeoutID: TimeoutID | null = null;
15
-let overlay: Overlay | null = null;
16
-
17
-export function hideOverlay() {
18
- timeoutID = null;
19
-
20
- if (overlay !== null) {
21
- overlay.remove();
22
- overlay = null;
23
- }
24
-}
25
-
26
-export function showOverlay(
27
- elements: Array<HTMLElement> | null,
28
- componentName: string | null,
29
- hideAfterTimeout: boolean,
30
-) {
31
- // TODO (npm-packages) Detect RN and support it somehow
32
- if (window.document == null) {
33
- return;
34
- }
35
-
36
- if (timeoutID !== null) {
37
- clearTimeout(timeoutID);
38
- }
39
-
40
- if (elements == null) {
41
- return;
42
- }
43
-
44
- if (overlay === null) {
45
- overlay = new Overlay();
46
- }
47
-
48
- overlay.inspect(elements, componentName);
49
-
50
- if (hideAfterTimeout) {
51
- timeoutID = setTimeout(hideOverlay, SHOW_DURATION);
52
- }
53
-}
packages/react-devtools-shared/src/backend/views/Highlighter/Overlay.js
deleted
-461
@@ -1,461 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import assign from 'object-assign';
11
-
12
-type Rect = {
13
- bottom: number,
14
- height: number,
15
- left: number,
16
- right: number,
17
- top: number,
18
- width: number,
19
-};
20
-
21
-type Box = {|top: number, left: number, width: number, height: number|};
22
-
23
-// Note that the Overlay components are not affected by the active Theme,
24
-// because they highlight elements in the main Chrome window (outside of devtools).
25
-// The colors below were chosen to roughly match those used by Chrome devtools.
26
-
27
-class OverlayRect {
28
- node: HTMLElement;
29
- border: HTMLElement;
30
- padding: HTMLElement;
31
- content: HTMLElement;
32
-
33
- constructor(doc: Document, container: HTMLElement) {
34
- this.node = doc.createElement('div');
35
- this.border = doc.createElement('div');
36
- this.padding = doc.createElement('div');
37
- this.content = doc.createElement('div');
38
-
39
- this.border.style.borderColor = overlayStyles.border;
40
- this.padding.style.borderColor = overlayStyles.padding;
41
- this.content.style.backgroundColor = overlayStyles.background;
42
-
43
- assign(this.node.style, {
44
- borderColor: overlayStyles.margin,
45
- pointerEvents: 'none',
46
- position: 'fixed',
47
- });
48
-
49
- this.node.style.zIndex = '10000000';
50
-
51
- this.node.appendChild(this.border);
52
- this.border.appendChild(this.padding);
53
- this.padding.appendChild(this.content);
54
- container.appendChild(this.node);
55
- }
56
-
57
- remove() {
58
- if (this.node.parentNode) {
59
- this.node.parentNode.removeChild(this.node);
60
- }
61
- }
62
-
63
- update(box: Rect, dims: any) {
64
- boxWrap(dims, 'margin', this.node);
65
- boxWrap(dims, 'border', this.border);
66
- boxWrap(dims, 'padding', this.padding);
67
-
68
- assign(this.content.style, {
69
- height:
70
- box.height -
71
- dims.borderTop -
72
- dims.borderBottom -
73
- dims.paddingTop -
74
- dims.paddingBottom +
75
- 'px',
76
- width:
77
- box.width -
78
- dims.borderLeft -
79
- dims.borderRight -
80
- dims.paddingLeft -
81
- dims.paddingRight +
82
- 'px',
83
- });
84
-
85
- assign(this.node.style, {
86
- top: box.top - dims.marginTop + 'px',
87
- left: box.left - dims.marginLeft + 'px',
88
- });
89
- }
90
-}
91
-
92
-class OverlayTip {
93
- tip: HTMLElement;
94
- nameSpan: HTMLElement;
95
- dimSpan: HTMLElement;
96
-
97
- constructor(doc: Document, container: HTMLElement) {
98
- this.tip = doc.createElement('div');
99
- assign(this.tip.style, {
100
- display: 'flex',
101
- flexFlow: 'row nowrap',
102
- backgroundColor: '#333740',
103
- borderRadius: '2px',
104
- fontFamily:
105
- '"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace',
106
- fontWeight: 'bold',
107
- padding: '3px 5px',
108
- pointerEvents: 'none',
109
- position: 'fixed',
110
- fontSize: '12px',
111
- whiteSpace: 'nowrap',
112
- });
113
-
114
- this.nameSpan = doc.createElement('span');
115
- this.tip.appendChild(this.nameSpan);
116
- assign(this.nameSpan.style, {
117
- color: '#ee78e6',
118
- borderRight: '1px solid #aaaaaa',
119
- paddingRight: '0.5rem',
120
- marginRight: '0.5rem',
121
- });
122
- this.dimSpan = doc.createElement('span');
123
- this.tip.appendChild(this.dimSpan);
124
- assign(this.dimSpan.style, {
125
- color: '#d7d7d7',
126
- });
127
-
128
- this.tip.style.zIndex = '10000000';
129
- container.appendChild(this.tip);
130
- }
131
-
132
- remove() {
133
- if (this.tip.parentNode) {
134
- this.tip.parentNode.removeChild(this.tip);
135
- }
136
- }
137
-
138
- updateText(name: string, width: number, height: number) {
139
- this.nameSpan.textContent = name;
140
- this.dimSpan.textContent =
141
- Math.round(width) + 'px × ' + Math.round(height) + 'px';
142
- }
143
-
144
- updatePosition(dims: Box, bounds: Box) {
145
- const tipRect = this.tip.getBoundingClientRect();
146
- const tipPos = findTipPos(dims, bounds, {
147
- width: tipRect.width,
148
- height: tipRect.height,
149
- });
150
- assign(this.tip.style, tipPos.style);
151
- }
152
-}
153
-
154
-export default class Overlay {
155
- window: window;
156
- tipBoundsWindow: window;
157
- container: HTMLElement;
158
- tip: OverlayTip;
159
- rects: Array<OverlayRect>;
160
-
161
- constructor() {
162
- // Find the root window, because overlays are positioned relative to it.
163
- let currentWindow = window.__REACT_DEVTOOLS_TARGET_WINDOW__ || window;
164
- this.window = currentWindow;
165
-
166
- // When opened in shells/dev, the tooltip should be bound by the app iframe, not by the topmost window.
167
- let tipBoundsWindow = window.__REACT_DEVTOOLS_TARGET_WINDOW__ || window;
168
- this.tipBoundsWindow = tipBoundsWindow;
169
-
170
- const doc = currentWindow.document;
171
- this.container = doc.createElement('div');
172
- this.container.style.zIndex = '10000000';
173
-
174
- this.tip = new OverlayTip(doc, this.container);
175
- this.rects = [];
176
-
177
- doc.body.appendChild(this.container);
178
- }
179
-
180
- remove() {
181
- this.tip.remove();
182
- this.rects.forEach(rect => {
183
- rect.remove();
184
- });
185
- this.rects.length = 0;
186
- if (this.container.parentNode) {
187
- this.container.parentNode.removeChild(this.container);
188
- }
189
- }
190
-
191
- inspect(nodes: Array<HTMLElement>, name?: ?string) {
192
- // We can't get the size of text nodes or comment nodes. React as of v15
193
- // heavily uses comment nodes to delimit text.
194
- const elements = nodes.filter(node => node.nodeType === Node.ELEMENT_NODE);
195
-
196
- while (this.rects.length > elements.length) {
197
- const rect = this.rects.pop();
198
- rect.remove();
199
- }
200
- if (elements.length === 0) {
201
- return;
202
- }
203
-
204
- while (this.rects.length < elements.length) {
205
- this.rects.push(new OverlayRect(this.window.document, this.container));
206
- }
207
-
208
- const outerBox = {
209
- top: Number.POSITIVE_INFINITY,
210
- right: Number.NEGATIVE_INFINITY,
211
- bottom: Number.NEGATIVE_INFINITY,
212
- left: Number.POSITIVE_INFINITY,
213
- };
214
- elements.forEach((element, index) => {
215
- const box = getNestedBoundingClientRect(element, this.window);
216
- const dims = getElementDimensions(element);
217
-
218
- outerBox.top = Math.min(outerBox.top, box.top - dims.marginTop);
219
- outerBox.right = Math.max(
220
- outerBox.right,
221
- box.left + box.width + dims.marginRight,
222
- );
223
- outerBox.bottom = Math.max(
224
- outerBox.bottom,
225
- box.top + box.height + dims.marginBottom,
226
- );
227
- outerBox.left = Math.min(outerBox.left, box.left - dims.marginLeft);
228
-
229
- const rect = this.rects[index];
230
- rect.update(box, dims);
231
- });
232
-
233
- if (!name) {
234
- name = elements[0].nodeName.toLowerCase();
235
- const ownerName = getOwnerDisplayName(elements[0]);
236
- if (ownerName) {
237
- name += ' (in ' + ownerName + ')';
238
- }
239
- }
240
-
241
- this.tip.updateText(
242
- name,
243
- outerBox.right - outerBox.left,
244
- outerBox.bottom - outerBox.top,
245
- );
246
- const tipBounds = getNestedBoundingClientRect(
247
- this.tipBoundsWindow.document.documentElement,
248
- this.window,
249
- );
250
-
251
- this.tip.updatePosition(
252
- {
253
- top: outerBox.top,
254
- left: outerBox.left,
255
- height: outerBox.bottom - outerBox.top,
256
- width: outerBox.right - outerBox.left,
257
- },
258
- {
259
- top: tipBounds.top + this.tipBoundsWindow.scrollY,
260
- left: tipBounds.left + this.tipBoundsWindow.scrollX,
261
- height: this.tipBoundsWindow.innerHeight,
262
- width: this.tipBoundsWindow.innerWidth,
263
- },
264
- );
265
- }
266
-}
267
-
268
-function getOwnerDisplayName(node) {
269
- const fiber = getFiber(node);
270
- if (fiber === null) {
271
- return null;
272
- }
273
- const owner = fiber._debugOwner;
274
- if (owner && owner.type) {
275
- const ownerName = owner.type.displayName || owner.type.name;
276
- return ownerName || null;
277
- }
278
- return null;
279
-}
280
-
281
-let lastFoundInternalKey = null;
282
-function getFiber(node) {
283
- if (
284
- lastFoundInternalKey !== null &&
285
- node.hasOwnProperty(lastFoundInternalKey)
286
- ) {
287
- return (node: any)[lastFoundInternalKey];
288
- }
289
- let internalKey = Object.keys(node).find(
290
- key => key.indexOf('__reactInternalInstance') === 0,
291
- );
292
- if (internalKey) {
293
- lastFoundInternalKey = internalKey;
294
- return (node: any)[lastFoundInternalKey];
295
- }
296
- return null;
297
-}
298
-
299
-function findTipPos(dims, bounds, tipSize) {
300
- const tipHeight = Math.max(tipSize.height, 20);
301
- const tipWidth = Math.max(tipSize.width, 60);
302
- const margin = 5;
303
-
304
- let top;
305
- if (dims.top + dims.height + tipHeight <= bounds.top + bounds.height) {
306
- if (dims.top + dims.height < bounds.top + 0) {
307
- top = bounds.top + margin;
308
- } else {
309
- top = dims.top + dims.height + margin;
310
- }
311
- } else if (dims.top - tipHeight <= bounds.top + bounds.height) {
312
- if (dims.top - tipHeight - margin < bounds.top + margin) {
313
- top = bounds.top + margin;
314
- } else {
315
- top = dims.top - tipHeight - margin;
316
- }
317
- } else {
318
- top = bounds.top + bounds.height - tipHeight - margin;
319
- }
320
-
321
- let left = dims.left + margin;
322
- if (dims.left < bounds.left) {
323
- left = bounds.left + margin;
324
- }
325
- if (dims.left + tipWidth > bounds.left + bounds.width) {
326
- left = bounds.left + bounds.width - tipWidth - margin;
327
- }
328
-
329
- top += 'px';
330
- left += 'px';
331
- return {
332
- style: {top, left},
333
- };
334
-}
335
-
336
-export function getElementDimensions(domElement: Element) {
337
- const calculatedStyle = window.getComputedStyle(domElement);
338
- return {
339
- borderLeft: parseInt(calculatedStyle.borderLeftWidth, 10),
340
- borderRight: parseInt(calculatedStyle.borderRightWidth, 10),
341
- borderTop: parseInt(calculatedStyle.borderTopWidth, 10),
342
- borderBottom: parseInt(calculatedStyle.borderBottomWidth, 10),
343
- marginLeft: parseInt(calculatedStyle.marginLeft, 10),
344
- marginRight: parseInt(calculatedStyle.marginRight, 10),
345
- marginTop: parseInt(calculatedStyle.marginTop, 10),
346
- marginBottom: parseInt(calculatedStyle.marginBottom, 10),
347
- paddingLeft: parseInt(calculatedStyle.paddingLeft, 10),
348
- paddingRight: parseInt(calculatedStyle.paddingRight, 10),
349
- paddingTop: parseInt(calculatedStyle.paddingTop, 10),
350
- paddingBottom: parseInt(calculatedStyle.paddingBottom, 10),
351
- };
352
-}
353
-
354
-// Get the window object for the document that a node belongs to,
355
-// or return null if it cannot be found (node not attached to DOM,
356
-// etc).
357
-function getOwnerWindow(node: HTMLElement): typeof window | null {
358
- if (!node.ownerDocument) {
359
- return null;
360
- }
361
- return node.ownerDocument.defaultView;
362
-}
363
-
364
-// Get the iframe containing a node, or return null if it cannot
365
-// be found (node not within iframe, etc).
366
-function getOwnerIframe(node: HTMLElement): HTMLElement | null {
367
- const nodeWindow = getOwnerWindow(node);
368
- if (nodeWindow) {
369
- return nodeWindow.frameElement;
370
- }
371
- return null;
372
-}
373
-
374
-// Get a bounding client rect for a node, with an
375
-// offset added to compensate for its border.
376
-function getBoundingClientRectWithBorderOffset(node: HTMLElement) {
377
- const dimensions = getElementDimensions(node);
378
- return mergeRectOffsets([
379
- node.getBoundingClientRect(),
380
- {
381
- top: dimensions.borderTop,
382
- left: dimensions.borderLeft,
383
- bottom: dimensions.borderBottom,
384
- right: dimensions.borderRight,
385
- // This width and height won't get used by mergeRectOffsets (since this
386
- // is not the first rect in the array), but we set them so that this
387
- // object typechecks as a ClientRect.
388
- width: 0,
389
- height: 0,
390
- },
391
- ]);
392
-}
393
-
394
-// Add together the top, left, bottom, and right properties of
395
-// each ClientRect, but keep the width and height of the first one.
396
-function mergeRectOffsets(rects: Array<Rect>): Rect {
397
- return rects.reduce((previousRect, rect) => {
398
- if (previousRect == null) {
399
- return rect;
400
- }
401
-
402
- return {
403
- top: previousRect.top + rect.top,
404
- left: previousRect.left + rect.left,
405
- width: previousRect.width,
406
- height: previousRect.height,
407
- bottom: previousRect.bottom + rect.bottom,
408
- right: previousRect.right + rect.right,
409
- };
410
- });
411
-}
412
-
413
-// Calculate a boundingClientRect for a node relative to boundaryWindow,
414
-// taking into account any offsets caused by intermediate iframes.
415
-function getNestedBoundingClientRect(
416
- node: HTMLElement,
417
- boundaryWindow: typeof window,
418
-): Rect {
419
- const ownerIframe = getOwnerIframe(node);
420
- if (ownerIframe && ownerIframe !== boundaryWindow) {
421
- const rects = [node.getBoundingClientRect()];
422
- let currentIframe = ownerIframe;
423
- let onlyOneMore = false;
424
- while (currentIframe) {
425
- const rect = getBoundingClientRectWithBorderOffset(currentIframe);
426
- rects.push(rect);
427
- currentIframe = getOwnerIframe(currentIframe);
428
-
429
- if (onlyOneMore) {
430
- break;
431
- }
432
- // We don't want to calculate iframe offsets upwards beyond
433
- // the iframe containing the boundaryWindow, but we
434
- // need to calculate the offset relative to the boundaryWindow.
435
- if (currentIframe && getOwnerWindow(currentIframe) === boundaryWindow) {
436
- onlyOneMore = true;
437
- }
438
- }
439
-
440
- return mergeRectOffsets(rects);
441
- } else {
442
- return node.getBoundingClientRect();
443
- }
444
-}
445
-
446
-function boxWrap(dims, what, node) {
447
- assign(node.style, {
448
- borderTopWidth: dims[what + 'Top'] + 'px',
449
- borderLeftWidth: dims[what + 'Left'] + 'px',
450
- borderRightWidth: dims[what + 'Right'] + 'px',
451
- borderBottomWidth: dims[what + 'Bottom'] + 'px',
452
- borderStyle: 'solid',
453
- });
454
-}
455
-
456
-const overlayStyles = {
457
- background: 'rgba(120, 170, 210, 0.7)',
458
- padding: 'rgba(77, 200, 0, 0.3)',
459
- margin: 'rgba(255, 155, 0, 0.3)',
460
- border: 'rgba(255, 200, 50, 0.3)',
461
-};
packages/react-devtools-shared/src/backend/views/Highlighter/index.js
deleted
-195
@@ -1,195 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import memoize from 'memoize-one';
11
-import throttle from 'lodash.throttle';
12
-import Agent from 'react-devtools-shared/src/backend/agent';
13
-import {hideOverlay, showOverlay} from './Highlighter';
14
-
15
-import type {BackendBridge} from 'react-devtools-shared/src/bridge';
16
-
17
-// This plug-in provides in-page highlighting of the selected element.
18
-// It is used by the browser extension nad the standalone DevTools shell (when connected to a browser).
19
-// It is not currently the mechanism used to highlight React Native views.
20
-// That is done by the React Native Inspector component.
21
-
22
-let iframesListeningTo: Set<HTMLIFrameElement> = new Set();
23
-
24
-export default function setupHighlighter(
25
- bridge: BackendBridge,
26
- agent: Agent,
27
-): void {
28
- bridge.addListener(
29
- 'clearNativeElementHighlight',
30
- clearNativeElementHighlight,
31
- );
32
- bridge.addListener('highlightNativeElement', highlightNativeElement);
33
- bridge.addListener('shutdown', stopInspectingNative);
34
- bridge.addListener('startInspectingNative', startInspectingNative);
35
- bridge.addListener('stopInspectingNative', stopInspectingNative);
36
-
37
- function startInspectingNative() {
38
- registerListenersOnWindow(window);
39
- }
40
-
41
- function registerListenersOnWindow(window) {
42
- // This plug-in may run in non-DOM environments (e.g. React Native).
43
- if (window && typeof window.addEventListener === 'function') {
44
- window.addEventListener('click', onClick, true);
45
- window.addEventListener('mousedown', onMouseEvent, true);
46
- window.addEventListener('mouseover', onMouseEvent, true);
47
- window.addEventListener('mouseup', onMouseEvent, true);
48
- window.addEventListener('pointerdown', onPointerDown, true);
49
- window.addEventListener('pointerover', onPointerOver, true);
50
- window.addEventListener('pointerup', onPointerUp, true);
51
- }
52
- }
53
-
54
- function stopInspectingNative() {
55
- hideOverlay();
56
- removeListenersOnWindow(window);
57
- iframesListeningTo.forEach(function(frame) {
58
- try {
59
- removeListenersOnWindow(frame.contentWindow);
60
- } catch (error) {
61
- // This can error when the iframe is on a cross-origin.
62
- }
63
- });
64
- iframesListeningTo = new Set();
65
- }
66
-
67
- function removeListenersOnWindow(window) {
68
- // This plug-in may run in non-DOM environments (e.g. React Native).
69
- if (window && typeof window.removeEventListener === 'function') {
70
- window.removeEventListener('click', onClick, true);
71
- window.removeEventListener('mousedown', onMouseEvent, true);
72
- window.removeEventListener('mouseover', onMouseEvent, true);
73
- window.removeEventListener('mouseup', onMouseEvent, true);
74
- window.removeEventListener('pointerdown', onPointerDown, true);
75
- window.removeEventListener('pointerover', onPointerOver, true);
76
- window.removeEventListener('pointerup', onPointerUp, true);
77
- }
78
- }
79
-
80
- function clearNativeElementHighlight() {
81
- hideOverlay();
82
- }
83
-
84
- function highlightNativeElement({
85
- displayName,
86
- hideAfterTimeout,
87
- id,
88
- openNativeElementsPanel,
89
- rendererID,
90
- scrollIntoView,
91
- }: {
92
- displayName: string | null,
93
- hideAfterTimeout: boolean,
94
- id: number,
95
- openNativeElementsPanel: boolean,
96
- rendererID: number,
97
- scrollIntoView: boolean,
98
- }) {
99
- const renderer = agent.rendererInterfaces[rendererID];
100
- if (renderer == null) {
101
- console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
102
- }
103
-
104
- let nodes: ?Array<HTMLElement> = null;
105
- if (renderer !== null) {
106
- nodes = ((renderer.findNativeNodesForFiberID(id): any): ?Array<
107
- HTMLElement,
108
- >);
109
- }
110
-
111
- if (nodes != null && nodes[0] != null) {
112
- const node = nodes[0];
113
- if (scrollIntoView && typeof node.scrollIntoView === 'function') {
114
- // If the node isn't visible show it before highlighting it.
115
- // We may want to reconsider this; it might be a little disruptive.
116
- // $FlowFixMe Flow only knows about 'start' | 'end'
117
- node.scrollIntoView({block: 'nearest', inline: 'nearest'});
118
- }
119
-
120
- showOverlay(nodes, displayName, hideAfterTimeout);
121
-
122
- if (openNativeElementsPanel) {
123
- window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 = node;
124
- bridge.send('syncSelectionToNativeElementsPanel');
125
- }
126
- } else {
127
- hideOverlay();
128
- }
129
- }
130
-
131
- function onClick(event: MouseEvent) {
132
- event.preventDefault();
133
- event.stopPropagation();
134
-
135
- stopInspectingNative();
136
-
137
- bridge.send('stopInspectingNative', true);
138
- }
139
-
140
- function onMouseEvent(event: MouseEvent) {
141
- event.preventDefault();
142
- event.stopPropagation();
143
- }
144
-
145
- function onPointerDown(event: MouseEvent) {
146
- event.preventDefault();
147
- event.stopPropagation();
148
-
149
- selectFiberForNode(((event.target: any): HTMLElement));
150
- }
151
-
152
- function onPointerOver(event: MouseEvent) {
153
- event.preventDefault();
154
- event.stopPropagation();
155
-
156
- const target = ((event.target: any): HTMLElement);
157
-
158
- if (target.tagName === 'IFRAME') {
159
- const iframe: HTMLIFrameElement = (target: any);
160
- try {
161
- if (!iframesListeningTo.has(iframe)) {
162
- const window = iframe.contentWindow;
163
- registerListenersOnWindow(window);
164
- iframesListeningTo.add(iframe);
165
- }
166
- } catch (error) {
167
- // This can error when the iframe is on a cross-origin.
168
- }
169
- }
170
-
171
- // Don't pass the name explicitly.
172
- // It will be inferred from DOM tag and Fiber owner.
173
- showOverlay([target], null, false);
174
-
175
- selectFiberForNode(target);
176
- }
177
-
178
- function onPointerUp(event: MouseEvent) {
179
- event.preventDefault();
180
- event.stopPropagation();
181
- }
182
-
183
- const selectFiberForNode = throttle(
184
- memoize((node: HTMLElement) => {
185
- const id = agent.getIDForNode(node);
186
- if (id !== null) {
187
- bridge.send('selectFiber', id);
188
- }
189
- }),
190
- 200,
191
- // Don't change the selection in the very first 200ms
192
- // because those are usually unintentional as you lift the cursor.
193
- {leading: false},
194
- );
195
-}
packages/react-devtools-shared/src/bridge.js
deleted
-248
@@ -1,248 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import EventEmitter from 'events';
11
-
12
-import type {ComponentFilter, Wall} from './types';
13
-import type {
14
- InspectedElementPayload,
15
- OwnersList,
16
- ProfilingDataBackend,
17
- RendererID,
18
-} from 'react-devtools-shared/src/backend/types';
19
-import type {StyleAndLayout as StyleAndLayoutPayload} from 'react-devtools-shared/src/backend/NativeStyleEditor/types';
20
-
21
-const BATCH_DURATION = 100;
22
-
23
-type ElementAndRendererID = {|id: number, rendererID: RendererID|};
24
-
25
-type Message = {|
26
- event: string,
27
- payload: any,
28
-|};
29
-
30
-type HighlightElementInDOM = {|
31
- ...ElementAndRendererID,
32
- displayName: string | null,
33
- hideAfterTimeout: boolean,
34
- openNativeElementsPanel: boolean,
35
- scrollIntoView: boolean,
36
-|};
37
-
38
-type OverrideValue = {|
39
- ...ElementAndRendererID,
40
- path: Array<string | number>,
41
- value: any,
42
-|};
43
-
44
-type OverrideHookState = {|
45
- ...OverrideValue,
46
- hookID: number,
47
-|};
48
-
49
-type OverrideSuspense = {|
50
- ...ElementAndRendererID,
51
- forceFallback: boolean,
52
-|};
53
-
54
-type InspectElementParams = {|
55
- ...ElementAndRendererID,
56
- path?: Array<string | number>,
57
-|};
58
-
59
-type NativeStyleEditor_RenameAttributeParams = {|
60
- ...ElementAndRendererID,
61
- oldName: string,
62
- newName: string,
63
- value: string,
64
-|};
65
-
66
-type NativeStyleEditor_SetValueParams = {|
67
- ...ElementAndRendererID,
68
- name: string,
69
- value: string,
70
-|};
71
-
72
-type BackendEvents = {|
73
- inspectedElement: [InspectedElementPayload],
74
- isBackendStorageAPISupported: [boolean],
75
- operations: [Array<number>],
76
- ownersList: [OwnersList],
77
- overrideComponentFilters: [Array<ComponentFilter>],
78
- profilingData: [ProfilingDataBackend],
79
- profilingStatus: [boolean],
80
- reloadAppForProfiling: [],
81
- selectFiber: [number],
82
- shutdown: [],
83
- stopInspectingNative: [boolean],
84
- syncSelectionFromNativeElementsPanel: [],
85
- syncSelectionToNativeElementsPanel: [],
86
-
87
- // React Native style editor plug-in.
88
- isNativeStyleEditorSupported: [
89
- {|isSupported: boolean, validAttributes: ?$ReadOnlyArray<string>|},
90
- ],
91
- NativeStyleEditor_styleAndLayout: [StyleAndLayoutPayload],
92
-|};
93
-
94
-type FrontendEvents = {|
95
- clearNativeElementHighlight: [],
96
- getOwnersList: [ElementAndRendererID],
97
- getProfilingData: [{|rendererID: RendererID|}],
98
- getProfilingStatus: [],
99
- highlightNativeElement: [HighlightElementInDOM],
100
- inspectElement: [InspectElementParams],
101
- logElementToConsole: [ElementAndRendererID],
102
- overrideContext: [OverrideValue],
103
- overrideHookState: [OverrideHookState],
104
- overrideProps: [OverrideValue],
105
- overrideState: [OverrideValue],
106
- overrideSuspense: [OverrideSuspense],
107
- profilingData: [ProfilingDataBackend],
108
- reloadAndProfile: [boolean],
109
- selectFiber: [number],
110
- shutdown: [],
111
- startInspectingNative: [],
112
- startProfiling: [boolean],
113
- stopInspectingNative: [boolean],
114
- stopProfiling: [],
115
- updateAppendComponentStack: [boolean],
116
- updateComponentFilters: [Array<ComponentFilter>],
117
- viewElementSource: [ElementAndRendererID],
118
-
119
- // React Native style editor plug-in.
120
- NativeStyleEditor_measure: [ElementAndRendererID],
121
- NativeStyleEditor_renameAttribute: [NativeStyleEditor_RenameAttributeParams],
122
- NativeStyleEditor_setValue: [NativeStyleEditor_SetValueParams],
123
-|};
124
-
125
-class Bridge<
126
- OutgoingEvents: Object,
127
- IncomingEvents: Object,
128
-> extends EventEmitter<{|
129
- ...IncomingEvents,
130
- ...OutgoingEvents,
131
-|}> {
132
- _isShutdown: boolean = false;
133
- _messageQueue: Array<any> = [];
134
- _timeoutID: TimeoutID | null = null;
135
- _wall: Wall;
136
- _wallUnlisten: Function | null = null;
137
-
138
- constructor(wall: Wall) {
139
- super();
140
-
141
- this._wall = wall;
142
-
143
- this._wallUnlisten =
144
- wall.listen((message: Message) => {
145
- (this: any).emit(message.event, message.payload);
146
- }) || null;
147
- }
148
-
149
- // Listening directly to the wall isn't advised.
150
- // It can be used to listen for legacy (v3) messages (since they use a different format).
151
- get wall(): Wall {
152
- return this._wall;
153
- }
154
-
155
- send<EventName: $Keys<OutgoingEvents>>(
156
- event: EventName,
157
- ...payload: $ElementType<OutgoingEvents, EventName>
158
- ) {
159
- if (this._isShutdown) {
160
- console.warn(
161
- `Cannot send message "${event}" through a Bridge that has been shutdown.`,
162
- );
163
- return;
164
- }
165
-
166
- // When we receive a message:
167
- // - we add it to our queue of messages to be sent
168
- // - if there hasn't been a message recently, we set a timer for 0 ms in
169
- // the future, allowing all messages created in the same tick to be sent
170
- // together
171
- // - if there *has* been a message flushed in the last BATCH_DURATION ms
172
- // (or we're waiting for our setTimeout-0 to fire), then _timeoutID will
173
- // be set, and we'll simply add to the queue and wait for that
174
- this._messageQueue.push(event, payload);
175
- if (!this._timeoutID) {
176
- this._timeoutID = setTimeout(this._flush, 0);
177
- }
178
- }
179
-
180
- shutdown() {
181
- if (this._isShutdown) {
182
- console.warn('Bridge was already shutdown.');
183
- return;
184
- }
185
-
186
- // Queue the shutdown outgoing message for subscribers.
187
- this.send('shutdown');
188
-
189
- // Mark this bridge as destroyed, i.e. disable its public API.
190
- this._isShutdown = true;
191
-
192
- // Disable the API inherited from EventEmitter that can add more listeners and send more messages.
193
- // $FlowFixMe This property is not writable.
194
- this.addListener = function() {};
195
- // $FlowFixMe This property is not writable.
196
- this.emit = function() {};
197
- // NOTE: There's also EventEmitter API like `on` and `prependListener` that we didn't add to our Flow type of EventEmitter.
198
-
199
- // Unsubscribe this bridge incoming message listeners to be sure, and so they don't have to do that.
200
- this.removeAllListeners();
201
-
202
- // Stop accepting and emitting incoming messages from the wall.
203
- const wallUnlisten = this._wallUnlisten;
204
- if (wallUnlisten) {
205
- wallUnlisten();
206
- }
207
-
208
- // Synchronously flush all queued outgoing messages.
209
- // At this step the subscribers' code may run in this call stack.
210
- do {
211
- this._flush();
212
- } while (this._messageQueue.length);
213
-
214
- // Make sure once again that there is no dangling timer.
215
- if (this._timeoutID !== null) {
216
- clearTimeout(this._timeoutID);
217
- this._timeoutID = null;
218
- }
219
- }
220
-
221
- _flush = () => {
222
- // This method is used after the bridge is marked as destroyed in shutdown sequence,
223
- // so we do not bail out if the bridge marked as destroyed.
224
- // It is a private method that the bridge ensures is only called at the right times.
225
-
226
- if (this._timeoutID !== null) {
227
- clearTimeout(this._timeoutID);
228
- this._timeoutID = null;
229
- }
230
-
231
- if (this._messageQueue.length) {
232
- for (let i = 0; i < this._messageQueue.length; i += 2) {
233
- this._wall.send(this._messageQueue[i], ...this._messageQueue[i + 1]);
234
- }
235
- this._messageQueue.length = 0;
236
-
237
- // Check again for queued messages in BATCH_DURATION ms. This will keep
238
- // flushing in a loop as long as messages continue to be added. Once no
239
- // more are, the timer expires.
240
- this._timeoutID = setTimeout(this._flush, BATCH_DURATION);
241
- }
242
- };
243
-}
244
-
245
-export type BackendBridge = Bridge<BackendEvents, FrontendEvents>;
246
-export type FrontendBridge = Bridge<FrontendEvents, BackendEvents>;
247
-
248
-export default Bridge;
packages/react-devtools-shared/src/constants.js
deleted
-67
@@ -1,67 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-// Flip this flag to true to enable verbose console debug logging.
11
-export const __DEBUG__ = false;
12
-
13
-export const TREE_OPERATION_ADD = 1;
14
-export const TREE_OPERATION_REMOVE = 2;
15
-export const TREE_OPERATION_REORDER_CHILDREN = 3;
16
-export const TREE_OPERATION_UPDATE_TREE_BASE_DURATION = 4;
17
-
18
-export const LOCAL_STORAGE_FILTER_PREFERENCES_KEY =
19
- 'React::DevTools::componentFilters';
20
-
21
-export const SESSION_STORAGE_LAST_SELECTION_KEY =
22
- 'React::DevTools::lastSelection';
23
-
24
-export const SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY =
25
- 'React::DevTools::recordChangeDescriptions';
26
-
27
-export const SESSION_STORAGE_RELOAD_AND_PROFILE_KEY =
28
- 'React::DevTools::reloadAndProfile';
29
-
30
-export const LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY =
31
- 'React::DevTools::appendComponentStack';
32
-
33
-export const PROFILER_EXPORT_VERSION = 4;
34
-
35
-export const CHANGE_LOG_URL =
36
- 'https://github.com/facebook/react/blob/master/packages/react-devtools/CHANGELOG.md';
37
-
38
-// HACK
39
-//
40
-// Extracting during build time avoids a temporarily invalid state for the inline target.
41
-// Sometimes the inline target is rendered before root styles are applied,
42
-// which would result in e.g. NaN itemSize being passed to react-window list.
43
-//
44
-let COMFORTABLE_LINE_HEIGHT;
45
-let COMPACT_LINE_HEIGHT;
46
-
47
-try {
48
- // $FlowFixMe
49
- const rawStyleString = require('!!raw-loader!react-devtools-shared/src/devtools/views/root.css')
50
- .default;
51
-
52
- const extractVar = varName => {
53
- const regExp = new RegExp(`${varName}: ([0-9]+)`);
54
- const match = rawStyleString.match(regExp);
55
- return parseInt(match[1], 10);
56
- };
57
-
58
- COMFORTABLE_LINE_HEIGHT = extractVar('comfortable-line-height-data');
59
- COMPACT_LINE_HEIGHT = extractVar('compact-line-height-data');
60
-} catch (error) {
61
- // We can't use the Webpack loader syntax in the context of Jest,
62
- // so tests need some reasonably meaningful fallback value.
63
- COMFORTABLE_LINE_HEIGHT = 15;
64
- COMPACT_LINE_HEIGHT = 10;
65
-}
66
-
67
-export {COMFORTABLE_LINE_HEIGHT, COMPACT_LINE_HEIGHT};
packages/react-devtools-shared/src/devtools/ProfilerStore.js
deleted
-347
@@ -1,347 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import EventEmitter from 'events';
11
-import {prepareProfilingDataFrontendFromBackendAndStore} from './views/Profiler/utils';
12
-import ProfilingCache from './ProfilingCache';
13
-import Store from './store';
14
-
15
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
16
-import type {ProfilingDataBackend} from 'react-devtools-shared/src/backend/types';
17
-import type {
18
- CommitDataFrontend,
19
- ProfilingDataForRootFrontend,
20
- ProfilingDataFrontend,
21
- SnapshotNode,
22
-} from './views/Profiler/types';
23
-
24
-export default class ProfilerStore extends EventEmitter<{|
25
- isProcessingData: [],
26
- isProfiling: [],
27
- profilingData: [],
28
-|}> {
29
- _bridge: FrontendBridge;
30
-
31
- // Suspense cache for lazily calculating derived profiling data.
32
- _cache: ProfilingCache;
33
-
34
- // Temporary store of profiling data from the backend renderer(s).
35
- // This data will be converted to the ProfilingDataFrontend format after being collected from all renderers.
36
- _dataBackends: Array<ProfilingDataBackend> = [];
37
-
38
- // Data from the most recently completed profiling session,
39
- // or data that has been imported from a previously exported session.
40
- // This object contains all necessary data to drive the Profiler UI interface,
41
- // even though some of it is lazily parsed/derived via the ProfilingCache.
42
- _dataFrontend: ProfilingDataFrontend | null = null;
43
-
44
- // Snapshot of all attached renderer IDs.
45
- // Once profiling is finished, this snapshot will be used to query renderers for profiling data.
46
- //
47
- // This map is initialized when profiling starts and updated when a new root is added while profiling;
48
- // Upon completion, it is converted into the exportable ProfilingDataFrontend format.
49
- _initialRendererIDs: Set<number> = new Set();
50
-
51
- // Snapshot of the state of the main Store (including all roots) when profiling started.
52
- // Once profiling is finished, this snapshot can be used along with "operations" messages emitted during profiling,
53
- // to reconstruct the state of each root for each commit.
54
- // It's okay to use a single root to store this information because node IDs are unique across all roots.
55
- //
56
- // This map is initialized when profiling starts and updated when a new root is added while profiling;
57
- // Upon completion, it is converted into the exportable ProfilingDataFrontend format.
58
- _initialSnapshotsByRootID: Map<number, Map<number, SnapshotNode>> = new Map();
59
-
60
- // Map of root (id) to a list of tree mutation that occur during profiling.
61
- // Once profiling is finished, these mutations can be used, along with the initial tree snapshots,
62
- // to reconstruct the state of each root for each commit.
63
- //
64
- // This map is only updated while profiling is in progress;
65
- // Upon completion, it is converted into the exportable ProfilingDataFrontend format.
66
- _inProgressOperationsByRootID: Map<number, Array<Array<number>>> = new Map();
67
-
68
- // The backend is currently profiling.
69
- // When profiling is in progress, operations are stored so that we can later reconstruct past commit trees.
70
- _isProfiling: boolean = false;
71
-
72
- // Tracks whether a specific renderer logged any profiling data during the most recent session.
73
- _rendererIDsThatReportedProfilingData: Set<number> = new Set();
74
-
75
- // After profiling, data is requested from each attached renderer using this queue.
76
- // So long as this queue is not empty, the store is retrieving and processing profiling data from the backend.
77
- _rendererQueue: Set<number> = new Set();
78
-
79
- _store: Store;
80
-
81
- constructor(
82
- bridge: FrontendBridge,
83
- store: Store,
84
- defaultIsProfiling: boolean,
85
- ) {
86
- super();
87
-
88
- this._bridge = bridge;
89
- this._isProfiling = defaultIsProfiling;
90
- this._store = store;
91
-
92
- bridge.addListener('operations', this.onBridgeOperations);
93
- bridge.addListener('profilingData', this.onBridgeProfilingData);
94
- bridge.addListener('profilingStatus', this.onProfilingStatus);
95
- bridge.addListener('shutdown', this.onBridgeShutdown);
96
-
97
- // It's possible that profiling has already started (e.g. "reload and start profiling")
98
- // so the frontend needs to ask the backend for its status after mounting.
99
- bridge.send('getProfilingStatus');
100
-
101
- this._cache = new ProfilingCache(this);
102
- }
103
-
104
- getCommitData(rootID: number, commitIndex: number): CommitDataFrontend {
105
- if (this._dataFrontend !== null) {
106
- const dataForRoot = this._dataFrontend.dataForRoots.get(rootID);
107
- if (dataForRoot != null) {
108
- const commitDatum = dataForRoot.commitData[commitIndex];
109
- if (commitDatum != null) {
110
- return commitDatum;
111
- }
112
- }
113
- }
114
-
115
- throw Error(
116
- `Could not find commit data for root "${rootID}" and commit ${commitIndex}`,
117
- );
118
- }
119
-
120
- getDataForRoot(rootID: number): ProfilingDataForRootFrontend {
121
- if (this._dataFrontend !== null) {
122
- const dataForRoot = this._dataFrontend.dataForRoots.get(rootID);
123
- if (dataForRoot != null) {
124
- return dataForRoot;
125
- }
126
- }
127
-
128
- throw Error(`Could not find commit data for root "${rootID}"`);
129
- }
130
-
131
- // Profiling data has been recorded for at least one root.
132
- get didRecordCommits(): boolean {
133
- return (
134
- this._dataFrontend !== null && this._dataFrontend.dataForRoots.size > 0
135
- );
136
- }
137
-
138
- get isProcessingData(): boolean {
139
- return this._rendererQueue.size > 0 || this._dataBackends.length > 0;
140
- }
141
-
142
- get isProfiling(): boolean {
143
- return this._isProfiling;
144
- }
145
-
146
- get profilingCache(): ProfilingCache {
147
- return this._cache;
148
- }
149
-
150
- get profilingData(): ProfilingDataFrontend | null {
151
- return this._dataFrontend;
152
- }
153
- set profilingData(value: ProfilingDataFrontend | null): void {
154
- if (this._isProfiling) {
155
- console.warn(
156
- 'Profiling data cannot be updated while profiling is in progress.',
157
- );
158
- return;
159
- }
160
-
161
- this._dataBackends.splice(0);
162
- this._dataFrontend = value;
163
- this._initialRendererIDs.clear();
164
- this._initialSnapshotsByRootID.clear();
165
- this._inProgressOperationsByRootID.clear();
166
- this._cache.invalidate();
167
-
168
- this.emit('profilingData');
169
- }
170
-
171
- clear(): void {
172
- this._dataBackends.splice(0);
173
- this._dataFrontend = null;
174
- this._initialRendererIDs.clear();
175
- this._initialSnapshotsByRootID.clear();
176
- this._inProgressOperationsByRootID.clear();
177
- this._rendererQueue.clear();
178
-
179
- // Invalidate suspense cache if profiling data is being (re-)recorded.
180
- // Note that we clear now because any existing data is "stale".
181
- this._cache.invalidate();
182
-
183
- this.emit('profilingData');
184
- }
185
-
186
- startProfiling(): void {
187
- this._bridge.send('startProfiling', this._store.recordChangeDescriptions);
188
-
189
- // Don't actually update the local profiling boolean yet!
190
- // Wait for onProfilingStatus() to confirm the status has changed.
191
- // This ensures the frontend and backend are in sync wrt which commits were profiled.
192
- // We do this to avoid mismatches on e.g. CommitTreeBuilder that would cause errors.
193
- }
194
-
195
- stopProfiling(): void {
196
- this._bridge.send('stopProfiling');
197
-
198
- // Don't actually update the local profiling boolean yet!
199
- // Wait for onProfilingStatus() to confirm the status has changed.
200
- // This ensures the frontend and backend are in sync wrt which commits were profiled.
201
- // We do this to avoid mismatches on e.g. CommitTreeBuilder that would cause errors.
202
- }
203
-
204
- _takeProfilingSnapshotRecursive = (
205
- elementID: number,
206
- profilingSnapshots: Map<number, SnapshotNode>,
207
- ) => {
208
- const element = this._store.getElementByID(elementID);
209
- if (element !== null) {
210
- const snapshotNode: SnapshotNode = {
211
- id: elementID,
212
- children: element.children.slice(0),
213
- displayName: element.displayName,
214
- key: element.key,
215
- type: element.type,
216
- };
217
- profilingSnapshots.set(elementID, snapshotNode);
218
-
219
- element.children.forEach(childID =>
220
- this._takeProfilingSnapshotRecursive(childID, profilingSnapshots),
221
- );
222
- }
223
- };
224
-
225
- onBridgeOperations = (operations: Array<number>) => {
226
- // The first two values are always rendererID and rootID
227
- const rendererID = operations[0];
228
- const rootID = operations[1];
229
-
230
- if (this._isProfiling) {
231
- let profilingOperations = this._inProgressOperationsByRootID.get(rootID);
232
- if (profilingOperations == null) {
233
- profilingOperations = [operations];
234
- this._inProgressOperationsByRootID.set(rootID, profilingOperations);
235
- } else {
236
- profilingOperations.push(operations);
237
- }
238
-
239
- if (!this._initialRendererIDs.has(rendererID)) {
240
- this._initialRendererIDs.add(rendererID);
241
- }
242
-
243
- if (!this._initialSnapshotsByRootID.has(rootID)) {
244
- this._initialSnapshotsByRootID.set(rootID, new Map());
245
- }
246
-
247
- this._rendererIDsThatReportedProfilingData.add(rendererID);
248
- }
249
- };
250
-
251
- onBridgeProfilingData = (dataBackend: ProfilingDataBackend) => {
252
- if (this._isProfiling) {
253
- // This should never happen, but if it does- ignore previous profiling data.
254
- return;
255
- }
256
-
257
- const {rendererID} = dataBackend;
258
-
259
- if (!this._rendererQueue.has(rendererID)) {
260
- throw Error(
261
- `Unexpected profiling data update from renderer "${rendererID}"`,
262
- );
263
- }
264
-
265
- this._dataBackends.push(dataBackend);
266
- this._rendererQueue.delete(rendererID);
267
-
268
- if (this._rendererQueue.size === 0) {
269
- this._dataFrontend = prepareProfilingDataFrontendFromBackendAndStore(
270
- this._dataBackends,
271
- this._inProgressOperationsByRootID,
272
- this._initialSnapshotsByRootID,
273
- );
274
-
275
- this._dataBackends.splice(0);
276
-
277
- this.emit('isProcessingData');
278
- }
279
- };
280
-
281
- onBridgeShutdown = () => {
282
- this._bridge.removeListener('operations', this.onBridgeOperations);
283
- this._bridge.removeListener('profilingData', this.onBridgeProfilingData);
284
- this._bridge.removeListener('profilingStatus', this.onProfilingStatus);
285
- this._bridge.removeListener('shutdown', this.onBridgeShutdown);
286
- };
287
-
288
- onProfilingStatus = (isProfiling: boolean) => {
289
- if (isProfiling) {
290
- this._dataBackends.splice(0);
291
- this._dataFrontend = null;
292
- this._initialRendererIDs.clear();
293
- this._initialSnapshotsByRootID.clear();
294
- this._inProgressOperationsByRootID.clear();
295
- this._rendererIDsThatReportedProfilingData.clear();
296
- this._rendererQueue.clear();
297
-
298
- // Record all renderer IDs initially too (in case of unmount)
299
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
300
- for (let rendererID of this._store.rootIDToRendererID.values()) {
301
- if (!this._initialRendererIDs.has(rendererID)) {
302
- this._initialRendererIDs.add(rendererID);
303
- }
304
- }
305
-
306
- // Record snapshot of tree at the time profiling is started.
307
- // This info is required to handle cases of e.g. nodes being removed during profiling.
308
- this._store.roots.forEach(rootID => {
309
- const profilingSnapshots = new Map();
310
- this._initialSnapshotsByRootID.set(rootID, profilingSnapshots);
311
- this._takeProfilingSnapshotRecursive(rootID, profilingSnapshots);
312
- });
313
- }
314
-
315
- if (this._isProfiling !== isProfiling) {
316
- this._isProfiling = isProfiling;
317
-
318
- // Invalidate suspense cache if profiling data is being (re-)recorded.
319
- // Note that we clear again, in case any views read from the cache while profiling.
320
- // (That would have resolved a now-stale value without any profiling data.)
321
- this._cache.invalidate();
322
-
323
- this.emit('isProfiling');
324
-
325
- // If we've just finished a profiling session, we need to fetch data stored in each renderer interface
326
- // and re-assemble it on the front-end into a format (ProfilingDataFrontend) that can power the Profiler UI.
327
- // During this time, DevTools UI should probably not be interactive.
328
- if (!isProfiling) {
329
- this._dataBackends.splice(0);
330
- this._rendererQueue.clear();
331
-
332
- // Only request data from renderers that actually logged it.
333
- // This avoids unnecessary bridge requests and also avoids edge case mixed renderer bugs.
334
- // (e.g. when v15 and v16 are both present)
335
- this._rendererIDsThatReportedProfilingData.forEach(rendererID => {
336
- if (!this._rendererQueue.has(rendererID)) {
337
- this._rendererQueue.add(rendererID);
338
-
339
- this._bridge.send('getProfilingData', {rendererID});
340
- }
341
- });
342
-
343
- this.emit('isProcessingData');
344
- }
345
- }
346
- };
347
-}
packages/react-devtools-shared/src/devtools/ProfilingCache.js
deleted
-129
@@ -1,129 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import ProfilerStore from './ProfilerStore';
11
-import {
12
- getCommitTree,
13
- invalidateCommitTrees,
14
-} from 'react-devtools-shared/src/devtools/views/Profiler/CommitTreeBuilder';
15
-import {
16
- getChartData as getFlamegraphChartData,
17
- invalidateChartData as invalidateFlamegraphChartData,
18
-} from 'react-devtools-shared/src/devtools/views/Profiler/FlamegraphChartBuilder';
19
-import {
20
- getChartData as getInteractionsChartData,
21
- invalidateChartData as invalidateInteractionsChartData,
22
-} from 'react-devtools-shared/src/devtools/views/Profiler/InteractionsChartBuilder';
23
-import {
24
- getChartData as getRankedChartData,
25
- invalidateChartData as invalidateRankedChartData,
26
-} from 'react-devtools-shared/src/devtools/views/Profiler/RankedChartBuilder';
27
-
28
-import type {CommitTree} from 'react-devtools-shared/src/devtools/views/Profiler/types';
29
-import type {ChartData as FlamegraphChartData} from 'react-devtools-shared/src/devtools/views/Profiler/FlamegraphChartBuilder';
30
-import type {ChartData as InteractionsChartData} from 'react-devtools-shared/src/devtools/views/Profiler/InteractionsChartBuilder';
31
-import type {ChartData as RankedChartData} from 'react-devtools-shared/src/devtools/views/Profiler/RankedChartBuilder';
32
-
33
-export default class ProfilingCache {
34
- _fiberCommits: Map<number, Array<number>> = new Map();
35
- _profilerStore: ProfilerStore;
36
-
37
- constructor(profilerStore: ProfilerStore) {
38
- this._profilerStore = profilerStore;
39
- }
40
-
41
- getCommitTree = ({
42
- commitIndex,
43
- rootID,
44
- }: {|
45
- commitIndex: number,
46
- rootID: number,
47
- |}) =>
48
- getCommitTree({
49
- commitIndex,
50
- profilerStore: this._profilerStore,
51
- rootID,
52
- });
53
-
54
- getFiberCommits = ({
55
- fiberID,
56
- rootID,
57
- }: {|
58
- fiberID: number,
59
- rootID: number,
60
- |}): Array<number> => {
61
- const cachedFiberCommits = this._fiberCommits.get(fiberID);
62
- if (cachedFiberCommits != null) {
63
- return cachedFiberCommits;
64
- }
65
-
66
- const fiberCommits = [];
67
- const dataForRoot = this._profilerStore.getDataForRoot(rootID);
68
- dataForRoot.commitData.forEach((commitDatum, commitIndex) => {
69
- if (commitDatum.fiberActualDurations.has(fiberID)) {
70
- fiberCommits.push(commitIndex);
71
- }
72
- });
73
-
74
- this._fiberCommits.set(fiberID, fiberCommits);
75
-
76
- return fiberCommits;
77
- };
78
-
79
- getFlamegraphChartData = ({
80
- commitIndex,
81
- commitTree,
82
- rootID,
83
- }: {|
84
- commitIndex: number,
85
- commitTree: CommitTree,
86
- rootID: number,
87
- |}): FlamegraphChartData =>
88
- getFlamegraphChartData({
89
- commitIndex,
90
- commitTree,
91
- profilerStore: this._profilerStore,
92
- rootID,
93
- });
94
-
95
- getInteractionsChartData = ({
96
- rootID,
97
- }: {|
98
- rootID: number,
99
- |}): InteractionsChartData =>
100
- getInteractionsChartData({
101
- profilerStore: this._profilerStore,
102
- rootID,
103
- });
104
-
105
- getRankedChartData = ({
106
- commitIndex,
107
- commitTree,
108
- rootID,
109
- }: {|
110
- commitIndex: number,
111
- commitTree: CommitTree,
112
- rootID: number,
113
- |}): RankedChartData =>
114
- getRankedChartData({
115
- commitIndex,
116
- commitTree,
117
- profilerStore: this._profilerStore,
118
- rootID,
119
- });
120
-
121
- invalidate() {
122
- this._fiberCommits.clear();
123
-
124
- invalidateCommitTrees();
125
- invalidateFlamegraphChartData();
126
- invalidateInteractionsChartData();
127
- invalidateRankedChartData();
128
- }
129
-}
packages/react-devtools-shared/src/devtools/cache.js
deleted
-203
@@ -1,203 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {createContext} from 'react';
11
-
12
-// Cache implementation was forked from the React repo:
13
-// https://github.com/facebook/react/blob/master/packages/react-cache/src/ReactCache.js
14
-//
15
-// This cache is simpler than react-cache in that:
16
-// 1. Individual items don't need to be invalidated.
17
-// Profiling data is invalidated as a whole.
18
-// 2. We didn't need the added overhead of an LRU cache.
19
-// The size of this cache is bounded by how many renders were profiled,
20
-// and it will be fully reset between profiling sessions.
21
-
22
-export type Thenable<T> = {
23
- then(resolve: (T) => mixed, reject: (mixed) => mixed): mixed,
24
-};
25
-
26
-type Suspender = {
27
- then(resolve: () => mixed, reject: () => mixed): mixed,
28
-};
29
-
30
-type PendingResult = {|
31
- status: 0,
32
- value: Suspender,
33
-|};
34
-
35
-type ResolvedResult<Value> = {|
36
- status: 1,
37
- value: Value,
38
-|};
39
-
40
-type RejectedResult = {|
41
- status: 2,
42
- value: mixed,
43
-|};
44
-
45
-type Result<Value> = PendingResult | ResolvedResult<Value> | RejectedResult;
46
-
47
-export type Resource<Input, Key, Value> = {
48
- clear(): void,
49
- invalidate(Key): void,
50
- read(Input): Value,
51
- preload(Input): void,
52
- write(Key, Value): void,
53
-};
54
-
55
-const Pending = 0;
56
-const Resolved = 1;
57
-const Rejected = 2;
58
-
59
-const ReactCurrentDispatcher = (React: any)
60
- .__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher;
61
-
62
-function readContext(Context, observedBits) {
63
- const dispatcher = ReactCurrentDispatcher.current;
64
- if (dispatcher === null) {
65
- throw new Error(
66
- 'react-cache: read and preload may only be called from within a ' +
67
- "component's render. They are not supported in event handlers or " +
68
- 'lifecycle methods.',
69
- );
70
- }
71
- return dispatcher.readContext(Context, observedBits);
72
-}
73
-
74
-const CacheContext = createContext(null);
75
-
76
-type Config = {
77
- useWeakMap?: boolean,
78
-};
79
-
80
-const entries: Map<
81
- Resource<any, any, any>,
82
- Map<any, any> | WeakMap<any, any>,
83
-> = new Map();
84
-const resourceConfigs: Map<Resource<any, any, any>, Config> = new Map();
85
-
86
-function getEntriesForResource(
87
- resource: any,
88
-): Map<any, any> | WeakMap<any, any> {
89
- let entriesForResource = ((entries.get(resource): any): Map<any, any>);
90
- if (entriesForResource === undefined) {
91
- const config = resourceConfigs.get(resource);
92
- entriesForResource =
93
- config !== undefined && config.useWeakMap ? new WeakMap() : new Map();
94
- entries.set(resource, entriesForResource);
95
- }
96
- return entriesForResource;
97
-}
98
-
99
-function accessResult<Input, Key, Value>(
100
- resource: any,
101
- fetch: Input => Thenable<Value>,
102
- input: Input,
103
- key: Key,
104
-): Result<Value> {
105
- const entriesForResource = getEntriesForResource(resource);
106
- const entry = entriesForResource.get(key);
107
- if (entry === undefined) {
108
- const thenable = fetch(input);
109
- thenable.then(
110
- value => {
111
- if (newResult.status === Pending) {
112
- const resolvedResult: ResolvedResult<Value> = (newResult: any);
113
- resolvedResult.status = Resolved;
114
- resolvedResult.value = value;
115
- }
116
- },
117
- error => {
118
- if (newResult.status === Pending) {
119
- const rejectedResult: RejectedResult = (newResult: any);
120
- rejectedResult.status = Rejected;
121
- rejectedResult.value = error;
122
- }
123
- },
124
- );
125
- const newResult: PendingResult = {
126
- status: Pending,
127
- value: thenable,
128
- };
129
- entriesForResource.set(key, newResult);
130
- return newResult;
131
- } else {
132
- return entry;
133
- }
134
-}
135
-
136
-export function createResource<Input, Key, Value>(
137
- fetch: Input => Thenable<Value>,
138
- hashInput: Input => Key,
139
- config?: Config = {},
140
-): Resource<Input, Key, Value> {
141
- const resource = {
142
- clear(): void {
143
- entries.delete(resource);
144
- },
145
-
146
- invalidate(key: Key): void {
147
- const entriesForResource = getEntriesForResource(resource);
148
- entriesForResource.delete(key);
149
- },
150
-
151
- read(input: Input): Value {
152
- // Prevent access outside of render.
153
- readContext(CacheContext);
154
-
155
- const key = hashInput(input);
156
- const result: Result<Value> = accessResult(resource, fetch, input, key);
157
- switch (result.status) {
158
- case Pending: {
159
- const suspender = result.value;
160
- throw suspender;
161
- }
162
- case Resolved: {
163
- const value = result.value;
164
- return value;
165
- }
166
- case Rejected: {
167
- const error = result.value;
168
- throw error;
169
- }
170
- default:
171
- // Should be unreachable
172
- return (undefined: any);
173
- }
174
- },
175
-
176
- preload(input: Input): void {
177
- // Prevent access outside of render.
178
- readContext(CacheContext);
179
-
180
- const key = hashInput(input);
181
- accessResult(resource, fetch, input, key);
182
- },
183
-
184
- write(key: Key, value: Value): void {
185
- const entriesForResource = getEntriesForResource(resource);
186
-
187
- const resolvedResult: ResolvedResult<Value> = {
188
- status: Resolved,
189
- value,
190
- };
191
-
192
- entriesForResource.set(key, resolvedResult);
193
- },
194
- };
195
-
196
- resourceConfigs.set(resource, config);
197
-
198
- return resource;
199
-}
200
-
201
-export function invalidateResources(): void {
202
- entries.clear();
203
-}
packages/react-devtools-shared/src/devtools/index.js
deleted
-21
@@ -1,21 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
11
-
12
-type Shell = {|
13
- connect: (callback: Function) => void,
14
- onReload: (reloadFn: Function) => void,
15
-|};
16
-
17
-export function initDevTools(shell: Shell) {
18
- shell.connect((bridge: FrontendBridge) => {
19
- // TODO ...
20
- });
21
-}
packages/react-devtools-shared/src/devtools/store.js
deleted
-1012
@@ -1,1012 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import EventEmitter from 'events';
11
-import {inspect} from 'util';
12
-import {
13
- TREE_OPERATION_ADD,
14
- TREE_OPERATION_REMOVE,
15
- TREE_OPERATION_REORDER_CHILDREN,
16
- TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
17
-} from '../constants';
18
-import {ElementTypeRoot} from '../types';
19
-import {
20
- getSavedComponentFilters,
21
- saveComponentFilters,
22
- separateDisplayNameAndHOCs,
23
- shallowDiffers,
24
- utfDecodeString,
25
-} from '../utils';
26
-import {localStorageGetItem, localStorageSetItem} from '../storage';
27
-import {__DEBUG__} from '../constants';
28
-import {printStore} from './utils';
29
-import ProfilerStore from './ProfilerStore';
30
-
31
-import type {Element} from './views/Components/types';
32
-import type {ComponentFilter, ElementType} from '../types';
33
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
34
-
35
-const debug = (methodName, ...args) => {
36
- if (__DEBUG__) {
37
- console.log(
38
- `%cStore %c${methodName}`,
39
- 'color: green; font-weight: bold;',
40
- 'font-weight: bold;',
41
- ...args,
42
- );
43
- }
44
-};
45
-
46
-const LOCAL_STORAGE_COLLAPSE_ROOTS_BY_DEFAULT_KEY =
47
- 'React::DevTools::collapseNodesByDefault';
48
-const LOCAL_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY =
49
- 'React::DevTools::recordChangeDescriptions';
50
-
51
-type Config = {|
52
- isProfiling?: boolean,
53
- supportsNativeInspection?: boolean,
54
- supportsReloadAndProfile?: boolean,
55
- supportsProfiling?: boolean,
56
-|};
57
-
58
-export type Capabilities = {|
59
- hasOwnerMetadata: boolean,
60
- supportsProfiling: boolean,
61
-|};
62
-
63
-/**
64
- * The store is the single source of truth for updates from the backend.
65
- * ContextProviders can subscribe to the Store for specific things they want to provide.
66
- */
67
-export default class Store extends EventEmitter<{|
68
- collapseNodesByDefault: [],
69
- componentFilters: [],
70
- mutated: [[Array<number>, Map<number, number>]],
71
- recordChangeDescriptions: [],
72
- roots: [],
73
- supportsNativeStyleEditor: [],
74
- supportsProfiling: [],
75
- supportsReloadAndProfile: [],
76
-|}> {
77
- _bridge: FrontendBridge;
78
-
79
- // Should new nodes be collapsed by default when added to the tree?
80
- _collapseNodesByDefault: boolean = true;
81
-
82
- _componentFilters: Array<ComponentFilter>;
83
-
84
- // At least one of the injected renderers contains (DEV only) owner metadata.
85
- _hasOwnerMetadata: boolean = false;
86
-
87
- // Map of ID to (mutable) Element.
88
- // Elements are mutated to avoid excessive cloning during tree updates.
89
- // The InspectedElementContext also relies on this mutability for its WeakMap usage.
90
- _idToElement: Map<number, Element> = new Map();
91
-
92
- // Should the React Native style editor panel be shown?
93
- _isNativeStyleEditorSupported: boolean = false;
94
-
95
- // Can the backend use the Storage API (e.g. localStorage)?
96
- // If not, features like reload-and-profile will not work correctly and must be disabled.
97
- _isBackendStorageAPISupported: boolean = false;
98
-
99
- _nativeStyleEditorValidAttributes: $ReadOnlyArray<string> | null = null;
100
-
101
- // Map of element (id) to the set of elements (ids) it owns.
102
- // This map enables getOwnersListForElement() to avoid traversing the entire tree.
103
- _ownersMap: Map<number, Set<number>> = new Map();
104
-
105
- _profilerStore: ProfilerStore;
106
-
107
- _recordChangeDescriptions: boolean = false;
108
-
109
- // Incremented each time the store is mutated.
110
- // This enables a passive effect to detect a mutation between render and commit phase.
111
- _revision: number = 0;
112
-
113
- // This Array must be treated as immutable!
114
- // Passive effects will check it for changes between render and mount.
115
- _roots: $ReadOnlyArray<number> = [];
116
-
117
- _rootIDToCapabilities: Map<number, Capabilities> = new Map();
118
-
119
- // Renderer ID is needed to support inspection fiber props, state, and hooks.
120
- _rootIDToRendererID: Map<number, number> = new Map();
121
-
122
- // These options may be initially set by a confiugraiton option when constructing the Store.
123
- // In the case of "supportsProfiling", the option may be updated based on the injected renderers.
124
- _supportsNativeInspection: boolean = true;
125
- _supportsProfiling: boolean = false;
126
- _supportsReloadAndProfile: boolean = false;
127
-
128
- // Total number of visible elements (within all roots).
129
- // Used for windowing purposes.
130
- _weightAcrossRoots: number = 0;
131
-
132
- constructor(bridge: FrontendBridge, config?: Config) {
133
- super();
134
-
135
- if (__DEBUG__) {
136
- debug('constructor', 'subscribing to Bridge');
137
- }
138
-
139
- this._collapseNodesByDefault =
140
- localStorageGetItem(LOCAL_STORAGE_COLLAPSE_ROOTS_BY_DEFAULT_KEY) ===
141
- 'true';
142
-
143
- this._recordChangeDescriptions =
144
- localStorageGetItem(LOCAL_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY) ===
145
- 'true';
146
-
147
- this._componentFilters = getSavedComponentFilters();
148
-
149
- let isProfiling = false;
150
- if (config != null) {
151
- isProfiling = config.isProfiling === true;
152
-
153
- const {
154
- supportsNativeInspection,
155
- supportsProfiling,
156
- supportsReloadAndProfile,
157
- } = config;
158
- this._supportsNativeInspection = supportsNativeInspection !== false;
159
- if (supportsProfiling) {
160
- this._supportsProfiling = true;
161
- }
162
- if (supportsReloadAndProfile) {
163
- this._supportsReloadAndProfile = true;
164
- }
165
- }
166
-
167
- this._bridge = bridge;
168
- bridge.addListener('operations', this.onBridgeOperations);
169
- bridge.addListener(
170
- 'overrideComponentFilters',
171
- this.onBridgeOverrideComponentFilters,
172
- );
173
- bridge.addListener('shutdown', this.onBridgeShutdown);
174
- bridge.addListener(
175
- 'isBackendStorageAPISupported',
176
- this.onBridgeStorageSupported,
177
- );
178
- bridge.addListener(
179
- 'isNativeStyleEditorSupported',
180
- this.onBridgeNativeStyleEditorSupported,
181
- );
182
-
183
- this._profilerStore = new ProfilerStore(bridge, this, isProfiling);
184
- }
185
-
186
- // This is only used in tests to avoid memory leaks.
187
- assertExpectedRootMapSizes() {
188
- if (this.roots.length === 0) {
189
- // The only safe time to assert these maps are empty is when the store is empty.
190
- this.assertMapSizeMatchesRootCount(this._idToElement, '_idToElement');
191
- this.assertMapSizeMatchesRootCount(this._ownersMap, '_ownersMap');
192
- }
193
-
194
- // These maps should always be the same size as the number of roots
195
- this.assertMapSizeMatchesRootCount(
196
- this._rootIDToCapabilities,
197
- '_rootIDToCapabilities',
198
- );
199
- this.assertMapSizeMatchesRootCount(
200
- this._rootIDToRendererID,
201
- '_rootIDToRendererID',
202
- );
203
- }
204
-
205
- // This is only used in tests to avoid memory leaks.
206
- assertMapSizeMatchesRootCount(map: Map<any, any>, mapName: string) {
207
- const expectedSize = this.roots.length;
208
- if (map.size !== expectedSize) {
209
- throw new Error(
210
- `Expected ${mapName} to contain ${expectedSize} items, but it contains ${
211
- map.size
212
- } items\n\n${inspect(map, {
213
- depth: 20,
214
- })}`,
215
- );
216
- }
217
- }
218
-
219
- get collapseNodesByDefault(): boolean {
220
- return this._collapseNodesByDefault;
221
- }
222
- set collapseNodesByDefault(value: boolean): void {
223
- this._collapseNodesByDefault = value;
224
-
225
- localStorageSetItem(
226
- LOCAL_STORAGE_COLLAPSE_ROOTS_BY_DEFAULT_KEY,
227
- value ? 'true' : 'false',
228
- );
229
-
230
- this.emit('collapseNodesByDefault');
231
- }
232
-
233
- get componentFilters(): Array<ComponentFilter> {
234
- return this._componentFilters;
235
- }
236
- set componentFilters(value: Array<ComponentFilter>): void {
237
- if (this._profilerStore.isProfiling) {
238
- // Re-mounting a tree while profiling is in progress might break a lot of assumptions.
239
- // If necessary, we could support this- but it doesn't seem like a necessary use case.
240
- throw Error('Cannot modify filter preferences while profiling');
241
- }
242
-
243
- // Filter updates are expensive to apply (since they impact the entire tree).
244
- // Let's determine if they've changed and avoid doing this work if they haven't.
245
- const prevEnabledComponentFilters = this._componentFilters.filter(
246
- filter => filter.isEnabled,
247
- );
248
- const nextEnabledComponentFilters = value.filter(
249
- filter => filter.isEnabled,
250
- );
251
- let haveEnabledFiltersChanged =
252
- prevEnabledComponentFilters.length !== nextEnabledComponentFilters.length;
253
- if (!haveEnabledFiltersChanged) {
254
- for (let i = 0; i < nextEnabledComponentFilters.length; i++) {
255
- const prevFilter = prevEnabledComponentFilters[i];
256
- const nextFilter = nextEnabledComponentFilters[i];
257
- if (shallowDiffers(prevFilter, nextFilter)) {
258
- haveEnabledFiltersChanged = true;
259
- break;
260
- }
261
- }
262
- }
263
-
264
- this._componentFilters = value;
265
-
266
- // Update persisted filter preferences stored in localStorage.
267
- saveComponentFilters(value);
268
-
269
- // Notify the renderer that filter prefernces have changed.
270
- // This is an expensive opreation; it unmounts and remounts the entire tree,
271
- // so only do it if the set of enabled component filters has changed.
272
- if (haveEnabledFiltersChanged) {
273
- this._bridge.send('updateComponentFilters', value);
274
- }
275
-
276
- this.emit('componentFilters');
277
- }
278
-
279
- get hasOwnerMetadata(): boolean {
280
- return this._hasOwnerMetadata;
281
- }
282
-
283
- get nativeStyleEditorValidAttributes(): $ReadOnlyArray<string> | null {
284
- return this._nativeStyleEditorValidAttributes;
285
- }
286
-
287
- get numElements(): number {
288
- return this._weightAcrossRoots;
289
- }
290
-
291
- get profilerStore(): ProfilerStore {
292
- return this._profilerStore;
293
- }
294
-
295
- get recordChangeDescriptions(): boolean {
296
- return this._recordChangeDescriptions;
297
- }
298
- set recordChangeDescriptions(value: boolean): void {
299
- this._recordChangeDescriptions = value;
300
-
301
- localStorageSetItem(
302
- LOCAL_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
303
- value ? 'true' : 'false',
304
- );
305
-
306
- this.emit('recordChangeDescriptions');
307
- }
308
-
309
- get revision(): number {
310
- return this._revision;
311
- }
312
-
313
- get rootIDToRendererID(): Map<number, number> {
314
- return this._rootIDToRendererID;
315
- }
316
-
317
- get roots(): $ReadOnlyArray<number> {
318
- return this._roots;
319
- }
320
-
321
- get supportsNativeInspection(): boolean {
322
- return this._supportsNativeInspection;
323
- }
324
-
325
- get supportsNativeStyleEditor(): boolean {
326
- return this._isNativeStyleEditorSupported;
327
- }
328
-
329
- get supportsProfiling(): boolean {
330
- return this._supportsProfiling;
331
- }
332
-
333
- get supportsReloadAndProfile(): boolean {
334
- // Does the DevTools shell support reloading and eagerly injecting the renderer interface?
335
- // And if so, can the backend use the localStorage API?
336
- // Both of these are required for the reload-and-profile feature to work.
337
- return this._supportsReloadAndProfile && this._isBackendStorageAPISupported;
338
- }
339
-
340
- containsElement(id: number): boolean {
341
- return this._idToElement.get(id) != null;
342
- }
343
-
344
- getElementAtIndex(index: number): Element | null {
345
- if (index < 0 || index >= this.numElements) {
346
- console.warn(
347
- `Invalid index ${index} specified; store contains ${
348
- this.numElements
349
- } items.`,
350
- );
351
-
352
- return null;
353
- }
354
-
355
- // Find wich root this element is in...
356
- let rootID;
357
- let root;
358
- let rootWeight = 0;
359
- for (let i = 0; i < this._roots.length; i++) {
360
- rootID = this._roots[i];
361
- root = ((this._idToElement.get(rootID): any): Element);
362
- if (root.children.length === 0) {
363
- continue;
364
- } else if (rootWeight + root.weight > index) {
365
- break;
366
- } else {
367
- rootWeight += root.weight;
368
- }
369
- }
370
-
371
- // Find the element in the tree using the weight of each node...
372
- // Skip over the root itself, because roots aren't visible in the Elements tree.
373
- let currentElement = ((root: any): Element);
374
- let currentWeight = rootWeight - 1;
375
- while (index !== currentWeight) {
376
- const numChildren = currentElement.children.length;
377
- for (let i = 0; i < numChildren; i++) {
378
- const childID = currentElement.children[i];
379
- const child = ((this._idToElement.get(childID): any): Element);
380
- const childWeight = child.isCollapsed ? 1 : child.weight;
381
-
382
- if (index <= currentWeight + childWeight) {
383
- currentWeight++;
384
- currentElement = child;
385
- break;
386
- } else {
387
- currentWeight += childWeight;
388
- }
389
- }
390
- }
391
-
392
- return ((currentElement: any): Element) || null;
393
- }
394
-
395
- getElementIDAtIndex(index: number): number | null {
396
- const element: Element | null = this.getElementAtIndex(index);
397
- return element === null ? null : element.id;
398
- }
399
-
400
- getElementByID(id: number): Element | null {
401
- const element = this._idToElement.get(id);
402
- if (element == null) {
403
- console.warn(`No element found with id "${id}"`);
404
- return null;
405
- }
406
-
407
- return element;
408
- }
409
-
410
- getIndexOfElementID(id: number): number | null {
411
- const element = this.getElementByID(id);
412
-
413
- if (element === null || element.parentID === 0) {
414
- return null;
415
- }
416
-
417
- // Walk up the tree to the root.
418
- // Increment the index by one for each node we encounter,
419
- // and by the weight of all nodes to the left of the current one.
420
- // This should be a relatively fast way of determining the index of a node within the tree.
421
- let previousID = id;
422
- let currentID = element.parentID;
423
- let index = 0;
424
- while (true) {
425
- const current = ((this._idToElement.get(currentID): any): Element);
426
-
427
- const {children} = current;
428
- for (let i = 0; i < children.length; i++) {
429
- const childID = children[i];
430
- if (childID === previousID) {
431
- break;
432
- }
433
- const child = ((this._idToElement.get(childID): any): Element);
434
- index += child.isCollapsed ? 1 : child.weight;
435
- }
436
-
437
- if (current.parentID === 0) {
438
- // We found the root; stop crawling.
439
- break;
440
- }
441
-
442
- index++;
443
-
444
- previousID = current.id;
445
- currentID = current.parentID;
446
- }
447
-
448
- // At this point, the current ID is a root (from the previous loop).
449
- // We also need to offset the index by previous root weights.
450
- for (let i = 0; i < this._roots.length; i++) {
451
- const rootID = this._roots[i];
452
- if (rootID === currentID) {
453
- break;
454
- }
455
- const root = ((this._idToElement.get(rootID): any): Element);
456
- index += root.weight;
457
- }
458
-
459
- return index;
460
- }
461
-
462
- getOwnersListForElement(ownerID: number): Array<Element> {
463
- const list = [];
464
- let element = this._idToElement.get(ownerID);
465
- if (element != null) {
466
- list.push({
467
- ...element,
468
- depth: 0,
469
- });
470
-
471
- const unsortedIDs = this._ownersMap.get(ownerID);
472
- if (unsortedIDs !== undefined) {
473
- const depthMap: Map<number, number> = new Map([[ownerID, 0]]);
474
-
475
- // Items in a set are ordered based on insertion.
476
- // This does not correlate with their order in the tree.
477
- // So first we need to order them.
478
- // I wish we could avoid this sorting operation; we could sort at insertion time,
479
- // but then we'd have to pay sorting costs even if the owners list was never used.
480
- // Seems better to defer the cost, since the set of ids is probably pretty small.
481
- const sortedIDs = Array.from(unsortedIDs).sort(
482
- (idA, idB) =>
483
- ((this.getIndexOfElementID(idA): any): number) -
484
- ((this.getIndexOfElementID(idB): any): number),
485
- );
486
-
487
- // Next we need to determine the appropriate depth for each element in the list.
488
- // The depth in the list may not correspond to the depth in the tree,
489
- // because the list has been filtered to remove intermediate components.
490
- // Perhaps the easiest way to do this is to walk up the tree until we reach either:
491
- // (1) another node that's already in the tree, or (2) the root (owner)
492
- // at which point, our depth is just the depth of that node plus one.
493
- sortedIDs.forEach(id => {
494
- const innerElement = this._idToElement.get(id);
495
- if (innerElement != null) {
496
- let parentID = innerElement.parentID;
497
-
498
- let depth = 0;
499
- while (parentID > 0) {
500
- if (parentID === ownerID || unsortedIDs.has(parentID)) {
501
- depth = depthMap.get(parentID) + 1;
502
- depthMap.set(id, depth);
503
- break;
504
- }
505
- const parent = this._idToElement.get(parentID);
506
- if (parent == null) {
507
- break;
508
- }
509
- parentID = parent.parentID;
510
- }
511
-
512
- if (depth === 0) {
513
- throw Error('Invalid owners list');
514
- }
515
-
516
- list.push({...innerElement, depth});
517
- }
518
- });
519
- }
520
- }
521
-
522
- return list;
523
- }
524
-
525
- getRendererIDForElement(id: number): number | null {
526
- let current = this._idToElement.get(id);
527
- while (current != null) {
528
- if (current.parentID === 0) {
529
- const rendererID = this._rootIDToRendererID.get(current.id);
530
- return rendererID == null ? null : rendererID;
531
- } else {
532
- current = this._idToElement.get(current.parentID);
533
- }
534
- }
535
- return null;
536
- }
537
-
538
- getRootIDForElement(id: number): number | null {
539
- let current = this._idToElement.get(id);
540
- while (current != null) {
541
- if (current.parentID === 0) {
542
- return current.id;
543
- } else {
544
- current = this._idToElement.get(current.parentID);
545
- }
546
- }
547
- return null;
548
- }
549
-
550
- isInsideCollapsedSubTree(id: number): boolean {
551
- let current = this._idToElement.get(id);
552
- while (current != null) {
553
- if (current.parentID === 0) {
554
- return false;
555
- } else {
556
- current = this._idToElement.get(current.parentID);
557
- if (current != null && current.isCollapsed) {
558
- return true;
559
- }
560
- }
561
- }
562
- return false;
563
- }
564
-
565
- // TODO Maybe split this into two methods: expand() and collapse()
566
- toggleIsCollapsed(id: number, isCollapsed: boolean): void {
567
- let didMutate = false;
568
-
569
- const element = this.getElementByID(id);
570
- if (element !== null) {
571
- if (isCollapsed) {
572
- if (element.type === ElementTypeRoot) {
573
- throw Error('Root nodes cannot be collapsed');
574
- }
575
-
576
- if (!element.isCollapsed) {
577
- didMutate = true;
578
- element.isCollapsed = true;
579
-
580
- const weightDelta = 1 - element.weight;
581
-
582
- let parentElement = ((this._idToElement.get(
583
- element.parentID,
584
- ): any): Element);
585
- while (parentElement != null) {
586
- // We don't need to break on a collapsed parent in the same way as the expand case below.
587
- // That's because collapsing a node doesn't "bubble" and affect its parents.
588
- parentElement.weight += weightDelta;
589
- parentElement = this._idToElement.get(parentElement.parentID);
590
- }
591
- }
592
- } else {
593
- let currentElement = element;
594
- while (currentElement != null) {
595
- const oldWeight = currentElement.isCollapsed
596
- ? 1
597
- : currentElement.weight;
598
-
599
- if (currentElement.isCollapsed) {
600
- didMutate = true;
601
- currentElement.isCollapsed = false;
602
-
603
- const newWeight = currentElement.isCollapsed
604
- ? 1
605
- : currentElement.weight;
606
- const weightDelta = newWeight - oldWeight;
607
-
608
- let parentElement = ((this._idToElement.get(
609
- currentElement.parentID,
610
- ): any): Element);
611
- while (parentElement != null) {
612
- parentElement.weight += weightDelta;
613
- if (parentElement.isCollapsed) {
614
- // It's important to break on a collapsed parent when expanding nodes.
615
- // That's because expanding a node "bubbles" up and expands all parents as well.
616
- // Breaking in this case prevents us from over-incrementing the expanded weights.
617
- break;
618
- }
619
- parentElement = this._idToElement.get(parentElement.parentID);
620
- }
621
- }
622
-
623
- currentElement =
624
- currentElement.parentID !== 0
625
- ? this.getElementByID(currentElement.parentID)
626
- : null;
627
- }
628
- }
629
-
630
- // Only re-calculate weights and emit an "update" event if the store was mutated.
631
- if (didMutate) {
632
- let weightAcrossRoots = 0;
633
- this._roots.forEach(rootID => {
634
- const {weight} = ((this.getElementByID(rootID): any): Element);
635
- weightAcrossRoots += weight;
636
- });
637
- this._weightAcrossRoots = weightAcrossRoots;
638
-
639
- // The Tree context's search reducer expects an explicit list of ids for nodes that were added or removed.
640
- // In this case, we can pass it empty arrays since nodes in a collapsed tree are still there (just hidden).
641
- // Updating the selected search index later may require auto-expanding a collapsed subtree though.
642
- this.emit('mutated', [[], new Map()]);
643
- }
644
- }
645
- }
646
-
647
- _adjustParentTreeWeight = (
648
- parentElement: Element | null,
649
- weightDelta: number,
650
- ) => {
651
- let isInsideCollapsedSubTree = false;
652
-
653
- while (parentElement != null) {
654
- parentElement.weight += weightDelta;
655
-
656
- // Additions and deletions within a collapsed subtree should not bubble beyond the collapsed parent.
657
- // Their weight will bubble up when the parent is expanded.
658
- if (parentElement.isCollapsed) {
659
- isInsideCollapsedSubTree = true;
660
- break;
661
- }
662
-
663
- parentElement = ((this._idToElement.get(
664
- parentElement.parentID,
665
- ): any): Element);
666
- }
667
-
668
- // Additions and deletions within a collapsed subtree should not affect the overall number of elements.
669
- if (!isInsideCollapsedSubTree) {
670
- this._weightAcrossRoots += weightDelta;
671
- }
672
- };
673
-
674
- onBridgeNativeStyleEditorSupported = ({
675
- isSupported,
676
- validAttributes,
677
- }: {|
678
- isSupported: boolean,
679
- validAttributes: ?$ReadOnlyArray<string>,
680
- |}) => {
681
- this._isNativeStyleEditorSupported = isSupported;
682
- this._nativeStyleEditorValidAttributes = validAttributes || null;
683
-
684
- this.emit('supportsNativeStyleEditor');
685
- };
686
-
687
- onBridgeOperations = (operations: Array<number>) => {
688
- if (__DEBUG__) {
689
- console.groupCollapsed('onBridgeOperations');
690
- debug('onBridgeOperations', operations.join(','));
691
- }
692
-
693
- let haveRootsChanged = false;
694
-
695
- // The first two values are always rendererID and rootID
696
- const rendererID = operations[0];
697
-
698
- const addedElementIDs: Array<number> = [];
699
- // This is a mapping of removed ID -> parent ID:
700
- const removedElementIDs: Map<number, number> = new Map();
701
- // We'll use the parent ID to adjust selection if it gets deleted.
702
-
703
- let i = 2;
704
-
705
- // Reassemble the string table.
706
- const stringTable = [
707
- null, // ID = 0 corresponds to the null string.
708
- ];
709
- const stringTableSize = operations[i++];
710
- const stringTableEnd = i + stringTableSize;
711
- while (i < stringTableEnd) {
712
- const nextLength = operations[i++];
713
- const nextString = utfDecodeString(
714
- (operations.slice(i, i + nextLength): any),
715
- );
716
- stringTable.push(nextString);
717
- i += nextLength;
718
- }
719
-
720
- while (i < operations.length) {
721
- const operation = operations[i];
722
- switch (operation) {
723
- case TREE_OPERATION_ADD: {
724
- const id = ((operations[i + 1]: any): number);
725
- const type = ((operations[i + 2]: any): ElementType);
726
-
727
- i += 3;
728
-
729
- if (this._idToElement.has(id)) {
730
- throw Error(
731
- `Cannot add node ${id} because a node with that id is already in the Store.`,
732
- );
733
- }
734
-
735
- let ownerID: number = 0;
736
- let parentID: number = ((null: any): number);
737
- if (type === ElementTypeRoot) {
738
- if (__DEBUG__) {
739
- debug('Add', `new root node ${id}`);
740
- }
741
-
742
- const supportsProfiling = operations[i] > 0;
743
- i++;
744
-
745
- const hasOwnerMetadata = operations[i] > 0;
746
- i++;
747
-
748
- this._roots = this._roots.concat(id);
749
- this._rootIDToRendererID.set(id, rendererID);
750
- this._rootIDToCapabilities.set(id, {
751
- hasOwnerMetadata,
752
- supportsProfiling,
753
- });
754
-
755
- this._idToElement.set(id, {
756
- children: [],
757
- depth: -1,
758
- displayName: null,
759
- hocDisplayNames: null,
760
- id,
761
- isCollapsed: false, // Never collapse roots; it would hide the entire tree.
762
- key: null,
763
- ownerID: 0,
764
- parentID: 0,
765
- type,
766
- weight: 0,
767
- });
768
-
769
- haveRootsChanged = true;
770
- } else {
771
- parentID = ((operations[i]: any): number);
772
- i++;
773
-
774
- ownerID = ((operations[i]: any): number);
775
- i++;
776
-
777
- const displayNameStringID = operations[i];
778
- const displayName = stringTable[displayNameStringID];
779
- i++;
780
-
781
- const keyStringID = operations[i];
782
- const key = stringTable[keyStringID];
783
- i++;
784
-
785
- if (__DEBUG__) {
786
- debug(
787
- 'Add',
788
- `node ${id} (${displayName || 'null'}) as child of ${parentID}`,
789
- );
790
- }
791
-
792
- if (!this._idToElement.has(parentID)) {
793
- throw Error(
794
- `Cannot add child ${id} to parent ${parentID} because parent node was not found in the Store.`,
795
- );
796
- }
797
-
798
- const parentElement = ((this._idToElement.get(
799
- parentID,
800
- ): any): Element);
801
- parentElement.children.push(id);
802
-
803
- const [
804
- displayNameWithoutHOCs,
805
- hocDisplayNames,
806
- ] = separateDisplayNameAndHOCs(displayName, type);
807
-
808
- const element: Element = {
809
- children: [],
810
- depth: parentElement.depth + 1,
811
- displayName: displayNameWithoutHOCs,
812
- hocDisplayNames,
813
- id,
814
- isCollapsed: this._collapseNodesByDefault,
815
- key,
816
- ownerID,
817
- parentID: parentElement.id,
818
- type,
819
- weight: 1,
820
- };
821
-
822
- this._idToElement.set(id, element);
823
- addedElementIDs.push(id);
824
- this._adjustParentTreeWeight(parentElement, 1);
825
-
826
- if (ownerID > 0) {
827
- let set = this._ownersMap.get(ownerID);
828
- if (set === undefined) {
829
- set = new Set();
830
- this._ownersMap.set(ownerID, set);
831
- }
832
- set.add(id);
833
- }
834
- }
835
- break;
836
- }
837
- case TREE_OPERATION_REMOVE: {
838
- const removeLength = ((operations[i + 1]: any): number);
839
- i += 2;
840
-
841
- for (let removeIndex = 0; removeIndex < removeLength; removeIndex++) {
842
- const id = ((operations[i]: any): number);
843
-
844
- if (!this._idToElement.has(id)) {
845
- throw Error(
846
- `Cannot remove node ${id} because no matching node was found in the Store.`,
847
- );
848
- }
849
-
850
- i += 1;
851
-
852
- const element = ((this._idToElement.get(id): any): Element);
853
- const {children, ownerID, parentID, weight} = element;
854
- if (children.length > 0) {
855
- throw new Error(`Node ${id} was removed before its children.`);
856
- }
857
-
858
- this._idToElement.delete(id);
859
-
860
- let parentElement = null;
861
- if (parentID === 0) {
862
- if (__DEBUG__) {
863
- debug('Remove', `node ${id} root`);
864
- }
865
-
866
- this._roots = this._roots.filter(rootID => rootID !== id);
867
- this._rootIDToRendererID.delete(id);
868
- this._rootIDToCapabilities.delete(id);
869
-
870
- haveRootsChanged = true;
871
- } else {
872
- if (__DEBUG__) {
873
- debug('Remove', `node ${id} from parent ${parentID}`);
874
- }
875
- parentElement = ((this._idToElement.get(parentID): any): Element);
876
- if (parentElement === undefined) {
877
- throw Error(
878
- `Cannot remove node ${id} from parent ${parentID} because no matching node was found in the Store.`,
879
- );
880
- }
881
- const index = parentElement.children.indexOf(id);
882
- parentElement.children.splice(index, 1);
883
- }
884
-
885
- this._adjustParentTreeWeight(parentElement, -weight);
886
- removedElementIDs.set(id, parentID);
887
-
888
- this._ownersMap.delete(id);
889
- if (ownerID > 0) {
890
- const set = this._ownersMap.get(ownerID);
891
- if (set !== undefined) {
892
- set.delete(id);
893
- }
894
- }
895
- }
896
- break;
897
- }
898
- case TREE_OPERATION_REORDER_CHILDREN: {
899
- const id = ((operations[i + 1]: any): number);
900
- const numChildren = ((operations[i + 2]: any): number);
901
- i += 3;
902
-
903
- if (!this._idToElement.has(id)) {
904
- throw Error(
905
- `Cannot reorder children for node ${id} because no matching node was found in the Store.`,
906
- );
907
- }
908
-
909
- const element = ((this._idToElement.get(id): any): Element);
910
- const children = element.children;
911
- if (children.length !== numChildren) {
912
- throw Error(
913
- `Children cannot be added or removed during a reorder operation.`,
914
- );
915
- }
916
-
917
- for (let j = 0; j < numChildren; j++) {
918
- const childID = operations[i + j];
919
- children[j] = childID;
920
- if (__DEV__) {
921
- // This check is more expensive so it's gated by __DEV__.
922
- const childElement = this._idToElement.get(childID);
923
- if (childElement == null || childElement.parentID !== id) {
924
- console.error(
925
- `Children cannot be added or removed during a reorder operation.`,
926
- );
927
- }
928
- }
929
- }
930
- i += numChildren;
931
-
932
- if (__DEBUG__) {
933
- debug('Re-order', `Node ${id} children ${children.join(',')}`);
934
- }
935
- break;
936
- }
937
- case TREE_OPERATION_UPDATE_TREE_BASE_DURATION:
938
- // Base duration updates are only sent while profiling is in progress.
939
- // We can ignore them at this point.
940
- // The profiler UI uses them lazily in order to generate the tree.
941
- i += 3;
942
- break;
943
- default:
944
- throw Error(`Unsupported Bridge operation ${operation}`);
945
- }
946
- }
947
-
948
- this._revision++;
949
-
950
- if (haveRootsChanged) {
951
- const prevSupportsProfiling = this._supportsProfiling;
952
-
953
- this._hasOwnerMetadata = false;
954
- this._supportsProfiling = false;
955
- this._rootIDToCapabilities.forEach(
956
- ({hasOwnerMetadata, supportsProfiling}) => {
957
- if (hasOwnerMetadata) {
958
- this._hasOwnerMetadata = true;
959
- }
960
- if (supportsProfiling) {
961
- this._supportsProfiling = true;
962
- }
963
- },
964
- );
965
-
966
- this.emit('roots');
967
-
968
- if (this._supportsProfiling !== prevSupportsProfiling) {
969
- this.emit('supportsProfiling');
970
- }
971
- }
972
-
973
- if (__DEBUG__) {
974
- console.log(printStore(this, true));
975
- console.groupEnd();
976
- }
977
-
978
- this.emit('mutated', [addedElementIDs, removedElementIDs]);
979
- };
980
-
981
- // Certain backends save filters on a per-domain basis.
982
- // In order to prevent filter preferences and applied filters from being out of sync,
983
- // this message enables the backend to override the frontend's current ("saved") filters.
984
- // This action should also override the saved filters too,
985
- // else reloading the frontend without reloading the backend would leave things out of sync.
986
- onBridgeOverrideComponentFilters = (
987
- componentFilters: Array<ComponentFilter>,
988
- ) => {
989
- this._componentFilters = componentFilters;
990
-
991
- saveComponentFilters(componentFilters);
992
- };
993
-
994
- onBridgeShutdown = () => {
995
- if (__DEBUG__) {
996
- debug('onBridgeShutdown', 'unsubscribing from Bridge');
997
- }
998
-
999
- this._bridge.removeListener('operations', this.onBridgeOperations);
1000
- this._bridge.removeListener('shutdown', this.onBridgeShutdown);
1001
- this._bridge.removeListener(
1002
- 'isBackendStorageAPISupported',
1003
- this.onBridgeStorageSupported,
1004
- );
1005
- };
1006
-
1007
- onBridgeStorageSupported = (isBackendStorageAPISupported: boolean) => {
1008
- this._isBackendStorageAPISupported = isBackendStorageAPISupported;
1009
-
1010
- this.emit('supportsReloadAndProfile');
1011
- };
1012
-}
packages/react-devtools-shared/src/devtools/utils.js
deleted
-84
@@ -1,84 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {Element} from './views/Components/types';
11
-import type Store from './store';
12
-
13
-export function printElement(element: Element, includeWeight: boolean = false) {
14
- let prefix = ' ';
15
- if (element.children.length > 0) {
16
- prefix = element.isCollapsed ? '▸' : '▾';
17
- }
18
-
19
- let key = '';
20
- if (element.key !== null) {
21
- key = ` key="${element.key}"`;
22
- }
23
-
24
- let hocs = '';
25
- if (element.hocDisplayNames !== null) {
26
- hocs = ` [${element.hocDisplayNames.join('][')}]`;
27
- }
28
-
29
- let suffix = '';
30
- if (includeWeight) {
31
- suffix = ` (${element.isCollapsed ? 1 : element.weight})`;
32
- }
33
-
34
- return `${' '.repeat(element.depth + 1)}${prefix} <${element.displayName ||
35
- 'null'}${key}>${hocs}${suffix}`;
36
-}
37
-
38
-export function printOwnersList(
39
- elements: Array<Element>,
40
- includeWeight: boolean = false,
41
-) {
42
- return elements
43
- .map(element => printElement(element, includeWeight))
44
- .join('\n');
45
-}
46
-
47
-export function printStore(store: Store, includeWeight: boolean = false) {
48
- const snapshotLines = [];
49
-
50
- let rootWeight = 0;
51
-
52
- store.roots.forEach(rootID => {
53
- const {weight} = ((store.getElementByID(rootID): any): Element);
54
-
55
- snapshotLines.push('[root]' + (includeWeight ? ` (${weight})` : ''));
56
-
57
- for (let i = rootWeight; i < rootWeight + weight; i++) {
58
- const element = store.getElementAtIndex(i);
59
-
60
- if (element == null) {
61
- throw Error(`Could not find element at index ${i}`);
62
- }
63
-
64
- snapshotLines.push(printElement(element, includeWeight));
65
- }
66
-
67
- rootWeight += weight;
68
- });
69
-
70
- // Make sure the pretty-printed test align with the Store's reported number of total rows.
71
- if (rootWeight !== store.numElements) {
72
- throw Error(
73
- `Inconsistent Store state. Individual root weights (${rootWeight}) do not match total weight (${
74
- store.numElements
75
- })`,
76
- );
77
- }
78
-
79
- // If roots have been unmounted, verify that they've been removed from maps.
80
- // This helps ensure the Store doesn't leak memory.
81
- store.assertExpectedRootMapSizes();
82
-
83
- return snapshotLines.join('\n');
84
-}
packages/react-devtools-shared/src/devtools/views/Button.css
deleted
-37
@@ -1,37 +0,0 @@
1
-.Button {
2
- border: none;
3
- background: var(--color-button-background);
4
- color: var(--color-button);
5
- padding: 0;
6
- border-radius: 0.25rem;
7
- flex: 0 0 auto;
8
-}
9
-.ButtonContent {
10
- display: inline-flex;
11
- align-items: center;
12
- border-radius: 0.25rem;
13
- padding: 0.25rem;
14
-}
15
-
16
-.Button:hover {
17
- color: var(--color-button-hover);
18
-}
19
-.Button:active {
20
- color: var(--color-button-focus);
21
- outline: none;
22
-}
23
-.Button:focus,
24
-.ButtonContent:focus {
25
- outline: none;
26
-}
27
-
28
-.Button:focus > .ButtonContent {
29
- background: var(--color-button-background-focus);
30
-}
31
-
32
-.Button:disabled,
33
-.Button:disabled:active {
34
- background: var(--color-button-background);
35
- color: var(--color-button-disabled);
36
- cursor: default;
37
-}
packages/react-devtools-shared/src/devtools/views/Button.js
deleted
-45
@@ -1,45 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-import Tooltip from '@reach/tooltip';
12
-
13
-import styles from './Button.css';
14
-import tooltipStyles from './Tooltip.css';
15
-
16
-type Props = {
17
- children: React$Node,
18
- className?: string,
19
- title?: string,
20
-};
21
-
22
-export default function Button({
23
- children,
24
- className = '',
25
- title = '',
26
- ...rest
27
-}: Props) {
28
- let button = (
29
- <button className={`${styles.Button} ${className}`} {...rest}>
30
- <span className={`${styles.ButtonContent} ${className}`} tabIndex={-1}>
31
- {children}
32
- </span>
33
- </button>
34
- );
35
-
36
- if (title) {
37
- button = (
38
- <Tooltip className={tooltipStyles.Tooltip} label={title}>
39
- {button}
40
- </Tooltip>
41
- );
42
- }
43
-
44
- return button;
45
-}
packages/react-devtools-shared/src/devtools/views/ButtonIcon.css
deleted
-5
@@ -1,5 +0,0 @@
1
-.ButtonIcon {
2
- width: 1rem;
3
- height: 1rem;
4
- fill: currentColor;
5
-}
packages/react-devtools-shared/src/devtools/views/ButtonIcon.js
deleted
-246
@@ -1,246 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-import styles from './ButtonIcon.css';
12
-
13
-export type IconType =
14
- | 'add'
15
- | 'cancel'
16
- | 'clear'
17
- | 'close'
18
- | 'collapsed'
19
- | 'copy'
20
- | 'delete'
21
- | 'down'
22
- | 'expanded'
23
- | 'export'
24
- | 'filter'
25
- | 'import'
26
- | 'log-data'
27
- | 'more'
28
- | 'next'
29
- | 'previous'
30
- | 'record'
31
- | 'reload'
32
- | 'save'
33
- | 'search'
34
- | 'settings'
35
- | 'suspend'
36
- | 'undo'
37
- | 'up'
38
- | 'view-dom'
39
- | 'view-source';
40
-
41
-type Props = {|
42
- className?: string,
43
- type: IconType,
44
-|};
45
-
46
-export default function ButtonIcon({className = '', type}: Props) {
47
- let pathData = null;
48
- switch (type) {
49
- case 'add':
50
- pathData = PATH_ADD;
51
- break;
52
- case 'cancel':
53
- pathData = PATH_CANCEL;
54
- break;
55
- case 'clear':
56
- pathData = PATH_CLEAR;
57
- break;
58
- case 'close':
59
- pathData = PATH_CLOSE;
60
- break;
61
- case 'collapsed':
62
- pathData = PATH_COLLAPSED;
63
- break;
64
- case 'copy':
65
- pathData = PATH_COPY;
66
- break;
67
- case 'delete':
68
- pathData = PATH_DELETE;
69
- break;
70
- case 'down':
71
- pathData = PATH_DOWN;
72
- break;
73
- case 'expanded':
74
- pathData = PATH_EXPANDED;
75
- break;
76
- case 'export':
77
- pathData = PATH_EXPORT;
78
- break;
79
- case 'filter':
80
- pathData = PATH_FILTER;
81
- break;
82
- case 'import':
83
- pathData = PATH_IMPORT;
84
- break;
85
- case 'log-data':
86
- pathData = PATH_LOG_DATA;
87
- break;
88
- case 'more':
89
- pathData = PATH_MORE;
90
- break;
91
- case 'next':
92
- pathData = PATH_NEXT;
93
- break;
94
- case 'previous':
95
- pathData = PATH_PREVIOUS;
96
- break;
97
- case 'record':
98
- pathData = PATH_RECORD;
99
- break;
100
- case 'reload':
101
- pathData = PATH_RELOAD;
102
- break;
103
- case 'save':
104
- pathData = PATH_SAVE;
105
- break;
106
- case 'search':
107
- pathData = PATH_SEARCH;
108
- break;
109
- case 'settings':
110
- pathData = PATH_SETTINGS;
111
- break;
112
- case 'suspend':
113
- pathData = PATH_SUSPEND;
114
- break;
115
- case 'undo':
116
- pathData = PATH_UNDO;
117
- break;
118
- case 'up':
119
- pathData = PATH_UP;
120
- break;
121
- case 'view-dom':
122
- pathData = PATH_VIEW_DOM;
123
- break;
124
- case 'view-source':
125
- pathData = PATH_VIEW_SOURCE;
126
- break;
127
- default:
128
- console.warn(`Unsupported type "${type}" specified for ButtonIcon`);
129
- break;
130
- }
131
-
132
- return (
133
- <svg
134
- xmlns="http://www.w3.org/2000/svg"
135
- className={`${styles.ButtonIcon} ${className}`}
136
- width="24"
137
- height="24"
138
- viewBox="0 0 24 24">
139
- <path d="M0 0h24v24H0z" fill="none" />
140
- <path fill="currentColor" d={pathData} />
141
- </svg>
142
- );
143
-}
144
-
145
-const PATH_ADD =
146
- 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z';
147
-
148
-const PATH_CANCEL = `
149
- M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z
150
-`;
151
-
152
-const PATH_CLEAR = `
153
- M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69
154
- 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z
155
-`;
156
-
157
-const PATH_CLOSE =
158
- 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z';
159
-
160
-const PATH_COLLAPSED = 'M10 17l5-5-5-5v10z';
161
-
162
-const PATH_COPY = `
163
- M3 13h2v-2H3v2zm0 4h2v-2H3v2zm2 4v-2H3a2 2 0 0 0 2 2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-18H9a2 2 0 0 0-2
164
- 2v10a2 2 0 0 0 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12H9V5h10v10zm-8 6h2v-2h-2v2zm-4 0h2v-2H7v2z
165
-`;
166
-
167
-const PATH_DELETE = `
168
- M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12
169
- 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z
170
-`;
171
-
172
-const PATH_DOWN = 'M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z';
173
-
174
-const PATH_EXPANDED = 'M7 10l5 5 5-5z';
175
-
176
-const PATH_EXPORT = 'M15.82,2.14v7H21l-9,9L3,9.18H8.18v-7ZM3,20.13H21v1.73H3Z';
177
-
178
-const PATH_FILTER = 'M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z';
179
-
180
-const PATH_IMPORT = 'M8.18,18.13v-7H3l9-8.95,9,9H15.82v7ZM3,20.13H21v1.73H3Z';
181
-
182
-const PATH_LOG_DATA = `
183
- M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41
184
- 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04
185
- 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6
186
- 8h-4v-2h4v2zm0-4h-4v-2h4v2z
187
-`;
188
-
189
-const PATH_MORE = `
190
- M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9
191
- 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z
192
-`;
193
-
194
-const PATH_NEXT = 'M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z';
195
-
196
-const PATH_PREVIOUS =
197
- 'M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z';
198
-
199
-const PATH_RECORD = 'M4,12a8,8 0 1,0 16,0a8,8 0 1,0 -16,0';
200
-
201
-const PATH_RELOAD = `
202
- M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0
203
- 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0
204
- 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z
205
-`;
206
-
207
-const PATH_SAVE = `
208
- M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z
209
-`;
210
-
211
-const PATH_SEARCH = `
212
- M8.5,22H3.7l-1.4-1.5V3.8l1.3-1.5h17.2l1,1.5v4.9h-1.3V4.3l-0.4-0.6H4.2L3.6,4.3V20l0.7,0.7h4.2V22z
213
- M23,13.9l-4.6,3.6l4.6,4.6l-1.1,1.1l-4.7-4.4l-3.3,4.4l-3.2-12.3L23,13.9z
214
-`;
215
-
216
-const PATH_SETTINGS = `
217
- M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49
218
- 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38
219
- 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11
220
- 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4
221
- 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49
222
- 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5
223
- 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z
224
-`;
225
-
226
-const PATH_SUSPEND = `
227
- M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.03-6.61l1.42-1.42c-.43-.51-.9-.99-1.41-1.41l-1.42 1.42C16.07 4.74 14.12 4 12 4c-4.97
228
- 0-9 4.03-9 9s4.02 9 9 9 9-4.03 9-9c0-2.12-.74-4.07-1.97-5.61zM12 20c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z
229
-`;
230
-
231
-const PATH_UNDO = `
232
- M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88
233
- 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z
234
-`;
235
-
236
-const PATH_UP = 'M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z';
237
-
238
-const PATH_VIEW_DOM = `
239
- M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12
240
- 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3
241
- 3-1.34 3-3-1.34-3-3-3z
242
-`;
243
-
244
-const PATH_VIEW_SOURCE = `
245
- M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z
246
- `;
packages/react-devtools-shared/src/devtools/views/Components/Badge.css
deleted
-17
@@ -1,17 +0,0 @@
1
-.Badge {
2
- display: inline-block;
3
- background-color: var(--color-component-badge-background);
4
- color: var(--color-text);
5
- padding: 0.125rem 0.25rem;
6
- line-height: normal;
7
- border-radius: 0.125rem;
8
- margin-right: 0.25rem;
9
- font-family: var(--font-family-monospace);
10
- font-size: var(--font-size-monospace-small);
11
-}
12
-
13
-.ExtraLabel {
14
- font-family: var(--font-family-monospace);
15
- font-size: var(--font-size-monospace-small);
16
- color: var(--color-component-badge-count);
17
-}
packages/react-devtools-shared/src/devtools/views/Components/Badge.js
deleted
-57
@@ -1,57 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment} from 'react';
11
-import {
12
- ElementTypeMemo,
13
- ElementTypeForwardRef,
14
-} from 'react-devtools-shared/src/types';
15
-import styles from './Badge.css';
16
-
17
-import type {ElementType} from 'react-devtools-shared/src/types';
18
-
19
-type Props = {|
20
- className?: string,
21
- hocDisplayNames: Array<string> | null,
22
- type: ElementType,
23
-|};
24
-
25
-export default function Badge({className, hocDisplayNames, type}: Props) {
26
- let hocDisplayName = null;
27
- let totalBadgeCount = 0;
28
- let typeLabel = null;
29
-
30
- if (hocDisplayNames !== null) {
31
- hocDisplayName = hocDisplayNames[0];
32
- totalBadgeCount += hocDisplayNames.length;
33
- }
34
-
35
- if (type === ElementTypeMemo) {
36
- typeLabel = 'Memo';
37
- totalBadgeCount++;
38
- } else if (type === ElementTypeForwardRef) {
39
- typeLabel = 'ForwardRef';
40
- totalBadgeCount++;
41
- }
42
-
43
- if (hocDisplayNames === null && typeLabel === null) {
44
- return null;
45
- }
46
-
47
- return (
48
- <Fragment>
49
- <div className={`${styles.Badge} ${className || ''}`}>
50
- {hocDisplayName || typeLabel}
51
- </div>
52
- {totalBadgeCount > 1 && (
53
- <div className={styles.ExtraLabel}>+{totalBadgeCount - 1}</div>
54
- )}
55
- </Fragment>
56
- );
57
-}
packages/react-devtools-shared/src/devtools/views/Components/Components.css
deleted
-45
@@ -1,45 +0,0 @@
1
-.Components {
2
- position: relative;
3
- width: 100%;
4
- height: 100%;
5
- display: flex;
6
- flex-direction: row;
7
- background-color: var(--color-background);
8
- color: var(--color-text);
9
- font-family: var(--font-family-sans);
10
-}
11
-
12
-.TreeWrapper {
13
- flex: 0 0 65%;
14
- overflow: auto;
15
-}
16
-
17
-.SelectedElementWrapper {
18
- flex: 0 0 35%;
19
- overflow-x: hidden;
20
- overflow-y: auto;
21
-}
22
-
23
-@media screen and (max-width: 600px) {
24
- .Components {
25
- flex-direction: column;
26
- }
27
-
28
- .TreeWrapper {
29
- flex: 0 0 50%;
30
- }
31
-
32
- .SelectedElementWrapper {
33
- flex: 0 0 50%;
34
- }
35
-}
36
-
37
-.Loading {
38
- height: 100%;
39
- padding-left: 0.5rem;
40
- display: flex;
41
- align-items: center;
42
- justify-content: center;
43
- font-size: var(--font-size-sans-large);
44
- color: var(--color-dim);
45
-}
packages/react-devtools-shared/src/devtools/views/Components/Components.js
deleted
-53
@@ -1,53 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Suspense} from 'react';
11
-import Tree from './Tree';
12
-import SelectedElement from './SelectedElement';
13
-import {InspectedElementContextController} from './InspectedElementContext';
14
-import {NativeStyleContextController} from './NativeStyleEditor/context';
15
-import {OwnersListContextController} from './OwnersListContext';
16
-import portaledContent from '../portaledContent';
17
-import {ModalDialog} from '../ModalDialog';
18
-import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal';
19
-import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext';
20
-
21
-import styles from './Components.css';
22
-
23
-function Components(_: {||}) {
24
- // TODO Flex wrappers below should be user resizable.
25
- return (
26
- <SettingsModalContextController>
27
- <OwnersListContextController>
28
- <InspectedElementContextController>
29
- <div className={styles.Components}>
30
- <div className={styles.TreeWrapper}>
31
- <Tree />
32
- </div>
33
- <div className={styles.SelectedElementWrapper}>
34
- <NativeStyleContextController>
35
- <Suspense fallback={<Loading />}>
36
- <SelectedElement />
37
- </Suspense>
38
- </NativeStyleContextController>
39
- </div>
40
- <ModalDialog />
41
- <SettingsModal />
42
- </div>
43
- </InspectedElementContextController>
44
- </OwnersListContextController>
45
- </SettingsModalContextController>
46
- );
47
-}
48
-
49
-function Loading() {
50
- return <div className={styles.Loading}>Loading...</div>;
51
-}
52
-
53
-export default portaledContent(Components);
packages/react-devtools-shared/src/devtools/views/Components/EditableValue.css
deleted
-30
@@ -1,30 +0,0 @@
1
-.CheckboxLabel {
2
- flex: 1 1 100%;
3
- display: flex;
4
-}
5
-.CheckboxLabel:focus-within {
6
- background-color: var(--color-button-background-focus);
7
-}
8
-
9
-.Checkbox:focus {
10
- outline: none;
11
-}
12
-
13
-.Input {
14
- flex: 1 1;
15
- background: none;
16
- border: 1px solid transparent;
17
- color: var(--color-attribute-editable-value);
18
- border-radius: 0.125rem;
19
- font-family: var(--font-family-monospace);
20
- font-size: var(--font-size-monospace-normal);
21
-}
22
-.Input:focus {
23
- background-color: var(--color-button-background-focus);
24
- outline: none;
25
-}
26
-
27
-.ResetButton {
28
- flex: 0 0 auto;
29
- padding: 0 0.5rem;
30
-}
packages/react-devtools-shared/src/devtools/views/Components/EditableValue.js
deleted
-149
@@ -1,149 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useCallback, useRef, useState} from 'react';
11
-import Button from '../Button';
12
-import ButtonIcon from '../ButtonIcon';
13
-import styles from './EditableValue.css';
14
-
15
-type OverrideValueFn = (path: Array<string | number>, value: any) => void;
16
-
17
-type EditableValueProps = {|
18
- dataType: string,
19
- overrideValueFn: OverrideValueFn,
20
- path: Array<string | number>,
21
- value: any,
22
-|};
23
-
24
-export default function EditableValue({
25
- dataType,
26
- overrideValueFn,
27
- path,
28
- value,
29
-}: EditableValueProps) {
30
- const [hasPendingChanges, setHasPendingChanges] = useState(false);
31
- const [editableValue, setEditableValue] = useState(value);
32
- const inputRef = useRef<HTMLInputElement | null>(null);
33
-
34
- if (hasPendingChanges && editableValue === value) {
35
- setHasPendingChanges(false);
36
- }
37
-
38
- const handleChange = useCallback(
39
- ({target}) => {
40
- if (dataType === 'boolean') {
41
- setEditableValue(target.checked);
42
- overrideValueFn(path, target.checked);
43
- } else {
44
- setEditableValue(target.value);
45
- }
46
- setHasPendingChanges(true);
47
- },
48
- [dataType, overrideValueFn, path],
49
- );
50
-
51
- const handleReset = useCallback(
52
- () => {
53
- setEditableValue(value);
54
- setHasPendingChanges(false);
55
-
56
- if (inputRef.current !== null) {
57
- inputRef.current.focus();
58
- }
59
- },
60
- [value],
61
- );
62
-
63
- const handleKeyDown = useCallback(
64
- event => {
65
- // Prevent keydown events from e.g. change selected element in the tree
66
- event.stopPropagation();
67
-
68
- const {key} = event;
69
-
70
- if (key === 'Enter') {
71
- if (dataType === 'number') {
72
- const parsedValue = parseFloat(editableValue);
73
- if (!Number.isNaN(parsedValue)) {
74
- overrideValueFn(path, parsedValue);
75
- }
76
- } else {
77
- overrideValueFn(path, editableValue);
78
- }
79
-
80
- // Don't reset the pending change flag here.
81
- // The inspected fiber won't be updated until after the next "inspectElement" message.
82
- // We'll reset that flag during a subsequent render.
83
- } else if (key === 'Escape') {
84
- setEditableValue(value);
85
- setHasPendingChanges(false);
86
- }
87
- },
88
- [editableValue, dataType, overrideValueFn, path, value],
89
- );
90
-
91
- // Render different input types based on the dataType
92
- let type = 'text';
93
- if (dataType === 'boolean') {
94
- type = 'checkbox';
95
- } else if (dataType === 'number') {
96
- type = 'number';
97
- }
98
-
99
- let inputValue = value == null ? '' : value;
100
- if (hasPendingChanges) {
101
- inputValue = editableValue == null ? '' : editableValue;
102
- }
103
-
104
- let placeholder = '';
105
- if (value === null) {
106
- placeholder = '(null)';
107
- } else if (value === undefined) {
108
- placeholder = '(undefined)';
109
- } else if (dataType === 'string') {
110
- placeholder = '(string)';
111
- }
112
-
113
- return (
114
- <Fragment>
115
- {dataType === 'boolean' && (
116
- <label className={styles.CheckboxLabel}>
117
- <input
118
- checked={inputValue}
119
- className={styles.Checkbox}
120
- onChange={handleChange}
121
- onKeyDown={handleKeyDown}
122
- ref={inputRef}
123
- type={type}
124
- />
125
- </label>
126
- )}
127
- {dataType !== 'boolean' && (
128
- <input
129
- className={styles.Input}
130
- onChange={handleChange}
131
- onKeyDown={handleKeyDown}
132
- placeholder={placeholder}
133
- ref={inputRef}
134
- type={type}
135
- value={inputValue}
136
- />
137
- )}
138
- {hasPendingChanges &&
139
- dataType !== 'boolean' && (
140
- <Button
141
- className={styles.ResetButton}
142
- onClick={handleReset}
143
- title="Reset value">
144
- <ButtonIcon type="undo" />
145
- </Button>
146
- )}
147
- </Fragment>
148
- );
149
-}
packages/react-devtools-shared/src/devtools/views/Components/Element.css
deleted
-75
@@ -1,75 +0,0 @@
1
-.Element,
2
-.InactiveSelectedElement,
3
-.SelectedElement,
4
-.HoveredElement {
5
- color: var(--color-component-name);
6
-}
7
-.HoveredElement {
8
- background-color: var(--color-background-hover);
9
-}
10
-.InactiveSelectedElement {
11
- background-color: var(--color-background-inactive);
12
-}
13
-
14
-.Wrapper {
15
- padding: 0 0.25rem;
16
- white-space: nowrap;
17
- height: var(--line-height-data);
18
- line-height: var(--line-height-data);
19
- display: inline-flex;
20
- align-items: center;
21
- cursor: default;
22
- user-select: none;
23
-}
24
-
25
-.ScrollAnchor {
26
- height: 100%;
27
- width: 0;
28
-}
29
-
30
-.SelectedElement {
31
- background-color: var(--color-background-selected);
32
- color: var(--color-text-selected);
33
-
34
- /* Invert colors */
35
- --color-component-name: var(--color-component-name-inverted);
36
- --color-text: var(--color-text-selected);
37
- --color-component-badge-background: var(
38
- --color-component-badge-background-inverted
39
- );
40
- --color-component-badge-count: var(--color-component-badge-count-inverted);
41
- --color-attribute-name: var(--color-attribute-name-inverted);
42
- --color-attribute-value: var(--color-attribute-value-inverted);
43
- --color-expand-collapse-toggle: var(--color-component-name-inverted);
44
-}
45
-
46
-.KeyName {
47
- color: var(--color-attribute-name);
48
-}
49
-
50
-.KeyValue {
51
- color: var(--color-attribute-value);
52
- user-select: text;
53
- max-width: 100px;
54
- overflow-x: hidden;
55
- text-overflow: ellipsis;
56
-}
57
-
58
-.Highlight {
59
- background-color: var(--color-search-match);
60
-}
61
-.CurrentHighlight {
62
- background-color: var(--color-search-match-current);
63
-}
64
-
65
-.ExpandCollapseToggle {
66
- display: inline-flex;
67
- width: 1rem;
68
- height: 1rem;
69
- flex: 0 0 1rem;
70
- color: var(--color-expand-collapse-toggle);
71
-}
72
-
73
-.Badge {
74
- margin-left: 0.25rem;
75
-}
packages/react-devtools-shared/src/devtools/views/Components/Element.js
deleted
-234
@@ -1,234 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useContext, useMemo, useState} from 'react';
11
-import Store from 'react-devtools-shared/src/devtools/store';
12
-import Badge from './Badge';
13
-import ButtonIcon from '../ButtonIcon';
14
-import {createRegExp} from '../utils';
15
-import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
16
-import {StoreContext} from '../context';
17
-
18
-import type {ItemData} from './Tree';
19
-import type {Element} from './types';
20
-
21
-import styles from './Element.css';
22
-
23
-type Props = {
24
- data: ItemData,
25
- index: number,
26
- style: Object,
27
-};
28
-
29
-export default function ElementView({data, index, style}: Props) {
30
- const store = useContext(StoreContext);
31
- const {ownerFlatTree, ownerID, selectedElementID} = useContext(
32
- TreeStateContext,
33
- );
34
- const dispatch = useContext(TreeDispatcherContext);
35
-
36
- const element =
37
- ownerFlatTree !== null
38
- ? ownerFlatTree[index]
39
- : store.getElementAtIndex(index);
40
-
41
- const [isHovered, setIsHovered] = useState(false);
42
-
43
- const {isNavigatingWithKeyboard, onElementMouseEnter, treeFocused} = data;
44
- const id = element === null ? null : element.id;
45
- const isSelected = selectedElementID === id;
46
-
47
- const handleDoubleClick = () => {
48
- if (id !== null) {
49
- dispatch({type: 'SELECT_OWNER', payload: id});
50
- }
51
- };
52
-
53
- const handleMouseDown = ({metaKey}) => {
54
- if (id !== null) {
55
- dispatch({
56
- type: 'SELECT_ELEMENT_BY_ID',
57
- payload: metaKey ? null : id,
58
- });
59
- }
60
- };
61
-
62
- const handleMouseEnter = () => {
63
- setIsHovered(true);
64
- if (id !== null) {
65
- onElementMouseEnter(id);
66
- }
67
- };
68
-
69
- const handleMouseLeave = () => {
70
- setIsHovered(false);
71
- };
72
-
73
- const handleKeyDoubleClick = event => {
74
- // Double clicks on key value are used for text selection (if the text has been truncated).
75
- // They should not enter the owners tree view.
76
- event.stopPropagation();
77
- event.preventDefault();
78
- };
79
-
80
- // Handle elements that are removed from the tree while an async render is in progress.
81
- if (element == null) {
82
- console.warn(`<ElementView> Could not find element at index ${index}`);
83
-
84
- // This return needs to happen after hooks, since hooks can't be conditional.
85
- return null;
86
- }
87
-
88
- const {
89
- depth,
90
- displayName,
91
- hocDisplayNames,
92
- key,
93
- type,
94
- } = ((element: any): Element);
95
-
96
- let className = styles.Element;
97
- if (isSelected) {
98
- className = treeFocused
99
- ? styles.SelectedElement
100
- : styles.InactiveSelectedElement;
101
- } else if (isHovered && !isNavigatingWithKeyboard) {
102
- className = styles.HoveredElement;
103
- }
104
-
105
- return (
106
- <div
107
- className={className}
108
- onMouseEnter={handleMouseEnter}
109
- onMouseLeave={handleMouseLeave}
110
- onMouseDown={handleMouseDown}
111
- onDoubleClick={handleDoubleClick}
112
- style={style}
113
- data-depth={depth}>
114
- {/* This wrapper is used by Tree for measurement purposes. */}
115
- <div
116
- className={styles.Wrapper}
117
- style={{
118
- // Left offset presents the appearance of a nested tree structure.
119
- // We must use padding rather than margin/left because of the selected background color.
120
- transform: `translateX(calc(${depth} * var(--indentation-size)))`,
121
- }}>
122
- {ownerID === null ? (
123
- <ExpandCollapseToggle element={element} store={store} />
124
- ) : null}
125
- <DisplayName displayName={displayName} id={((id: any): number)} />
126
- {key && (
127
- <Fragment>
128
- <span className={styles.KeyName}>key</span>="
129
- <span
130
- className={styles.KeyValue}
131
- title={key}
132
- onDoubleClick={handleKeyDoubleClick}>
133
- {key}
134
- </span>
135
- "
136
- </Fragment>
137
- )}
138
- <Badge
139
- className={styles.Badge}
140
- hocDisplayNames={hocDisplayNames}
141
- type={type}
142
- />
143
- </div>
144
- </div>
145
- );
146
-}
147
-
148
-// Prevent double clicks on toggle from drilling into the owner list.
149
-const swallowDoubleClick = event => {
150
- event.preventDefault();
151
- event.stopPropagation();
152
-};
153
-
154
-type ExpandCollapseToggleProps = {|
155
- element: Element,
156
- store: Store,
157
-|};
158
-
159
-function ExpandCollapseToggle({element, store}: ExpandCollapseToggleProps) {
160
- const {children, id, isCollapsed} = element;
161
-
162
- const toggleCollapsed = event => {
163
- event.preventDefault();
164
- event.stopPropagation();
165
-
166
- store.toggleIsCollapsed(id, !isCollapsed);
167
- };
168
-
169
- const stopPropagation = event => {
170
- // Prevent the row from selecting
171
- event.stopPropagation();
172
- };
173
-
174
- if (children.length === 0) {
175
- return <div className={styles.ExpandCollapseToggle} />;
176
- }
177
-
178
- return (
179
- <div
180
- className={styles.ExpandCollapseToggle}
181
- onMouseDown={stopPropagation}
182
- onClick={toggleCollapsed}
183
- onDoubleClick={swallowDoubleClick}>
184
- <ButtonIcon type={isCollapsed ? 'collapsed' : 'expanded'} />
185
- </div>
186
- );
187
-}
188
-
189
-type DisplayNameProps = {|
190
- displayName: string | null,
191
- id: number,
192
-|};
193
-
194
-function DisplayName({displayName, id}: DisplayNameProps) {
195
- const {searchIndex, searchResults, searchText} = useContext(TreeStateContext);
196
- const isSearchResult = useMemo(
197
- () => {
198
- return searchResults.includes(id);
199
- },
200
- [id, searchResults],
201
- );
202
- const isCurrentResult =
203
- searchIndex !== null && id === searchResults[searchIndex];
204
-
205
- if (!isSearchResult || displayName === null) {
206
- return displayName;
207
- }
208
-
209
- const match = createRegExp(searchText).exec(displayName);
210
-
211
- if (match === null) {
212
- return displayName;
213
- }
214
-
215
- const startIndex = match.index;
216
- const stopIndex = startIndex + match[0].length;
217
-
218
- const children = [];
219
- if (startIndex > 0) {
220
- children.push(<span key="begin">{displayName.slice(0, startIndex)}</span>);
221
- }
222
- children.push(
223
- <mark
224
- key="middle"
225
- className={isCurrentResult ? styles.CurrentHighlight : styles.Highlight}>
226
- {displayName.slice(startIndex, stopIndex)}
227
- </mark>,
228
- );
229
- if (stopIndex < displayName.length) {
230
- children.push(<span key="end">{displayName.slice(stopIndex)}</span>);
231
- }
232
-
233
- return children;
234
-}
packages/react-devtools-shared/src/devtools/views/Components/ExpandCollapseToggle.css
deleted
-7
@@ -1,7 +0,0 @@
1
-.ExpandCollapseToggle {
2
- flex: 0 0 1rem;
3
- width: 1rem;
4
- height: 1rem;
5
- padding: 0;
6
- color: var(--color-expand-collapse-toggle);
7
-}
packages/react-devtools-shared/src/devtools/views/Components/ExpandCollapseToggle.js
deleted
-33
@@ -1,33 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-import Button from '../Button';
12
-import ButtonIcon from '../ButtonIcon';
13
-
14
-import styles from './ExpandCollapseToggle.css';
15
-
16
-type ExpandCollapseToggleProps = {|
17
- isOpen: boolean,
18
- setIsOpen: Function,
19
-|};
20
-
21
-export default function ExpandCollapseToggle({
22
- isOpen,
23
- setIsOpen,
24
-}: ExpandCollapseToggleProps) {
25
- return (
26
- <Button
27
- className={styles.ExpandCollapseToggle}
28
- onClick={() => setIsOpen(prevIsOpen => !prevIsOpen)}
29
- title={`${isOpen ? 'Collapse' : 'Expand'} prop value`}>
30
- <ButtonIcon type={isOpen ? 'expanded' : 'collapsed'} />
31
- </Button>
32
- );
33
-}
packages/react-devtools-shared/src/devtools/views/Components/HocBadges.css
deleted
-16
@@ -1,16 +0,0 @@
1
-.HocBadges {
2
- padding: 0.125rem 0.25rem;
3
- user-select: none;
4
-}
5
-
6
-.Badge {
7
- display: inline-block;
8
- background-color: var(--color-component-badge-background);
9
- color: var(--color-text);
10
- padding: 0.125rem 0.25rem;
11
- line-height: normal;
12
- border-radius: 0.125rem;
13
- margin-right: 0.25rem;
14
- font-family: var(--font-family-monospace);
15
- font-size: var(--font-size-monospace-small);
16
-}
packages/react-devtools-shared/src/devtools/views/Components/HocBadges.js
deleted
-48
@@ -1,48 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-import {
12
- ElementTypeForwardRef,
13
- ElementTypeMemo,
14
-} from 'react-devtools-shared/src/types';
15
-import styles from './HocBadges.css';
16
-
17
-import type {Element} from './types';
18
-
19
-type Props = {|
20
- element: Element,
21
-|};
22
-
23
-export default function HocBadges({element}: Props) {
24
- const {hocDisplayNames, type} = ((element: any): Element);
25
-
26
- let typeBadge = null;
27
- if (type === ElementTypeMemo) {
28
- typeBadge = 'Memo';
29
- } else if (type === ElementTypeForwardRef) {
30
- typeBadge = 'ForwardRef';
31
- }
32
-
33
- if (hocDisplayNames === null && typeBadge === null) {
34
- return null;
35
- }
36
-
37
- return (
38
- <div className={styles.HocBadges}>
39
- {typeBadge !== null && <div className={styles.Badge}>{typeBadge}</div>}
40
- {hocDisplayNames !== null &&
41
- hocDisplayNames.map(hocDisplayName => (
42
- <div key={hocDisplayName} className={styles.Badge}>
43
- {hocDisplayName}
44
- </div>
45
- ))}
46
- </div>
47
- );
48
-}
packages/react-devtools-shared/src/devtools/views/Components/HooksTree.css
deleted
-69
@@ -1,69 +0,0 @@
1
-.HooksTreeView {
2
- padding: 0.25rem;
3
- border-top: 1px solid var(--color-border);
4
-}
5
-
6
-.Hook {
7
-}
8
-
9
-.Children {
10
- padding-left: 1rem;
11
-}
12
-
13
-.HeaderRow {
14
- display: flex;
15
- align-items: center;
16
-}
17
-
18
-.Header {
19
- flex: 1 1;
20
- font-family: var(--font-family-sans);
21
-}
22
-
23
-.NameValueRow {
24
- display: flex;
25
-}
26
-
27
-.Name,
28
-.NameAnonymous {
29
- flex: 0 0 auto;
30
- user-select: none;
31
-}
32
-.Name {
33
- color: var(--color-dim);
34
-}
35
-.NameAnonymous {
36
- color: var(--color-dimmer);
37
-}
38
-
39
-.EditableName {
40
- color: var(--color-attribute-name);
41
- flex: 0 0 auto;
42
- user-select: none;
43
-}
44
-.EditableName:after,
45
-.Name:after {
46
- color: var(--color-text);
47
- content: ': ';
48
- margin-right: 0.5rem;
49
-}
50
-
51
-.Value {
52
- color: var(--color-attribute-value);
53
- overflow: hidden;
54
- text-overflow: ellipsis;
55
-}
56
-
57
-.None {
58
- color: var(--color-dimmer);
59
- font-style: italic;
60
-}
61
-
62
-.TruncationIndicator {
63
- color: var(--color-dimmer);
64
-}
65
-
66
-.ExpandCollapseToggleSpacer {
67
- flex: 0 0 1rem;
68
- width: 1rem;
69
-}
packages/react-devtools-shared/src/devtools/views/Components/HooksTree.js
deleted
-290
@@ -1,290 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {copy} from 'clipboard-js';
11
-import React, {useCallback, useContext, useState} from 'react';
12
-import {BridgeContext, StoreContext} from '../context';
13
-import Button from '../Button';
14
-import ButtonIcon from '../ButtonIcon';
15
-import EditableValue from './EditableValue';
16
-import ExpandCollapseToggle from './ExpandCollapseToggle';
17
-import {InspectedElementContext} from './InspectedElementContext';
18
-import KeyValue from './KeyValue';
19
-import {serializeHooksForCopy} from '../utils';
20
-import styles from './HooksTree.css';
21
-import {meta} from '../../../hydration';
22
-
23
-import type {InspectPath} from './SelectedElement';
24
-import type {HooksNode, HooksTree} from 'react-debug-tools/src/ReactDebugHooks';
25
-
26
-type HooksTreeViewProps = {|
27
- canEditHooks: boolean,
28
- hooks: HooksTree | null,
29
- id: number,
30
-|};
31
-
32
-export function HooksTreeView({canEditHooks, hooks, id}: HooksTreeViewProps) {
33
- const {getInspectedElementPath} = useContext(InspectedElementContext);
34
- const inspectPath = useCallback(
35
- (path: Array<string | number>) => {
36
- getInspectedElementPath(id, ['hooks', ...path]);
37
- },
38
- [getInspectedElementPath, id],
39
- );
40
- const handleCopy = useCallback(() => copy(serializeHooksForCopy(hooks)), [
41
- hooks,
42
- ]);
43
-
44
- if (hooks === null) {
45
- return null;
46
- } else {
47
- return (
48
- <div className={styles.HooksTreeView}>
49
- <div className={styles.HeaderRow}>
50
- <div className={styles.Header}>hooks</div>
51
- <Button onClick={handleCopy} title="Copy to clipboard">
52
- <ButtonIcon type="copy" />
53
- </Button>
54
- </div>
55
- <InnerHooksTreeView
56
- canEditHooks={canEditHooks}
57
- hooks={hooks}
58
- id={id}
59
- inspectPath={inspectPath}
60
- path={[]}
61
- />
62
- </div>
63
- );
64
- }
65
-}
66
-
67
-type InnerHooksTreeViewProps = {|
68
- canEditHooks: boolean,
69
- hooks: HooksTree,
70
- id: number,
71
- inspectPath: InspectPath,
72
- path: Array<string | number>,
73
-|};
74
-
75
-export function InnerHooksTreeView({
76
- canEditHooks,
77
- hooks,
78
- id,
79
- inspectPath,
80
- path,
81
-}: InnerHooksTreeViewProps) {
82
- // $FlowFixMe "Missing type annotation for U" whatever that means
83
- return hooks.map((hook, index) => (
84
- <HookView
85
- key={index}
86
- canEditHooks={canEditHooks}
87
- hook={hooks[index]}
88
- id={id}
89
- inspectPath={inspectPath}
90
- path={path.concat([index])}
91
- />
92
- ));
93
-}
94
-
95
-type HookViewProps = {|
96
- canEditHooks: boolean,
97
- hook: HooksNode,
98
- id: number,
99
- inspectPath: InspectPath,
100
- path: Array<string | number>,
101
-|};
102
-
103
-function HookView({canEditHooks, hook, id, inspectPath, path}: HookViewProps) {
104
- const {name, id: hookID, isStateEditable, subHooks, value} = hook;
105
-
106
- const bridge = useContext(BridgeContext);
107
- const store = useContext(StoreContext);
108
-
109
- const [isOpen, setIsOpen] = useState<boolean>(false);
110
-
111
- const toggleIsOpen = useCallback(
112
- () => setIsOpen(prevIsOpen => !prevIsOpen),
113
- [],
114
- );
115
-
116
- if (hook.hasOwnProperty(meta.inspected)) {
117
- // This Hook is too deep and hasn't been hydrated.
118
- if (__DEV__) {
119
- console.warn('Unexpected dehydrated hook; this is a DevTools error.');
120
- }
121
- return (
122
- <div className={styles.Hook}>
123
- <div className={styles.NameValueRow}>
124
- <span className={styles.TruncationIndicator}>...</span>
125
- </div>
126
- </div>
127
- );
128
- }
129
-
130
- const isCustomHook = subHooks.length > 0;
131
-
132
- const type = typeof value;
133
-
134
- let displayValue;
135
- let isComplexDisplayValue = false;
136
-
137
- // Format data for display to mimic the props/state/context for now.
138
- if (type === 'string') {
139
- displayValue = `"${((value: any): string)}"`;
140
- } else if (type === 'boolean') {
141
- displayValue = value ? 'true' : 'false';
142
- } else if (type === 'number') {
143
- displayValue = value;
144
- } else if (value === null) {
145
- displayValue = 'null';
146
- } else if (value === undefined) {
147
- displayValue = null;
148
- } else if (Array.isArray(value)) {
149
- isComplexDisplayValue = true;
150
- displayValue = 'Array';
151
- } else if (type === 'object') {
152
- isComplexDisplayValue = true;
153
- displayValue = 'Object';
154
- }
155
-
156
- if (isCustomHook) {
157
- const subHooksView = Array.isArray(subHooks) ? (
158
- <InnerHooksTreeView
159
- canEditHooks={canEditHooks}
160
- hooks={subHooks}
161
- id={id}
162
- inspectPath={inspectPath}
163
- path={path.concat(['subHooks'])}
164
- />
165
- ) : (
166
- <KeyValue
167
- depth={1}
168
- alphaSort={false}
169
- inspectPath={inspectPath}
170
- name="subHooks"
171
- path={path.concat(['subHooks'])}
172
- value={subHooks}
173
- />
174
- );
175
-
176
- if (isComplexDisplayValue) {
177
- return (
178
- <div className={styles.Hook}>
179
- <div className={styles.NameValueRow}>
180
- <ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
181
- <span
182
- onClick={toggleIsOpen}
183
- className={name !== '' ? styles.Name : styles.NameAnonymous}>
184
- {name || 'Anonymous'}
185
- </span>
186
- </div>
187
- <div className={styles.Children} hidden={!isOpen}>
188
- <KeyValue
189
- depth={1}
190
- alphaSort={false}
191
- inspectPath={inspectPath}
192
- name="DebugValue"
193
- path={path.concat(['value'])}
194
- value={value}
195
- />
196
- {subHooksView}
197
- </div>
198
- </div>
199
- );
200
- } else {
201
- return (
202
- <div className={styles.Hook}>
203
- <div className={styles.NameValueRow}>
204
- <ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
205
- <span
206
- onClick={toggleIsOpen}
207
- className={name !== '' ? styles.Name : styles.NameAnonymous}>
208
- {name || 'Anonymous'}
209
- </span>{' '}
210
- {/* $FlowFixMe */}
211
- <span className={styles.Value}>{displayValue}</span>
212
- </div>
213
- <div className={styles.Children} hidden={!isOpen}>
214
- {subHooksView}
215
- </div>
216
- </div>
217
- );
218
- }
219
- } else {
220
- let overrideValueFn = null;
221
- // TODO Maybe read editable value from debug hook?
222
- if (canEditHooks && isStateEditable) {
223
- overrideValueFn = (
224
- absolutePath: Array<string | number>,
225
- newValue: any,
226
- ) => {
227
- const rendererID = store.getRendererIDForElement(id);
228
- if (rendererID !== null) {
229
- bridge.send('overrideHookState', {
230
- id,
231
- hookID,
232
- // Hooks override function expects a relative path for the specified hook (id),
233
- // starting with its id within the (flat) hooks list structure.
234
- // This relative path does not include the fake tree structure DevTools uses for display,
235
- // so it's important that we remove that part of the path before sending the update.
236
- path: absolutePath.slice(path.length + 1),
237
- rendererID,
238
- value: newValue,
239
- });
240
- }
241
- };
242
- }
243
-
244
- if (isComplexDisplayValue) {
245
- return (
246
- <div className={styles.Hook}>
247
- <KeyValue
248
- depth={1}
249
- alphaSort={false}
250
- inspectPath={inspectPath}
251
- name={name}
252
- overrideValueFn={overrideValueFn}
253
- path={path.concat(['value'])}
254
- value={value}
255
- />
256
- </div>
257
- );
258
- } else {
259
- return (
260
- <div className={styles.Hook}>
261
- <div className={styles.NameValueRow}>
262
- <span className={styles.ExpandCollapseToggleSpacer} />
263
- <span
264
- className={
265
- typeof overrideValueFn === 'function'
266
- ? styles.EditableName
267
- : styles.Name
268
- }>
269
- {name}
270
- </span>
271
- {typeof overrideValueFn === 'function' ? (
272
- <EditableValue
273
- dataType={type}
274
- overrideValueFn={overrideValueFn}
275
- path={[]}
276
- value={value}
277
- />
278
- ) : (
279
- // $FlowFixMe Cannot create span element because in property children
280
- <span className={styles.Value}>{displayValue}</span>
281
- )}
282
- </div>
283
- </div>
284
- );
285
- }
286
- }
287
-}
288
-
289
-// $FlowFixMe
290
-export default React.memo(HooksTreeView);
packages/react-devtools-shared/src/devtools/views/Components/InspectHostNodesToggle.js
deleted
-50
@@ -1,50 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useContext, useEffect, useState} from 'react';
11
-import {BridgeContext} from '../context';
12
-import Toggle from '../Toggle';
13
-import ButtonIcon from '../ButtonIcon';
14
-
15
-export default function InspectHostNodesToggle() {
16
- const [isInspecting, setIsInspecting] = useState(false);
17
- const bridge = useContext(BridgeContext);
18
-
19
- const handleChange = useCallback(
20
- (isChecked: boolean) => {
21
- setIsInspecting(isChecked);
22
-
23
- if (isChecked) {
24
- bridge.send('startInspectingNative');
25
- } else {
26
- bridge.send('stopInspectingNative', false);
27
- }
28
- },
29
- [bridge],
30
- );
31
-
32
- useEffect(
33
- () => {
34
- const onStopInspectingNative = () => setIsInspecting(false);
35
- bridge.addListener('stopInspectingNative', onStopInspectingNative);
36
- return () =>
37
- bridge.removeListener('stopInspectingNative', onStopInspectingNative);
38
- },
39
- [bridge],
40
- );
41
-
42
- return (
43
- <Toggle
44
- onChange={handleChange}
45
- isChecked={isInspecting}
46
- title="Select an element in the page to inspect it">
47
- <ButtonIcon type="search" />
48
- </Toggle>
49
- );
50
-}
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js
deleted
-325
@@ -1,325 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- createContext,
12
- useCallback,
13
- useContext,
14
- useEffect,
15
- useMemo,
16
- useState,
17
-} from 'react';
18
-import {unstable_batchedUpdates as batchedUpdates} from 'react-dom';
19
-import {createResource} from '../../cache';
20
-import {BridgeContext, StoreContext} from '../context';
21
-import {hydrate, fillInPath} from 'react-devtools-shared/src/hydration';
22
-import {TreeStateContext} from './TreeContext';
23
-import {separateDisplayNameAndHOCs} from 'react-devtools-shared/src/utils';
24
-
25
-import type {
26
- InspectedElement as InspectedElementBackend,
27
- InspectedElementPayload,
28
-} from 'react-devtools-shared/src/backend/types';
29
-import type {
30
- DehydratedData,
31
- Element,
32
- InspectedElement as InspectedElementFrontend,
33
-} from 'react-devtools-shared/src/devtools/views/Components/types';
34
-import type {Resource, Thenable} from '../../cache';
35
-
36
-export type GetInspectedElementPath = (
37
- id: number,
38
- path: Array<string | number>,
39
-) => void;
40
-export type GetInspectedElement = (
41
- id: number,
42
-) => InspectedElementFrontend | null;
43
-
44
-type Context = {|
45
- getInspectedElementPath: GetInspectedElementPath,
46
- getInspectedElement: GetInspectedElement,
47
-|};
48
-
49
-const InspectedElementContext = createContext<Context>(((null: any): Context));
50
-InspectedElementContext.displayName = 'InspectedElementContext';
51
-
52
-type ResolveFn = (inspectedElement: InspectedElementFrontend) => void;
53
-type InProgressRequest = {|
54
- promise: Thenable<InspectedElementFrontend>,
55
- resolveFn: ResolveFn,
56
-|};
57
-
58
-const inProgressRequests: WeakMap<Element, InProgressRequest> = new WeakMap();
59
-const resource: Resource<
60
- Element,
61
- Element,
62
- InspectedElementFrontend,
63
-> = createResource(
64
- (element: Element) => {
65
- let request = inProgressRequests.get(element);
66
- if (request != null) {
67
- return request.promise;
68
- }
69
-
70
- let resolveFn = ((null: any): ResolveFn);
71
- const promise = new Promise(resolve => {
72
- resolveFn = resolve;
73
- });
74
-
75
- inProgressRequests.set(element, {promise, resolveFn});
76
-
77
- return promise;
78
- },
79
- (element: Element) => element,
80
- {useWeakMap: true},
81
-);
82
-
83
-type Props = {|
84
- children: React$Node,
85
-|};
86
-
87
-function InspectedElementContextController({children}: Props) {
88
- const bridge = useContext(BridgeContext);
89
- const store = useContext(StoreContext);
90
-
91
- // Ask the backend to fill in a "dehydrated" path; this will result in a "inspectedElement".
92
- const getInspectedElementPath = useCallback<GetInspectedElementPath>(
93
- (id: number, path: Array<string | number>) => {
94
- const rendererID = store.getRendererIDForElement(id);
95
- if (rendererID !== null) {
96
- bridge.send('inspectElement', {id, path, rendererID});
97
- }
98
- },
99
- [bridge, store],
100
- );
101
-
102
- const getInspectedElement = useCallback<GetInspectedElement>(
103
- (id: number) => {
104
- const element = store.getElementByID(id);
105
- if (element !== null) {
106
- return resource.read(element);
107
- } else {
108
- return null;
109
- }
110
- },
111
- [store],
112
- );
113
-
114
- // It's very important that this context consumes selectedElementID and not inspectedElementID.
115
- // Otherwise the effect that sends the "inspect" message across the bridge-
116
- // would itself be blocked by the same render that suspends (waiting for the data).
117
- const {selectedElementID} = useContext(TreeStateContext);
118
-
119
- const [
120
- currentlyInspectedElement,
121
- setCurrentlyInspectedElement,
122
- ] = useState<InspectedElementFrontend | null>(null);
123
-
124
- // This effect handler invalidates the suspense cache and schedules rendering updates with React.
125
- useEffect(
126
- () => {
127
- const onInspectedElement = (data: InspectedElementPayload) => {
128
- const {id} = data;
129
-
130
- let element;
131
-
132
- switch (data.type) {
133
- case 'no-change':
134
- case 'not-found':
135
- // No-op
136
- break;
137
- case 'hydrated-path':
138
- // Merge new data into previous object and invalidate cache
139
- element = store.getElementByID(id);
140
- if (element !== null) {
141
- if (currentlyInspectedElement != null) {
142
- const value = hydrateHelper(data.value, data.path);
143
- const inspectedElement = {...currentlyInspectedElement};
144
-
145
- fillInPath(inspectedElement, data.value, data.path, value);
146
-
147
- resource.write(element, inspectedElement);
148
-
149
- // Schedule update with React if the curently-selected element has been invalidated.
150
- if (id === selectedElementID) {
151
- setCurrentlyInspectedElement(inspectedElement);
152
- }
153
- }
154
- }
155
- break;
156
- case 'full-data':
157
- const {
158
- canEditFunctionProps,
159
- canEditHooks,
160
- canToggleSuspense,
161
- canViewSource,
162
- source,
163
- type,
164
- owners,
165
- context,
166
- hooks,
167
- props,
168
- state,
169
- } = ((data.value: any): InspectedElementBackend);
170
-
171
- const inspectedElement: InspectedElementFrontend = {
172
- canEditFunctionProps,
173
- canEditHooks,
174
- canToggleSuspense,
175
- canViewSource,
176
- id,
177
- source,
178
- type,
179
- owners:
180
- owners === null
181
- ? null
182
- : owners.map(owner => {
183
- const [
184
- displayName,
185
- hocDisplayNames,
186
- ] = separateDisplayNameAndHOCs(
187
- owner.displayName,
188
- owner.type,
189
- );
190
- return {
191
- ...owner,
192
- displayName,
193
- hocDisplayNames,
194
- };
195
- }),
196
- context: hydrateHelper(context),
197
- hooks: hydrateHelper(hooks),
198
- props: hydrateHelper(props),
199
- state: hydrateHelper(state),
200
- };
201
-
202
- element = store.getElementByID(id);
203
- if (element !== null) {
204
- const request = inProgressRequests.get(element);
205
- if (request != null) {
206
- inProgressRequests.delete(element);
207
- batchedUpdates(() => {
208
- request.resolveFn(inspectedElement);
209
- setCurrentlyInspectedElement(inspectedElement);
210
- });
211
- } else {
212
- resource.write(element, inspectedElement);
213
-
214
- // Schedule update with React if the curently-selected element has been invalidated.
215
- if (id === selectedElementID) {
216
- setCurrentlyInspectedElement(inspectedElement);
217
- }
218
- }
219
- }
220
- break;
221
- default:
222
- break;
223
- }
224
- };
225
-
226
- bridge.addListener('inspectedElement', onInspectedElement);
227
- return () =>
228
- bridge.removeListener('inspectedElement', onInspectedElement);
229
- },
230
- [bridge, currentlyInspectedElement, selectedElementID, store],
231
- );
232
-
233
- // This effect handler polls for updates on the currently selected element.
234
- useEffect(
235
- () => {
236
- if (selectedElementID === null) {
237
- return () => {};
238
- }
239
-
240
- const rendererID = store.getRendererIDForElement(selectedElementID);
241
-
242
- let timeoutID: TimeoutID | null = null;
243
-
244
- const sendRequest = () => {
245
- timeoutID = null;
246
-
247
- if (rendererID !== null) {
248
- bridge.send('inspectElement', {id: selectedElementID, rendererID});
249
- }
250
- };
251
-
252
- // Send the initial inspection request.
253
- // We'll poll for an update in the response handler below.
254
- sendRequest();
255
-
256
- const onInspectedElement = (data: InspectedElementPayload) => {
257
- // If this is the element we requested, wait a little bit and then ask for another update.
258
- if (data.id === selectedElementID) {
259
- switch (data.type) {
260
- case 'no-change':
261
- case 'full-data':
262
- case 'hydrated-path':
263
- if (timeoutID !== null) {
264
- clearTimeout(timeoutID);
265
- }
266
- timeoutID = setTimeout(sendRequest, 1000);
267
- break;
268
- default:
269
- break;
270
- }
271
- }
272
- };
273
-
274
- bridge.addListener('inspectedElement', onInspectedElement);
275
-
276
- return () => {
277
- bridge.removeListener('inspectedElement', onInspectedElement);
278
-
279
- if (timeoutID !== null) {
280
- clearTimeout(timeoutID);
281
- }
282
- };
283
- },
284
- [bridge, selectedElementID, store],
285
- );
286
-
287
- const value = useMemo(
288
- () => ({getInspectedElement, getInspectedElementPath}),
289
- // InspectedElement is used to invalidate the cache and schedule an update with React.
290
- [currentlyInspectedElement, getInspectedElement, getInspectedElementPath],
291
- );
292
-
293
- return (
294
- <InspectedElementContext.Provider value={value}>
295
- {children}
296
- </InspectedElementContext.Provider>
297
- );
298
-}
299
-
300
-function hydrateHelper(
301
- dehydratedData: DehydratedData | null,
302
- path?: Array<string | number>,
303
-): Object | null {
304
- if (dehydratedData !== null) {
305
- let {cleaned, data, unserializable} = dehydratedData;
306
-
307
- if (path) {
308
- const {length} = path;
309
- if (length > 0) {
310
- // Hydration helper requires full paths, but inspection dehydrates with relative paths.
311
- // In that event it's important that we adjust the "cleaned" paths to match.
312
- cleaned = cleaned.map(cleanedPath => cleanedPath.slice(length));
313
- unserializable = unserializable.map(unserializablePath =>
314
- unserializablePath.slice(length),
315
- );
316
- }
317
- }
318
-
319
- return hydrate(data, cleaned, unserializable);
320
- } else {
321
- return null;
322
- }
323
-}
324
-
325
-export {InspectedElementContext, InspectedElementContextController};
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementTree.css
deleted
-48
@@ -1,48 +0,0 @@
1
-.InspectedElementTree {
2
- padding: 0.25rem;
3
- border-top: 1px solid var(--color-border);
4
-}
5
-.InspectedElementTree:first-of-type {
6
- border-top: none;
7
-}
8
-
9
-.HeaderRow {
10
- display: flex;
11
- align-items: center;
12
-}
13
-
14
-.Header {
15
- flex: 1 1;
16
- font-family: var(--font-family-sans);
17
-}
18
-
19
-.Item {
20
- display: flex;
21
-}
22
-
23
-.Name {
24
- color: var(--color-attribute-name);
25
- flex: 0 0 auto;
26
-}
27
-.Name:after {
28
- content: ': ';
29
- color: var(--color-text);
30
- margin-right: 0.5rem;
31
-}
32
-
33
-.Value {
34
- color: var(--color-attribute-value);
35
- overflow: hidden;
36
- text-overflow: ellipsis;
37
-}
38
-
39
-.None {
40
- color: var(--color-dimmer);
41
- font-style: italic;
42
-}
43
-
44
-.Empty {
45
- color: var(--color-dimmer);
46
- font-style: italic;
47
- padding-left: 0.75rem;
48
-}
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementTree.js
deleted
-79
@@ -1,79 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {copy} from 'clipboard-js';
11
-import React, {useCallback} from 'react';
12
-import Button from '../Button';
13
-import ButtonIcon from '../ButtonIcon';
14
-import KeyValue from './KeyValue';
15
-import {alphaSortEntries, serializeDataForCopy} from '../utils';
16
-import styles from './InspectedElementTree.css';
17
-
18
-import type {InspectPath} from './SelectedElement';
19
-
20
-type OverrideValueFn = (path: Array<string | number>, value: any) => void;
21
-
22
-type Props = {|
23
- data: Object | null,
24
- inspectPath?: InspectPath,
25
- label: string,
26
- overrideValueFn?: ?OverrideValueFn,
27
- showWhenEmpty?: boolean,
28
-|};
29
-
30
-export default function InspectedElementTree({
31
- data,
32
- inspectPath,
33
- label,
34
- overrideValueFn,
35
- showWhenEmpty = false,
36
-}: Props) {
37
- const entries = data != null ? Object.entries(data) : null;
38
- if (entries !== null) {
39
- entries.sort(alphaSortEntries);
40
- }
41
-
42
- const isEmpty = entries === null || entries.length === 0;
43
-
44
- const handleCopy = useCallback(
45
- () => copy(serializeDataForCopy(((data: any): Object))),
46
- [data],
47
- );
48
-
49
- if (isEmpty && !showWhenEmpty) {
50
- return null;
51
- } else {
52
- return (
53
- <div className={styles.InspectedElementTree}>
54
- <div className={styles.HeaderRow}>
55
- <div className={styles.Header}>{label}</div>
56
- {!isEmpty && (
57
- <Button onClick={handleCopy} title="Copy to clipboard">
58
- <ButtonIcon type="copy" />
59
- </Button>
60
- )}
61
- </div>
62
- {isEmpty && <div className={styles.Empty}>None</div>}
63
- {!isEmpty &&
64
- (entries: any).map(([name, value]) => (
65
- <KeyValue
66
- key={name}
67
- alphaSort={true}
68
- depth={1}
69
- inspectPath={inspectPath}
70
- name={name}
71
- overrideValueFn={overrideValueFn}
72
- path={[name]}
73
- value={value}
74
- />
75
- ))}
76
- </div>
77
- );
78
- }
79
-}
packages/react-devtools-shared/src/devtools/views/Components/KeyValue.css
deleted
-41
@@ -1,41 +0,0 @@
1
-.Item:not([hidden]) {
2
- display: flex;
3
-}
4
-
5
-.Name {
6
- color: var(--color-dim);
7
- flex: 0 0 auto;
8
- user-select: none;
9
-}
10
-.EditableName {
11
- color: var(--color-attribute-name);
12
- flex: 0 0 auto;
13
- user-select: none;
14
-}
15
-.EditableName:after,
16
-.Name:after {
17
- content: ': ';
18
- color: var(--color-text);
19
- margin-right: 0.5rem;
20
-}
21
-
22
-.Value {
23
- color: var(--color-attribute-value);
24
- white-space: nowrap;
25
- overflow: hidden;
26
- text-overflow: ellipsis;
27
-}
28
-
29
-.None {
30
- color: var(--color-dimmer);
31
- font-style: italic;
32
-}
33
-
34
-.ExpandCollapseToggleSpacer {
35
- flex: 0 0 1rem;
36
- width: 1rem;
37
-}
38
-
39
-.Empty {
40
- color: var(--color-dimmer);
41
-}
packages/react-devtools-shared/src/devtools/views/Components/KeyValue.js
deleted
-229
@@ -1,229 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useEffect, useRef, useState} from 'react';
11
-import type {Element} from 'react';
12
-import EditableValue from './EditableValue';
13
-import ExpandCollapseToggle from './ExpandCollapseToggle';
14
-import {alphaSortEntries, getMetaValueLabel} from '../utils';
15
-import {meta} from '../../../hydration';
16
-import styles from './KeyValue.css';
17
-
18
-import type {InspectPath} from './SelectedElement';
19
-
20
-type OverrideValueFn = (path: Array<string | number>, value: any) => void;
21
-
22
-type KeyValueProps = {|
23
- alphaSort: boolean,
24
- depth: number,
25
- hidden?: boolean,
26
- inspectPath?: InspectPath,
27
- isReadOnly?: boolean,
28
- name: string,
29
- overrideValueFn?: ?OverrideValueFn,
30
- path: Array<any>,
31
- value: any,
32
-|};
33
-
34
-export default function KeyValue({
35
- alphaSort,
36
- depth,
37
- inspectPath,
38
- isReadOnly,
39
- hidden,
40
- name,
41
- overrideValueFn,
42
- path,
43
- value,
44
-}: KeyValueProps) {
45
- const [isOpen, setIsOpen] = useState<boolean>(false);
46
- const prevIsOpenRef = useRef(isOpen);
47
-
48
- const isInspectable =
49
- value !== null &&
50
- typeof value === 'object' &&
51
- value[meta.inspectable] &&
52
- value[meta.size] !== 0;
53
-
54
- useEffect(
55
- () => {
56
- if (
57
- isInspectable &&
58
- isOpen &&
59
- !prevIsOpenRef.current &&
60
- typeof inspectPath === 'function'
61
- ) {
62
- inspectPath(path);
63
- }
64
- prevIsOpenRef.current = isOpen;
65
- },
66
- [inspectPath, isInspectable, isOpen, path],
67
- );
68
-
69
- const toggleIsOpen = () => setIsOpen(prevIsOpen => !prevIsOpen);
70
-
71
- const dataType = typeof value;
72
- const isSimpleType =
73
- dataType === 'number' ||
74
- dataType === 'string' ||
75
- dataType === 'boolean' ||
76
- value == null;
77
-
78
- const style = {
79
- paddingLeft: `${(depth - 1) * 0.75}rem`,
80
- };
81
-
82
- let children = null;
83
- if (isSimpleType) {
84
- let displayValue = value;
85
- if (dataType === 'string') {
86
- displayValue = `"${value}"`;
87
- } else if (dataType === 'boolean') {
88
- displayValue = value ? 'true' : 'false';
89
- } else if (value === null) {
90
- displayValue = 'null';
91
- } else if (value === undefined) {
92
- displayValue = 'undefined';
93
- }
94
-
95
- const isEditable = typeof overrideValueFn === 'function' && !isReadOnly;
96
-
97
- children = (
98
- <div key="root" className={styles.Item} hidden={hidden} style={style}>
99
- <div className={styles.ExpandCollapseToggleSpacer} />
100
- <span className={isEditable ? styles.EditableName : styles.Name}>
101
- {name}
102
- </span>
103
- {isEditable ? (
104
- <EditableValue
105
- dataType={dataType}
106
- overrideValueFn={((overrideValueFn: any): OverrideValueFn)}
107
- path={path}
108
- value={value}
109
- />
110
- ) : (
111
- <span className={styles.Value}>{displayValue}</span>
112
- )}
113
- </div>
114
- );
115
- } else if (
116
- value.hasOwnProperty(meta.type) &&
117
- !value.hasOwnProperty(meta.unserializable)
118
- ) {
119
- children = (
120
- <div key="root" className={styles.Item} hidden={hidden} style={style}>
121
- {isInspectable ? (
122
- <ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
123
- ) : (
124
- <div className={styles.ExpandCollapseToggleSpacer} />
125
- )}
126
- <span
127
- className={styles.Name}
128
- onClick={isInspectable ? toggleIsOpen : undefined}>
129
- {name}
130
- </span>
131
- <span className={styles.Value}>{getMetaValueLabel(value)}</span>
132
- </div>
133
- );
134
- } else {
135
- if (Array.isArray(value)) {
136
- const hasChildren = value.length > 0;
137
-
138
- children = value.map((innerValue, index) => (
139
- <KeyValue
140
- key={index}
141
- alphaSort={alphaSort}
142
- depth={depth + 1}
143
- inspectPath={inspectPath}
144
- isReadOnly={isReadOnly}
145
- hidden={hidden || !isOpen}
146
- name={index}
147
- overrideValueFn={overrideValueFn}
148
- path={path.concat(index)}
149
- value={value[index]}
150
- />
151
- ));
152
- children.unshift(
153
- <div
154
- key={`${depth}-root`}
155
- className={styles.Item}
156
- hidden={hidden}
157
- style={style}>
158
- {hasChildren ? (
159
- <ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
160
- ) : (
161
- <div className={styles.ExpandCollapseToggleSpacer} />
162
- )}
163
- <span
164
- className={styles.Name}
165
- onClick={hasChildren ? toggleIsOpen : undefined}>
166
- {name}
167
- </span>
168
- <span>
169
- Array{' '}
170
- {hasChildren ? '' : <span className={styles.Empty}>(empty)</span>}
171
- </span>
172
- </div>,
173
- );
174
- } else {
175
- // TRICKY
176
- // It's important to use Object.entries() rather than Object.keys()
177
- // because of the hidden meta Symbols used for hydration and unserializable values.
178
- const entries = Object.entries(value);
179
- if (alphaSort) {
180
- entries.sort(alphaSortEntries);
181
- }
182
-
183
- const hasChildren = entries.length > 0;
184
- const displayName = value.hasOwnProperty(meta.unserializable)
185
- ? getMetaValueLabel(value)
186
- : 'Object';
187
-
188
- let areChildrenReadOnly = isReadOnly || !!value[meta.readonly];
189
- children = entries.map<Element<any>>(([key, keyValue]) => (
190
- <KeyValue
191
- key={key}
192
- alphaSort={alphaSort}
193
- depth={depth + 1}
194
- inspectPath={inspectPath}
195
- isReadOnly={areChildrenReadOnly}
196
- hidden={hidden || !isOpen}
197
- name={key}
198
- overrideValueFn={overrideValueFn}
199
- path={path.concat(key)}
200
- value={keyValue}
201
- />
202
- ));
203
- children.unshift(
204
- <div
205
- key={`${depth}-root`}
206
- className={styles.Item}
207
- hidden={hidden}
208
- style={style}>
209
- {hasChildren ? (
210
- <ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
211
- ) : (
212
- <div className={styles.ExpandCollapseToggleSpacer} />
213
- )}
214
- <span
215
- className={styles.Name}
216
- onClick={hasChildren ? toggleIsOpen : undefined}>
217
- {name}
218
- </span>
219
- <span>
220
- {`${displayName || ''} `}
221
- {hasChildren ? '' : <span className={styles.Empty}>(empty)</span>}
222
- </span>
223
- </div>,
224
- );
225
- }
226
- }
227
-
228
- return children;
229
-}
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/AutoSizeInput.css
deleted
-26
@@ -1,26 +0,0 @@
1
-.Input {
2
- width: 0;
3
- min-width: 0.5rem;
4
- flex: 1 1 auto;
5
- border: none;
6
- background: transparent;
7
- outline: none;
8
- padding: 0;
9
- border: none;
10
- font-family: var(--font-family-monospace);
11
- font-size: var(--font-size-monospace-normal);
12
-}
13
-
14
-.Input:focus {
15
- border-color: var(--color-border);
16
-}
17
-
18
-.HiddenDiv {
19
- position: absolute;
20
- top: 0;
21
- left: 0;
22
- visibility: hidden;
23
- height: 0;
24
- overflow: scroll;
25
- white-space: pre;
26
-}
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/AutoSizeInput.js
deleted
-107
@@ -1,107 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useLayoutEffect, useRef} from 'react';
11
-import styles from './AutoSizeInput.css';
12
-
13
-type Props = {
14
- className?: string,
15
- onFocus?: (event: FocusEvent) => void,
16
- placeholder?: string,
17
- value: any,
18
-};
19
-
20
-export default function AutoSizeInput({
21
- className,
22
- onFocus,
23
- placeholder,
24
- value,
25
- ...rest
26
-}: Props) {
27
- const hiddenDivRef = useRef<HTMLDivElement | null>(null);
28
- const inputRef = useRef<HTMLInputElement | null>(null);
29
-
30
- const onFocusWrapper = event => {
31
- if (inputRef.current !== null) {
32
- inputRef.current.selectionStart = 0;
33
- inputRef.current.selectionEnd = value.length;
34
- }
35
-
36
- if (typeof onFocus === 'function') {
37
- onFocus(event);
38
- }
39
- };
40
-
41
- // Copy text stlyes from <input> to hidden sizing <div>
42
- useLayoutEffect(() => {
43
- if (
44
- typeof window.getComputedStyle !== 'function' ||
45
- inputRef.current === null
46
- ) {
47
- return;
48
- }
49
-
50
- const inputStyle = window.getComputedStyle(inputRef.current);
51
- if (!inputStyle) {
52
- return;
53
- }
54
-
55
- if (hiddenDivRef.current !== null) {
56
- const divStyle = hiddenDivRef.current.style;
57
- divStyle.border = inputStyle.border;
58
- divStyle.fontFamily = inputStyle.fontFamily;
59
- divStyle.fontSize = inputStyle.fontSize;
60
- divStyle.fontStyle = inputStyle.fontStyle;
61
- divStyle.fontWeight = inputStyle.fontWeight;
62
- divStyle.letterSpacing = inputStyle.letterSpacing;
63
- divStyle.padding = inputStyle.padding;
64
- }
65
- }, []);
66
-
67
- // Resize input any time text changes
68
- useLayoutEffect(
69
- () => {
70
- if (hiddenDivRef.current === null) {
71
- return;
72
- }
73
-
74
- const scrollWidth = hiddenDivRef.current.getBoundingClientRect().width;
75
- if (!scrollWidth) {
76
- return;
77
- }
78
-
79
- // Adding an extra pixel avoids a slight horizontal scroll when changing text selection/cursor.
80
- // Not sure why this is, but the old DevTools did a similar thing.
81
- const targetWidth = Math.ceil(scrollWidth) + 1;
82
-
83
- if (inputRef.current !== null) {
84
- inputRef.current.style.width = `${targetWidth}px`;
85
- }
86
- },
87
- [value],
88
- );
89
-
90
- const isEmpty = value === '' || value === '""';
91
-
92
- return (
93
- <Fragment>
94
- <input
95
- ref={inputRef}
96
- className={`${className ? className : ''} ${styles.Input}`}
97
- onFocus={onFocusWrapper}
98
- placeholder={placeholder}
99
- value={isEmpty ? '' : value}
100
- {...rest}
101
- />
102
- <div ref={hiddenDivRef} className={styles.HiddenDiv}>
103
- {isEmpty ? placeholder : value}
104
- </div>
105
- </Fragment>
106
- );
107
-}
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/LayoutViewer.css
deleted
-50
@@ -1,50 +0,0 @@
1
-.LayoutViewer {
2
- padding: 0.25rem;
3
- border-top: 1px solid var(--color-border);
4
- font-family: var(--font-family-monospace);
5
- font-size: var(--font-size-monospace-small);
6
-}
7
-
8
-.Header {
9
- font-family: var(--font-family-sans);
10
-}
11
-
12
-.DashedBox,
13
-.SolidBox {
14
- flex: 1 1 auto;
15
- display: flex;
16
- flex-direction: column;
17
- align-items: center;
18
- border-width: 1px;
19
- border-color: var(--color-dim);
20
- padding: 0.25rem;
21
- margin: 0.25rem;
22
-}
23
-.DashedBox {
24
- border-style: dashed;
25
-}
26
-.SolidBox {
27
- border-style: solid;
28
-}
29
-
30
-.LabelRow {
31
- width: 100%;
32
- position: relative;
33
- display: flex;
34
- align-items: center;
35
- justify-content: center;
36
-}
37
-
38
-.Label {
39
- position: absolute;
40
- left: 0.5rem;
41
- flex: 1 0 100px;
42
- color: var(--color-attribute-name);
43
-}
44
-
45
-.BoxRow {
46
- width: 100%;
47
- display: flex;
48
- flex-direction: row;
49
- align-items: center;
50
-}
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/LayoutViewer.js
deleted
-71
@@ -1,71 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-import styles from './LayoutViewer.css';
12
-
13
-import type {Layout} from './types';
14
-
15
-type Props = {|
16
- id: number,
17
- layout: Layout,
18
-|};
19
-
20
-export default function LayoutViewer({id, layout}: Props) {
21
- const {height, margin, padding, y, width, x} = layout;
22
-
23
- return (
24
- <div className={styles.LayoutViewer}>
25
- <div className={styles.Header}>layout</div>
26
- <div className={styles.DashedBox}>
27
- <div className={styles.LabelRow}>
28
- <label className={styles.Label}>margin</label>
29
-
30
- <label>{margin.top || '-'}</label>
31
- </div>
32
-
33
- <div className={styles.BoxRow}>
34
- <label>{margin.left || '-'}</label>
35
-
36
- <div className={styles.SolidBox}>
37
- <div className={styles.LabelRow}>
38
- <label className={styles.Label}>padding</label>
39
-
40
- <label>{padding.top || '-'}</label>
41
- </div>
42
-
43
- <div className={styles.BoxRow}>
44
- <label>{padding.left || '-'}</label>
45
-
46
- <div className={styles.DashedBox}>
47
- <div className={styles.LabelRow}>
48
- {format(width)} x {format(height)} ({format(x)}, {format(y)})
49
- </div>
50
- </div>
51
-
52
- <label>{padding.right || '-'}</label>
53
- </div>
54
-
55
- <label>{padding.bottom || '-'}</label>
56
- </div>
57
- <label>{margin.right || '-'}</label>
58
- </div>
59
- <label>{margin.bottom || '-'}</label>
60
- </div>
61
- </div>
62
- );
63
-}
64
-
65
-function format(number: number): string | number {
66
- if (Math.round(number) === number) {
67
- return number;
68
- } else {
69
- return number.toFixed(1);
70
- }
71
-}
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/StyleEditor.css
deleted
-58
@@ -1,58 +0,0 @@
1
-.StyleEditor {
2
- font-family: var(--font-family-monospace);
3
- font-size: var(--font-size-monospace-normal);
4
- padding: 0.25rem;
5
- border-top: 1px solid var(--color-border);
6
-}
7
-
8
-.HeaderRow {
9
- display: flex;
10
- align-items: center;
11
-}
12
-
13
-.Header {
14
- flex: 1 1;
15
-}
16
-
17
-.Brackets {
18
- font-family: var(--font-family-sans);
19
- font-size: var(--font-size-sans-small);
20
-}
21
-
22
-.Row {
23
- white-space: nowrap;
24
- padding-left: 1rem;
25
- display: flex;
26
- align-items: center;
27
-}
28
-
29
-.Invalid {
30
- background-color: var(--color-background-invalid);
31
- color: var(--color-text-invalid);
32
-
33
- --color-border: var(--color-text-invalid);
34
-}
35
-.Attribute {
36
- color: var(--color-attribute-name);
37
-}
38
-
39
-.Value {
40
- color: var(--color-attribute-value);
41
-}
42
-
43
-.Input {
44
- flex: 0 1 auto;
45
- padding: 1px;
46
- box-shadow: 0px 1px 3px transparent;
47
-}
48
-.Input:focus {
49
- color: var(--color-text);
50
- box-shadow: 0px 1px 3px var(--color-shadow);
51
-}
52
-
53
-.Empty {
54
- color: var(--color-dimmer);
55
- font-style: italic;
56
- user-select: none;
57
- padding-left: 1rem;
58
-}
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/StyleEditor.js
deleted
-305
@@ -1,305 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useContext, useMemo, useRef, useState} from 'react';
11
-import {unstable_batchedUpdates as batchedUpdates} from 'react-dom';
12
-import {copy} from 'clipboard-js';
13
-import {
14
- BridgeContext,
15
- StoreContext,
16
-} from 'react-devtools-shared/src/devtools/views/context';
17
-import Button from '../../Button';
18
-import ButtonIcon from '../../ButtonIcon';
19
-import {serializeDataForCopy} from '../../utils';
20
-import AutoSizeInput from './AutoSizeInput';
21
-import styles from './StyleEditor.css';
22
-
23
-import type {Style} from './types';
24
-
25
-type Props = {|
26
- id: number,
27
- style: Style,
28
-|};
29
-
30
-type ChangeAttributeFn = (oldName: string, newName: string, value: any) => void;
31
-type ChangeValueFn = (name: string, value: any) => void;
32
-
33
-export default function StyleEditor({id, style}: Props) {
34
- const bridge = useContext(BridgeContext);
35
- const store = useContext(StoreContext);
36
-
37
- const changeAttribute = (oldName: string, newName: string, value: any) => {
38
- const rendererID = store.getRendererIDForElement(id);
39
- if (rendererID !== null) {
40
- bridge.send('NativeStyleEditor_renameAttribute', {
41
- id,
42
- rendererID,
43
- oldName,
44
- newName,
45
- value,
46
- });
47
- }
48
- };
49
-
50
- const changeValue = (name: string, value: any) => {
51
- const rendererID = store.getRendererIDForElement(id);
52
- if (rendererID !== null) {
53
- bridge.send('NativeStyleEditor_setValue', {
54
- id,
55
- rendererID,
56
- name,
57
- value,
58
- });
59
- }
60
- };
61
-
62
- const keys = useMemo(() => Array.from(Object.keys(style)), [style]);
63
-
64
- const handleCopy = () => copy(serializeDataForCopy(style));
65
-
66
- return (
67
- <div className={styles.StyleEditor}>
68
- <div className={styles.HeaderRow}>
69
- <div className={styles.Header}>
70
- <div className={styles.Brackets}>{'style {'}</div>
71
- </div>
72
- <Button onClick={handleCopy} title="Copy to clipboard">
73
- <ButtonIcon type="copy" />
74
- </Button>
75
- </div>
76
- {keys.length > 0 &&
77
- keys.map(attribute => (
78
- <Row
79
- key={attribute}
80
- attribute={attribute}
81
- changeAttribute={changeAttribute}
82
- changeValue={changeValue}
83
- validAttributes={store.nativeStyleEditorValidAttributes}
84
- value={style[attribute]}
85
- />
86
- ))}
87
- <NewRow
88
- changeAttribute={changeAttribute}
89
- changeValue={changeValue}
90
- validAttributes={store.nativeStyleEditorValidAttributes}
91
- />
92
- <div className={styles.Brackets}>{'}'}</div>
93
- </div>
94
- );
95
-}
96
-
97
-type NewRowProps = {|
98
- changeAttribute: ChangeAttributeFn,
99
- changeValue: ChangeValueFn,
100
- validAttributes: $ReadOnlyArray<string> | null,
101
-|};
102
-
103
-function NewRow({changeAttribute, changeValue, validAttributes}: NewRowProps) {
104
- const [key, setKey] = useState<number>(0);
105
- const reset = () => setKey(key + 1);
106
-
107
- const newAttributeRef = useRef<string>('');
108
-
109
- const changeAttributeWrapper = (
110
- oldAttribute: string,
111
- newAttribute: string,
112
- value: any,
113
- ) => {
114
- // Ignore attribute changes until a value has been specified
115
- newAttributeRef.current = newAttribute;
116
- };
117
-
118
- const changeValueWrapper = (attribute: string, value: any) => {
119
- // Blur events should reset/cancel if there's no value or no attribute
120
- if (newAttributeRef.current !== '') {
121
- if (value !== '') {
122
- changeValue(newAttributeRef.current, value);
123
- }
124
- reset();
125
- }
126
- };
127
-
128
- return (
129
- <Row
130
- key={key}
131
- attribute={''}
132
- attributePlaceholder="attribute"
133
- changeAttribute={changeAttributeWrapper}
134
- changeValue={changeValueWrapper}
135
- validAttributes={validAttributes}
136
- value={''}
137
- valuePlaceholder="value"
138
- />
139
- );
140
-}
141
-
142
-type RowProps = {|
143
- attribute: string,
144
- attributePlaceholder?: string,
145
- changeAttribute: ChangeAttributeFn,
146
- changeValue: ChangeValueFn,
147
- validAttributes: $ReadOnlyArray<string> | null,
148
- value: any,
149
- valuePlaceholder?: string,
150
-|};
151
-
152
-function Row({
153
- attribute,
154
- attributePlaceholder,
155
- changeAttribute,
156
- changeValue,
157
- validAttributes,
158
- value,
159
- valuePlaceholder,
160
-}: RowProps) {
161
- // TODO (RN style editor) Use @reach/combobox to auto-complete attributes.
162
- // The list of valid attributes would need to be injected by RN backend,
163
- // which would need to require them from ReactNativeViewViewConfig "validAttributes.style" keys.
164
- // This would need to degrade gracefully for react-native-web,
165
- // althoguh we could let it also inject a custom set of whitelisted attributes.
166
-
167
- const [localAttribute, setLocalAttribute] = useState(attribute);
168
- const [localValue, setLocalValue] = useState(JSON.stringify(value));
169
- const [isAttributeValid, setIsAttributeValid] = useState(true);
170
- const [isValueValid, setIsValueValid] = useState(true);
171
-
172
- const validateAndSetLocalAttribute = newAttribute => {
173
- const isValid =
174
- newAttribute === '' ||
175
- validAttributes === null ||
176
- validAttributes.indexOf(newAttribute) >= 0;
177
-
178
- batchedUpdates(() => {
179
- setLocalAttribute(newAttribute);
180
- setIsAttributeValid(isValid);
181
- });
182
- };
183
-
184
- const validateAndSetLocalValue = newValue => {
185
- let isValid = false;
186
- try {
187
- JSON.parse(sanitizeForParse(newValue));
188
- isValid = true;
189
- } catch (error) {}
190
-
191
- batchedUpdates(() => {
192
- setLocalValue(newValue);
193
- setIsValueValid(isValid);
194
- });
195
- };
196
-
197
- const resetAttribute = () => {
198
- setLocalAttribute(attribute);
199
- };
200
-
201
- const resetValue = () => {
202
- setLocalValue(value);
203
- };
204
-
205
- const submitValueChange = () => {
206
- if (isAttributeValid && isValueValid) {
207
- const parsedLocalValue = JSON.parse(sanitizeForParse(localValue));
208
- if (value !== parsedLocalValue) {
209
- changeValue(attribute, parsedLocalValue);
210
- }
211
- }
212
- };
213
-
214
- const submitAttributeChange = () => {
215
- if (isAttributeValid && isValueValid) {
216
- if (attribute !== localAttribute) {
217
- changeAttribute(attribute, localAttribute, value);
218
- }
219
- }
220
- };
221
-
222
- return (
223
- <div className={styles.Row}>
224
- <Field
225
- className={isAttributeValid ? styles.Attribute : styles.Invalid}
226
- onChange={validateAndSetLocalAttribute}
227
- onReset={resetAttribute}
228
- onSubmit={submitAttributeChange}
229
- placeholder={attributePlaceholder}
230
- value={localAttribute}
231
- />
232
- :
233
- <Field
234
- className={isValueValid ? styles.Value : styles.Invalid}
235
- onChange={validateAndSetLocalValue}
236
- onReset={resetValue}
237
- onSubmit={submitValueChange}
238
- placeholder={valuePlaceholder}
239
- value={localValue}
240
- />
241
- ;
242
- </div>
243
- );
244
-}
245
-
246
-type FieldProps = {|
247
- className: string,
248
- onChange: (value: any) => void,
249
- onReset: () => void,
250
- onSubmit: () => void,
251
- placeholder?: string,
252
- value: any,
253
-|};
254
-
255
-function Field({
256
- className,
257
- onChange,
258
- onReset,
259
- onSubmit,
260
- placeholder,
261
- value,
262
-}: FieldProps) {
263
- const onKeyDown = event => {
264
- switch (event.key) {
265
- case 'Enter':
266
- onSubmit();
267
- break;
268
- case 'Escape':
269
- onReset();
270
- break;
271
- case 'ArrowDown':
272
- case 'ArrowLeft':
273
- case 'ArrowRight':
274
- case 'ArrowUp':
275
- event.stopPropagation();
276
- break;
277
- default:
278
- break;
279
- }
280
- };
281
-
282
- return (
283
- <AutoSizeInput
284
- className={`${className} ${styles.Input}`}
285
- onBlur={onSubmit}
286
- onChange={event => onChange(event.target.value)}
287
- onKeyDown={onKeyDown}
288
- placeholder={placeholder}
289
- value={value}
290
- />
291
- );
292
-}
293
-
294
-// We use JSON.parse to parse string values
295
-// e.g. 'foo' is not valid JSON but it is a valid string
296
-// so this method replaces e.g. 'foo' with "foo"
297
-function sanitizeForParse(value: any) {
298
- if (typeof value === 'string') {
299
- if (value.charAt(0) === "'" && value.charAt(value.length - 1) === "'") {
300
- return '"' + value.substr(1, value.length - 2) + '"';
301
- }
302
- }
303
-
304
- return value;
305
-}
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/context.js
deleted
-207
@@ -1,207 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- createContext,
12
- useCallback,
13
- useContext,
14
- useEffect,
15
- useMemo,
16
- useState,
17
-} from 'react';
18
-import {unstable_batchedUpdates as batchedUpdates} from 'react-dom';
19
-import {createResource} from 'react-devtools-shared/src/devtools/cache';
20
-import {
21
- BridgeContext,
22
- StoreContext,
23
-} from 'react-devtools-shared/src/devtools/views/context';
24
-import {TreeStateContext} from '../TreeContext';
25
-
26
-import type {StyleAndLayout as StyleAndLayoutBackend} from 'react-devtools-shared/src/backend/NativeStyleEditor/types';
27
-import type {StyleAndLayout as StyleAndLayoutFrontend} from './types';
28
-import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types';
29
-import type {
30
- Resource,
31
- Thenable,
32
-} from 'react-devtools-shared/src/devtools/cache';
33
-
34
-export type GetStyleAndLayout = (id: number) => StyleAndLayoutFrontend | null;
35
-
36
-type Context = {|
37
- getStyleAndLayout: GetStyleAndLayout,
38
-|};
39
-
40
-const NativeStyleContext = createContext<Context>(((null: any): Context));
41
-NativeStyleContext.displayName = 'NativeStyleContext';
42
-
43
-type ResolveFn = (styleAndLayout: StyleAndLayoutFrontend) => void;
44
-type InProgressRequest = {|
45
- promise: Thenable<StyleAndLayoutFrontend>,
46
- resolveFn: ResolveFn,
47
-|};
48
-
49
-const inProgressRequests: WeakMap<Element, InProgressRequest> = new WeakMap();
50
-const resource: Resource<
51
- Element,
52
- Element,
53
- StyleAndLayoutFrontend,
54
-> = createResource(
55
- (element: Element) => {
56
- let request = inProgressRequests.get(element);
57
- if (request != null) {
58
- return request.promise;
59
- }
60
-
61
- let resolveFn = ((null: any): ResolveFn);
62
- const promise = new Promise(resolve => {
63
- resolveFn = resolve;
64
- });
65
-
66
- inProgressRequests.set(element, {promise, resolveFn});
67
-
68
- return promise;
69
- },
70
- (element: Element) => element,
71
- {useWeakMap: true},
72
-);
73
-
74
-type Props = {|
75
- children: React$Node,
76
-|};
77
-
78
-function NativeStyleContextController({children}: Props) {
79
- const bridge = useContext(BridgeContext);
80
- const store = useContext(StoreContext);
81
-
82
- const getStyleAndLayout = useCallback<GetStyleAndLayout>(
83
- (id: number) => {
84
- const element = store.getElementByID(id);
85
- if (element !== null) {
86
- return resource.read(element);
87
- } else {
88
- return null;
89
- }
90
- },
91
- [store],
92
- );
93
-
94
- // It's very important that this context consumes selectedElementID and not NativeStyleID.
95
- // Otherwise the effect that sends the "inspect" message across the bridge-
96
- // would itself be blocked by the same render that suspends (waiting for the data).
97
- const {selectedElementID} = useContext(TreeStateContext);
98
-
99
- const [
100
- currentStyleAndLayout,
101
- setCurrentStyleAndLayout,
102
- ] = useState<StyleAndLayoutFrontend | null>(null);
103
-
104
- // This effect handler invalidates the suspense cache and schedules rendering updates with React.
105
- useEffect(
106
- () => {
107
- const onStyleAndLayout = ({id, layout, style}: StyleAndLayoutBackend) => {
108
- let element = store.getElementByID(id);
109
- if (element !== null) {
110
- const styleAndLayout: StyleAndLayoutFrontend = {
111
- layout,
112
- style,
113
- };
114
- const request = inProgressRequests.get(element);
115
- if (request != null) {
116
- inProgressRequests.delete(element);
117
- batchedUpdates(() => {
118
- request.resolveFn(styleAndLayout);
119
- setCurrentStyleAndLayout(styleAndLayout);
120
- });
121
- } else {
122
- resource.write(element, styleAndLayout);
123
-
124
- // Schedule update with React if the curently-selected element has been invalidated.
125
- if (id === selectedElementID) {
126
- setCurrentStyleAndLayout(styleAndLayout);
127
- }
128
- }
129
- }
130
- };
131
-
132
- bridge.addListener('NativeStyleEditor_styleAndLayout', onStyleAndLayout);
133
- return () =>
134
- bridge.removeListener(
135
- 'NativeStyleEditor_styleAndLayout',
136
- onStyleAndLayout,
137
- );
138
- },
139
- [bridge, currentStyleAndLayout, selectedElementID, store],
140
- );
141
-
142
- // This effect handler polls for updates on the currently selected element.
143
- useEffect(
144
- () => {
145
- if (selectedElementID === null) {
146
- return () => {};
147
- }
148
-
149
- const rendererID = store.getRendererIDForElement(selectedElementID);
150
-
151
- let timeoutID: TimeoutID | null = null;
152
-
153
- const sendRequest = () => {
154
- timeoutID = null;
155
-
156
- if (rendererID !== null) {
157
- bridge.send('NativeStyleEditor_measure', {
158
- id: selectedElementID,
159
- rendererID,
160
- });
161
- }
162
- };
163
-
164
- // Send the initial measurement request.
165
- // We'll poll for an update in the response handler below.
166
- sendRequest();
167
-
168
- const onStyleAndLayout = ({id}: StyleAndLayoutBackend) => {
169
- // If this is the element we requested, wait a little bit and then ask for another update.
170
- if (id === selectedElementID) {
171
- if (timeoutID !== null) {
172
- clearTimeout(timeoutID);
173
- }
174
- timeoutID = setTimeout(sendRequest, 1000);
175
- }
176
- };
177
-
178
- bridge.addListener('NativeStyleEditor_styleAndLayout', onStyleAndLayout);
179
-
180
- return () => {
181
- bridge.removeListener(
182
- 'NativeStyleEditor_styleAndLayout',
183
- onStyleAndLayout,
184
- );
185
-
186
- if (timeoutID !== null) {
187
- clearTimeout(timeoutID);
188
- }
189
- };
190
- },
191
- [bridge, selectedElementID, store],
192
- );
193
-
194
- const value = useMemo(
195
- () => ({getStyleAndLayout}),
196
- // NativeStyle is used to invalidate the cache and schedule an update with React.
197
- [currentStyleAndLayout, getStyleAndLayout],
198
- );
199
-
200
- return (
201
- <NativeStyleContext.Provider value={value}>
202
- {children}
203
- </NativeStyleContext.Provider>
204
- );
205
-}
206
-
207
-export {NativeStyleContext, NativeStyleContextController};
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/index.js
deleted
-72
@@ -1,72 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useContext, useMemo} from 'react';
11
-import {StoreContext} from 'react-devtools-shared/src/devtools/views/context';
12
-import {useSubscription} from 'react-devtools-shared/src/devtools/views/hooks';
13
-import {NativeStyleContext} from './context';
14
-import LayoutViewer from './LayoutViewer';
15
-import StyleEditor from './StyleEditor';
16
-import {TreeStateContext} from '../TreeContext';
17
-
18
-type Props = {||};
19
-
20
-export default function NativeStyleEditorWrapper(_: Props) {
21
- const store = useContext(StoreContext);
22
-
23
- const subscription = useMemo(
24
- () => ({
25
- getCurrentValue: () => store.supportsNativeStyleEditor,
26
- subscribe: (callback: Function) => {
27
- store.addListener('supportsNativeStyleEditor', callback);
28
- return () => {
29
- store.removeListener('supportsNativeStyleEditor', callback);
30
- };
31
- },
32
- }),
33
- [store],
34
- );
35
- const supportsNativeStyleEditor = useSubscription<boolean>(subscription);
36
-
37
- if (!supportsNativeStyleEditor) {
38
- return null;
39
- }
40
-
41
- return <NativeStyleEditor />;
42
-}
43
-
44
-function NativeStyleEditor(_: Props) {
45
- const {getStyleAndLayout} = useContext(NativeStyleContext);
46
-
47
- const {inspectedElementID} = useContext(TreeStateContext);
48
- if (inspectedElementID === null) {
49
- return null;
50
- }
51
-
52
- const maybeStyleAndLayout = getStyleAndLayout(inspectedElementID);
53
- if (maybeStyleAndLayout === null) {
54
- return null;
55
- }
56
-
57
- const {layout, style} = maybeStyleAndLayout;
58
-
59
- return (
60
- <Fragment>
61
- {layout !== null && (
62
- <LayoutViewer id={inspectedElementID} layout={layout} />
63
- )}
64
- {style !== null && (
65
- <StyleEditor
66
- id={inspectedElementID}
67
- style={style !== null ? style : {}}
68
- />
69
- )}
70
- </Fragment>
71
- );
72
-}
packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/types.js
deleted
-20
@@ -1,20 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {
11
- Layout as LayoutBackend,
12
- Style as StyleBackend,
13
-} from 'react-devtools-shared/src/backend/NativeStyleEditor/types';
14
-
15
-export type Layout = LayoutBackend;
16
-export type Style = StyleBackend;
17
-export type StyleAndLayout = {|
18
- layout: LayoutBackend | null,
19
- style: StyleBackend | null,
20
-|};
packages/react-devtools-shared/src/devtools/views/Components/OwnersListContext.js
deleted
-138
@@ -1,138 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {createContext, useCallback, useContext, useEffect} from 'react';
11
-import {createResource} from '../../cache';
12
-import {BridgeContext, StoreContext} from '../context';
13
-import {TreeStateContext} from './TreeContext';
14
-import {separateDisplayNameAndHOCs} from 'react-devtools-shared/src/utils';
15
-
16
-import type {OwnersList} from 'react-devtools-shared/src/backend/types';
17
-import type {
18
- Element,
19
- Owner,
20
-} from 'react-devtools-shared/src/devtools/views/Components/types';
21
-import type {Resource, Thenable} from '../../cache';
22
-
23
-type Context = (id: number) => Array<Owner> | null;
24
-
25
-const OwnersListContext = createContext<Context>(((null: any): Context));
26
-OwnersListContext.displayName = 'OwnersListContext';
27
-
28
-type ResolveFn = (ownersList: Array<Owner> | null) => void;
29
-type InProgressRequest = {|
30
- promise: Thenable<Array<Owner>>,
31
- resolveFn: ResolveFn,
32
-|};
33
-
34
-const inProgressRequests: WeakMap<Element, InProgressRequest> = new WeakMap();
35
-const resource: Resource<Element, Element, Array<Owner>> = createResource(
36
- (element: Element) => {
37
- let request = inProgressRequests.get(element);
38
- if (request != null) {
39
- return request.promise;
40
- }
41
-
42
- let resolveFn = ((null: any): ResolveFn);
43
- const promise = new Promise(resolve => {
44
- resolveFn = resolve;
45
- });
46
-
47
- inProgressRequests.set(element, {promise, resolveFn});
48
-
49
- return promise;
50
- },
51
- (element: Element) => element,
52
- {useWeakMap: true},
53
-);
54
-
55
-type Props = {|
56
- children: React$Node,
57
-|};
58
-
59
-function OwnersListContextController({children}: Props) {
60
- const bridge = useContext(BridgeContext);
61
- const store = useContext(StoreContext);
62
- const {ownerID} = useContext(TreeStateContext);
63
-
64
- const read = useCallback(
65
- (id: number) => {
66
- const element = store.getElementByID(id);
67
- if (element !== null) {
68
- return resource.read(element);
69
- } else {
70
- return null;
71
- }
72
- },
73
- [store],
74
- );
75
-
76
- useEffect(
77
- () => {
78
- const onOwnersList = (ownersList: OwnersList) => {
79
- const id = ownersList.id;
80
-
81
- const element = store.getElementByID(id);
82
- if (element !== null) {
83
- const request = inProgressRequests.get(element);
84
- if (request != null) {
85
- inProgressRequests.delete(element);
86
-
87
- request.resolveFn(
88
- ownersList.owners === null
89
- ? null
90
- : ownersList.owners.map(owner => {
91
- const [
92
- displayNameWithoutHOCs,
93
- hocDisplayNames,
94
- ] = separateDisplayNameAndHOCs(
95
- owner.displayName,
96
- owner.type,
97
- );
98
-
99
- return {
100
- ...owner,
101
- displayName: displayNameWithoutHOCs,
102
- hocDisplayNames,
103
- };
104
- }),
105
- );
106
- }
107
- }
108
- };
109
-
110
- bridge.addListener('ownersList', onOwnersList);
111
- return () => bridge.removeListener('ownersList', onOwnersList);
112
- },
113
- [bridge, store],
114
- );
115
-
116
- // This effect requests an updated owners list any time the selected owner changes
117
- useEffect(
118
- () => {
119
- if (ownerID !== null) {
120
- const rendererID = store.getRendererIDForElement(ownerID);
121
- if (rendererID !== null) {
122
- bridge.send('getOwnersList', {id: ownerID, rendererID});
123
- }
124
- }
125
-
126
- return () => {};
127
- },
128
- [bridge, ownerID, store],
129
- );
130
-
131
- return (
132
- <OwnersListContext.Provider value={read}>
133
- {children}
134
- </OwnersListContext.Provider>
135
- );
136
-}
137
-
138
-export {OwnersListContext, OwnersListContextController};
packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.css
deleted
-104
@@ -1,104 +0,0 @@
1
-.OwnerStack {
2
- max-width: 100%;
3
- overflow-x: auto;
4
- flex: 1;
5
- display: flex;
6
- align-items: center;
7
- position: relative;
8
-}
9
-
10
-.Component,
11
-.Component[data-reach-menu-item] {
12
- font-family: var(--font-family-monospace);
13
- font-size: var(--font-size-monospace-normal);
14
- user-select: none;
15
- white-space: nowrap;
16
- display: flex;
17
- align-items: center;
18
-}
19
-
20
-.Component[data-reach-menu-item][data-selected],
21
-.Component[data-reach-menu-item][data-selected]:hover {
22
- color: var(--color-text-selected);
23
- background: var(--color-background-selected);
24
-}
25
-.Component[data-reach-menu-item][data-selected]:focus {
26
- outline: none;
27
-}
28
-
29
-.Bar {
30
- display: flex;
31
- flex: 1 1 auto;
32
- overflow-x: auto;
33
-}
34
-
35
-.VRule {
36
- flex: 0 0 auto;
37
- height: 20px;
38
- width: 1px;
39
- background-color: var(--color-border);
40
- margin: 0 0.5rem;
41
-}
42
-
43
-.MenuButton {
44
- border-radius: 0.25rem;
45
- display: inline-flex;
46
- align-items: center;
47
- padding: 0;
48
- flex: 0 0 auto;
49
- border: none;
50
- background: var(--color-button-background);
51
- color: var(--color-button);
52
-}
53
-.MenuButtonContent {
54
- display: inline-flex;
55
- align-items: center;
56
- border-radius: 0.25rem;
57
- padding: 0.25rem;
58
-}
59
-.MenuButton:hover {
60
- color: var(--color-button-hover);
61
-}
62
-.MenuButton[aria-expanded='true'],
63
-.MenuButton[aria-expanded='true']:active {
64
- color: var(--color-button-active);
65
- outline: none;
66
-}
67
-
68
-.MenuButton:focus,
69
-.MenuButtonContent:focus {
70
- outline: none;
71
-}
72
-.MenuButton:focus > .MenuButtonContent {
73
- background: var(--color-button-background-focus);
74
-}
75
-
76
-.Modal[data-reach-menu-list] {
77
- display: inline-flex;
78
- flex-direction: column;
79
- background-color: var(--color-background);
80
- color: var(--color-button);
81
- padding: 0.25rem 0;
82
- padding-right: 0;
83
- border: 1px solid var(--color-border);
84
- border-radius: 0.25rem;
85
- max-height: 10rem;
86
- overflow: auto;
87
-
88
- /* Make sure this is above the DevTools, which are above the Overlay */
89
- z-index: 10000002;
90
- position: relative;
91
-
92
- /* Reach UI tries to set its own :( */
93
- font-family: var(--font-family-monospace);
94
- font-size: var(--font-size-monospace-normal);
95
-}
96
-
97
-.NotInStore,
98
-.NotInStore:hover {
99
- color: var(--color-dimmest);
100
-}
101
-
102
-.Badge {
103
- margin-left: 0.25rem;
104
-}
packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js
deleted
-310
@@ -1,310 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-import React, {
10
- Fragment,
11
- useCallback,
12
- useContext,
13
- useLayoutEffect,
14
- useReducer,
15
- useRef,
16
- useState,
17
-} from 'react';
18
-import Tooltip from '@reach/tooltip';
19
-import {Menu, MenuList, MenuButton, MenuItem} from '@reach/menu-button';
20
-import Button from '../Button';
21
-import ButtonIcon from '../ButtonIcon';
22
-import Toggle from '../Toggle';
23
-import Badge from './Badge';
24
-import {OwnersListContext} from './OwnersListContext';
25
-import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
26
-import {useIsOverflowing} from '../hooks';
27
-import {StoreContext} from '../context';
28
-
29
-import type {Owner} from './types';
30
-
31
-import styles from './OwnersStack.css';
32
-
33
-type SelectOwner = (owner: Owner | null) => void;
34
-
35
-type ACTION_UPDATE_OWNER_ID = {|
36
- type: 'UPDATE_OWNER_ID',
37
- ownerID: number | null,
38
- owners: Array<Owner>,
39
-|};
40
-type ACTION_UPDATE_SELECTED_INDEX = {|
41
- type: 'UPDATE_SELECTED_INDEX',
42
- selectedIndex: number,
43
-|};
44
-
45
-type Action = ACTION_UPDATE_OWNER_ID | ACTION_UPDATE_SELECTED_INDEX;
46
-
47
-type State = {|
48
- ownerID: number | null,
49
- owners: Array<Owner>,
50
- selectedIndex: number,
51
-|};
52
-
53
-function dialogReducer(state, action) {
54
- switch (action.type) {
55
- case 'UPDATE_OWNER_ID':
56
- const selectedIndex = action.owners.findIndex(
57
- owner => owner.id === action.ownerID,
58
- );
59
- return {
60
- ownerID: action.ownerID,
61
- owners: action.owners,
62
- selectedIndex,
63
- };
64
- case 'UPDATE_SELECTED_INDEX':
65
- return {
66
- ...state,
67
- selectedIndex: action.selectedIndex,
68
- };
69
- default:
70
- throw new Error(`Invalid action "${action.type}"`);
71
- }
72
-}
73
-
74
-export default function OwnerStack() {
75
- const read = useContext(OwnersListContext);
76
- const {ownerID} = useContext(TreeStateContext);
77
- const treeDispatch = useContext(TreeDispatcherContext);
78
-
79
- const [state, dispatch] = useReducer<State, Action>(dialogReducer, {
80
- ownerID: null,
81
- owners: [],
82
- selectedIndex: 0,
83
- });
84
-
85
- // When an owner is selected, we either need to update the selected index, or we need to fetch a new list of owners.
86
- // We use a reducer here so that we can avoid fetching a new list unless the owner ID has actually changed.
87
- if (ownerID === null) {
88
- dispatch({
89
- type: 'UPDATE_OWNER_ID',
90
- ownerID: null,
91
- owners: [],
92
- });
93
- } else if (ownerID !== state.ownerID) {
94
- const isInStore =
95
- state.owners.findIndex(owner => owner.id === ownerID) >= 0;
96
- dispatch({
97
- type: 'UPDATE_OWNER_ID',
98
- ownerID,
99
- owners: isInStore ? state.owners : read(ownerID) || [],
100
- });
101
- }
102
-
103
- const {owners, selectedIndex} = state;
104
-
105
- const selectOwner = useCallback<SelectOwner>(
106
- (owner: Owner | null) => {
107
- if (owner !== null) {
108
- const index = owners.indexOf(owner);
109
- dispatch({
110
- type: 'UPDATE_SELECTED_INDEX',
111
- selectedIndex: index >= 0 ? index : 0,
112
- });
113
- treeDispatch({type: 'SELECT_OWNER', payload: owner.id});
114
- } else {
115
- dispatch({
116
- type: 'UPDATE_SELECTED_INDEX',
117
- selectedIndex: 0,
118
- });
119
- treeDispatch({type: 'RESET_OWNER_STACK'});
120
- }
121
- },
122
- [owners, treeDispatch],
123
- );
124
-
125
- const [elementsTotalWidth, setElementsTotalWidth] = useState(0);
126
- const elementsBarRef = useRef<HTMLDivElement | null>(null);
127
- const isOverflowing = useIsOverflowing(elementsBarRef, elementsTotalWidth);
128
-
129
- const selectedOwner = owners[selectedIndex];
130
-
131
- useLayoutEffect(
132
- () => {
133
- // If we're already overflowing, then we don't need to re-measure items.
134
- // That's because once the owners stack is open, it can only get larger (by driling in).
135
- // A totally new stack can only be reached by exiting this mode and re-entering it.
136
- if (elementsBarRef.current === null || isOverflowing) {
137
- return () => {};
138
- }
139
-
140
- let totalWidth = 0;
141
- for (let i = 0; i < owners.length; i++) {
142
- const element = elementsBarRef.current.children[i];
143
- const computedStyle = getComputedStyle(element);
144
-
145
- totalWidth +=
146
- element.offsetWidth +
147
- parseInt(computedStyle.marginLeft, 10) +
148
- parseInt(computedStyle.marginRight, 10);
149
- }
150
-
151
- setElementsTotalWidth(totalWidth);
152
- },
153
- [elementsBarRef, isOverflowing, owners.length],
154
- );
155
-
156
- return (
157
- <div className={styles.OwnerStack}>
158
- <div className={styles.Bar} ref={elementsBarRef}>
159
- {isOverflowing && (
160
- <Fragment>
161
- <ElementsDropdown
162
- owners={owners}
163
- selectedIndex={selectedIndex}
164
- selectOwner={selectOwner}
165
- />
166
- <BackToOwnerButton
167
- owners={owners}
168
- selectedIndex={selectedIndex}
169
- selectOwner={selectOwner}
170
- />
171
- {selectedOwner != null && (
172
- <ElementView
173
- owner={selectedOwner}
174
- isSelected={true}
175
- selectOwner={selectOwner}
176
- />
177
- )}
178
- </Fragment>
179
- )}
180
- {!isOverflowing &&
181
- owners.map((owner, index) => (
182
- <ElementView
183
- key={index}
184
- owner={owner}
185
- isSelected={index === selectedIndex}
186
- selectOwner={selectOwner}
187
- />
188
- ))}
189
- </div>
190
- <div className={styles.VRule} />
191
- <Button
192
- className={styles.IconButton}
193
- onClick={() => selectOwner(null)}
194
- title="Back to tree view">
195
- <ButtonIcon type="close" />
196
- </Button>
197
- </div>
198
- );
199
-}
200
-
201
-type ElementsDropdownProps = {
202
- owners: Array<Owner>,
203
- selectedIndex: number,
204
- selectOwner: SelectOwner,
205
-};
206
-function ElementsDropdown({
207
- owners,
208
- selectedIndex,
209
- selectOwner,
210
-}: ElementsDropdownProps) {
211
- const store = useContext(StoreContext);
212
-
213
- const menuItems = [];
214
- for (let index = owners.length - 1; index >= 0; index--) {
215
- const owner = owners[index];
216
- const isInStore = store.containsElement(owner.id);
217
- menuItems.push(
218
- <MenuItem
219
- key={owner.id}
220
- className={`${styles.Component} ${isInStore ? '' : styles.NotInStore}`}
221
- onSelect={() => (isInStore ? selectOwner(owner) : null)}>
222
- {owner.displayName}
223
-
224
- <Badge
225
- className={styles.Badge}
226
- hocDisplayNames={owner.hocDisplayNames}
227
- type={owner.type}
228
- />
229
- </MenuItem>,
230
- );
231
- }
232
-
233
- return (
234
- <Menu>
235
- <MenuButton className={styles.MenuButton}>
236
- <Tooltip label="Open elements dropdown">
237
- <span className={styles.MenuButtonContent} tabIndex={-1}>
238
- <ButtonIcon type="more" />
239
- </span>
240
- </Tooltip>
241
- </MenuButton>
242
- <MenuList className={styles.Modal}>{menuItems}</MenuList>
243
- </Menu>
244
- );
245
-}
246
-
247
-type ElementViewProps = {
248
- isSelected: boolean,
249
- owner: Owner,
250
- selectOwner: SelectOwner,
251
-};
252
-function ElementView({isSelected, owner, selectOwner}: ElementViewProps) {
253
- const store = useContext(StoreContext);
254
-
255
- const {displayName, hocDisplayNames, type} = owner;
256
- const isInStore = store.containsElement(owner.id);
257
-
258
- const handleChange = useCallback(
259
- () => {
260
- if (isInStore) {
261
- selectOwner(owner);
262
- }
263
- },
264
- [isInStore, selectOwner, owner],
265
- );
266
-
267
- return (
268
- <Toggle
269
- className={`${styles.Component} ${isInStore ? '' : styles.NotInStore}`}
270
- isChecked={isSelected}
271
- onChange={handleChange}>
272
- {displayName}
273
-
274
- <Badge
275
- className={styles.Badge}
276
- hocDisplayNames={hocDisplayNames}
277
- type={type}
278
- />
279
- </Toggle>
280
- );
281
-}
282
-
283
-type BackToOwnerButtonProps = {|
284
- owners: Array<Owner>,
285
- selectedIndex: number,
286
- selectOwner: SelectOwner,
287
-|};
288
-function BackToOwnerButton({
289
- owners,
290
- selectedIndex,
291
- selectOwner,
292
-}: BackToOwnerButtonProps) {
293
- const store = useContext(StoreContext);
294
-
295
- if (selectedIndex <= 0) {
296
- return null;
297
- }
298
-
299
- const owner = owners[selectedIndex - 1];
300
- const isInStore = store.containsElement(owner.id);
301
-
302
- return (
303
- <Button
304
- className={isInStore ? undefined : styles.NotInStore}
305
- onClick={() => (isInStore ? selectOwner(owner) : null)}
306
- title={`Up to ${owner.displayName || 'owner'}`}>
307
- <ButtonIcon type="previous" />
308
- </Button>
309
- );
310
-}
packages/react-devtools-shared/src/devtools/views/Components/SearchInput.css
deleted
-42
@@ -1,42 +0,0 @@
1
-.SearchInput {
2
- flex: 1 1;
3
- display: flex;
4
- align-items: center;
5
-}
6
-
7
-.Input {
8
- flex: 1 1 100px;
9
- width: 100px;
10
- font-size: var(--font-size-sans-large);
11
- outline: none;
12
- border: none;
13
- background-color: var(--color-background);
14
- color: var(--color-text);
15
- padding-left: 1.5rem;
16
- margin-left: -1rem;
17
-}
18
-
19
-.InputIcon {
20
- pointer-events: none;
21
- z-index: 2;
22
- color: var(--color-dimmer);
23
-}
24
-
25
-.IndexLabel {
26
- color: var(--color-dim);
27
- font-size: var(--font-size-sans-normal);
28
- white-space: pre;
29
-}
30
-
31
-.LeftVRule,
32
-.RightVRule {
33
- height: 20px;
34
- width: 1px;
35
- background-color: var(--color-border);
36
-}
37
-.LeftVRule {
38
- margin: 0 0.25rem 0 0.5rem;
39
-}
40
-.RightVRule {
41
- margin: 0 0.5rem 0 0.25rem;
42
-}
packages/react-devtools-shared/src/devtools/views/Components/SearchInput.js
deleted
-136
@@ -1,136 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useContext, useEffect, useRef} from 'react';
11
-import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
12
-import Button from '../Button';
13
-import ButtonIcon from '../ButtonIcon';
14
-import Icon from '../Icon';
15
-
16
-import styles from './SearchInput.css';
17
-
18
-type Props = {||};
19
-
20
-export default function SearchInput(props: Props) {
21
- const {searchIndex, searchResults, searchText} = useContext(TreeStateContext);
22
- const dispatch = useContext(TreeDispatcherContext);
23
-
24
- const inputRef = useRef<HTMLInputElement | null>(null);
25
-
26
- const handleTextChange = useCallback(
27
- ({currentTarget}) =>
28
- dispatch({type: 'SET_SEARCH_TEXT', payload: currentTarget.value}),
29
- [dispatch],
30
- );
31
- const resetSearch = useCallback(
32
- () => dispatch({type: 'SET_SEARCH_TEXT', payload: ''}),
33
- [dispatch],
34
- );
35
-
36
- const handleKeyDown = useCallback(
37
- event => {
38
- // For convenience, let up/down arrow keys change Tree selection.
39
- switch (event.key) {
40
- case 'ArrowDown':
41
- dispatch({type: 'SELECT_NEXT_ELEMENT_IN_TREE'});
42
- event.preventDefault();
43
- break;
44
- case 'ArrowUp':
45
- dispatch({type: 'SELECT_PREVIOUS_ELEMENT_IN_TREE'});
46
- event.preventDefault();
47
- break;
48
- default:
49
- break;
50
- }
51
- },
52
- [dispatch],
53
- );
54
-
55
- const handleInputKeyPress = useCallback(
56
- ({key}) => {
57
- if (key === 'Enter') {
58
- dispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'});
59
- }
60
- },
61
- [dispatch],
62
- );
63
-
64
- // Auto-focus search input
65
- useEffect(
66
- () => {
67
- if (inputRef.current === null) {
68
- return () => {};
69
- }
70
-
71
- const handleWindowKey = (event: KeyboardEvent) => {
72
- const {key, metaKey} = event;
73
- if (key === 'f' && metaKey) {
74
- if (inputRef.current !== null) {
75
- inputRef.current.focus();
76
- event.preventDefault();
77
- event.stopPropagation();
78
- }
79
- }
80
- };
81
-
82
- // It's important to listen to the ownerDocument to support the browser extension.
83
- // Here we use portals to render individual tabs (e.g. Profiler),
84
- // and the root document might belong to a different window.
85
- const ownerDocument = inputRef.current.ownerDocument;
86
- ownerDocument.addEventListener('keydown', handleWindowKey);
87
-
88
- return () =>
89
- ownerDocument.removeEventListener('keydown', handleWindowKey);
90
- },
91
- [inputRef],
92
- );
93
-
94
- return (
95
- <div className={styles.SearchInput}>
96
- <Icon className={styles.InputIcon} type="search" />
97
- <input
98
- className={styles.Input}
99
- onChange={handleTextChange}
100
- onKeyDown={handleKeyDown}
101
- onKeyPress={handleInputKeyPress}
102
- placeholder="Search (text or /regex/)"
103
- ref={inputRef}
104
- value={searchText}
105
- />
106
- {!!searchText && (
107
- <span className={styles.IndexLabel}>
108
- {Math.min(searchIndex + 1, searchResults.length)} |{' '}
109
- {searchResults.length}
110
- </span>
111
- )}
112
- <div className={styles.LeftVRule} />
113
- <Button
114
- className={styles.IconButton}
115
- disabled={!searchText}
116
- onClick={() => dispatch({type: 'GO_TO_PREVIOUS_SEARCH_RESULT'})}
117
- title="Scroll to previous search result">
118
- <ButtonIcon type="up" />
119
- </Button>
120
- <Button
121
- className={styles.IconButton}
122
- disabled={!searchText}
123
- onClick={() => dispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'})}
124
- title="Scroll to next search result">
125
- <ButtonIcon type="down" />
126
- </Button>
127
- <Button
128
- className={styles.IconButton}
129
- disabled={!searchText}
130
- onClick={resetSearch}
131
- title="Reset search">
132
- <ButtonIcon type="close" />
133
- </Button>
134
- </div>
135
- );
136
-}
packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.css
deleted
-89
@@ -1,89 +0,0 @@
1
-.SelectedElement {
2
- display: flex;
3
- flex-direction: column;
4
- height: 100%;
5
- width: 100%;
6
- border-left: 1px solid var(--color-border);
7
- border-top: 1px solid var(--color-border);
8
-}
9
-
10
-.TitleRow {
11
- flex: 0 0 42px;
12
- display: flex;
13
- align-items: center;
14
- font-size: var(--font-size-monospace-large);
15
- border-bottom: 1px solid var(--color-border);
16
- padding: 0.5rem;
17
-}
18
-
19
-.SelectedComponentName {
20
- flex: 1 1 auto;
21
- overflow: hidden;
22
- text-overflow: ellipsis;
23
-}
24
-
25
-.Owners {
26
- padding: 0.25rem;
27
- border-top: 1px solid var(--color-border);
28
-}
29
-
30
-.OwnersHeader {
31
- font-family: var(--font-family-sans);
32
-}
33
-
34
-.Component,
35
-.Owner {
36
- color: var(--color-component-name);
37
- font-family: var(--font-family-monospace);
38
- font-size: var(--font-size-monospace-normal);
39
- white-space: nowrap;
40
- overflow: hidden;
41
- text-overflow: ellipsis;
42
- max-width: 100%;
43
-}
44
-
45
-.Component {
46
- flex: 1 1 auto;
47
-}
48
-
49
-.InspectedElement {
50
- overflow-x: hidden;
51
- overflow-y: auto;
52
- font-family: var(--font-family-monospace);
53
- font-size: var(--font-size-monospace-normal);
54
- line-height: var(--line-height-data);
55
-}
56
-
57
-.Owner {
58
- border-radius: 0.25rem;
59
- padding: 0.125rem 0.25rem;
60
- cursor: pointer;
61
- background: none;
62
- border: none;
63
- display: block;
64
-}
65
-.Owner:focus {
66
- outline: none;
67
- background-color: var(--color-button-background-focus);
68
-}
69
-
70
-.Loading {
71
- padding: 0.25rem;
72
- color: var(--color-dimmer);
73
- font-style: italic;
74
-}
75
-
76
-.CannotSuspendWarningMessage {
77
-}
78
-
79
-.NotInStore {
80
- color: var(--color-dim);
81
- cursor: default;
82
-}
83
-
84
-.OwnerButton {
85
- display: flex;
86
- align-items: center;
87
- margin-left: 0.5rem;
88
- padding: 0;
89
-}
packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.js
deleted
-476
@@ -1,476 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useContext} from 'react';
11
-import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
12
-import {BridgeContext, StoreContext} from '../context';
13
-import Button from '../Button';
14
-import ButtonIcon from '../ButtonIcon';
15
-import HooksTree from './HooksTree';
16
-import {ModalDialogContext} from '../ModalDialog';
17
-import HocBadges from './HocBadges';
18
-import InspectedElementTree from './InspectedElementTree';
19
-import {InspectedElementContext} from './InspectedElementContext';
20
-import ViewElementSourceContext from './ViewElementSourceContext';
21
-import NativeStyleEditor from './NativeStyleEditor';
22
-import Toggle from '../Toggle';
23
-import Badge from './Badge';
24
-import {
25
- ComponentFilterElementType,
26
- ElementTypeClass,
27
- ElementTypeForwardRef,
28
- ElementTypeFunction,
29
- ElementTypeMemo,
30
- ElementTypeSuspense,
31
-} from 'react-devtools-shared/src/types';
32
-
33
-import styles from './SelectedElement.css';
34
-
35
-import type {GetInspectedElementPath} from './InspectedElementContext';
36
-import type {Element, InspectedElement} from './types';
37
-import type {ElementType} from 'react-devtools-shared/src/types';
38
-
39
-export type Props = {||};
40
-
41
-export default function SelectedElement(_: Props) {
42
- const {inspectedElementID} = useContext(TreeStateContext);
43
- const dispatch = useContext(TreeDispatcherContext);
44
- const {canViewElementSourceFunction, viewElementSourceFunction} = useContext(
45
- ViewElementSourceContext,
46
- );
47
- const bridge = useContext(BridgeContext);
48
- const store = useContext(StoreContext);
49
- const {dispatch: modalDialogDispatch} = useContext(ModalDialogContext);
50
-
51
- const {getInspectedElementPath, getInspectedElement} = useContext(
52
- InspectedElementContext,
53
- );
54
-
55
- const element =
56
- inspectedElementID !== null
57
- ? store.getElementByID(inspectedElementID)
58
- : null;
59
-
60
- const inspectedElement =
61
- inspectedElementID != null ? getInspectedElement(inspectedElementID) : null;
62
-
63
- const highlightElement = useCallback(
64
- () => {
65
- if (element !== null && inspectedElementID !== null) {
66
- const rendererID = store.getRendererIDForElement(inspectedElementID);
67
- if (rendererID !== null) {
68
- bridge.send('highlightNativeElement', {
69
- displayName: element.displayName,
70
- hideAfterTimeout: true,
71
- id: inspectedElementID,
72
- openNativeElementsPanel: true,
73
- rendererID,
74
- scrollIntoView: true,
75
- });
76
- }
77
- }
78
- },
79
- [bridge, element, inspectedElementID, store],
80
- );
81
-
82
- const logElement = useCallback(
83
- () => {
84
- if (inspectedElementID !== null) {
85
- const rendererID = store.getRendererIDForElement(inspectedElementID);
86
- if (rendererID !== null) {
87
- bridge.send('logElementToConsole', {
88
- id: inspectedElementID,
89
- rendererID,
90
- });
91
- }
92
- }
93
- },
94
- [bridge, inspectedElementID, store],
95
- );
96
-
97
- const viewSource = useCallback(
98
- () => {
99
- if (viewElementSourceFunction != null && inspectedElement !== null) {
100
- viewElementSourceFunction(
101
- inspectedElement.id,
102
- ((inspectedElement: any): InspectedElement),
103
- );
104
- }
105
- },
106
- [inspectedElement, viewElementSourceFunction],
107
- );
108
-
109
- // In some cases (e.g. FB internal usage) the standalone shell might not be able to view the source.
110
- // To detect this case, we defer to an injected helper function (if present).
111
- const canViewSource =
112
- inspectedElement !== null &&
113
- inspectedElement.canViewSource &&
114
- viewElementSourceFunction !== null &&
115
- (canViewElementSourceFunction === null ||
116
- canViewElementSourceFunction(inspectedElement));
117
-
118
- const isSuspended =
119
- element !== null &&
120
- element.type === ElementTypeSuspense &&
121
- inspectedElement != null &&
122
- inspectedElement.state != null;
123
-
124
- const canToggleSuspense =
125
- inspectedElement != null && inspectedElement.canToggleSuspense;
126
-
127
- // TODO (suspense toggle) Would be nice to eventually use a two setState pattern here as well.
128
- const toggleSuspended = useCallback(
129
- () => {
130
- let nearestSuspenseElement = null;
131
- let currentElement = element;
132
- while (currentElement !== null) {
133
- if (currentElement.type === ElementTypeSuspense) {
134
- nearestSuspenseElement = currentElement;
135
- break;
136
- } else if (currentElement.parentID > 0) {
137
- currentElement = store.getElementByID(currentElement.parentID);
138
- } else {
139
- currentElement = null;
140
- }
141
- }
142
-
143
- // If we didn't find a Suspense ancestor, we can't suspend.
144
- // Instead we can show a warning to the user.
145
- if (nearestSuspenseElement === null) {
146
- modalDialogDispatch({
147
- type: 'SHOW',
148
- content: <CannotSuspendWarningMessage />,
149
- });
150
- } else {
151
- const nearestSuspenseElementID = nearestSuspenseElement.id;
152
-
153
- // If we're suspending from an arbitary (non-Suspense) component, select the nearest Suspense element in the Tree.
154
- // This way when the fallback UI is shown and the current element is hidden, something meaningful is selected.
155
- if (nearestSuspenseElement !== element) {
156
- dispatch({
157
- type: 'SELECT_ELEMENT_BY_ID',
158
- payload: nearestSuspenseElementID,
159
- });
160
- }
161
-
162
- const rendererID = store.getRendererIDForElement(
163
- nearestSuspenseElementID,
164
- );
165
-
166
- // Toggle suspended
167
- if (rendererID !== null) {
168
- bridge.send('overrideSuspense', {
169
- id: nearestSuspenseElementID,
170
- rendererID,
171
- forceFallback: !isSuspended,
172
- });
173
- }
174
- }
175
- },
176
- [bridge, dispatch, element, isSuspended, modalDialogDispatch, store],
177
- );
178
-
179
- if (element === null) {
180
- return (
181
- <div className={styles.SelectedElement}>
182
- <div className={styles.TitleRow} />
183
- </div>
184
- );
185
- }
186
-
187
- return (
188
- <div className={styles.SelectedElement}>
189
- <div className={styles.TitleRow}>
190
- <div className={styles.SelectedComponentName}>
191
- <div className={styles.Component} title={element.displayName}>
192
- {element.displayName}
193
- </div>
194
- </div>
195
-
196
- {canToggleSuspense && (
197
- <Toggle
198
- className={styles.IconButton}
199
- isChecked={isSuspended}
200
- onChange={toggleSuspended}
201
- title={
202
- isSuspended
203
- ? 'Unsuspend the selected component'
204
- : 'Suspend the selected component'
205
- }>
206
- <ButtonIcon type="suspend" />
207
- </Toggle>
208
- )}
209
- {store.supportsNativeInspection && (
210
- <Button
211
- className={styles.IconButton}
212
- onClick={highlightElement}
213
- title="Inspect the matching DOM element">
214
- <ButtonIcon type="view-dom" />
215
- </Button>
216
- )}
217
- <Button
218
- className={styles.IconButton}
219
- onClick={logElement}
220
- title="Log this component data to the console">
221
- <ButtonIcon type="log-data" />
222
- </Button>
223
- <Button
224
- className={styles.IconButton}
225
- disabled={!canViewSource}
226
- onClick={viewSource}
227
- title="View source for this element">
228
- <ButtonIcon type="view-source" />
229
- </Button>
230
- </div>
231
-
232
- {inspectedElement === null && (
233
- <div className={styles.Loading}>Loading...</div>
234
- )}
235
-
236
- {inspectedElement !== null && (
237
- <InspectedElementView
238
- key={
239
- inspectedElementID /* Force reset when seleted Element changes */
240
- }
241
- element={element}
242
- getInspectedElementPath={getInspectedElementPath}
243
- inspectedElement={inspectedElement}
244
- />
245
- )}
246
- </div>
247
- );
248
-}
249
-
250
-export type InspectPath = (path: Array<string | number>) => void;
251
-
252
-type InspectedElementViewProps = {|
253
- element: Element,
254
- getInspectedElementPath: GetInspectedElementPath,
255
- inspectedElement: InspectedElement,
256
-|};
257
-
258
-const IS_SUSPENDED = 'Suspended';
259
-
260
-function InspectedElementView({
261
- element,
262
- getInspectedElementPath,
263
- inspectedElement,
264
-}: InspectedElementViewProps) {
265
- const {id, type} = element;
266
- const {
267
- canEditFunctionProps,
268
- canEditHooks,
269
- canToggleSuspense,
270
- context,
271
- hooks,
272
- owners,
273
- props,
274
- state,
275
- } = inspectedElement;
276
-
277
- const {ownerID} = useContext(TreeStateContext);
278
- const bridge = useContext(BridgeContext);
279
- const store = useContext(StoreContext);
280
-
281
- const inspectContextPath = useCallback(
282
- (path: Array<string | number>) => {
283
- getInspectedElementPath(id, ['context', ...path]);
284
- },
285
- [getInspectedElementPath, id],
286
- );
287
- const inspectPropsPath = useCallback(
288
- (path: Array<string | number>) => {
289
- getInspectedElementPath(id, ['props', ...path]);
290
- },
291
- [getInspectedElementPath, id],
292
- );
293
- const inspectStatePath = useCallback(
294
- (path: Array<string | number>) => {
295
- getInspectedElementPath(id, ['state', ...path]);
296
- },
297
- [getInspectedElementPath, id],
298
- );
299
-
300
- let overrideContextFn = null;
301
- let overridePropsFn = null;
302
- let overrideStateFn = null;
303
- let overrideSuspenseFn = null;
304
- if (type === ElementTypeClass) {
305
- overrideContextFn = (path: Array<string | number>, value: any) => {
306
- const rendererID = store.getRendererIDForElement(id);
307
- if (rendererID !== null) {
308
- bridge.send('overrideContext', {id, path, rendererID, value});
309
- }
310
- };
311
- overridePropsFn = (path: Array<string | number>, value: any) => {
312
- const rendererID = store.getRendererIDForElement(id);
313
- if (rendererID !== null) {
314
- bridge.send('overrideProps', {id, path, rendererID, value});
315
- }
316
- };
317
- overrideStateFn = (path: Array<string | number>, value: any) => {
318
- const rendererID = store.getRendererIDForElement(id);
319
- if (rendererID !== null) {
320
- bridge.send('overrideState', {id, path, rendererID, value});
321
- }
322
- };
323
- } else if (
324
- (type === ElementTypeFunction ||
325
- type === ElementTypeMemo ||
326
- type === ElementTypeForwardRef) &&
327
- canEditFunctionProps
328
- ) {
329
- overridePropsFn = (path: Array<string | number>, value: any) => {
330
- const rendererID = store.getRendererIDForElement(id);
331
- if (rendererID !== null) {
332
- bridge.send('overrideProps', {id, path, rendererID, value});
333
- }
334
- };
335
- } else if (type === ElementTypeSuspense && canToggleSuspense) {
336
- overrideSuspenseFn = (path: Array<string | number>, value: boolean) => {
337
- if (path.length !== 1 && path !== IS_SUSPENDED) {
338
- throw new Error('Unexpected path.');
339
- }
340
- const rendererID = store.getRendererIDForElement(id);
341
- if (rendererID !== null) {
342
- bridge.send('overrideSuspense', {
343
- id,
344
- rendererID,
345
- forceFallback: value,
346
- });
347
- }
348
- };
349
- }
350
-
351
- return (
352
- <div className={styles.InspectedElement}>
353
- <HocBadges element={element} />
354
- <InspectedElementTree
355
- label="props"
356
- data={props}
357
- inspectPath={inspectPropsPath}
358
- overrideValueFn={overridePropsFn}
359
- showWhenEmpty={true}
360
- />
361
- {type === ElementTypeSuspense ? (
362
- <InspectedElementTree
363
- label="suspense"
364
- data={{
365
- [IS_SUSPENDED]: state !== null,
366
- }}
367
- overrideValueFn={overrideSuspenseFn}
368
- />
369
- ) : (
370
- <InspectedElementTree
371
- label="state"
372
- data={state}
373
- inspectPath={inspectStatePath}
374
- overrideValueFn={overrideStateFn}
375
- />
376
- )}
377
- <HooksTree canEditHooks={canEditHooks} hooks={hooks} id={id} />
378
- <InspectedElementTree
379
- label="context"
380
- data={context}
381
- inspectPath={inspectContextPath}
382
- overrideValueFn={overrideContextFn}
383
- />
384
-
385
- <NativeStyleEditor />
386
-
387
- {ownerID === null &&
388
- owners !== null &&
389
- owners.length > 0 && (
390
- <div className={styles.Owners}>
391
- <div className={styles.OwnersHeader}>rendered by</div>
392
- {owners.map(owner => (
393
- <OwnerView
394
- key={owner.id}
395
- displayName={owner.displayName || 'Anonymous'}
396
- hocDisplayNames={owner.hocDisplayNames}
397
- id={owner.id}
398
- isInStore={store.containsElement(owner.id)}
399
- type={owner.type}
400
- />
401
- ))}
402
- </div>
403
- )}
404
- </div>
405
- );
406
-}
407
-
408
-type OwnerViewProps = {|
409
- displayName: string,
410
- hocDisplayNames: Array<string> | null,
411
- id: number,
412
- isInStore: boolean,
413
- type: ElementType,
414
-|};
415
-
416
-function OwnerView({
417
- displayName,
418
- hocDisplayNames,
419
- id,
420
- isInStore,
421
- type,
422
-}: OwnerViewProps) {
423
- const dispatch = useContext(TreeDispatcherContext);
424
-
425
- const handleClick = useCallback(
426
- () =>
427
- dispatch({
428
- type: 'SELECT_ELEMENT_BY_ID',
429
- payload: id,
430
- }),
431
- [dispatch, id],
432
- );
433
-
434
- return (
435
- <Button
436
- key={id}
437
- className={styles.OwnerButton}
438
- disabled={!isInStore}
439
- onClick={handleClick}>
440
- <span
441
- className={`${styles.Owner} ${isInStore ? '' : styles.NotInStore}`}
442
- title={displayName}>
443
- {displayName}
444
- </span>
445
- <Badge hocDisplayNames={hocDisplayNames} type={type} />
446
- </Button>
447
- );
448
-}
449
-
450
-function CannotSuspendWarningMessage() {
451
- const store = useContext(StoreContext);
452
- const areSuspenseElementsHidden = !!store.componentFilters.find(
453
- filter =>
454
- filter.type === ComponentFilterElementType &&
455
- filter.value === ElementTypeSuspense &&
456
- filter.isEnabled,
457
- );
458
-
459
- // Has the user filted out Suspense nodes from the tree?
460
- // If so, the selected element might actually be in a Suspense tree after all.
461
- if (areSuspenseElementsHidden) {
462
- return (
463
- <div className={styles.CannotSuspendWarningMessage}>
464
- Suspended state cannot be toggled while Suspense components are hidden.
465
- Disable the filter and try agan.
466
- </div>
467
- );
468
- } else {
469
- return (
470
- <div className={styles.CannotSuspendWarningMessage}>
471
- The selected element is not within a Suspense container. Suspending it
472
- would cause an error.
473
- </div>
474
- );
475
- }
476
-}
packages/react-devtools-shared/src/devtools/views/Components/SelectedTreeHighlight.css
deleted
-16
@@ -1,16 +0,0 @@
1
-.Active,
2
-.Inactive {
3
- position: absolute;
4
- left: 0;
5
- width: 100%;
6
- z-index: 0;
7
- pointer-events: none;
8
-}
9
-
10
-.Active {
11
- background-color: var(--color-selected-tree-highlight-active);
12
-}
13
-
14
-.Inactive {
15
- background-color: var(--color-selected-tree-highlight-inactive);
16
-}
packages/react-devtools-shared/src/devtools/views/Components/SelectedTreeHighlight.js
deleted
-107
@@ -1,107 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useContext, useMemo} from 'react';
11
-import {TreeStateContext} from './TreeContext';
12
-import {SettingsContext} from '../Settings/SettingsContext';
13
-import TreeFocusedContext from './TreeFocusedContext';
14
-import {StoreContext} from '../context';
15
-import {useSubscription} from '../hooks';
16
-
17
-import styles from './SelectedTreeHighlight.css';
18
-
19
-type Data = {|
20
- startIndex: number,
21
- stopIndex: number,
22
-|};
23
-
24
-export default function SelectedTreeHighlight(_: {||}) {
25
- const {lineHeight} = useContext(SettingsContext);
26
- const store = useContext(StoreContext);
27
- const treeFocused = useContext(TreeFocusedContext);
28
- const {ownerID, selectedElementID} = useContext(TreeStateContext);
29
-
30
- const subscription = useMemo(
31
- () => ({
32
- getCurrentValue: () => {
33
- if (
34
- selectedElementID === null ||
35
- store.isInsideCollapsedSubTree(selectedElementID)
36
- ) {
37
- return null;
38
- }
39
-
40
- const element = store.getElementByID(selectedElementID);
41
- if (
42
- element === null ||
43
- element.isCollapsed ||
44
- element.children.length === 0
45
- ) {
46
- return null;
47
- }
48
-
49
- const startIndex = store.getIndexOfElementID(element.children[0]);
50
- if (startIndex === null) {
51
- return null;
52
- }
53
-
54
- let stopIndex = null;
55
- let current = element;
56
- while (current !== null) {
57
- if (current.isCollapsed || current.children.length === 0) {
58
- // We've found the last/deepest descendant.
59
- stopIndex = store.getIndexOfElementID(current.id);
60
- current = null;
61
- } else {
62
- const lastChildID = current.children[current.children.length - 1];
63
- current = store.getElementByID(lastChildID);
64
- }
65
- }
66
-
67
- if (stopIndex === null) {
68
- return null;
69
- }
70
-
71
- return {
72
- startIndex,
73
- stopIndex,
74
- };
75
- },
76
- subscribe: (callback: Function) => {
77
- store.addListener('mutated', callback);
78
- return () => {
79
- store.removeListener('mutated', callback);
80
- };
81
- },
82
- }),
83
- [selectedElementID, store],
84
- );
85
- const data = useSubscription<Data | null>(subscription);
86
-
87
- if (ownerID !== null) {
88
- return null;
89
- }
90
-
91
- if (data === null) {
92
- return null;
93
- }
94
-
95
- const {startIndex, stopIndex} = data;
96
-
97
- return (
98
- <div
99
- className={treeFocused ? styles.Active : styles.Inactive}
100
- style={{
101
- position: 'absolute',
102
- top: `${startIndex * lineHeight}px`,
103
- height: `${(stopIndex + 1 - startIndex) * lineHeight}px`,
104
- }}
105
- />
106
- );
107
-}
packages/react-devtools-shared/src/devtools/views/Components/Tree.css
deleted
-60
@@ -1,60 +0,0 @@
1
-.Tree {
2
- position: relative;
3
- height: 100%;
4
- width: 100%;
5
- display: flex;
6
- flex-direction: column;
7
- border-top: 1px solid var(--color-border);
8
-
9
- /* Default size will be adjusted by Tree after scrolling */
10
- --indentation-size: 12px;
11
-}
12
-
13
-.List {
14
- overflow-x: hidden !important;
15
-}
16
-
17
-.InnerElementType {
18
- overflow-x: hidden;
19
-}
20
-
21
-.SearchInput {
22
- flex: 0 0 42px;
23
- display: flex;
24
- align-items: center;
25
- border-bottom: 1px solid var(--color-border);
26
- padding: 0.5rem;
27
-}
28
-
29
-.AutoSizerWrapper {
30
- width: 100%;
31
- overflow: hidden;
32
- flex: 1 0 auto;
33
-}
34
-.AutoSizerWrapper:focus {
35
- outline: none;
36
-}
37
-
38
-.List {
39
- font-family: var(--font-family-monospace);
40
- font-size: var(--font-size-monospace-normal);
41
- line-height: var(--line-height-data);
42
-}
43
-
44
-.VRule {
45
- height: 20px;
46
- width: 1px;
47
- margin: 0 0.5rem;
48
- background-color: var(--color-border);
49
-}
50
-
51
-.Loading {
52
- height: 100%;
53
- padding-left: 0.5rem;
54
- display: flex;
55
- align-items: center;
56
- flex: 1;
57
- justify-content: flex-start;
58
- font-size: var(--font-size-sans-large);
59
- color: var(--color-dim);
60
-}
packages/react-devtools-shared/src/devtools/views/Components/Tree.js
deleted
-518
@@ -1,518 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- Fragment,
12
- Suspense,
13
- useCallback,
14
- useContext,
15
- useEffect,
16
- useMemo,
17
- useRef,
18
- useState,
19
-} from 'react';
20
-import AutoSizer from 'react-virtualized-auto-sizer';
21
-import {FixedSizeList} from 'react-window';
22
-import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
23
-import {SettingsContext} from '../Settings/SettingsContext';
24
-import {BridgeContext, StoreContext} from '../context';
25
-import ElementView from './Element';
26
-import InspectHostNodesToggle from './InspectHostNodesToggle';
27
-import OwnersStack from './OwnersStack';
28
-import SearchInput from './SearchInput';
29
-import SettingsModalContextToggle from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContextToggle';
30
-import SelectedTreeHighlight from './SelectedTreeHighlight';
31
-import TreeFocusedContext from './TreeFocusedContext';
32
-
33
-import styles from './Tree.css';
34
-
35
-// Never indent more than this number of pixels (even if we have the room).
36
-const DEFAULT_INDENTATION_SIZE = 12;
37
-
38
-export type ItemData = {|
39
- numElements: number,
40
- isNavigatingWithKeyboard: boolean,
41
- lastScrolledIDRef: {current: number | null},
42
- onElementMouseEnter: (id: number) => void,
43
- treeFocused: boolean,
44
-|};
45
-
46
-type Props = {||};
47
-
48
-export default function Tree(props: Props) {
49
- const dispatch = useContext(TreeDispatcherContext);
50
- const {
51
- numElements,
52
- ownerID,
53
- searchIndex,
54
- searchResults,
55
- selectedElementID,
56
- selectedElementIndex,
57
- } = useContext(TreeStateContext);
58
- const bridge = useContext(BridgeContext);
59
- const store = useContext(StoreContext);
60
- const [isNavigatingWithKeyboard, setIsNavigatingWithKeyboard] = useState(
61
- false,
62
- );
63
- const treeRef = useRef<HTMLDivElement | null>(null);
64
- const focusTargetRef = useRef<HTMLDivElement | null>(null);
65
-
66
- const [treeFocused, setTreeFocused] = useState<boolean>(false);
67
-
68
- const {lineHeight} = useContext(SettingsContext);
69
-
70
- // Make sure a newly selected element is visible in the list.
71
- // This is helpful for things like the owners list and search.
72
- //
73
- // TRICKY:
74
- // It's important to use a callback ref for this, rather than a ref object and an effect.
75
- // As an optimization, the AutoSizer component does not render children when their size would be 0.
76
- // This means that in some cases (if the browser panel size is initially really small),
77
- // the Tree component might render without rendering an inner List.
78
- // In this case, the list ref would be null on mount (when the scroll effect runs),
79
- // meaning the scroll action would be skipped (since ref updates don't re-run effects).
80
- // Using a callback ref accounts for this case...
81
- const listCallbackRef = useCallback(
82
- list => {
83
- if (list != null && selectedElementIndex !== null) {
84
- list.scrollToItem(selectedElementIndex, 'smart');
85
- }
86
- },
87
- [selectedElementIndex],
88
- );
89
-
90
- // Picking an element in the inspector should put focus into the tree.
91
- // This ensures that keyboard navigation works right after picking a node.
92
- useEffect(
93
- () => {
94
- function handleStopInspectingNative(didSelectNode) {
95
- if (didSelectNode && focusTargetRef.current !== null) {
96
- focusTargetRef.current.focus();
97
- }
98
- }
99
- bridge.addListener('stopInspectingNative', handleStopInspectingNative);
100
- return () =>
101
- bridge.removeListener(
102
- 'stopInspectingNative',
103
- handleStopInspectingNative,
104
- );
105
- },
106
- [bridge],
107
- );
108
-
109
- // This ref is passed down the context to elements.
110
- // It lets them avoid autoscrolling to the same item many times
111
- // when a selected virtual row goes in and out of the viewport.
112
- const lastScrolledIDRef = useRef<number | null>(null);
113
-
114
- // Navigate the tree with up/down arrow keys.
115
- useEffect(
116
- () => {
117
- if (treeRef.current === null) {
118
- return () => {};
119
- }
120
-
121
- const handleKeyDown = (event: KeyboardEvent) => {
122
- if ((event: any).target.tagName === 'INPUT' || event.defaultPrevented) {
123
- return;
124
- }
125
-
126
- // TODO We should ignore arrow keys if the focus is outside of DevTools.
127
- // Otherwise the inline (embedded) DevTools might change selection unexpectedly,
128
- // e.g. when a text input or a select has focus.
129
-
130
- let element;
131
- switch (event.key) {
132
- case 'ArrowDown':
133
- event.preventDefault();
134
- dispatch({type: 'SELECT_NEXT_ELEMENT_IN_TREE'});
135
- break;
136
- case 'ArrowLeft':
137
- event.preventDefault();
138
- element =
139
- selectedElementID !== null
140
- ? store.getElementByID(selectedElementID)
141
- : null;
142
- if (element !== null) {
143
- if (element.children.length > 0 && !element.isCollapsed) {
144
- store.toggleIsCollapsed(element.id, true);
145
- } else {
146
- dispatch({type: 'SELECT_PARENT_ELEMENT_IN_TREE'});
147
- }
148
- }
149
- break;
150
- case 'ArrowRight':
151
- event.preventDefault();
152
- element =
153
- selectedElementID !== null
154
- ? store.getElementByID(selectedElementID)
155
- : null;
156
- if (element !== null) {
157
- if (element.children.length > 0 && element.isCollapsed) {
158
- store.toggleIsCollapsed(element.id, false);
159
- } else {
160
- dispatch({type: 'SELECT_CHILD_ELEMENT_IN_TREE'});
161
- }
162
- }
163
- break;
164
- case 'ArrowUp':
165
- event.preventDefault();
166
- dispatch({type: 'SELECT_PREVIOUS_ELEMENT_IN_TREE'});
167
- break;
168
- default:
169
- return;
170
- }
171
- setIsNavigatingWithKeyboard(true);
172
- };
173
-
174
- // It's important to listen to the ownerDocument to support the browser extension.
175
- // Here we use portals to render individual tabs (e.g. Profiler),
176
- // and the root document might belong to a different window.
177
- const ownerDocument = treeRef.current.ownerDocument;
178
- ownerDocument.addEventListener('keydown', handleKeyDown);
179
-
180
- return () => {
181
- ownerDocument.removeEventListener('keydown', handleKeyDown);
182
- };
183
- },
184
- [dispatch, selectedElementID, store],
185
- );
186
-
187
- // Focus management.
188
- const handleBlur = useCallback(() => setTreeFocused(false), []);
189
- const handleFocus = useCallback(
190
- () => {
191
- setTreeFocused(true);
192
-
193
- if (selectedElementIndex === null && numElements > 0) {
194
- dispatch({
195
- type: 'SELECT_ELEMENT_AT_INDEX',
196
- payload: 0,
197
- });
198
- }
199
- },
200
- [dispatch, numElements, selectedElementIndex],
201
- );
202
-
203
- const handleKeyPress = useCallback(
204
- event => {
205
- switch (event.key) {
206
- case 'Enter':
207
- case ' ':
208
- if (selectedElementID !== null) {
209
- dispatch({type: 'SELECT_OWNER', payload: selectedElementID});
210
- }
211
- break;
212
- default:
213
- break;
214
- }
215
- },
216
- [dispatch, selectedElementID],
217
- );
218
-
219
- const highlightNativeElement = useCallback(
220
- (id: number) => {
221
- const element = store.getElementByID(id);
222
- const rendererID = store.getRendererIDForElement(id);
223
- if (element !== null && rendererID !== null) {
224
- bridge.send('highlightNativeElement', {
225
- displayName: element.displayName,
226
- hideAfterTimeout: false,
227
- id,
228
- openNativeElementsPanel: false,
229
- rendererID,
230
- scrollIntoView: false,
231
- });
232
- }
233
- },
234
- [store, bridge],
235
- );
236
-
237
- // If we switch the selected element while using the keyboard,
238
- // start highlighting it in the DOM instead of the last hovered node.
239
- const searchRef = useRef({searchIndex, searchResults});
240
- useEffect(
241
- () => {
242
- let didSelectNewSearchResult = false;
243
- if (
244
- searchRef.current.searchIndex !== searchIndex ||
245
- searchRef.current.searchResults !== searchResults
246
- ) {
247
- searchRef.current.searchIndex = searchIndex;
248
- searchRef.current.searchResults = searchResults;
249
- didSelectNewSearchResult = true;
250
- }
251
- if (isNavigatingWithKeyboard || didSelectNewSearchResult) {
252
- if (selectedElementID !== null) {
253
- highlightNativeElement(selectedElementID);
254
- } else {
255
- bridge.send('clearNativeElementHighlight');
256
- }
257
- }
258
- },
259
- [
260
- bridge,
261
- isNavigatingWithKeyboard,
262
- highlightNativeElement,
263
- searchIndex,
264
- searchResults,
265
- selectedElementID,
266
- ],
267
- );
268
-
269
- // Highlight last hovered element.
270
- const handleElementMouseEnter = useCallback(
271
- id => {
272
- // Ignore hover while we're navigating with keyboard.
273
- // This avoids flicker from the hovered nodes under the mouse.
274
- if (!isNavigatingWithKeyboard) {
275
- highlightNativeElement(id);
276
- }
277
- },
278
- [isNavigatingWithKeyboard, highlightNativeElement],
279
- );
280
-
281
- const handleMouseMove = useCallback(() => {
282
- // We started using the mouse again.
283
- // This will enable hover styles in individual rows.
284
- setIsNavigatingWithKeyboard(false);
285
- }, []);
286
-
287
- const handleMouseLeave = useCallback(
288
- () => {
289
- bridge.send('clearNativeElementHighlight');
290
- },
291
- [bridge],
292
- );
293
-
294
- // Let react-window know to re-render any time the underlying tree data changes.
295
- // This includes the owner context, since it controls a filtered view of the tree.
296
- const itemData = useMemo<ItemData>(
297
- () => ({
298
- numElements,
299
- isNavigatingWithKeyboard,
300
- onElementMouseEnter: handleElementMouseEnter,
301
- lastScrolledIDRef,
302
- treeFocused,
303
- }),
304
- [
305
- numElements,
306
- isNavigatingWithKeyboard,
307
- handleElementMouseEnter,
308
- lastScrolledIDRef,
309
- treeFocused,
310
- ],
311
- );
312
-
313
- const itemKey = useCallback(
314
- (index: number) => store.getElementIDAtIndex(index),
315
- [store],
316
- );
317
-
318
- return (
319
- <TreeFocusedContext.Provider value={treeFocused}>
320
- <div className={styles.Tree} ref={treeRef}>
321
- <div className={styles.SearchInput}>
322
- {store.supportsNativeInspection && (
323
- <Fragment>
324
- <InspectHostNodesToggle />
325
- <div className={styles.VRule} />
326
- </Fragment>
327
- )}
328
- <Suspense fallback={<Loading />}>
329
- {ownerID !== null ? <OwnersStack /> : <SearchInput />}
330
- </Suspense>
331
- <div className={styles.VRule} />
332
- <SettingsModalContextToggle />
333
- </div>
334
- <div
335
- className={styles.AutoSizerWrapper}
336
- onBlur={handleBlur}
337
- onFocus={handleFocus}
338
- onKeyPress={handleKeyPress}
339
- onMouseMove={handleMouseMove}
340
- onMouseLeave={handleMouseLeave}
341
- ref={focusTargetRef}
342
- tabIndex={0}>
343
- <AutoSizer>
344
- {({height, width}) => (
345
- // $FlowFixMe https://github.com/facebook/flow/issues/7341
346
- <FixedSizeList
347
- className={styles.List}
348
- height={height}
349
- innerElementType={InnerElementType}
350
- itemCount={numElements}
351
- itemData={itemData}
352
- itemKey={itemKey}
353
- itemSize={lineHeight}
354
- ref={listCallbackRef}
355
- width={width}>
356
- {ElementView}
357
- </FixedSizeList>
358
- )}
359
- </AutoSizer>
360
- </div>
361
- </div>
362
- </TreeFocusedContext.Provider>
363
- );
364
-}
365
-
366
-// Indentation size can be adjusted but child width is fixed.
367
-// We need to adjust indentations so the widest child can fit without overflowing.
368
-// Sometimes the widest child is also the deepest in the tree:
369
-// ┏----------------------┓
370
-// ┆ <Foo> ┆
371
-// ┆ ••••<Foobar> ┆
372
-// ┆ ••••••••<Baz> ┆
373
-// ┗----------------------┛
374
-//
375
-// But this is not always the case.
376
-// Even with the above example, a change in indentation may change the overall widest child:
377
-// ┏----------------------┓
378
-// ┆ <Foo> ┆
379
-// ┆ ••<Foobar> ┆
380
-// ┆ ••••<Baz> ┆
381
-// ┗----------------------┛
382
-//
383
-// In extreme cases this difference can be important:
384
-// ┏----------------------┓
385
-// ┆ <ReallyLongName> ┆
386
-// ┆ ••<Foo> ┆
387
-// ┆ ••••<Bar> ┆
388
-// ┆ ••••••<Baz> ┆
389
-// ┆ ••••••••<Qux> ┆
390
-// ┗----------------------┛
391
-//
392
-// In the above example, the current indentation is fine,
393
-// but if we naively assumed that the widest element is also the deepest element,
394
-// we would end up compressing the indentation unnecessarily:
395
-// ┏----------------------┓
396
-// ┆ <ReallyLongName> ┆
397
-// ┆ •<Foo> ┆
398
-// ┆ ••<Bar> ┆
399
-// ┆ •••<Baz> ┆
400
-// ┆ ••••<Qux> ┆
401
-// ┗----------------------┛
402
-//
403
-// The way we deal with this is to compute the max indentation size that can fit each child,
404
-// given the child's fixed width and depth within the tree.
405
-// Then we take the smallest of these indentation sizes...
406
-function updateIndentationSizeVar(
407
- innerDiv: HTMLDivElement,
408
- cachedChildWidths: WeakMap<HTMLElement, number>,
409
- indentationSizeRef: {|current: number|},
410
- prevListWidthRef: {|current: number|},
411
-): void {
412
- const list = ((innerDiv.parentElement: any): HTMLDivElement);
413
- const listWidth = list.clientWidth;
414
-
415
- // Skip measurements when the Components panel is hidden.
416
- if (listWidth === 0) {
417
- return;
418
- }
419
-
420
- // Reset the max indentation size if the width of the tree has increased.
421
- if (listWidth > prevListWidthRef.current) {
422
- indentationSizeRef.current = DEFAULT_INDENTATION_SIZE;
423
- }
424
- prevListWidthRef.current = listWidth;
425
-
426
- let maxIndentationSize: number = indentationSizeRef.current;
427
-
428
- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
429
- for (let child of innerDiv.children) {
430
- const depth = parseInt(child.getAttribute('data-depth'), 10) || 0;
431
-
432
- let childWidth: number = 0;
433
-
434
- const cachedChildWidth = cachedChildWidths.get(child);
435
- if (cachedChildWidth != null) {
436
- childWidth = cachedChildWidth;
437
- } else {
438
- const {firstElementChild} = child;
439
-
440
- // Skip over e.g. the guideline element
441
- if (firstElementChild != null) {
442
- childWidth = firstElementChild.clientWidth;
443
- cachedChildWidths.set(child, childWidth);
444
- }
445
- }
446
-
447
- const remainingWidth = Math.max(0, listWidth - childWidth);
448
-
449
- maxIndentationSize = Math.min(maxIndentationSize, remainingWidth / depth);
450
- }
451
-
452
- indentationSizeRef.current = maxIndentationSize;
453
-
454
- list.style.setProperty('--indentation-size', `${maxIndentationSize}px`);
455
-}
456
-
457
-function InnerElementType({children, style, ...rest}) {
458
- const {ownerID} = useContext(TreeStateContext);
459
-
460
- const cachedChildWidths = useMemo<WeakMap<HTMLElement, number>>(
461
- () => new WeakMap(),
462
- [],
463
- );
464
-
465
- // This ref tracks the current indentation size.
466
- // We decrease indentation to fit wider/deeper trees.
467
- // We indentionally do not increase it again afterward, to avoid the perception of content "jumping"
468
- // e.g. clicking to toggle/collapse a row might otherwise jump horizontally beneath your cursor,
469
- // e.g. scrolling a wide row off screen could cause narrower rows to jump to the right some.
470
- //
471
- // There are two exceptions for this:
472
- // 1. The first is when the width of the tree increases.
473
- // The user may have resized the window specifically to make more room for DevTools.
474
- // In either case, this should reset our max indentation size logic.
475
- // 2. The second is when the user enters or exits an owner tree.
476
- const indentationSizeRef = useRef<number>(DEFAULT_INDENTATION_SIZE);
477
- const prevListWidthRef = useRef<number>(0);
478
- const prevOwnerIDRef = useRef<number | null>(ownerID);
479
- const divRef = useRef<HTMLDivElement | null>(null);
480
-
481
- // We shouldn't retain this width across different conceptual trees though,
482
- // so when the user opens the "owners tree" view, we should discard the previous width.
483
- if (ownerID !== prevOwnerIDRef.current) {
484
- prevOwnerIDRef.current = ownerID;
485
- indentationSizeRef.current = DEFAULT_INDENTATION_SIZE;
486
- }
487
-
488
- // When we render new content, measure to see if we need to shrink indentation to fit it.
489
- useEffect(() => {
490
- if (divRef.current !== null) {
491
- updateIndentationSizeVar(
492
- divRef.current,
493
- cachedChildWidths,
494
- indentationSizeRef,
495
- prevListWidthRef,
496
- );
497
- }
498
- });
499
-
500
- // This style override enables the background color to fill the full visible width,
501
- // when combined with the CSS tweaks in Element.
502
- // A lot of options were considered; this seemed the one that requires the least code.
503
- // See https://github.com/bvaughn/react-devtools-experimental/issues/9
504
- return (
505
- <div
506
- className={styles.InnerElementType}
507
- ref={divRef}
508
- style={style}
509
- {...rest}>
510
- <SelectedTreeHighlight />
511
- {children}
512
- </div>
513
- );
514
-}
515
-
516
-function Loading() {
517
- return <div className={styles.Loading}>Loading...</div>;
518
-}
packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js
deleted
-824
@@ -1,824 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-// This context combines tree/selection state, search, and the owners stack.
11
-// These values are managed together because changes in one often impact the others.
12
-// Combining them enables us to avoid cascading renders.
13
-//
14
-// Changes to search state may impact tree state.
15
-// For example, updating the selected search result also updates the tree's selected value.
16
-// Search does not fundamanetally change the tree though.
17
-// It is also possible to update the selected tree value independently.
18
-//
19
-// Changes to owners state mask search and tree values.
20
-// When owners statck is not empty, search is temporarily disabnled,
21
-// and tree values (e.g. num elements, selected element) are masked.
22
-// Both tree and search values are restored when the owners stack is cleared.
23
-//
24
-// For this reason, changes to the tree context are processed in sequence: tree -> search -> owners
25
-// This enables each section to potentially override (or mask) previous values.
26
-
27
-import React, {
28
- createContext,
29
- useCallback,
30
- useContext,
31
- useEffect,
32
- useLayoutEffect,
33
- useMemo,
34
- useReducer,
35
- useRef,
36
-} from 'react';
37
-import {
38
- unstable_next as next,
39
- unstable_runWithPriority as runWithPriority,
40
- unstable_UserBlockingPriority as UserBlockingPriority,
41
-} from 'scheduler';
42
-import {createRegExp} from '../utils';
43
-import {BridgeContext, StoreContext} from '../context';
44
-import Store from '../../store';
45
-
46
-import type {Element} from './types';
47
-
48
-export type StateContext = {|
49
- // Tree
50
- numElements: number,
51
- selectedElementID: number | null,
52
- selectedElementIndex: number | null,
53
-
54
- // Search
55
- searchIndex: number | null,
56
- searchResults: Array<number>,
57
- searchText: string,
58
-
59
- // Owners
60
- ownerID: number | null,
61
- ownerFlatTree: Array<Element> | null,
62
-
63
- // Inspection element panel
64
- inspectedElementID: number | null,
65
-|};
66
-
67
-type ACTION_GO_TO_NEXT_SEARCH_RESULT = {|
68
- type: 'GO_TO_NEXT_SEARCH_RESULT',
69
-|};
70
-type ACTION_GO_TO_PREVIOUS_SEARCH_RESULT = {|
71
- type: 'GO_TO_PREVIOUS_SEARCH_RESULT',
72
-|};
73
-type ACTION_HANDLE_STORE_MUTATION = {|
74
- type: 'HANDLE_STORE_MUTATION',
75
- payload: [Array<number>, Map<number, number>],
76
-|};
77
-type ACTION_RESET_OWNER_STACK = {|
78
- type: 'RESET_OWNER_STACK',
79
-|};
80
-type ACTION_SELECT_CHILD_ELEMENT_IN_TREE = {|
81
- type: 'SELECT_CHILD_ELEMENT_IN_TREE',
82
-|};
83
-type ACTION_SELECT_ELEMENT_AT_INDEX = {|
84
- type: 'SELECT_ELEMENT_AT_INDEX',
85
- payload: number | null,
86
-|};
87
-type ACTION_SELECT_ELEMENT_BY_ID = {|
88
- type: 'SELECT_ELEMENT_BY_ID',
89
- payload: number | null,
90
-|};
91
-type ACTION_SELECT_NEXT_ELEMENT_IN_TREE = {|
92
- type: 'SELECT_NEXT_ELEMENT_IN_TREE',
93
-|};
94
-type ACTION_SELECT_PARENT_ELEMENT_IN_TREE = {|
95
- type: 'SELECT_PARENT_ELEMENT_IN_TREE',
96
-|};
97
-type ACTION_SELECT_PREVIOUS_ELEMENT_IN_TREE = {|
98
- type: 'SELECT_PREVIOUS_ELEMENT_IN_TREE',
99
-|};
100
-type ACTION_SELECT_OWNER = {|
101
- type: 'SELECT_OWNER',
102
- payload: number,
103
-|};
104
-type ACTION_SET_SEARCH_TEXT = {|
105
- type: 'SET_SEARCH_TEXT',
106
- payload: string,
107
-|};
108
-type ACTION_UPDATE_INSPECTED_ELEMENT_ID = {|
109
- type: 'UPDATE_INSPECTED_ELEMENT_ID',
110
-|};
111
-
112
-type Action =
113
- | ACTION_GO_TO_NEXT_SEARCH_RESULT
114
- | ACTION_GO_TO_PREVIOUS_SEARCH_RESULT
115
- | ACTION_HANDLE_STORE_MUTATION
116
- | ACTION_RESET_OWNER_STACK
117
- | ACTION_SELECT_CHILD_ELEMENT_IN_TREE
118
- | ACTION_SELECT_ELEMENT_AT_INDEX
119
- | ACTION_SELECT_ELEMENT_BY_ID
120
- | ACTION_SELECT_NEXT_ELEMENT_IN_TREE
121
- | ACTION_SELECT_PARENT_ELEMENT_IN_TREE
122
- | ACTION_SELECT_PREVIOUS_ELEMENT_IN_TREE
123
- | ACTION_SELECT_OWNER
124
- | ACTION_SET_SEARCH_TEXT
125
- | ACTION_UPDATE_INSPECTED_ELEMENT_ID;
126
-
127
-export type DispatcherContext = (action: Action) => void;
128
-
129
-const TreeStateContext = createContext<StateContext>(
130
- ((null: any): StateContext),
131
-);
132
-TreeStateContext.displayName = 'TreeStateContext';
133
-
134
-const TreeDispatcherContext = createContext<DispatcherContext>(
135
- ((null: any): DispatcherContext),
136
-);
137
-TreeDispatcherContext.displayName = 'TreeDispatcherContext';
138
-
139
-type State = {|
140
- // Tree
141
- numElements: number,
142
- selectedElementID: number | null,
143
- selectedElementIndex: number | null,
144
-
145
- // Search
146
- searchIndex: number | null,
147
- searchResults: Array<number>,
148
- searchText: string,
149
-
150
- // Owners
151
- ownerID: number | null,
152
- ownerFlatTree: Array<Element> | null,
153
-
154
- // Inspection element panel
155
- inspectedElementID: number | null,
156
-|};
157
-
158
-function reduceTreeState(store: Store, state: State, action: Action): State {
159
- let {numElements, ownerID, selectedElementIndex, selectedElementID} = state;
160
-
161
- let lookupIDForIndex = true;
162
-
163
- // Base tree should ignore selected element changes when the owner's tree is active.
164
- if (ownerID === null) {
165
- switch (action.type) {
166
- case 'HANDLE_STORE_MUTATION':
167
- numElements = store.numElements;
168
-
169
- // If the currently-selected Element has been removed from the tree, update selection state.
170
- const removedIDs = action.payload[1];
171
- // Find the closest parent that wasn't removed during this batch.
172
- // We deduce the parent-child mapping from removedIDs (id -> parentID)
173
- // because by now it's too late to read them from the store.
174
- while (
175
- selectedElementID !== null &&
176
- removedIDs.has(selectedElementID)
177
- ) {
178
- selectedElementID = ((removedIDs.get(
179
- selectedElementID,
180
- ): any): number);
181
- }
182
- if (selectedElementID === 0) {
183
- // The whole root was removed.
184
- selectedElementIndex = null;
185
- }
186
- break;
187
- case 'SELECT_CHILD_ELEMENT_IN_TREE':
188
- if (selectedElementIndex !== null) {
189
- const selectedElement = store.getElementAtIndex(
190
- ((selectedElementIndex: any): number),
191
- );
192
- if (
193
- selectedElement !== null &&
194
- selectedElement.children.length > 0 &&
195
- !selectedElement.isCollapsed
196
- ) {
197
- const firstChildID = selectedElement.children[0];
198
- const firstChildIndex = store.getIndexOfElementID(firstChildID);
199
- if (firstChildIndex !== null) {
200
- selectedElementIndex = firstChildIndex;
201
- }
202
- }
203
- }
204
- break;
205
- case 'SELECT_ELEMENT_AT_INDEX':
206
- selectedElementIndex = (action: ACTION_SELECT_ELEMENT_AT_INDEX).payload;
207
- break;
208
- case 'SELECT_ELEMENT_BY_ID':
209
- // Skip lookup in this case; it would be redundant.
210
- // It might also cause problems if the specified element was inside of a (not yet expanded) subtree.
211
- lookupIDForIndex = false;
212
-
213
- selectedElementID = (action: ACTION_SELECT_ELEMENT_BY_ID).payload;
214
- selectedElementIndex =
215
- selectedElementID === null
216
- ? null
217
- : store.getIndexOfElementID(selectedElementID);
218
- break;
219
- case 'SELECT_NEXT_ELEMENT_IN_TREE':
220
- if (
221
- selectedElementIndex === null ||
222
- selectedElementIndex + 1 >= numElements
223
- ) {
224
- selectedElementIndex = 0;
225
- } else {
226
- selectedElementIndex++;
227
- }
228
- break;
229
- case 'SELECT_PARENT_ELEMENT_IN_TREE':
230
- if (selectedElementIndex !== null) {
231
- const selectedElement = store.getElementAtIndex(
232
- ((selectedElementIndex: any): number),
233
- );
234
- if (selectedElement !== null && selectedElement.parentID !== null) {
235
- const parentIndex = store.getIndexOfElementID(
236
- selectedElement.parentID,
237
- );
238
- if (parentIndex !== null) {
239
- selectedElementIndex = parentIndex;
240
- }
241
- }
242
- }
243
- break;
244
- case 'SELECT_PREVIOUS_ELEMENT_IN_TREE':
245
- if (selectedElementIndex === null || selectedElementIndex === 0) {
246
- selectedElementIndex = numElements - 1;
247
- } else {
248
- selectedElementIndex--;
249
- }
250
- break;
251
- default:
252
- // React can bailout of no-op updates.
253
- return state;
254
- }
255
- }
256
-
257
- // Keep selected item ID and index in sync.
258
- if (lookupIDForIndex && selectedElementIndex !== state.selectedElementIndex) {
259
- if (selectedElementIndex === null) {
260
- selectedElementID = null;
261
- } else {
262
- selectedElementID = store.getElementIDAtIndex(
263
- ((selectedElementIndex: any): number),
264
- );
265
- }
266
- }
267
-
268
- return {
269
- ...state,
270
-
271
- numElements,
272
- selectedElementIndex,
273
- selectedElementID,
274
- };
275
-}
276
-
277
-function reduceSearchState(store: Store, state: State, action: Action): State {
278
- let {
279
- ownerID,
280
- searchIndex,
281
- searchResults,
282
- searchText,
283
- selectedElementID,
284
- selectedElementIndex,
285
- } = state;
286
-
287
- const prevSearchIndex = searchIndex;
288
- const prevSearchText = searchText;
289
- const numPrevSearchResults = searchResults.length;
290
-
291
- // We track explicitly whether search was requested because
292
- // we might want to search even if search index didn't change.
293
- // For example, if you press "next result" on a search with a single
294
- // result but a different current selection, we'll set this to true.
295
- let didRequestSearch = false;
296
-
297
- // Search isn't supported when the owner's tree is active.
298
- if (ownerID === null) {
299
- switch (action.type) {
300
- case 'GO_TO_NEXT_SEARCH_RESULT':
301
- if (numPrevSearchResults > 0) {
302
- didRequestSearch = true;
303
- searchIndex =
304
- searchIndex + 1 < numPrevSearchResults ? searchIndex + 1 : 0;
305
- }
306
- break;
307
- case 'GO_TO_PREVIOUS_SEARCH_RESULT':
308
- if (numPrevSearchResults > 0) {
309
- didRequestSearch = true;
310
- searchIndex =
311
- ((searchIndex: any): number) > 0
312
- ? ((searchIndex: any): number) - 1
313
- : numPrevSearchResults - 1;
314
- }
315
- break;
316
- case 'HANDLE_STORE_MUTATION':
317
- if (searchText !== '') {
318
- const [
319
- addedElementIDs,
320
- removedElementIDs,
321
- ] = (action: ACTION_HANDLE_STORE_MUTATION).payload;
322
-
323
- removedElementIDs.forEach((parentID, id) => {
324
- // Prune this item from the search results.
325
- const index = searchResults.indexOf(id);
326
- if (index >= 0) {
327
- searchResults = searchResults
328
- .slice(0, index)
329
- .concat(searchResults.slice(index + 1));
330
-
331
- // If the results are now empty, also deselect things.
332
- if (searchResults.length === 0) {
333
- searchIndex = null;
334
- } else if (((searchIndex: any): number) >= searchResults.length) {
335
- searchIndex = searchResults.length - 1;
336
- }
337
- }
338
- });
339
-
340
- addedElementIDs.forEach(id => {
341
- const element = ((store.getElementByID(id): any): Element);
342
-
343
- // It's possible that multiple tree operations will fire before this action has run.
344
- // So it's important to check for elements that may have been added and then removed.
345
- if (element !== null) {
346
- const {displayName} = element;
347
-
348
- // Add this item to the search results if it matches.
349
- const regExp = createRegExp(searchText);
350
- if (displayName !== null && regExp.test(displayName)) {
351
- const newElementIndex = ((store.getIndexOfElementID(
352
- id,
353
- ): any): number);
354
-
355
- let foundMatch = false;
356
- for (let index = 0; index < searchResults.length; index++) {
357
- const resultID = searchResults[index];
358
- if (
359
- newElementIndex <
360
- ((store.getIndexOfElementID(resultID): any): number)
361
- ) {
362
- foundMatch = true;
363
- searchResults = searchResults
364
- .slice(0, index)
365
- .concat(resultID)
366
- .concat(searchResults.slice(index));
367
- break;
368
- }
369
- }
370
- if (!foundMatch) {
371
- searchResults = searchResults.concat(id);
372
- }
373
-
374
- searchIndex = searchIndex === null ? 0 : searchIndex;
375
- }
376
- }
377
- });
378
- }
379
- break;
380
- case 'SET_SEARCH_TEXT':
381
- searchIndex = null;
382
- searchResults = [];
383
- searchText = (action: ACTION_SET_SEARCH_TEXT).payload;
384
-
385
- if (searchText !== '') {
386
- const regExp = createRegExp(searchText);
387
- store.roots.forEach(rootID => {
388
- recursivelySearchTree(store, rootID, regExp, searchResults);
389
- });
390
- if (searchResults.length > 0) {
391
- if (prevSearchIndex === null) {
392
- if (selectedElementIndex !== null) {
393
- searchIndex = getNearestResultIndex(
394
- store,
395
- searchResults,
396
- selectedElementIndex,
397
- );
398
- } else {
399
- searchIndex = 0;
400
- }
401
- } else {
402
- searchIndex = Math.min(
403
- ((prevSearchIndex: any): number),
404
- searchResults.length - 1,
405
- );
406
- }
407
- }
408
- }
409
- break;
410
- default:
411
- // React can bailout of no-op updates.
412
- return state;
413
- }
414
- }
415
-
416
- if (searchText !== prevSearchText) {
417
- const newSearchIndex = searchResults.indexOf(selectedElementID);
418
- if (newSearchIndex === -1) {
419
- // Only move the selection if the new query
420
- // doesn't match the current selection anymore.
421
- didRequestSearch = true;
422
- } else {
423
- // Selected item still matches the new search query.
424
- // Adjust the index to reflect its position in new results.
425
- searchIndex = newSearchIndex;
426
- }
427
- }
428
- if (didRequestSearch && searchIndex !== null) {
429
- selectedElementID = ((searchResults[searchIndex]: any): number);
430
- selectedElementIndex = store.getIndexOfElementID(
431
- ((selectedElementID: any): number),
432
- );
433
- }
434
-
435
- return {
436
- ...state,
437
-
438
- selectedElementID,
439
- selectedElementIndex,
440
-
441
- searchIndex,
442
- searchResults,
443
- searchText,
444
- };
445
-}
446
-
447
-function reduceOwnersState(store: Store, state: State, action: Action): State {
448
- let {
449
- numElements,
450
- selectedElementID,
451
- selectedElementIndex,
452
- ownerID,
453
- ownerFlatTree,
454
- searchIndex,
455
- searchResults,
456
- searchText,
457
- } = state;
458
-
459
- let prevSelectedElementIndex = selectedElementIndex;
460
-
461
- switch (action.type) {
462
- case 'HANDLE_STORE_MUTATION':
463
- if (ownerID !== null) {
464
- if (!store.containsElement(ownerID)) {
465
- ownerID = null;
466
- ownerFlatTree = null;
467
- selectedElementID = null;
468
- } else {
469
- ownerFlatTree = store.getOwnersListForElement(ownerID);
470
- if (selectedElementID !== null) {
471
- // Mutation might have caused the index of this ID to shift.
472
- selectedElementIndex = ownerFlatTree.findIndex(
473
- element => element.id === selectedElementID,
474
- );
475
- }
476
- }
477
- } else {
478
- if (selectedElementID !== null) {
479
- // Mutation might have caused the index of this ID to shift.
480
- selectedElementIndex = store.getIndexOfElementID(selectedElementID);
481
- }
482
- }
483
- if (selectedElementIndex === -1) {
484
- // If we couldn't find this ID after mutation, unselect it.
485
- selectedElementIndex = null;
486
- selectedElementID = null;
487
- }
488
- break;
489
- case 'RESET_OWNER_STACK':
490
- ownerID = null;
491
- ownerFlatTree = null;
492
- selectedElementIndex =
493
- selectedElementID !== null
494
- ? store.getIndexOfElementID(selectedElementID)
495
- : null;
496
- break;
497
- case 'SELECT_ELEMENT_AT_INDEX':
498
- if (ownerFlatTree !== null) {
499
- selectedElementIndex = (action: ACTION_SELECT_ELEMENT_AT_INDEX).payload;
500
- }
501
- break;
502
- case 'SELECT_ELEMENT_BY_ID':
503
- if (ownerFlatTree !== null) {
504
- const payload = (action: ACTION_SELECT_ELEMENT_BY_ID).payload;
505
- if (payload === null) {
506
- selectedElementIndex = null;
507
- } else {
508
- selectedElementIndex = ownerFlatTree.findIndex(
509
- element => element.id === payload,
510
- );
511
-
512
- // If the selected element is outside of the current owners list,
513
- // exit the list and select the element in the main tree.
514
- // This supports features like toggling Suspense.
515
- if (selectedElementIndex !== null && selectedElementIndex < 0) {
516
- ownerID = null;
517
- ownerFlatTree = null;
518
- selectedElementIndex = store.getIndexOfElementID(payload);
519
- }
520
- }
521
- }
522
- break;
523
- case 'SELECT_NEXT_ELEMENT_IN_TREE':
524
- if (ownerFlatTree !== null && ownerFlatTree.length > 0) {
525
- if (selectedElementIndex === null) {
526
- selectedElementIndex = 0;
527
- } else if (selectedElementIndex + 1 < ownerFlatTree.length) {
528
- selectedElementIndex++;
529
- }
530
- }
531
- break;
532
- case 'SELECT_PREVIOUS_ELEMENT_IN_TREE':
533
- if (ownerFlatTree !== null && ownerFlatTree.length > 0) {
534
- if (selectedElementIndex !== null && selectedElementIndex > 0) {
535
- selectedElementIndex--;
536
- }
537
- }
538
- break;
539
- case 'SELECT_OWNER':
540
- // If the Store doesn't have any owners metadata, don't drill into an empty stack.
541
- // This is a confusing user experience.
542
- if (store.hasOwnerMetadata) {
543
- ownerID = (action: ACTION_SELECT_OWNER).payload;
544
- ownerFlatTree = store.getOwnersListForElement(ownerID);
545
-
546
- // Always force reset selection to be the top of the new owner tree.
547
- selectedElementIndex = 0;
548
- prevSelectedElementIndex = null;
549
- }
550
- break;
551
- default:
552
- // React can bailout of no-op updates.
553
- return state;
554
- }
555
-
556
- // Changes in the selected owner require re-calculating the owners tree.
557
- if (
558
- ownerFlatTree !== state.ownerFlatTree ||
559
- action.type === 'HANDLE_STORE_MUTATION'
560
- ) {
561
- if (ownerFlatTree === null) {
562
- numElements = store.numElements;
563
- } else {
564
- numElements = ownerFlatTree.length;
565
- }
566
- }
567
-
568
- // Keep selected item ID and index in sync.
569
- if (selectedElementIndex !== prevSelectedElementIndex) {
570
- if (selectedElementIndex === null) {
571
- selectedElementID = null;
572
- } else {
573
- if (ownerFlatTree !== null) {
574
- selectedElementID = ownerFlatTree[selectedElementIndex].id;
575
- }
576
- }
577
- }
578
-
579
- return {
580
- ...state,
581
-
582
- numElements,
583
- selectedElementID,
584
- selectedElementIndex,
585
-
586
- searchIndex,
587
- searchResults,
588
- searchText,
589
-
590
- ownerID,
591
- ownerFlatTree,
592
- };
593
-}
594
-
595
-function reduceSuspenseState(
596
- store: Store,
597
- state: State,
598
- action: Action,
599
-): State {
600
- const {type} = action;
601
- switch (type) {
602
- case 'UPDATE_INSPECTED_ELEMENT_ID':
603
- if (state.inspectedElementID !== state.selectedElementID) {
604
- return {
605
- ...state,
606
- inspectedElementID: state.selectedElementID,
607
- };
608
- }
609
- break;
610
- default:
611
- break;
612
- }
613
-
614
- // React can bailout of no-op updates.
615
- return state;
616
-}
617
-
618
-type Props = {|
619
- children: React$Node,
620
-
621
- // Used for automated testing
622
- defaultOwnerID?: ?number,
623
- defaultSelectedElementID?: ?number,
624
- defaultSelectedElementIndex?: ?number,
625
-|};
626
-
627
-// TODO Remove TreeContextController wrapper element once global ConsearchText.write API exists.
628
-function TreeContextController({
629
- children,
630
- defaultOwnerID,
631
- defaultSelectedElementID,
632
- defaultSelectedElementIndex,
633
-}: Props) {
634
- const bridge = useContext(BridgeContext);
635
- const store = useContext(StoreContext);
636
-
637
- const initialRevision = useMemo(() => store.revision, [store]);
638
-
639
- // This reducer is created inline because it needs access to the Store.
640
- // The store is mutable, but the Store itself is global and lives for the lifetime of the DevTools,
641
- // so it's okay for the reducer to have an empty dependencies array.
642
- const reducer = useMemo(
643
- () => (state: State, action: Action): State => {
644
- const {type} = action;
645
- switch (type) {
646
- case 'GO_TO_NEXT_SEARCH_RESULT':
647
- case 'GO_TO_PREVIOUS_SEARCH_RESULT':
648
- case 'HANDLE_STORE_MUTATION':
649
- case 'RESET_OWNER_STACK':
650
- case 'SELECT_ELEMENT_AT_INDEX':
651
- case 'SELECT_ELEMENT_BY_ID':
652
- case 'SELECT_CHILD_ELEMENT_IN_TREE':
653
- case 'SELECT_NEXT_ELEMENT_IN_TREE':
654
- case 'SELECT_PARENT_ELEMENT_IN_TREE':
655
- case 'SELECT_PREVIOUS_ELEMENT_IN_TREE':
656
- case 'SELECT_OWNER':
657
- case 'UPDATE_INSPECTED_ELEMENT_ID':
658
- case 'SET_SEARCH_TEXT':
659
- state = reduceTreeState(store, state, action);
660
- state = reduceSearchState(store, state, action);
661
- state = reduceOwnersState(store, state, action);
662
- state = reduceSuspenseState(store, state, action);
663
-
664
- // If the selected ID is in a collapsed subtree, reset the selected index to null.
665
- // We'll know the correct index after the layout effect will toggle the tree,
666
- // and the store tree is mutated to account for that.
667
- if (
668
- state.selectedElementID !== null &&
669
- store.isInsideCollapsedSubTree(state.selectedElementID)
670
- ) {
671
- return {
672
- ...state,
673
- selectedElementIndex: null,
674
- };
675
- }
676
-
677
- return state;
678
- default:
679
- throw new Error(`Unrecognized action "${type}"`);
680
- }
681
- },
682
- [store],
683
- );
684
-
685
- const [state, dispatch] = useReducer(reducer, {
686
- // Tree
687
- numElements: store.numElements,
688
- selectedElementID:
689
- defaultSelectedElementID == null ? null : defaultSelectedElementID,
690
- selectedElementIndex:
691
- defaultSelectedElementIndex == null ? null : defaultSelectedElementIndex,
692
-
693
- // Search
694
- searchIndex: null,
695
- searchResults: [],
696
- searchText: '',
697
-
698
- // Owners
699
- ownerID: defaultOwnerID == null ? null : defaultOwnerID,
700
- ownerFlatTree: null,
701
-
702
- // Inspection element panel
703
- inspectedElementID: null,
704
- });
705
-
706
- const dispatchWrapper = useCallback(
707
- (action: Action) => {
708
- // Run the first update at "user-blocking" priority in case dispatch is called from a non-React event.
709
- // In this case, the current (and "next") priorities would both be "normal",
710
- // and suspense would potentially block both updates.
711
- runWithPriority(UserBlockingPriority, () => dispatch(action));
712
- next(() => dispatch({type: 'UPDATE_INSPECTED_ELEMENT_ID'}));
713
- },
714
- [dispatch],
715
- );
716
-
717
- // Listen for host element selections.
718
- useEffect(
719
- () => {
720
- const handleSelectFiber = (id: number) =>
721
- dispatchWrapper({type: 'SELECT_ELEMENT_BY_ID', payload: id});
722
- bridge.addListener('selectFiber', handleSelectFiber);
723
- return () => bridge.removeListener('selectFiber', handleSelectFiber);
724
- },
725
- [bridge, dispatchWrapper],
726
- );
727
-
728
- // If a newly-selected search result or inspection selection is inside of a collapsed subtree, auto expand it.
729
- // This needs to be a layout effect to avoid temporarily flashing an incorrect selection.
730
- const prevSelectedElementID = useRef<number | null>(null);
731
- useLayoutEffect(
732
- () => {
733
- if (state.selectedElementID !== prevSelectedElementID.current) {
734
- prevSelectedElementID.current = state.selectedElementID;
735
-
736
- if (state.selectedElementID !== null) {
737
- let element = store.getElementByID(state.selectedElementID);
738
- if (element !== null && element.parentID > 0) {
739
- store.toggleIsCollapsed(element.parentID, false);
740
- }
741
- }
742
- }
743
- },
744
- [state.selectedElementID, store],
745
- );
746
-
747
- // Mutations to the underlying tree may impact this context (e.g. search results, selection state).
748
- useEffect(
749
- () => {
750
- const handleStoreMutated = ([addedElementIDs, removedElementIDs]: [
751
- Array<number>,
752
- Map<number, number>,
753
- ]) => {
754
- dispatchWrapper({
755
- type: 'HANDLE_STORE_MUTATION',
756
- payload: [addedElementIDs, removedElementIDs],
757
- });
758
- };
759
-
760
- // Since this is a passive effect, the tree may have been mutated before our initial subscription.
761
- if (store.revision !== initialRevision) {
762
- // At the moment, we can treat this as a mutation.
763
- // We don't know which Elements were newly added/removed, but that should be okay in this case.
764
- // It would only impact the search state, which is unlikely to exist yet at this point.
765
- dispatchWrapper({
766
- type: 'HANDLE_STORE_MUTATION',
767
- payload: [[], new Map()],
768
- });
769
- }
770
-
771
- store.addListener('mutated', handleStoreMutated);
772
-
773
- return () => store.removeListener('mutated', handleStoreMutated);
774
- },
775
- [dispatchWrapper, initialRevision, store],
776
- );
777
-
778
- return (
779
- <TreeStateContext.Provider value={state}>
780
- <TreeDispatcherContext.Provider value={dispatchWrapper}>
781
- {children}
782
- </TreeDispatcherContext.Provider>
783
- </TreeStateContext.Provider>
784
- );
785
-}
786
-function recursivelySearchTree(
787
- store: Store,
788
- elementID: number,
789
- regExp: RegExp,
790
- searchResults: Array<number>,
791
-): void {
792
- const {children, displayName, hocDisplayNames} = ((store.getElementByID(
793
- elementID,
794
- ): any): Element);
795
-
796
- if (displayName != null && regExp.test(displayName) === true) {
797
- searchResults.push(elementID);
798
- } else if (
799
- hocDisplayNames != null &&
800
- hocDisplayNames.length > 0 &&
801
- hocDisplayNames.some(name => regExp.test(name)) === true
802
- ) {
803
- searchResults.push(elementID);
804
- }
805
-
806
- children.forEach(childID =>
807
- recursivelySearchTree(store, childID, regExp, searchResults),
808
- );
809
-}
810
-
811
-function getNearestResultIndex(
812
- store: Store,
813
- searchResults: Array<number>,
814
- selectedElementIndex: number,
815
-): number {
816
- const index = searchResults.findIndex(id => {
817
- const innerIndex = store.getIndexOfElementID(id);
818
- return innerIndex !== null && innerIndex >= selectedElementIndex;
819
- });
820
-
821
- return index === -1 ? 0 : index;
822
-}
823
-
824
-export {TreeDispatcherContext, TreeStateContext, TreeContextController};
packages/react-devtools-shared/src/devtools/views/Components/TreeFocusedContext.js
deleted
-14
@@ -1,14 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {createContext} from 'react';
11
-
12
-const TreeFocusedContext = createContext<boolean>(false);
13
-
14
-export default TreeFocusedContext;
packages/react-devtools-shared/src/devtools/views/Components/ViewElementSourceContext.js
deleted
-25
@@ -1,25 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {createContext} from 'react';
11
-
12
-import type {
13
- CanViewElementSource,
14
- ViewElementSource,
15
-} from 'react-devtools-shared/src/devtools/views/DevTools';
16
-
17
-export type Context = {|
18
- canViewElementSourceFunction: CanViewElementSource | null,
19
- viewElementSourceFunction: ViewElementSource | null,
20
-|};
21
-
22
-const ViewElementSourceContext = createContext<Context>(((null: any): Context));
23
-ViewElementSourceContext.displayName = 'ViewElementSourceContext';
24
-
25
-export default ViewElementSourceContext;
packages/react-devtools-shared/src/devtools/views/Components/types.js
deleted
-101
@@ -1,101 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {Source} from 'shared/ReactElementType';
11
-import type {
12
- Dehydrated,
13
- Unserializable,
14
-} from 'react-devtools-shared/src/hydration';
15
-import type {ElementType} from 'react-devtools-shared/src/types';
16
-
17
-// Each element on the frontend corresponds to a Fiber on the backend.
18
-// Some of its information (e.g. id, type, displayName) come from the backend.
19
-// Other bits (e.g. weight and depth) are computed on the frontend for windowing and display purposes.
20
-// Elements are udpated on a push basis– meaning the backend pushes updates to the frontend when needed.
21
-export type Element = {|
22
- id: number,
23
- parentID: number,
24
- children: Array<number>,
25
- type: ElementType,
26
- displayName: string | null,
27
- key: number | string | null,
28
-
29
- hocDisplayNames: null | Array<string>,
30
-
31
- // Should the elements children be visible in the tree?
32
- isCollapsed: boolean,
33
-
34
- // Owner (if available)
35
- ownerID: number,
36
-
37
- // How many levels deep within the tree is this element?
38
- // This determines how much indentation (left padding) should be used in the Elements tree.
39
- depth: number,
40
-
41
- // How many nodes (including itself) are below this Element within the tree.
42
- // This property is used to quickly determine the total number of Elements,
43
- // and the Element at any given index (for windowing purposes).
44
- weight: number,
45
-|};
46
-
47
-export type Owner = {|
48
- displayName: string | null,
49
- id: number,
50
- hocDisplayNames: Array<string> | null,
51
- type: ElementType,
52
-|};
53
-
54
-export type OwnersList = {|
55
- id: number,
56
- owners: Array<Owner> | null,
57
-|};
58
-
59
-export type InspectedElement = {|
60
- id: number,
61
-
62
- // Does the current renderer support editable hooks?
63
- canEditHooks: boolean,
64
-
65
- // Does the current renderer support editable function props?
66
- canEditFunctionProps: boolean,
67
-
68
- // Is this Suspense, and can its value be overriden now?
69
- canToggleSuspense: boolean,
70
-
71
- // Can view component source location.
72
- canViewSource: boolean,
73
-
74
- // Inspectable properties.
75
- context: Object | null,
76
- hooks: Object | null,
77
- props: Object | null,
78
- state: Object | null,
79
-
80
- // List of owners
81
- owners: Array<Owner> | null,
82
-
83
- // Location of component in source coude.
84
- source: Source | null,
85
-
86
- type: ElementType,
87
-|};
88
-
89
-// TODO: Add profiling type
90
-
91
-export type DehydratedData = {|
92
- cleaned: Array<Array<string | number>>,
93
- data:
94
- | string
95
- | Dehydrated
96
- | Unserializable
97
- | Array<Dehydrated>
98
- | Array<Unserializable>
99
- | {[key: string]: string | Dehydrated | Unserializable},
100
- unserializable: Array<Array<string | number>>,
101
-|};
packages/react-devtools-shared/src/devtools/views/DevTools.css
deleted
-54
@@ -1,54 +0,0 @@
1
-.DevTools {
2
- width: 100%;
3
- height: 100%;
4
- display: flex;
5
- flex-direction: column;
6
- background-color: var(--color-background);
7
- color: var(--color-text);
8
-}
9
-
10
-.TabBar {
11
- flex: 0 0 auto;
12
- display: flex;
13
- align-items: center;
14
- padding: 0 0.5rem;
15
- background-color: var(--color-background);
16
- border-top: 1px solid var(--color-border);
17
- font-family: var(--font-family-sans);
18
- font-size: var(--font-size-sans-large);
19
- user-select: none;
20
-
21
- /* Electron drag area */
22
- -webkit-app-region: drag;
23
-}
24
-
25
-.Spacer {
26
- flex: 1;
27
-}
28
-
29
-.TabContent {
30
- flex: 1 1 100%;
31
- overflow: auto;
32
-}
33
-
34
-.DevToolsVersion {
35
- font-size: var(--font-size-sans-normal);
36
- margin-right: 0.5rem;
37
-}
38
-
39
-.DevToolsVersion:before {
40
- font-size: var(--font-size-sans-large);
41
- content: 'DevTools ';
42
-}
43
-
44
-@media screen and (max-width: 400px) {
45
- .DevToolsVersion:before {
46
- content: '';
47
- }
48
-}
49
-
50
-@media screen and (max-width: 300px) {
51
- .DevToolsVersion {
52
- display: none;
53
- }
54
-}
packages/react-devtools-shared/src/devtools/views/DevTools.js
deleted
-177
@@ -1,177 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-// Reach styles need to come before any component styles.
11
-// This makes overridding the styles simpler.
12
-import '@reach/menu-button/styles.css';
13
-import '@reach/tooltip/styles.css';
14
-
15
-import React, {useEffect, useMemo, useState} from 'react';
16
-import Store from '../store';
17
-import {BridgeContext, StoreContext} from './context';
18
-import Components from './Components/Components';
19
-import Profiler from './Profiler/Profiler';
20
-import TabBar from './TabBar';
21
-import {SettingsContextController} from './Settings/SettingsContext';
22
-import {TreeContextController} from './Components/TreeContext';
23
-import ViewElementSourceContext from './Components/ViewElementSourceContext';
24
-import {ProfilerContextController} from './Profiler/ProfilerContext';
25
-import {ModalDialogContextController} from './ModalDialog';
26
-import ReactLogo from './ReactLogo';
27
-import WarnIfLegacyBackendDetected from './WarnIfLegacyBackendDetected';
28
-import ShowWelcomeToTheNewDevToolsDialog from './ShowWelcomeToTheNewDevToolsDialog';
29
-
30
-import styles from './DevTools.css';
31
-
32
-import './root.css';
33
-
34
-import type {InspectedElement} from 'react-devtools-shared/src/devtools/views/Components/types';
35
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
36
-
37
-export type BrowserTheme = 'dark' | 'light';
38
-export type TabID = 'components' | 'profiler';
39
-export type ViewElementSource = (
40
- id: number,
41
- inspectedElement: InspectedElement,
42
-) => void;
43
-export type CanViewElementSource = (
44
- inspectedElement: InspectedElement,
45
-) => boolean;
46
-
47
-export type Props = {|
48
- bridge: FrontendBridge,
49
- browserTheme?: BrowserTheme,
50
- canViewElementSourceFunction?: ?CanViewElementSource,
51
- defaultTab?: TabID,
52
- showTabBar?: boolean,
53
- showWelcomeToTheNewDevToolsDialog?: boolean,
54
- store: Store,
55
- warnIfLegacyBackendDetected?: boolean,
56
- viewElementSourceFunction?: ?ViewElementSource,
57
-
58
- // This property is used only by the web extension target.
59
- // The built-in tab UI is hidden in that case, in favor of the browser's own panel tabs.
60
- // This is done to save space within the app.
61
- // Because of this, the extension needs to be able to change which tab is active/rendered.
62
- overrideTab?: TabID,
63
-
64
- // To avoid potential multi-root trickiness, the web extension uses portals to render tabs.
65
- // The root <DevTools> app is rendered in the top-level extension window,
66
- // but individual tabs (e.g. Components, Profiling) can be rendered into portals within their browser panels.
67
- componentsPortalContainer?: Element,
68
- profilerPortalContainer?: Element,
69
-|};
70
-
71
-const componentsTab = {
72
- id: ('components': TabID),
73
- icon: 'components',
74
- label: 'Components',
75
- title: 'React Components',
76
-};
77
-const profilerTab = {
78
- id: ('profiler': TabID),
79
- icon: 'profiler',
80
- label: 'Profiler',
81
- title: 'React Profiler',
82
-};
83
-
84
-const tabs = [componentsTab, profilerTab];
85
-
86
-export default function DevTools({
87
- bridge,
88
- browserTheme = 'light',
89
- canViewElementSourceFunction,
90
- defaultTab = 'components',
91
- componentsPortalContainer,
92
- overrideTab,
93
- profilerPortalContainer,
94
- showTabBar = false,
95
- showWelcomeToTheNewDevToolsDialog = false,
96
- store,
97
- warnIfLegacyBackendDetected = false,
98
- viewElementSourceFunction,
99
-}: Props) {
100
- const [tab, setTab] = useState(defaultTab);
101
- if (overrideTab != null && overrideTab !== tab) {
102
- setTab(overrideTab);
103
- }
104
-
105
- const viewElementSource = useMemo(
106
- () => ({
107
- canViewElementSourceFunction: canViewElementSourceFunction || null,
108
- viewElementSourceFunction: viewElementSourceFunction || null,
109
- }),
110
- [canViewElementSourceFunction, viewElementSourceFunction],
111
- );
112
-
113
- useEffect(
114
- () => {
115
- return () => {
116
- try {
117
- bridge.shutdown();
118
- } catch (error) {
119
- // Attempting to use a disconnected port.
120
- }
121
- };
122
- },
123
- [bridge],
124
- );
125
-
126
- return (
127
- <BridgeContext.Provider value={bridge}>
128
- <StoreContext.Provider value={store}>
129
- <ModalDialogContextController>
130
- <SettingsContextController
131
- browserTheme={browserTheme}
132
- componentsPortalContainer={componentsPortalContainer}
133
- profilerPortalContainer={profilerPortalContainer}>
134
- <ViewElementSourceContext.Provider value={viewElementSource}>
135
- <TreeContextController>
136
- <ProfilerContextController>
137
- <div className={styles.DevTools}>
138
- {showTabBar && (
139
- <div className={styles.TabBar}>
140
- <ReactLogo />
141
- <span className={styles.DevToolsVersion}>
142
- {process.env.DEVTOOLS_VERSION}
143
- </span>
144
- <div className={styles.Spacer} />
145
- <TabBar
146
- currentTab={tab}
147
- id="DevTools"
148
- selectTab={setTab}
149
- tabs={tabs}
150
- type="navigation"
151
- />
152
- </div>
153
- )}
154
- <div
155
- className={styles.TabContent}
156
- hidden={tab !== 'components'}>
157
- <Components portalContainer={componentsPortalContainer} />
158
- </div>
159
- <div
160
- className={styles.TabContent}
161
- hidden={tab !== 'profiler'}>
162
- <Profiler portalContainer={profilerPortalContainer} />
163
- </div>
164
- </div>
165
- </ProfilerContextController>
166
- </TreeContextController>
167
- </ViewElementSourceContext.Provider>
168
- </SettingsContextController>
169
- {warnIfLegacyBackendDetected && <WarnIfLegacyBackendDetected />}
170
- {showWelcomeToTheNewDevToolsDialog && (
171
- <ShowWelcomeToTheNewDevToolsDialog />
172
- )}
173
- </ModalDialogContextController>
174
- </StoreContext.Provider>
175
- </BridgeContext.Provider>
176
- );
177
-}
packages/react-devtools-shared/src/devtools/views/ErrorBoundary.css
deleted
-24
@@ -1,24 +0,0 @@
1
-.ErrorBoundary {
2
- height: 100%;
3
- width: 100%;
4
- background-color: white;
5
- color: red;
6
- padding: 0.5rem;
7
- overflow: auto;
8
-}
9
-
10
-.Header {
11
- font-size: var(--font-size-sans-large);
12
- font-weight: bold;
13
-}
14
-
15
-.Stack {
16
- margin-top: 0.5rem;
17
- white-space: pre-wrap;
18
- font-family: var(--font-family-monospace);
19
- font-size: var(--font-size-monospace-small);
20
- background-color: hsl(0, 100%, 97%);
21
- border: 1px solid hsl(0, 100%, 92%);
22
- border-radius: 0.25rem;
23
- padding: 0.5rem;
24
-}
packages/react-devtools-shared/src/devtools/views/ErrorBoundary.js
deleted
-114
@@ -1,114 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Component} from 'react';
11
-import styles from './ErrorBoundary.css';
12
-
13
-type Props = {|
14
- children: React$Node,
15
-|};
16
-
17
-type State = {|
18
- callStack: string | null,
19
- componentStack: string | null,
20
- errorMessage: string | null,
21
- hasError: boolean,
22
-|};
23
-
24
-export default class ErrorBoundary extends Component<Props, State> {
25
- state: State = {
26
- callStack: null,
27
- componentStack: null,
28
- errorMessage: null,
29
- hasError: false,
30
- };
31
-
32
- componentDidCatch(error: any, {componentStack}: any) {
33
- const errorMessage =
34
- typeof error === 'object' && error.hasOwnProperty('message')
35
- ? error.message
36
- : error;
37
-
38
- const callStack =
39
- typeof error === 'object' && error.hasOwnProperty('stack')
40
- ? error.stack
41
- .split('\n')
42
- .slice(1)
43
- .join('\n')
44
- : null;
45
-
46
- this.setState({
47
- callStack,
48
- componentStack,
49
- errorMessage,
50
- hasError: true,
51
- });
52
- }
53
-
54
- render() {
55
- const {children} = this.props;
56
- const {callStack, componentStack, errorMessage, hasError} = this.state;
57
-
58
- let bugURL = process.env.GITHUB_URL;
59
- if (bugURL) {
60
- const title = `Error: "${errorMessage || ''}"`;
61
- const label = 'Component: Developer Tools';
62
-
63
- let body = 'Describe what you were doing when the bug occurred:';
64
- body += '\n1. ';
65
- body += '\n2. ';
66
- body += '\n3. ';
67
- body += '\n\n---------------------------------------------';
68
- body += '\nPlease do not remove the text below this line';
69
- body += '\n---------------------------------------------';
70
- body += `\n\nDevTools version: ${process.env.DEVTOOLS_VERSION || ''}`;
71
- if (callStack) {
72
- body += `\n\nCall stack: ${callStack.trim()}`;
73
- }
74
- if (componentStack) {
75
- body += `\n\nComponent stack: ${componentStack.trim()}`;
76
- }
77
-
78
- bugURL += `/issues/new?labels=${encodeURI(label)}&title=${encodeURI(
79
- title,
80
- )}&body=${encodeURI(body)}`;
81
- }
82
-
83
- if (hasError) {
84
- return (
85
- <div className={styles.ErrorBoundary}>
86
- <div className={styles.Header}>
87
- An error was thrown: "{errorMessage}"
88
- </div>
89
- {bugURL && (
90
- <a
91
- href={bugURL}
92
- rel="noopener noreferrer"
93
- target="_blank"
94
- title="Report bug">
95
- Report this issue
96
- </a>
97
- )}
98
- {!!callStack && (
99
- <div className={styles.Stack}>
100
- The error was thrown {callStack.trim()}
101
- </div>
102
- )}
103
- {!!componentStack && (
104
- <div className={styles.Stack}>
105
- The error occurred {componentStack.trim()}
106
- </div>
107
- )}
108
- </div>
109
- );
110
- }
111
-
112
- return children;
113
- }
114
-}
packages/react-devtools-shared/src/devtools/views/Icon.css
deleted
-5
@@ -1,5 +0,0 @@
1
-.Icon {
2
- width: 1rem;
3
- height: 1rem;
4
- fill: currentColor;
5
-}
packages/react-devtools-shared/src/devtools/views/Icon.js
deleted
-117
@@ -1,117 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-import styles from './Icon.css';
12
-
13
-export type IconType =
14
- | 'arrow'
15
- | 'components'
16
- | 'flame-chart'
17
- | 'interactions'
18
- | 'profiler'
19
- | 'ranked-chart'
20
- | 'search'
21
- | 'settings';
22
-
23
-type Props = {|
24
- className?: string,
25
- type: IconType,
26
-|};
27
-
28
-export default function Icon({className = '', type}: Props) {
29
- let pathData = null;
30
- switch (type) {
31
- case 'arrow':
32
- pathData = PATH_ARROW;
33
- break;
34
- case 'components':
35
- pathData = PATH_COMPONENTS;
36
- break;
37
- case 'flame-chart':
38
- pathData = PATH_FLAME_CHART;
39
- break;
40
- case 'interactions':
41
- pathData = PATH_INTERACTIONS;
42
- break;
43
- case 'profiler':
44
- pathData = PATH_PROFILER;
45
- break;
46
- case 'ranked-chart':
47
- pathData = PATH_RANKED_CHART;
48
- break;
49
- case 'search':
50
- pathData = PATH_SEARCH;
51
- break;
52
- case 'settings':
53
- pathData = PATH_SETTINGS;
54
- break;
55
- default:
56
- console.warn(`Unsupported type "${type}" specified for Icon`);
57
- break;
58
- }
59
-
60
- return (
61
- <svg
62
- xmlns="http://www.w3.org/2000/svg"
63
- className={`${styles.Icon} ${className}`}
64
- width="24"
65
- height="24"
66
- viewBox="0 0 24 24">
67
- <path d="M0 0h24v24H0z" fill="none" />
68
- <path fill="currentColor" d={pathData} />
69
- </svg>
70
- );
71
-}
72
-
73
-const PATH_ARROW = 'M8 5v14l11-7z';
74
-
75
-const PATH_COMPONENTS =
76
- 'M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z';
77
-
78
-const PATH_FLAME_CHART = `
79
- M10.0650893,21.5040462 C7.14020814,20.6850349 5,18.0558698 5,14.9390244 C5,14.017627
80
- 5,9.81707317 7.83333333,7.37804878 C7.83333333,7.37804878 7.58333333,11.199187 10,
81
- 10.6300813 C11.125,10.326087 13.0062497,7.63043487 8.91666667,2.5 C14.1666667,3.06910569
82
- 19,9.32926829 19,14.9390244 C19,18.0558698 16.8597919,20.6850349 13.9349107,21.5040462
83
- C14.454014,21.0118505 14.7765152,20.3233394 14.7765152,19.5613412 C14.7765152,17.2826087
84
- 12,15.0875871 12,15.0875871 C12,15.0875871 9.22348485,17.2826087 9.22348485,19.5613412
85
- C9.22348485,20.3233394 9.54598603,21.0118505 10.0650893,21.5040462 Z M12.0833333,20.6514763
86
- C11.3814715,20.6514763 10.8125,20.1226027 10.8125,19.4702042 C10.8125,18.6069669
87
- 12.0833333,16.9347829 12.0833333,16.9347829 C12.0833333,16.9347829 13.3541667,18.6069669
88
- 13.3541667,19.4702042 C13.3541667,20.1226027 12.7851952,20.6514763 12.0833333,20.6514763 Z
89
-`;
90
-
91
-const PATH_INTERACTIONS = `
92
- M23 8c0 1.1-.9 2-2 2-.18 0-.35-.02-.51-.07l-3.56 3.55c.05.16.07.34.07.52 0 1.1-.9 2-2
93
- 2s-2-.9-2-2c0-.18.02-.36.07-.52l-2.55-2.55c-.16.05-.34.07-.52.07s-.36-.02-.52-.07l-4.55
94
- 4.56c.05.16.07.33.07.51 0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2c.18 0 .35.02.51.07l4.56-4.55C8.02
95
- 9.36 8 9.18 8 9c0-1.1.9-2 2-2s2 .9 2 2c0 .18-.02.36-.07.52l2.55
96
- 2.55c.16-.05.34-.07.52-.07s.36.02.52.07l3.55-3.56C19.02 8.35 19 8.18 19 8c0-1.1.9-2 2-2s2 .9 2 2z
97
-`;
98
-
99
-const PATH_PROFILER = 'M5 9.2h3V19H5zM10.6 5h2.8v14h-2.8zm5.6 8H19v6h-2.8z';
100
-
101
-const PATH_SEARCH = `
102
- M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91
103
- 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99
104
- 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z
105
-`;
106
-
107
-const PATH_RANKED_CHART = 'M3 5h18v3H3zM3 10.5h13v3H3zM3 16h8v3H3z';
108
-
109
-const PATH_SETTINGS = `
110
- M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49
111
- 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38
112
- 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11
113
- 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4
114
- 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49
115
- 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5
116
- 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z
117
-`;
packages/react-devtools-shared/src/devtools/views/ModalDialog.css
deleted
-40
@@ -1,40 +0,0 @@
1
-.Background {
2
- position: absolute;
3
- width: 100%;
4
- height: 100%;
5
- display: flex;
6
- align-items: flex-start;
7
- justify-content: center;
8
- padding: 1rem;
9
- background-color: var(--color-modal-background);
10
- overflow: auto;
11
-}
12
-
13
-.Dialog {
14
- position: relative;
15
- z-index: 3;
16
- width: 25rem;
17
- min-width: 20rem;
18
- max-width: 100%;
19
- display: inline-block;
20
- background-color: var(--color-background);
21
- box-shadow: 0 2px 4px var(--color-shadow);
22
- padding: 0.5rem;
23
- border: 1px solid var(--color-border);
24
- border-radius: 0.25rem;
25
- font-size: var(--font-size-sans-normal);
26
-}
27
-
28
-.Title {
29
- font-size: var(--font-size-sans-large);
30
- margin-bottom: 0.5rem;
31
-}
32
-
33
-.Buttons {
34
- text-align: right;
35
- margin-top: 0.5rem;
36
-}
37
-
38
-.Button {
39
- font-size: var(--font-size-sans-large);
40
-}
packages/react-devtools-shared/src/devtools/views/ModalDialog.js
deleted
-162
@@ -1,162 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- createContext,
12
- useCallback,
13
- useContext,
14
- useMemo,
15
- useReducer,
16
- useRef,
17
-} from 'react';
18
-import Button from './Button';
19
-import {useModalDismissSignal} from './hooks';
20
-
21
-import styles from './ModalDialog.css';
22
-
23
-type DIALOG_ACTION_HIDE = {|
24
- type: 'HIDE',
25
-|};
26
-type DIALOG_ACTION_SHOW = {|
27
- type: 'SHOW',
28
- canBeDismissed?: boolean,
29
- content: React$Node,
30
- title?: React$Node | null,
31
-|};
32
-
33
-type Action = DIALOG_ACTION_HIDE | DIALOG_ACTION_SHOW;
34
-
35
-type Dispatch = (action: Action) => void;
36
-
37
-type State = {|
38
- canBeDismissed: boolean,
39
- content: React$Node | null,
40
- isVisible: boolean,
41
- title: React$Node | null,
42
-|};
43
-
44
-type ModalDialogContextType = {|
45
- ...State,
46
- dispatch: Dispatch,
47
-|};
48
-
49
-const ModalDialogContext = createContext<ModalDialogContextType>(
50
- ((null: any): ModalDialogContextType),
51
-);
52
-ModalDialogContext.displayName = 'ModalDialogContext';
53
-
54
-function dialogReducer(state, action) {
55
- switch (action.type) {
56
- case 'HIDE':
57
- return {
58
- canBeDismissed: true,
59
- content: null,
60
- isVisible: false,
61
- title: null,
62
- };
63
- case 'SHOW':
64
- return {
65
- canBeDismissed: action.canBeDismissed !== false,
66
- content: action.content,
67
- isVisible: true,
68
- title: action.title || null,
69
- };
70
- default:
71
- throw new Error(`Invalid action "${action.type}"`);
72
- }
73
-}
74
-
75
-type Props = {|
76
- children: React$Node,
77
-|};
78
-
79
-function ModalDialogContextController({children}: Props) {
80
- const [state, dispatch] = useReducer<State, Action>(dialogReducer, {
81
- canBeDismissed: true,
82
- content: null,
83
- isVisible: false,
84
- title: null,
85
- });
86
-
87
- const value = useMemo<ModalDialogContextType>(
88
- () => ({
89
- canBeDismissed: state.canBeDismissed,
90
- content: state.content,
91
- isVisible: state.isVisible,
92
- title: state.title,
93
- dispatch,
94
- }),
95
- [state, dispatch],
96
- );
97
-
98
- return (
99
- <ModalDialogContext.Provider value={value}>
100
- {children}
101
- </ModalDialogContext.Provider>
102
- );
103
-}
104
-
105
-function ModalDialog(_: {||}) {
106
- const {isVisible} = useContext(ModalDialogContext);
107
- return isVisible ? <ModalDialogImpl /> : null;
108
-}
109
-
110
-function ModalDialogImpl(_: {||}) {
111
- const {canBeDismissed, content, dispatch, title} = useContext(
112
- ModalDialogContext,
113
- );
114
- const dismissModal = useCallback(
115
- () => {
116
- if (canBeDismissed) {
117
- dispatch({type: 'HIDE'});
118
- }
119
- },
120
- [canBeDismissed, dispatch],
121
- );
122
- const dialogRef = useRef<HTMLDivElement | null>(null);
123
-
124
- // It's important to trap click events within the dialog,
125
- // so the dismiss hook will use it for click hit detection.
126
- // Because multiple tabs may be showing this ModalDialog,
127
- // the normal `dialog.contains(target)` check would fail on a background tab.
128
- useModalDismissSignal(dialogRef, dismissModal, false);
129
-
130
- // Clicks on the dialog should not bubble.
131
- // This way we can dismiss by listening to clicks on the background.
132
- const handleDialogClick = (event: any) => {
133
- event.stopPropagation();
134
-
135
- // It is important that we don't also prevent default,
136
- // or clicks within the dialog (e.g. on links) won't work.
137
- };
138
-
139
- return (
140
- <div className={styles.Background} onClick={dismissModal}>
141
- <div
142
- ref={dialogRef}
143
- className={styles.Dialog}
144
- onClick={handleDialogClick}>
145
- {title !== null && <div className={styles.Title}>{title}</div>}
146
- {content}
147
- {canBeDismissed && (
148
- <div className={styles.Buttons}>
149
- <Button
150
- autoFocus={true}
151
- className={styles.Button}
152
- onClick={dismissModal}>
153
- Okay
154
- </Button>
155
- </div>
156
- )}
157
- </div>
158
- </div>
159
- );
160
-}
161
-
162
-export {ModalDialog, ModalDialogContext, ModalDialogContextController};
packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.css
deleted
-31
@@ -1,31 +0,0 @@
1
-.Group {
2
- transition: all ease-in-out 250ms;
3
-}
4
-
5
-.Rect {
6
- cursor: pointer;
7
- stroke: var(--color-background);
8
- transition: all ease-in-out 250ms;
9
-}
10
-
11
-.ForeignObject {
12
- pointer-events: none;
13
- transition: all ease-in-out 250ms;
14
-}
15
-
16
-.Div {
17
- pointer-events: none;
18
- white-space: nowrap;
19
- text-overflow: ellipsis;
20
- overflow: hidden;
21
- font-family: var(--font-family-sans);
22
- font-size: var(--font-size-sans-normal);
23
- margin-left: 0.25rem;
24
- margin-right: 0.25rem;
25
- line-height: 1.5;
26
- padding: 0 0 0;
27
- font-weight: 400;
28
- color: var(--color-commit-gradient-text);
29
- text-align: left;
30
- transition: all ease-in-out 250ms;
31
-}
packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.js
deleted
-74
@@ -1,74 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-
12
-import styles from './ChartNode.css';
13
-
14
-type Props = {|
15
- color: string,
16
- height: number,
17
- isDimmed?: boolean,
18
- label: string,
19
- onClick: (event: SyntheticMouseEvent<*>) => mixed,
20
- onDoubleClick?: (event: SyntheticMouseEvent<*>) => mixed,
21
- placeLabelAboveNode?: boolean,
22
- textStyle?: Object,
23
- width: number,
24
- x: number,
25
- y: number,
26
-|};
27
-
28
-const minWidthToDisplay = 35;
29
-
30
-export default function ChartNode({
31
- color,
32
- height,
33
- isDimmed = false,
34
- label,
35
- onClick,
36
- onDoubleClick,
37
- textStyle,
38
- width,
39
- x,
40
- y,
41
-}: Props) {
42
- return (
43
- <g className={styles.Group} transform={`translate(${x},${y})`}>
44
- <title>{label}</title>
45
- <rect
46
- width={width}
47
- height={height}
48
- fill={color}
49
- onClick={onClick}
50
- onDoubleClick={onDoubleClick}
51
- className={styles.Rect}
52
- style={{
53
- opacity: isDimmed ? 0.5 : 1,
54
- }}
55
- />
56
- {width >= minWidthToDisplay && (
57
- <foreignObject
58
- width={width}
59
- height={height}
60
- className={styles.ForeignObject}
61
- style={{
62
- paddingLeft: x < 0 ? -x : 0,
63
- opacity: isDimmed ? 0.75 : 1,
64
- display: width < minWidthToDisplay ? 'none' : 'block',
65
- }}
66
- y={0}>
67
- <div className={styles.Div} style={textStyle}>
68
- {label}
69
- </div>
70
- </foreignObject>
71
- )}
72
- </g>
73
- );
74
-}
packages/react-devtools-shared/src/devtools/views/Profiler/ClearProfilingDataButton.js
deleted
-31
@@ -1,31 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useContext} from 'react';
11
-import {ProfilerContext} from './ProfilerContext';
12
-import Button from '../Button';
13
-import ButtonIcon from '../ButtonIcon';
14
-import {StoreContext} from '../context';
15
-
16
-export default function ClearProfilingDataButton() {
17
- const store = useContext(StoreContext);
18
- const {didRecordCommits, isProfiling} = useContext(ProfilerContext);
19
- const {profilerStore} = store;
20
-
21
- const clear = useCallback(() => profilerStore.clear(), [profilerStore]);
22
-
23
- return (
24
- <Button
25
- disabled={isProfiling || !didRecordCommits}
26
- onClick={clear}
27
- title="Clear profiling data">
28
- <ButtonIcon type="clear" />
29
- </Button>
30
- );
31
-}
packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.css
deleted
-10
@@ -1,10 +0,0 @@
1
-.Container {
2
- width: 100%;
3
- flex: 1;
4
- padding: 0.5rem;
5
-}
6
-
7
-.PatternPath {
8
- stroke: var(--color-commit-did-not-render-pattern);
9
- stroke-width: 1;
10
-}
packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js
deleted
-172
@@ -1,172 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {forwardRef, useCallback, useContext, useMemo} from 'react';
11
-import AutoSizer from 'react-virtualized-auto-sizer';
12
-import {FixedSizeList} from 'react-window';
13
-import {ProfilerContext} from './ProfilerContext';
14
-import NoCommitData from './NoCommitData';
15
-import CommitFlamegraphListItem from './CommitFlamegraphListItem';
16
-import {scale} from './utils';
17
-import {StoreContext} from '../context';
18
-import {SettingsContext} from '../Settings/SettingsContext';
19
-
20
-import styles from './CommitFlamegraph.css';
21
-
22
-import type {ChartData, ChartNode} from './FlamegraphChartBuilder';
23
-import type {CommitTree} from './types';
24
-
25
-export type ItemData = {|
26
- chartData: ChartData,
27
- scaleX: (value: number, fallbackValue: number) => number,
28
- selectedChartNode: ChartNode | null,
29
- selectedChartNodeIndex: number,
30
- selectFiber: (id: number | null, name: string | null) => void,
31
- width: number,
32
-|};
33
-
34
-export default function CommitFlamegraphAutoSizer(_: {||}) {
35
- const {profilerStore} = useContext(StoreContext);
36
- const {rootID, selectedCommitIndex, selectFiber} = useContext(
37
- ProfilerContext,
38
- );
39
- const {profilingCache} = profilerStore;
40
-
41
- const deselectCurrentFiber = useCallback(
42
- event => {
43
- event.stopPropagation();
44
- selectFiber(null, null);
45
- },
46
- [selectFiber],
47
- );
48
-
49
- let commitTree: CommitTree | null = null;
50
- let chartData: ChartData | null = null;
51
- if (selectedCommitIndex !== null) {
52
- commitTree = profilingCache.getCommitTree({
53
- commitIndex: selectedCommitIndex,
54
- rootID: ((rootID: any): number),
55
- });
56
-
57
- chartData = profilingCache.getFlamegraphChartData({
58
- commitIndex: selectedCommitIndex,
59
- commitTree,
60
- rootID: ((rootID: any): number),
61
- });
62
- }
63
-
64
- if (commitTree != null && chartData != null && chartData.depth > 0) {
65
- return (
66
- <div className={styles.Container} onClick={deselectCurrentFiber}>
67
- <AutoSizer>
68
- {({height, width}) => (
69
- // Force Flow types to avoid checking for `null` here because there's no static proof that
70
- // by the time this render prop function is called, the values of the `let` variables have not changed.
71
- <CommitFlamegraph
72
- chartData={((chartData: any): ChartData)}
73
- commitTree={((commitTree: any): CommitTree)}
74
- height={height}
75
- width={width}
76
- />
77
- )}
78
- </AutoSizer>
79
- </div>
80
- );
81
- } else {
82
- return <NoCommitData />;
83
- }
84
-}
85
-
86
-type Props = {|
87
- chartData: ChartData,
88
- commitTree: CommitTree,
89
- height: number,
90
- width: number,
91
-|};
92
-
93
-function CommitFlamegraph({chartData, commitTree, height, width}: Props) {
94
- const {lineHeight} = useContext(SettingsContext);
95
- const {selectFiber, selectedFiberID} = useContext(ProfilerContext);
96
-
97
- const selectedChartNodeIndex = useMemo<number>(
98
- () => {
99
- if (selectedFiberID === null) {
100
- return 0;
101
- }
102
- // The selected node might not be in the tree for this commit,
103
- // so it's important that we have a fallback plan.
104
- const depth = chartData.idToDepthMap.get(selectedFiberID);
105
- return depth !== undefined ? depth - 1 : 0;
106
- },
107
- [chartData, selectedFiberID],
108
- );
109
-
110
- const selectedChartNode = useMemo(
111
- () => {
112
- if (selectedFiberID !== null) {
113
- return (
114
- chartData.rows[selectedChartNodeIndex].find(
115
- chartNode => chartNode.id === selectedFiberID,
116
- ) || null
117
- );
118
- }
119
- return null;
120
- },
121
- [chartData, selectedFiberID, selectedChartNodeIndex],
122
- );
123
-
124
- const itemData = useMemo<ItemData>(
125
- () => ({
126
- chartData,
127
- scaleX: scale(
128
- 0,
129
- selectedChartNode !== null
130
- ? selectedChartNode.treeBaseDuration
131
- : chartData.baseDuration,
132
- 0,
133
- width,
134
- ),
135
- selectedChartNode,
136
- selectedChartNodeIndex,
137
- selectFiber,
138
- width,
139
- }),
140
- [chartData, selectedChartNode, selectedChartNodeIndex, selectFiber, width],
141
- );
142
-
143
- return (
144
- <FixedSizeList
145
- height={height}
146
- innerElementType={InnerElementType}
147
- itemCount={chartData.depth}
148
- itemData={itemData}
149
- itemSize={lineHeight}
150
- width={width}>
151
- {CommitFlamegraphListItem}
152
- </FixedSizeList>
153
- );
154
-}
155
-
156
-const InnerElementType = forwardRef(({children, ...rest}, ref) => (
157
- <svg ref={ref} {...rest}>
158
- <defs>
159
- <pattern
160
- id="didNotRenderPattern"
161
- patternUnits="userSpaceOnUse"
162
- width="4"
163
- height="4">
164
- <path
165
- d="M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2"
166
- className={styles.PatternPath}
167
- />
168
- </pattern>
169
- </defs>
170
- {children}
171
- </svg>
172
-));
packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js
deleted
-117
@@ -1,117 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, memo, useCallback, useContext} from 'react';
11
-import {areEqual} from 'react-window';
12
-import {barWidthThreshold} from './constants';
13
-import {getGradientColor} from './utils';
14
-import ChartNode from './ChartNode';
15
-import {SettingsContext} from '../Settings/SettingsContext';
16
-
17
-import type {ItemData} from './CommitFlamegraph';
18
-
19
-type Props = {
20
- data: ItemData,
21
- index: number,
22
- style: Object,
23
-};
24
-
25
-function CommitFlamegraphListItem({data, index, style}: Props) {
26
- const {
27
- chartData,
28
- scaleX,
29
- selectedChartNode,
30
- selectedChartNodeIndex,
31
- selectFiber,
32
- width,
33
- } = data;
34
- const {renderPathNodes, maxSelfDuration, rows} = chartData;
35
-
36
- const {lineHeight} = useContext(SettingsContext);
37
- const handleClick = useCallback(
38
- (event: SyntheticMouseEvent<*>, id: number, name: string) => {
39
- event.stopPropagation();
40
- selectFiber(id, name);
41
- },
42
- [selectFiber],
43
- );
44
-
45
- // List items are absolutely positioned using the CSS "top" attribute.
46
- // The "left" value will always be 0.
47
- // Since height is fixed, and width is based on the node's duration,
48
- // We can ignore those values as well.
49
- const top = parseInt(style.top, 10);
50
-
51
- const row = rows[index];
52
-
53
- let selectedNodeOffset = scaleX(
54
- selectedChartNode !== null ? selectedChartNode.offset : 0,
55
- width,
56
- );
57
-
58
- return (
59
- <Fragment>
60
- {row.map(chartNode => {
61
- const {
62
- didRender,
63
- id,
64
- label,
65
- name,
66
- offset,
67
- selfDuration,
68
- treeBaseDuration,
69
- } = chartNode;
70
-
71
- const nodeOffset = scaleX(offset, width);
72
- const nodeWidth = scaleX(treeBaseDuration, width);
73
-
74
- // Filter out nodes that are too small to see or click.
75
- // This also helps render large trees faster.
76
- if (nodeWidth < barWidthThreshold) {
77
- return null;
78
- }
79
-
80
- // Filter out nodes that are outside of the horizontal window.
81
- if (
82
- nodeOffset + nodeWidth < selectedNodeOffset ||
83
- nodeOffset > selectedNodeOffset + width
84
- ) {
85
- return null;
86
- }
87
-
88
- let color = 'url(#didNotRenderPattern)';
89
- let textColor = 'var(--color-commit-did-not-render-pattern-text)';
90
- if (didRender) {
91
- color = getGradientColor(selfDuration / maxSelfDuration);
92
- textColor = 'var(--color-commit-gradient-text)';
93
- } else if (renderPathNodes.has(id)) {
94
- color = 'var(--color-commit-did-not-render-fill)';
95
- textColor = 'var(--color-commit-did-not-render-fill-text)';
96
- }
97
-
98
- return (
99
- <ChartNode
100
- color={color}
101
- height={lineHeight}
102
- isDimmed={index < selectedChartNodeIndex}
103
- key={id}
104
- label={label}
105
- onClick={event => handleClick(event, id, name)}
106
- textStyle={{color: textColor}}
107
- width={nodeWidth}
108
- x={nodeOffset - selectedNodeOffset}
109
- y={top}
110
- />
111
- );
112
- })}
113
- </Fragment>
114
- );
115
-}
116
-
117
-export default memo<Props>(CommitFlamegraphListItem, areEqual);
packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.css
deleted
-5
@@ -1,5 +0,0 @@
1
-.Container {
2
- width: 100%;
3
- flex: 1;
4
- padding: 0.5rem;
5
-}
packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js
deleted
-136
@@ -1,136 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useContext, useMemo} from 'react';
11
-import AutoSizer from 'react-virtualized-auto-sizer';
12
-import {FixedSizeList} from 'react-window';
13
-import {ProfilerContext} from './ProfilerContext';
14
-import NoCommitData from './NoCommitData';
15
-import CommitRankedListItem from './CommitRankedListItem';
16
-import {scale} from './utils';
17
-import {StoreContext} from '../context';
18
-import {SettingsContext} from '../Settings/SettingsContext';
19
-
20
-import styles from './CommitRanked.css';
21
-
22
-import type {ChartData} from './RankedChartBuilder';
23
-import type {CommitTree} from './types';
24
-
25
-export type ItemData = {|
26
- chartData: ChartData,
27
- scaleX: (value: number, fallbackValue: number) => number,
28
- selectedFiberID: number | null,
29
- selectedFiberIndex: number,
30
- selectFiber: (id: number | null, name: string | null) => void,
31
- width: number,
32
-|};
33
-
34
-export default function CommitRankedAutoSizer(_: {||}) {
35
- const {profilerStore} = useContext(StoreContext);
36
- const {rootID, selectedCommitIndex, selectFiber} = useContext(
37
- ProfilerContext,
38
- );
39
- const {profilingCache} = profilerStore;
40
-
41
- const deselectCurrentFiber = useCallback(
42
- event => {
43
- event.stopPropagation();
44
- selectFiber(null, null);
45
- },
46
- [selectFiber],
47
- );
48
-
49
- let commitTree: CommitTree | null = null;
50
- let chartData: ChartData | null = null;
51
- if (selectedCommitIndex !== null) {
52
- commitTree = profilingCache.getCommitTree({
53
- commitIndex: selectedCommitIndex,
54
- rootID: ((rootID: any): number),
55
- });
56
-
57
- chartData = profilingCache.getRankedChartData({
58
- commitIndex: selectedCommitIndex,
59
- commitTree,
60
- rootID: ((rootID: any): number),
61
- });
62
- }
63
-
64
- if (commitTree != null && chartData != null && chartData.nodes.length > 0) {
65
- return (
66
- <div className={styles.Container} onClick={deselectCurrentFiber}>
67
- <AutoSizer>
68
- {({height, width}) => (
69
- <CommitRanked
70
- chartData={((chartData: any): ChartData)}
71
- commitTree={((commitTree: any): CommitTree)}
72
- height={height}
73
- width={width}
74
- />
75
- )}
76
- </AutoSizer>
77
- </div>
78
- );
79
- } else {
80
- return <NoCommitData />;
81
- }
82
-}
83
-
84
-type Props = {|
85
- chartData: ChartData,
86
- commitTree: CommitTree,
87
- height: number,
88
- width: number,
89
-|};
90
-
91
-function CommitRanked({chartData, commitTree, height, width}: Props) {
92
- const {lineHeight} = useContext(SettingsContext);
93
- const {selectedFiberID, selectFiber} = useContext(ProfilerContext);
94
-
95
- const selectedFiberIndex = useMemo(
96
- () => getNodeIndex(chartData, selectedFiberID),
97
- [chartData, selectedFiberID],
98
- );
99
-
100
- const itemData = useMemo<ItemData>(
101
- () => ({
102
- chartData,
103
- scaleX: scale(0, chartData.nodes[selectedFiberIndex].value, 0, width),
104
- selectedFiberID,
105
- selectedFiberIndex,
106
- selectFiber,
107
- width,
108
- }),
109
- [chartData, selectedFiberID, selectedFiberIndex, selectFiber, width],
110
- );
111
-
112
- return (
113
- <FixedSizeList
114
- height={height}
115
- innerElementType="svg"
116
- itemCount={chartData.nodes.length}
117
- itemData={itemData}
118
- itemSize={lineHeight}
119
- width={width}>
120
- {CommitRankedListItem}
121
- </FixedSizeList>
122
- );
123
-}
124
-
125
-const getNodeIndex = (chartData: ChartData, id: number | null): number => {
126
- if (id === null) {
127
- return 0;
128
- }
129
- const {nodes} = chartData;
130
- for (let index = 0; index < nodes.length; index++) {
131
- if (nodes[index].id === id) {
132
- return index;
133
- }
134
- }
135
- return 0;
136
-};
packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js
deleted
-61
@@ -1,61 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {memo, useCallback, useContext} from 'react';
11
-import {areEqual} from 'react-window';
12
-import {minBarWidth} from './constants';
13
-import {getGradientColor} from './utils';
14
-import ChartNode from './ChartNode';
15
-import {SettingsContext} from '../Settings/SettingsContext';
16
-
17
-import type {ItemData} from './CommitRanked';
18
-
19
-type Props = {
20
- data: ItemData,
21
- index: number,
22
- style: Object,
23
-};
24
-
25
-function CommitRankedListItem({data, index, style}: Props) {
26
- const {chartData, scaleX, selectedFiberIndex, selectFiber, width} = data;
27
-
28
- const node = chartData.nodes[index];
29
-
30
- const {lineHeight} = useContext(SettingsContext);
31
-
32
- const handleClick = useCallback(
33
- event => {
34
- event.stopPropagation();
35
- selectFiber(node.id, node.name);
36
- },
37
- [node, selectFiber],
38
- );
39
-
40
- // List items are absolutely positioned using the CSS "top" attribute.
41
- // The "left" value will always be 0.
42
- // Since height is fixed, and width is based on the node's duration,
43
- // We can ignore those values as well.
44
- const top = parseInt(style.top, 10);
45
-
46
- return (
47
- <ChartNode
48
- color={getGradientColor(node.value / chartData.maxValue)}
49
- height={lineHeight}
50
- isDimmed={index < selectedFiberIndex}
51
- key={node.id}
52
- label={node.label}
53
- onClick={handleClick}
54
- width={Math.max(minBarWidth, scaleX(node.value, width))}
55
- x={0}
56
- y={top}
57
- />
58
- );
59
-}
60
-
61
-export default memo<Props>(CommitRankedListItem, areEqual);
packages/react-devtools-shared/src/devtools/views/Profiler/CommitTreeBuilder.js
deleted
-371
@@ -1,371 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {
11
- __DEBUG__,
12
- TREE_OPERATION_ADD,
13
- TREE_OPERATION_REMOVE,
14
- TREE_OPERATION_REORDER_CHILDREN,
15
- TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
16
-} from 'react-devtools-shared/src/constants';
17
-import {utfDecodeString} from 'react-devtools-shared/src/utils';
18
-import {ElementTypeRoot} from 'react-devtools-shared/src/types';
19
-import ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore';
20
-
21
-import type {ElementType} from 'react-devtools-shared/src/types';
22
-import type {
23
- CommitTree,
24
- CommitTreeNode,
25
- ProfilingDataForRootFrontend,
26
-} from 'react-devtools-shared/src/devtools/views/Profiler/types';
27
-
28
-const debug = (methodName, ...args) => {
29
- if (__DEBUG__) {
30
- console.log(
31
- `%cCommitTreeBuilder %c${methodName}`,
32
- 'color: pink; font-weight: bold;',
33
- 'font-weight: bold;',
34
- ...args,
35
- );
36
- }
37
-};
38
-
39
-const rootToCommitTreeMap: Map<number, Array<CommitTree>> = new Map();
40
-
41
-export function getCommitTree({
42
- commitIndex,
43
- profilerStore,
44
- rootID,
45
-}: {|
46
- commitIndex: number,
47
- profilerStore: ProfilerStore,
48
- rootID: number,
49
-|}): CommitTree {
50
- if (!rootToCommitTreeMap.has(rootID)) {
51
- rootToCommitTreeMap.set(rootID, []);
52
- }
53
-
54
- const commitTrees = ((rootToCommitTreeMap.get(rootID): any): Array<
55
- CommitTree,
56
- >);
57
-
58
- if (commitIndex < commitTrees.length) {
59
- return commitTrees[commitIndex];
60
- }
61
-
62
- const {profilingData} = profilerStore;
63
- if (profilingData === null) {
64
- throw Error(`No profiling data available`);
65
- }
66
-
67
- const dataForRoot = profilingData.dataForRoots.get(rootID);
68
- if (dataForRoot == null) {
69
- throw Error(`Could not find profiling data for root "${rootID}"`);
70
- }
71
-
72
- const {operations} = dataForRoot;
73
-
74
- // Commits are generated sequentially and cached.
75
- // If this is the very first commit, start with the cached snapshot and apply the first mutation.
76
- // Otherwise load (or generate) the previous commit and append a mutation to it.
77
- if (commitIndex === 0) {
78
- const nodes = new Map();
79
-
80
- // Construct the initial tree.
81
- recursivelyInitializeTree(rootID, 0, nodes, dataForRoot);
82
-
83
- // Mutate the tree
84
- if (operations != null && commitIndex < operations.length) {
85
- const commitTree = updateTree({nodes, rootID}, operations[commitIndex]);
86
-
87
- if (__DEBUG__) {
88
- __printTree(commitTree);
89
- }
90
-
91
- commitTrees.push(commitTree);
92
- return commitTree;
93
- }
94
- } else {
95
- const previousCommitTree = getCommitTree({
96
- commitIndex: commitIndex - 1,
97
- profilerStore,
98
- rootID,
99
- });
100
-
101
- if (operations != null && commitIndex < operations.length) {
102
- const commitTree = updateTree(
103
- previousCommitTree,
104
- operations[commitIndex],
105
- );
106
-
107
- if (__DEBUG__) {
108
- __printTree(commitTree);
109
- }
110
-
111
- commitTrees.push(commitTree);
112
- return commitTree;
113
- }
114
- }
115
-
116
- throw Error(
117
- `getCommitTree(): Unable to reconstruct tree for root "${rootID}" and commit ${commitIndex}`,
118
- );
119
-}
120
-
121
-function recursivelyInitializeTree(
122
- id: number,
123
- parentID: number,
124
- nodes: Map<number, CommitTreeNode>,
125
- dataForRoot: ProfilingDataForRootFrontend,
126
-): void {
127
- const node = dataForRoot.snapshots.get(id);
128
- if (node != null) {
129
- nodes.set(id, {
130
- id,
131
- children: node.children,
132
- displayName: node.displayName,
133
- key: node.key,
134
- parentID,
135
- treeBaseDuration: ((dataForRoot.initialTreeBaseDurations.get(
136
- id,
137
- ): any): number),
138
- type: node.type,
139
- });
140
-
141
- node.children.forEach(childID =>
142
- recursivelyInitializeTree(childID, id, nodes, dataForRoot),
143
- );
144
- }
145
-}
146
-
147
-function updateTree(
148
- commitTree: CommitTree,
149
- operations: Array<number>,
150
-): CommitTree {
151
- // Clone the original tree so edits don't affect it.
152
- const nodes = new Map(commitTree.nodes);
153
-
154
- // Clone nodes before mutating them so edits don't affect them.
155
- const getClonedNode = (id: number): CommitTreeNode => {
156
- const clonedNode = ((Object.assign(
157
- {},
158
- nodes.get(id),
159
- ): any): CommitTreeNode);
160
- nodes.set(id, clonedNode);
161
- return clonedNode;
162
- };
163
-
164
- let i = 2;
165
- let id: number = ((null: any): number);
166
-
167
- // Reassemble the string table.
168
- const stringTable = [
169
- null, // ID = 0 corresponds to the null string.
170
- ];
171
- const stringTableSize = operations[i++];
172
- const stringTableEnd = i + stringTableSize;
173
- while (i < stringTableEnd) {
174
- const nextLength = operations[i++];
175
- const nextString = utfDecodeString(
176
- (operations.slice(i, i + nextLength): any),
177
- );
178
- stringTable.push(nextString);
179
- i += nextLength;
180
- }
181
-
182
- while (i < operations.length) {
183
- const operation = operations[i];
184
-
185
- switch (operation) {
186
- case TREE_OPERATION_ADD:
187
- id = ((operations[i + 1]: any): number);
188
- const type = ((operations[i + 2]: any): ElementType);
189
-
190
- i += 3;
191
-
192
- if (nodes.has(id)) {
193
- throw new Error(
194
- 'Commit tree already contains fiber ' +
195
- id +
196
- '. This is a bug in React DevTools.',
197
- );
198
- }
199
-
200
- if (type === ElementTypeRoot) {
201
- i++; // supportsProfiling flag
202
- i++; // hasOwnerMetadata flag
203
-
204
- if (__DEBUG__) {
205
- debug('Add', `new root fiber ${id}`);
206
- }
207
-
208
- const node: CommitTreeNode = {
209
- children: [],
210
- displayName: null,
211
- id,
212
- key: null,
213
- parentID: 0,
214
- treeBaseDuration: 0, // This will be updated by a subsequent operation
215
- type,
216
- };
217
-
218
- nodes.set(id, node);
219
- } else {
220
- const parentID = ((operations[i]: any): number);
221
- i++;
222
-
223
- i++; // ownerID
224
-
225
- const displayNameStringID = operations[i];
226
- const displayName = stringTable[displayNameStringID];
227
- i++;
228
-
229
- const keyStringID = operations[i];
230
- const key = stringTable[keyStringID];
231
- i++;
232
-
233
- if (__DEBUG__) {
234
- debug(
235
- 'Add',
236
- `fiber ${id} (${displayName || 'null'}) as child of ${parentID}`,
237
- );
238
- }
239
-
240
- const parentNode = getClonedNode(parentID);
241
- parentNode.children = parentNode.children.concat(id);
242
-
243
- const node: CommitTreeNode = {
244
- children: [],
245
- displayName,
246
- id,
247
- key,
248
- parentID,
249
- treeBaseDuration: 0, // This will be updated by a subsequent operation
250
- type,
251
- };
252
-
253
- nodes.set(id, node);
254
- }
255
-
256
- break;
257
- case TREE_OPERATION_REMOVE: {
258
- const removeLength = ((operations[i + 1]: any): number);
259
- i += 2;
260
-
261
- for (let removeIndex = 0; removeIndex < removeLength; removeIndex++) {
262
- id = ((operations[i]: any): number);
263
- i++;
264
-
265
- if (!nodes.has(id)) {
266
- throw new Error(
267
- 'Commit tree does not contain fiber ' +
268
- id +
269
- '. This is a bug in React DevTools.',
270
- );
271
- }
272
-
273
- const node = getClonedNode(id);
274
- const parentID = node.parentID;
275
-
276
- nodes.delete(id);
277
-
278
- if (!nodes.has(parentID)) {
279
- // No-op
280
- } else {
281
- const parentNode = getClonedNode(parentID);
282
-
283
- if (__DEBUG__) {
284
- debug('Remove', `fiber ${id} from parent ${parentID}`);
285
- }
286
-
287
- parentNode.children = parentNode.children.filter(
288
- childID => childID !== id,
289
- );
290
- }
291
- }
292
- break;
293
- }
294
- case TREE_OPERATION_REORDER_CHILDREN: {
295
- id = ((operations[i + 1]: any): number);
296
- const numChildren = ((operations[i + 2]: any): number);
297
- const children = ((operations.slice(
298
- i + 3,
299
- i + 3 + numChildren,
300
- ): any): Array<number>);
301
-
302
- i = i + 3 + numChildren;
303
-
304
- if (__DEBUG__) {
305
- debug('Re-order', `fiber ${id} children ${children.join(',')}`);
306
- }
307
-
308
- const node = getClonedNode(id);
309
- node.children = Array.from(children);
310
-
311
- break;
312
- }
313
- case TREE_OPERATION_UPDATE_TREE_BASE_DURATION: {
314
- id = operations[i + 1];
315
-
316
- const node = getClonedNode(id);
317
- node.treeBaseDuration = operations[i + 2] / 1000; // Convert microseconds back to milliseconds;
318
-
319
- if (__DEBUG__) {
320
- debug(
321
- 'Update',
322
- `fiber ${id} treeBaseDuration to ${node.treeBaseDuration}`,
323
- );
324
- }
325
-
326
- i += 3;
327
- break;
328
- }
329
- default:
330
- throw Error(`Unsupported Bridge operation ${operation}`);
331
- }
332
- }
333
-
334
- return {
335
- nodes,
336
- rootID: commitTree.rootID,
337
- };
338
-}
339
-
340
-export function invalidateCommitTrees(): void {
341
- rootToCommitTreeMap.clear();
342
-}
343
-
344
-// DEBUG
345
-const __printTree = (commitTree: CommitTree) => {
346
- if (__DEBUG__) {
347
- const {nodes, rootID} = commitTree;
348
- console.group('__printTree()');
349
- const queue = [rootID, 0];
350
- while (queue.length > 0) {
351
- const id = queue.shift();
352
- const depth = queue.shift();
353
-
354
- const node = nodes.get(id);
355
- if (node == null) {
356
- throw Error(`Could not find node with id "${id}" in commit tree`);
357
- }
358
-
359
- console.log(
360
- `${'•'.repeat(depth)}${node.id}:${node.displayName || ''} ${
361
- node.key ? `key:"${node.key}"` : ''
362
- } (${node.treeBaseDuration})`,
363
- );
364
-
365
- node.children.forEach(childID => {
366
- queue.push(childID, depth + 1);
367
- });
368
- }
369
- console.groupEnd();
370
- }
371
-};
packages/react-devtools-shared/src/devtools/views/Profiler/FlamegraphChartBuilder.js
deleted
-189
@@ -1,189 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {
11
- ElementTypeForwardRef,
12
- ElementTypeMemo,
13
-} from 'react-devtools-shared/src/types';
14
-import {formatDuration} from './utils';
15
-import ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore';
16
-
17
-import type {CommitTree} from './types';
18
-
19
-export type ChartNode = {|
20
- actualDuration: number,
21
- didRender: boolean,
22
- id: number,
23
- label: string,
24
- name: string,
25
- offset: number,
26
- selfDuration: number,
27
- treeBaseDuration: number,
28
-|};
29
-
30
-export type ChartData = {|
31
- baseDuration: number,
32
- depth: number,
33
- idToDepthMap: Map<number, number>,
34
- maxSelfDuration: number,
35
- renderPathNodes: Set<number>,
36
- rows: Array<Array<ChartNode>>,
37
-|};
38
-
39
-const cachedChartData: Map<string, ChartData> = new Map();
40
-
41
-export function getChartData({
42
- commitIndex,
43
- commitTree,
44
- profilerStore,
45
- rootID,
46
-}: {|
47
- commitIndex: number,
48
- commitTree: CommitTree,
49
- profilerStore: ProfilerStore,
50
- rootID: number,
51
-|}): ChartData {
52
- const commitDatum = profilerStore.getCommitData(rootID, commitIndex);
53
-
54
- const {fiberActualDurations, fiberSelfDurations} = commitDatum;
55
- const {nodes} = commitTree;
56
-
57
- const chartDataKey = `${rootID}-${commitIndex}`;
58
- if (cachedChartData.has(chartDataKey)) {
59
- return ((cachedChartData.get(chartDataKey): any): ChartData);
60
- }
61
-
62
- const idToDepthMap: Map<number, number> = new Map();
63
- const renderPathNodes: Set<number> = new Set();
64
- const rows: Array<Array<ChartNode>> = [];
65
-
66
- let maxDepth = 0;
67
- let maxSelfDuration = 0;
68
-
69
- // Generate flame graph structure using tree base durations.
70
- const walkTree = (id: number, rightOffset: number, currentDepth: number) => {
71
- idToDepthMap.set(id, currentDepth);
72
-
73
- const node = nodes.get(id);
74
- if (node == null) {
75
- throw Error(`Could not find node with id "${id}" in commit tree`);
76
- }
77
-
78
- const {children, displayName, key, treeBaseDuration, type} = node;
79
-
80
- const actualDuration = fiberActualDurations.get(id) || 0;
81
- const selfDuration = fiberSelfDurations.get(id) || 0;
82
- const didRender = fiberActualDurations.has(id);
83
-
84
- const name = displayName || 'Anonymous';
85
- const maybeKey = key !== null ? ` key="${key}"` : '';
86
-
87
- let maybeBadge = '';
88
- if (type === ElementTypeForwardRef) {
89
- maybeBadge = ' (ForwardRef)';
90
- } else if (type === ElementTypeMemo) {
91
- maybeBadge = ' (Memo)';
92
- }
93
-
94
- let label = `${name}${maybeBadge}${maybeKey}`;
95
- if (didRender) {
96
- label += ` (${formatDuration(selfDuration)}ms of ${formatDuration(
97
- actualDuration,
98
- )}ms)`;
99
- }
100
-
101
- maxDepth = Math.max(maxDepth, currentDepth);
102
- maxSelfDuration = Math.max(maxSelfDuration, selfDuration);
103
-
104
- const chartNode: ChartNode = {
105
- actualDuration,
106
- didRender,
107
- id,
108
- label,
109
- name,
110
- offset: rightOffset - treeBaseDuration,
111
- selfDuration,
112
- treeBaseDuration,
113
- };
114
-
115
- if (currentDepth > rows.length) {
116
- rows.push([chartNode]);
117
- } else {
118
- rows[currentDepth - 1].push(chartNode);
119
- }
120
-
121
- for (let i = children.length - 1; i >= 0; i--) {
122
- const childID = children[i];
123
- const childChartNode = walkTree(childID, rightOffset, currentDepth + 1);
124
- rightOffset -= childChartNode.treeBaseDuration;
125
- }
126
-
127
- return chartNode;
128
- };
129
-
130
- let baseDuration = 0;
131
-
132
- // Special case to handle unmounted roots.
133
- if (nodes.size > 0) {
134
- // Skip over the root; we don't want to show it in the flamegraph.
135
- const root = nodes.get(rootID);
136
- if (root == null) {
137
- throw Error(
138
- `Could not find root node with id "${rootID}" in commit tree`,
139
- );
140
- }
141
-
142
- // Don't assume a single root.
143
- // Component filters or Fragments might lead to multiple "roots" in a flame graph.
144
- for (let i = root.children.length - 1; i >= 0; i--) {
145
- const id = root.children[i];
146
- const node = nodes.get(id);
147
- if (node == null) {
148
- throw Error(`Could not find node with id "${id}" in commit tree`);
149
- }
150
- baseDuration += node.treeBaseDuration;
151
- walkTree(id, baseDuration, 1);
152
- }
153
-
154
- fiberActualDurations.forEach((duration, id) => {
155
- let node = nodes.get(id);
156
- if (node != null) {
157
- let currentID = node.parentID;
158
- while (currentID !== 0) {
159
- if (renderPathNodes.has(currentID)) {
160
- // We've already walked this path; we can skip it.
161
- break;
162
- } else {
163
- renderPathNodes.add(currentID);
164
- }
165
-
166
- node = nodes.get(currentID);
167
- currentID = node != null ? node.parentID : 0;
168
- }
169
- }
170
- });
171
- }
172
-
173
- const chartData = {
174
- baseDuration,
175
- depth: maxDepth,
176
- idToDepthMap,
177
- maxSelfDuration,
178
- renderPathNodes,
179
- rows,
180
- };
181
-
182
- cachedChartData.set(chartDataKey, chartData);
183
-
184
- return chartData;
185
-}
186
-
187
-export function invalidateChartData(): void {
188
- cachedChartData.clear();
189
-}
packages/react-devtools-shared/src/devtools/views/Profiler/InteractionListItem.css
deleted
-43
@@ -1,43 +0,0 @@
1
-.Interaction,
2
-.SelectedInteraction {
3
- display: flex;
4
- align-items: center;
5
- padding: 0 0.25rem;
6
- border-bottom: 1px solid var(--color-border);
7
-}
8
-
9
-.Interaction:hover {
10
- background-color: var(--color-background-hover);
11
-}
12
-
13
-.SelectedInteraction {
14
- background-color: var(--color-background-hover);
15
-}
16
-
17
-.Name {
18
- white-space: nowrap;
19
- overflow-x: hidden;
20
- text-overflow: ellipsis;
21
-}
22
-
23
-.Timeline {
24
- position: relative;
25
- height: 100%;
26
-}
27
-
28
-.InteractionLine {
29
- position: absolute;
30
- height: 3px;
31
- background-color: var(--color-commit-did-not-render-fill);
32
- color: var(--color-commit-did-not-render-fill-text);
33
- border-radius: 0.125rem;
34
-}
35
-
36
-.CommitBox {
37
- position: absolute;
38
- width: var(--interaction-commit-size);
39
- height: var(--interaction-commit-size);
40
- background-color: var(--color-commit-did-not-render-fill);
41
- color: var(--color-commit-did-not-render-fill-text);
42
- cursor: pointer;
43
-}
packages/react-devtools-shared/src/devtools/views/Profiler/InteractionListItem.js
deleted
-106
@@ -1,106 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {memo, useCallback} from 'react';
11
-import {areEqual} from 'react-window';
12
-import {getGradientColor} from './utils';
13
-
14
-import styles from './InteractionListItem.css';
15
-
16
-import type {ItemData} from './Interactions';
17
-
18
-type Props = {
19
- data: ItemData,
20
- index: number,
21
- style: Object,
22
-};
23
-
24
-function InteractionListItem({data: itemData, index, style}: Props) {
25
- const {
26
- chartData,
27
- dataForRoot,
28
- labelWidth,
29
- scaleX,
30
- selectedInteractionID,
31
- selectCommitIndex,
32
- selectInteraction,
33
- selectTab,
34
- } = itemData;
35
-
36
- const {commitData, interactionCommits} = dataForRoot;
37
- const {interactions, lastInteractionTime, maxCommitDuration} = chartData;
38
-
39
- const interaction = interactions[index];
40
- if (interaction == null) {
41
- throw Error(`Could not find interaction #${index}`);
42
- }
43
-
44
- const handleClick = useCallback(
45
- () => {
46
- selectInteraction(interaction.id);
47
- },
48
- [interaction, selectInteraction],
49
- );
50
-
51
- const commits = interactionCommits.get(interaction.id) || [];
52
-
53
- const startTime = interaction.timestamp;
54
- const stopTime = lastInteractionTime;
55
-
56
- const viewCommit = (commitIndex: number) => {
57
- selectTab('flame-chart');
58
- selectCommitIndex(commitIndex);
59
- };
60
-
61
- return (
62
- <div
63
- className={
64
- selectedInteractionID === interaction.id
65
- ? styles.SelectedInteraction
66
- : styles.Interaction
67
- }
68
- onClick={handleClick}
69
- style={style}>
70
- <div
71
- className={styles.Name}
72
- style={{maxWidth: labelWidth}}
73
- title={interaction.name}>
74
- {interaction.name}
75
- </div>
76
- <div
77
- className={styles.InteractionLine}
78
- style={{
79
- left: labelWidth + scaleX(startTime, 0),
80
- width: scaleX(stopTime - startTime, 0),
81
- }}
82
- />
83
- {commits.map(commitIndex => (
84
- <div
85
- className={styles.CommitBox}
86
- key={commitIndex}
87
- onClick={() => viewCommit(commitIndex)}
88
- style={{
89
- backgroundColor: getGradientColor(
90
- Math.min(
91
- 1,
92
- Math.max(
93
- 0,
94
- commitData[commitIndex].duration / maxCommitDuration,
95
- ),
96
- ) || 0,
97
- ),
98
- left: labelWidth + scaleX(commitData[commitIndex].timestamp, 0),
99
- }}
100
- />
101
- ))}
102
- </div>
103
- );
104
-}
105
-
106
-export default memo<Props>(InteractionListItem, areEqual);
packages/react-devtools-shared/src/devtools/views/Profiler/Interactions.css
deleted
-9
@@ -1,9 +0,0 @@
1
-.Container {
2
- width: 100%;
3
- flex: 1;
4
- padding: 0.5rem;
5
-}
6
-
7
-.FocusTarget:focus {
8
- outline: none;
9
-}
packages/react-devtools-shared/src/devtools/views/Profiler/Interactions.js
deleted
-148
@@ -1,148 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useContext, useMemo} from 'react';
11
-import AutoSizer from 'react-virtualized-auto-sizer';
12
-import {FixedSizeList} from 'react-window';
13
-import {ProfilerContext} from './ProfilerContext';
14
-import InteractionListItem from './InteractionListItem';
15
-import NoInteractions from './NoInteractions';
16
-import {StoreContext} from '../context';
17
-import {scale} from './utils';
18
-
19
-import styles from './Interactions.css';
20
-
21
-import type {ProfilingDataForRootFrontend} from './types';
22
-import type {ChartData} from './InteractionsChartBuilder';
23
-import type {TabID} from './ProfilerContext';
24
-
25
-export type ItemData = {|
26
- chartData: ChartData,
27
- dataForRoot: ProfilingDataForRootFrontend,
28
- labelWidth: number,
29
- scaleX: (value: number, fallbackValue: number) => number,
30
- selectedInteractionID: number | null,
31
- selectCommitIndex: (id: number | null) => void,
32
- selectInteraction: (id: number | null) => void,
33
- selectTab: (id: TabID) => void,
34
-|};
35
-
36
-export default function InteractionsAutoSizer(_: {||}) {
37
- return (
38
- <div className={styles.Container}>
39
- <AutoSizer>
40
- {({height, width}) => <Interactions height={height} width={width} />}
41
- </AutoSizer>
42
- </div>
43
- );
44
-}
45
-
46
-function Interactions({height, width}: {|height: number, width: number|}) {
47
- const {
48
- rootID,
49
- selectedInteractionID,
50
- selectInteraction,
51
- selectCommitIndex,
52
- selectTab,
53
- } = useContext(ProfilerContext);
54
- const {profilerStore} = useContext(StoreContext);
55
- const {profilingCache} = profilerStore;
56
-
57
- const dataForRoot = profilerStore.getDataForRoot(((rootID: any): number));
58
-
59
- const chartData = profilingCache.getInteractionsChartData({
60
- rootID: ((rootID: any): number),
61
- });
62
-
63
- const {interactions} = chartData;
64
-
65
- const handleKeyDown = useCallback(
66
- event => {
67
- let index;
68
- switch (event.key) {
69
- case 'ArrowDown':
70
- index = interactions.findIndex(
71
- interaction => interaction.id === selectedInteractionID,
72
- );
73
- selectInteraction(Math.min(interactions.length - 1, index + 1));
74
- event.stopPropagation();
75
- break;
76
- case 'ArrowUp':
77
- index = interactions.findIndex(
78
- interaction => interaction.id === selectedInteractionID,
79
- );
80
- selectInteraction(Math.max(0, index - 1));
81
- event.stopPropagation();
82
- break;
83
- default:
84
- break;
85
- }
86
- },
87
- [interactions, selectedInteractionID, selectInteraction],
88
- );
89
-
90
- const itemData = useMemo<ItemData>(
91
- () => {
92
- const interactionCommitSize = parseInt(
93
- getComputedStyle((document.body: any)).getPropertyValue(
94
- '--interaction-commit-size',
95
- ),
96
- 10,
97
- );
98
- const interactionLabelWidth = parseInt(
99
- getComputedStyle((document.body: any)).getPropertyValue(
100
- '--interaction-label-width',
101
- ),
102
- 10,
103
- );
104
-
105
- const labelWidth = Math.min(interactionLabelWidth, width / 5);
106
- const timelineWidth = width - labelWidth - interactionCommitSize;
107
-
108
- return {
109
- chartData,
110
- dataForRoot,
111
- labelWidth,
112
- scaleX: scale(0, chartData.lastInteractionTime, 0, timelineWidth),
113
- selectedInteractionID,
114
- selectCommitIndex,
115
- selectInteraction,
116
- selectTab,
117
- };
118
- },
119
- [
120
- chartData,
121
- dataForRoot,
122
- selectedInteractionID,
123
- selectCommitIndex,
124
- selectInteraction,
125
- selectTab,
126
- width,
127
- ],
128
- );
129
-
130
- // If a commit contains no fibers with an actualDuration > 0,
131
- // Display a fallback message.
132
- if (interactions.length === 0) {
133
- return <NoInteractions height={height} width={width} />;
134
- }
135
-
136
- return (
137
- <div className={styles.FocusTarget} onKeyDown={handleKeyDown} tabIndex={0}>
138
- <FixedSizeList
139
- height={height}
140
- itemCount={interactions.length}
141
- itemData={itemData}
142
- itemSize={30}
143
- width={width}>
144
- {InteractionListItem}
145
- </FixedSizeList>
146
- </div>
147
- );
148
-}
packages/react-devtools-shared/src/devtools/views/Profiler/InteractionsChartBuilder.js
deleted
-62
@@ -1,62 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore';
11
-
12
-import type {Interaction} from './types';
13
-
14
-export type ChartData = {|
15
- interactions: Array<Interaction>,
16
- lastInteractionTime: number,
17
- maxCommitDuration: number,
18
-|};
19
-
20
-const cachedChartData: Map<number, ChartData> = new Map();
21
-
22
-export function getChartData({
23
- profilerStore,
24
- rootID,
25
-}: {|
26
- profilerStore: ProfilerStore,
27
- rootID: number,
28
-|}): ChartData {
29
- if (cachedChartData.has(rootID)) {
30
- return ((cachedChartData.get(rootID): any): ChartData);
31
- }
32
-
33
- const dataForRoot = profilerStore.getDataForRoot(rootID);
34
- if (dataForRoot == null) {
35
- throw Error(`Could not find profiling data for root "${rootID}"`);
36
- }
37
-
38
- const {commitData, interactions} = dataForRoot;
39
-
40
- const lastInteractionTime =
41
- commitData.length > 0 ? commitData[commitData.length - 1].timestamp : 0;
42
-
43
- let maxCommitDuration = 0;
44
-
45
- commitData.forEach(commitDatum => {
46
- maxCommitDuration = Math.max(maxCommitDuration, commitDatum.duration);
47
- });
48
-
49
- const chartData = {
50
- interactions: Array.from(interactions.values()),
51
- lastInteractionTime,
52
- maxCommitDuration,
53
- };
54
-
55
- cachedChartData.set(rootID, chartData);
56
-
57
- return chartData;
58
-}
59
-
60
-export function invalidateChartData(): void {
61
- cachedChartData.clear();
62
-}
packages/react-devtools-shared/src/devtools/views/Profiler/NoCommitData.css
deleted
-18
@@ -1,18 +0,0 @@
1
-.NoCommitData {
2
- width: 100%;
3
- height: 100%;
4
- display: flex;
5
- flex-direction: column;
6
- align-items: center;
7
- justify-content: center;
8
-}
9
-
10
-.Header {
11
- font-size: var(--font-size-sans-large);
12
- margin-bottom: 0.5rem;
13
-}
14
-
15
-.FilterMessage {
16
- display: flex;
17
- align-items: center;
18
-}
packages/react-devtools-shared/src/devtools/views/Profiler/NoCommitData.js
deleted
-25
@@ -1,25 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-
12
-import styles from './NoCommitData.css';
13
-
14
-export default function NoCommitData(_: {||}) {
15
- return (
16
- <div className={styles.NoCommitData}>
17
- <div className={styles.Header}>
18
- There is no data matching the current filter criteria.
19
- </div>
20
- <div className={styles.FilterMessage}>
21
- Try adjusting the commit filter in Profiler settings.
22
- </div>
23
- </div>
24
- );
25
-}
packages/react-devtools-shared/src/devtools/views/Profiler/NoInteractions.css
deleted
-16
@@ -1,16 +0,0 @@
1
-.NoInteractions {
2
- width: 100%;
3
- height: 100%;
4
- display: flex;
5
- flex-direction: column;
6
- align-items: center;
7
- justify-content: center;
8
-}
9
-
10
-.Header {
11
- font-size: var(--font-size-sans-large);
12
-}
13
-
14
-.Link {
15
- color: var(--color-button);
16
-}
packages/react-devtools-shared/src/devtools/views/Profiler/NoInteractions.js
deleted
-35
@@ -1,35 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-
12
-import styles from './NoInteractions.css';
13
-
14
-export default function NoInteractions({
15
- height,
16
- width,
17
-}: {|
18
- height: number,
19
- width: number,
20
-|}) {
21
- return (
22
- <div className={styles.NoInteractions} style={{height, width}}>
23
- <p className={styles.Header}>No interactions were recorded.</p>
24
- <p>
25
- <a
26
- className={styles.Link}
27
- href="http://fb.me/react-interaction-tracing"
28
- rel="noopener noreferrer"
29
- target="_blank">
30
- Learn more about the interaction tracing API here.
31
- </a>
32
- </p>
33
- </div>
34
- );
35
-}
packages/react-devtools-shared/src/devtools/views/Profiler/Profiler.css
deleted
-112
@@ -1,112 +0,0 @@
1
-.Profiler {
2
- width: 100%;
3
- height: 100%;
4
- position: relative;
5
- display: flex;
6
- flex-direction: row;
7
- align-items: stretch;
8
- font-family: var(--font-family-sans);
9
- font-size: var(--font-size-sans-normal);
10
- background-color: var(--color-background);
11
- color: var(--color-text);
12
-}
13
-
14
-.LeftColumn {
15
- display: flex;
16
- flex-direction: column;
17
- flex: 2 1 200px;
18
- border-top: 1px solid var(--color-border);
19
-}
20
-
21
-.RightColumn {
22
- display: flex;
23
- flex-direction: column;
24
- flex: 1 1 100px;
25
- max-width: 300px;
26
- overflow-x: hidden;
27
- border-left: 1px solid var(--color-border);
28
- border-top: 1px solid var(--color-border);
29
-}
30
-
31
-.Content {
32
- position: relative;
33
- flex: 1 1 auto;
34
- display: flex;
35
- flex-direction: column;
36
- align-items: center;
37
- justify-content: center;
38
-}
39
-
40
-.Column {
41
- display: flex;
42
- flex-direction: column;
43
- align-items: center;
44
- justify-content: center;
45
- padding: 0 1rem;
46
-}
47
-
48
-.Paragraph {
49
- text-align: center;
50
-}
51
-
52
-.Row {
53
- display: flex;
54
- flex-direction: row;
55
- align-items: center;
56
- justify-content: center;
57
-}
58
-
59
-.Header {
60
- font-size: var(--font-size-sans-large);
61
- margin-bottom: 0.5rem;
62
-}
63
-
64
-.Toolbar {
65
- height: 2.25rem;
66
- padding: 0 0.25rem;
67
- flex: 0 0 auto;
68
- display: flex;
69
- align-items: center;
70
- border-bottom: 1px solid var(--color-border);
71
-}
72
-
73
-.VRule {
74
- height: 20px;
75
- width: 1px;
76
- border-left: 1px solid var(--color-border);
77
- padding-left: 0.25rem;
78
- margin-left: 0.25rem;
79
-}
80
-
81
-.Spacer {
82
- flex: 1;
83
-}
84
-
85
-.StopRecordingButton {
86
- font-size: var(--font-size-sans-large);
87
- padding: 0.5rem;
88
-}
89
-
90
-.ContentFallback {
91
- width: 100%;
92
- height: 100%;
93
- display: flex;
94
- align-items: center;
95
- justify-content: center;
96
- font-size: var(--font-size-sans-large);
97
- color: var(--color-dim);
98
-}
99
-
100
-.SnapshotSelectorFallback {
101
- height: 100%;
102
- padding-left: 0.5rem;
103
- display: flex;
104
- align-items: center;
105
- justify-content: center;
106
- font-size: var(--font-size-sans-large);
107
- color: var(--color-dim);
108
-}
109
-
110
-.Link {
111
- color: var(--color-button);
112
-}
packages/react-devtools-shared/src/devtools/views/Profiler/Profiler.js
deleted
-203
@@ -1,203 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useContext} from 'react';
11
-import {ModalDialog} from '../ModalDialog';
12
-import {ProfilerContext} from './ProfilerContext';
13
-import TabBar from '../TabBar';
14
-import ClearProfilingDataButton from './ClearProfilingDataButton';
15
-import CommitFlamegraph from './CommitFlamegraph';
16
-import CommitRanked from './CommitRanked';
17
-import Interactions from './Interactions';
18
-import RootSelector from './RootSelector';
19
-import RecordToggle from './RecordToggle';
20
-import ReloadAndProfileButton from './ReloadAndProfileButton';
21
-import ProfilingImportExportButtons from './ProfilingImportExportButtons';
22
-import SnapshotSelector from './SnapshotSelector';
23
-import SidebarCommitInfo from './SidebarCommitInfo';
24
-import SidebarInteractions from './SidebarInteractions';
25
-import SidebarSelectedFiberInfo from './SidebarSelectedFiberInfo';
26
-import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal';
27
-import SettingsModalContextToggle from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContextToggle';
28
-import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext';
29
-import portaledContent from '../portaledContent';
30
-
31
-import styles from './Profiler.css';
32
-
33
-function Profiler(_: {||}) {
34
- const {
35
- didRecordCommits,
36
- isProcessingData,
37
- isProfiling,
38
- selectedCommitIndex,
39
- selectedFiberID,
40
- selectedTabID,
41
- selectTab,
42
- supportsProfiling,
43
- } = useContext(ProfilerContext);
44
-
45
- let view = null;
46
- if (didRecordCommits) {
47
- switch (selectedTabID) {
48
- case 'flame-chart':
49
- view = <CommitFlamegraph />;
50
- break;
51
- case 'ranked-chart':
52
- view = <CommitRanked />;
53
- break;
54
- case 'interactions':
55
- view = <Interactions />;
56
- break;
57
- default:
58
- break;
59
- }
60
- } else if (isProfiling) {
61
- view = <RecordingInProgress />;
62
- } else if (isProcessingData) {
63
- view = <ProcessingData />;
64
- } else if (supportsProfiling) {
65
- view = <NoProfilingData />;
66
- } else {
67
- view = <ProfilingNotSupported />;
68
- }
69
-
70
- let sidebar = null;
71
- if (!isProfiling && !isProcessingData && didRecordCommits) {
72
- switch (selectedTabID) {
73
- case 'interactions':
74
- sidebar = <SidebarInteractions />;
75
- break;
76
- case 'flame-chart':
77
- case 'ranked-chart':
78
- // TRICKY
79
- // Handle edge case where no commit is selected because of a min-duration filter update.
80
- // In that case, the selected commit index would be null.
81
- // We could still show a sidebar for the previously selected fiber,
82
- // but it would be an odd user experience.
83
- // TODO (ProfilerContext) This check should not be necessary.
84
- if (selectedCommitIndex !== null) {
85
- if (selectedFiberID !== null) {
86
- sidebar = <SidebarSelectedFiberInfo />;
87
- } else {
88
- sidebar = <SidebarCommitInfo />;
89
- }
90
- }
91
- break;
92
- default:
93
- break;
94
- }
95
- }
96
-
97
- return (
98
- <SettingsModalContextController>
99
- <div className={styles.Profiler}>
100
- <div className={styles.LeftColumn}>
101
- <div className={styles.Toolbar}>
102
- <RecordToggle disabled={!supportsProfiling} />
103
- <ReloadAndProfileButton />
104
- <ClearProfilingDataButton />
105
- <ProfilingImportExportButtons />
106
- <div className={styles.VRule} />
107
- <TabBar
108
- currentTab={selectedTabID}
109
- id="Profiler"
110
- selectTab={selectTab}
111
- tabs={tabs}
112
- type="profiler"
113
- />
114
- <RootSelector />
115
- <div className={styles.Spacer} />
116
- <SettingsModalContextToggle />
117
- {didRecordCommits && (
118
- <Fragment>
119
- <div className={styles.VRule} />
120
- <SnapshotSelector />
121
- </Fragment>
122
- )}
123
- </div>
124
- <div className={styles.Content}>
125
- {view}
126
- <ModalDialog />
127
- </div>
128
- </div>
129
- <div className={styles.RightColumn}>{sidebar}</div>
130
- <SettingsModal />
131
- </div>
132
- </SettingsModalContextController>
133
- );
134
-}
135
-
136
-const tabs = [
137
- {
138
- id: 'flame-chart',
139
- icon: 'flame-chart',
140
- label: 'Flamegraph',
141
- title: 'Flamegraph chart',
142
- },
143
- {
144
- id: 'ranked-chart',
145
- icon: 'ranked-chart',
146
- label: 'Ranked',
147
- title: 'Ranked chart',
148
- },
149
- {
150
- id: 'interactions',
151
- icon: 'interactions',
152
- label: 'Interactions',
153
- title: 'Profiled interactions',
154
- },
155
-];
156
-
157
-const NoProfilingData = () => (
158
- <div className={styles.Column}>
159
- <div className={styles.Header}>No profiling data has been recorded.</div>
160
- <div className={styles.Row}>
161
- Click the record button <RecordToggle /> to start recording.
162
- </div>
163
- </div>
164
-);
165
-
166
-const ProfilingNotSupported = () => (
167
- <div className={styles.Column}>
168
- <div className={styles.Header}>Profiling not supported.</div>
169
- <p className={styles.Paragraph}>
170
- Profiling support requires either a development or production-profiling
171
- build of React v16.5+.
172
- </p>
173
- <p className={styles.Paragraph}>
174
- Learn more at{' '}
175
- <a
176
- className={styles.Link}
177
- href="https://fb.me/react-profiling"
178
- rel="noopener noreferrer"
179
- target="_blank">
180
- fb.me/react-profiling
181
- </a>
182
- .
183
- </p>
184
- </div>
185
-);
186
-
187
-const ProcessingData = () => (
188
- <div className={styles.Column}>
189
- <div className={styles.Header}>Processing data...</div>
190
- <div className={styles.Row}>This should only take a minute.</div>
191
- </div>
192
-);
193
-
194
-const RecordingInProgress = () => (
195
- <div className={styles.Column}>
196
- <div className={styles.Header}>Profiling is in progress...</div>
197
- <div className={styles.Row}>
198
- Click the record button <RecordToggle /> to stop recording.
199
- </div>
200
- </div>
201
-);
202
-
203
-export default portaledContent(Profiler);
packages/react-devtools-shared/src/devtools/views/Profiler/ProfilerContext.js
deleted
-297
@@ -1,297 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- createContext,
12
- useCallback,
13
- useContext,
14
- useMemo,
15
- useState,
16
-} from 'react';
17
-import {unstable_batchedUpdates as batchedUpdates} from 'react-dom';
18
-import {useLocalStorage, useSubscription} from '../hooks';
19
-import {
20
- TreeDispatcherContext,
21
- TreeStateContext,
22
-} from '../Components/TreeContext';
23
-import {StoreContext} from '../context';
24
-
25
-import type {ProfilingDataFrontend} from './types';
26
-
27
-export type TabID = 'flame-chart' | 'ranked-chart' | 'interactions';
28
-
29
-export type Context = {|
30
- // Which tab is selexted in the Profiler UI?
31
- selectedTabID: TabID,
32
- selectTab(id: TabID): void,
33
-
34
- // Store subscription based values.
35
- // The isProfiling value may be modified by the record button in the Profiler toolbar,
36
- // or from the backend itself (after a reload-and-profile action).
37
- // It is synced between the backend and frontend via a Store subscription.
38
- didRecordCommits: boolean,
39
- isProcessingData: boolean,
40
- isProfiling: boolean,
41
- profilingData: ProfilingDataFrontend | null,
42
- startProfiling(): void,
43
- stopProfiling(): void,
44
- supportsProfiling: boolean,
45
-
46
- // Which root should profiling data be shown for?
47
- // This value should be initialized to either:
48
- // 1. The selected root in the Components tree (if it has any profiling data) or
49
- // 2. The first root in the list with profiling data.
50
- rootID: number | null,
51
- setRootID: (id: number) => void,
52
-
53
- // Controls whether commits are filtered by duration.
54
- // This value is controlled by a filter toggle UI in the Profiler toolbar.
55
- // It impacts the commit selector UI as well as the fiber commits bar chart.
56
- isCommitFilterEnabled: boolean,
57
- setIsCommitFilterEnabled: (value: boolean) => void,
58
- minCommitDuration: number,
59
- setMinCommitDuration: (value: number) => void,
60
-
61
- // Which commit is currently selected in the commit selector UI.
62
- // Note that this is the index of the commit in all commits (non-filtered) that were profiled.
63
- // This value is controlled by the commit selector UI in the Profiler toolbar.
64
- // It impacts the flame graph and ranked charts.
65
- selectedCommitIndex: number | null,
66
- selectCommitIndex: (value: number | null) => void,
67
-
68
- // Which fiber is currently selected in the Ranked or Flamegraph charts?
69
- selectedFiberID: number | null,
70
- selectedFiberName: string | null,
71
- selectFiber: (id: number | null, name: string | null) => void,
72
-
73
- // Which interaction is currently selected in the Interactions graph?
74
- selectedInteractionID: number | null,
75
- selectInteraction: (id: number | null) => void,
76
-|};
77
-
78
-const ProfilerContext = createContext<Context>(((null: any): Context));
79
-ProfilerContext.displayName = 'ProfilerContext';
80
-
81
-type StoreProfilingState = {|
82
- didRecordCommits: boolean,
83
- isProcessingData: boolean,
84
- isProfiling: boolean,
85
- profilingData: ProfilingDataFrontend | null,
86
- supportsProfiling: boolean,
87
-|};
88
-
89
-type Props = {|
90
- children: React$Node,
91
-|};
92
-
93
-function ProfilerContextController({children}: Props) {
94
- const store = useContext(StoreContext);
95
- const {selectedElementID} = useContext(TreeStateContext);
96
- const dispatch = useContext(TreeDispatcherContext);
97
-
98
- const {profilerStore} = store;
99
-
100
- const subscription = useMemo(
101
- () => ({
102
- getCurrentValue: () => ({
103
- didRecordCommits: profilerStore.didRecordCommits,
104
- isProcessingData: profilerStore.isProcessingData,
105
- isProfiling: profilerStore.isProfiling,
106
- profilingData: profilerStore.profilingData,
107
- supportsProfiling: store.supportsProfiling,
108
- }),
109
- subscribe: (callback: Function) => {
110
- profilerStore.addListener('profilingData', callback);
111
- profilerStore.addListener('isProcessingData', callback);
112
- profilerStore.addListener('isProfiling', callback);
113
- store.addListener('supportsProfiling', callback);
114
- return () => {
115
- profilerStore.removeListener('profilingData', callback);
116
- profilerStore.removeListener('isProcessingData', callback);
117
- profilerStore.removeListener('isProfiling', callback);
118
- store.removeListener('supportsProfiling', callback);
119
- };
120
- },
121
- }),
122
- [profilerStore, store],
123
- );
124
- const {
125
- didRecordCommits,
126
- isProcessingData,
127
- isProfiling,
128
- profilingData,
129
- supportsProfiling,
130
- } = useSubscription<StoreProfilingState>(subscription);
131
-
132
- const [prevProfilingData, setPrevProfilingData] = useState();
133
- const [rootID, setRootID] = useState<number | null>(null);
134
-
135
- if (prevProfilingData !== profilingData) {
136
- batchedUpdates(() => {
137
- setPrevProfilingData(profilingData);
138
-
139
- const dataForRoots =
140
- profilingData !== null ? profilingData.dataForRoots : null;
141
- if (dataForRoots != null) {
142
- const firstRootID = dataForRoots.keys().next().value || null;
143
-
144
- if (rootID === null || !dataForRoots.has(rootID)) {
145
- let selectedElementRootID = null;
146
- if (selectedElementID !== null) {
147
- selectedElementRootID = store.getRootIDForElement(
148
- selectedElementID,
149
- );
150
- }
151
- if (
152
- selectedElementRootID !== null &&
153
- dataForRoots.has(selectedElementRootID)
154
- ) {
155
- setRootID(selectedElementRootID);
156
- } else {
157
- setRootID(firstRootID);
158
- }
159
- }
160
- }
161
- });
162
- }
163
-
164
- const startProfiling = useCallback(
165
- () => store.profilerStore.startProfiling(),
166
- [store],
167
- );
168
- const stopProfiling = useCallback(() => store.profilerStore.stopProfiling(), [
169
- store,
170
- ]);
171
-
172
- const [isCommitFilterEnabled, setIsCommitFilterEnabled] = useLocalStorage<
173
- boolean,
174
- >('React::DevTools::isCommitFilterEnabled', false);
175
- const [minCommitDuration, setMinCommitDuration] = useLocalStorage<number>(
176
- 'minCommitDuration',
177
- 0,
178
- );
179
-
180
- const [selectedCommitIndex, selectCommitIndex] = useState<number | null>(
181
- null,
182
- );
183
- const [selectedTabID, selectTab] = useState<TabID>('flame-chart');
184
- const [selectedFiberID, selectFiberID] = useState<number | null>(null);
185
- const [selectedFiberName, selectFiberName] = useState<string | null>(null);
186
- const [selectedInteractionID, selectInteraction] = useState<number | null>(
187
- null,
188
- );
189
-
190
- const selectFiber = useCallback(
191
- (id: number | null, name: string | null) => {
192
- selectFiberID(id);
193
- selectFiberName(name);
194
-
195
- // Sync selection to the Components tab for convenience.
196
- if (id !== null) {
197
- const element = store.getElementByID(id);
198
-
199
- // Keep in mind that profiling data may be from a previous session.
200
- // In that case, IDs may match up arbitrarily; to be safe, compare both ID and display name.
201
- if (element !== null && element.displayName === name) {
202
- dispatch({
203
- type: 'SELECT_ELEMENT_BY_ID',
204
- payload: id,
205
- });
206
- }
207
- }
208
- },
209
- [dispatch, selectFiberID, selectFiberName, store],
210
- );
211
-
212
- if (isProfiling) {
213
- batchedUpdates(() => {
214
- if (selectedCommitIndex !== null) {
215
- selectCommitIndex(null);
216
- }
217
- if (selectedFiberID !== null) {
218
- selectFiberID(null);
219
- selectFiberName(null);
220
- }
221
- if (selectedInteractionID !== null) {
222
- selectInteraction(null);
223
- }
224
- });
225
- }
226
-
227
- const value = useMemo(
228
- () => ({
229
- selectedTabID,
230
- selectTab,
231
-
232
- didRecordCommits,
233
- isProcessingData,
234
- isProfiling,
235
- profilingData,
236
- startProfiling,
237
- stopProfiling,
238
- supportsProfiling,
239
-
240
- rootID,
241
- setRootID,
242
-
243
- isCommitFilterEnabled,
244
- setIsCommitFilterEnabled,
245
- minCommitDuration,
246
- setMinCommitDuration,
247
-
248
- selectedCommitIndex,
249
- selectCommitIndex,
250
-
251
- selectedFiberID,
252
- selectedFiberName,
253
- selectFiber,
254
-
255
- selectedInteractionID,
256
- selectInteraction,
257
- }),
258
- [
259
- selectedTabID,
260
- selectTab,
261
-
262
- didRecordCommits,
263
- isProcessingData,
264
- isProfiling,
265
- profilingData,
266
- startProfiling,
267
- stopProfiling,
268
- supportsProfiling,
269
-
270
- rootID,
271
- setRootID,
272
-
273
- isCommitFilterEnabled,
274
- setIsCommitFilterEnabled,
275
- minCommitDuration,
276
- setMinCommitDuration,
277
-
278
- selectedCommitIndex,
279
- selectCommitIndex,
280
-
281
- selectedFiberID,
282
- selectedFiberName,
283
- selectFiber,
284
-
285
- selectedInteractionID,
286
- selectInteraction,
287
- ],
288
- );
289
-
290
- return (
291
- <ProfilerContext.Provider value={value}>
292
- {children}
293
- </ProfilerContext.Provider>
294
- );
295
-}
296
-
297
-export {ProfilerContext, ProfilerContextController};
packages/react-devtools-shared/src/devtools/views/Profiler/ProfilingImportExportButtons.css
deleted
-25
@@ -1,25 +0,0 @@
1
-.VRule {
2
- height: 20px;
3
- width: 1px;
4
- border-left: 1px solid var(--color-border);
5
- padding-left: 0.25rem;
6
- margin-left: 0.25rem;
7
-}
8
-
9
-/**
10
- * https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications
11
- */
12
-.Input {
13
- position: absolute !important;
14
- height: 1px;
15
- width: 1px;
16
- overflow: hidden;
17
- clip: rect(1px, 1px, 1px, 1px);
18
-}
19
-
20
-.ErrorMessage {
21
- margin: 0.5rem 0;
22
- color: var(--color-dim);
23
- font-family: var(--font-family-monospace);
24
- font-size: var(--font-size-monospace-normal);
25
-}
packages/react-devtools-shared/src/devtools/views/Profiler/ProfilingImportExportButtons.js
deleted
-131
@@ -1,131 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useContext, useCallback, useRef} from 'react';
11
-import {ProfilerContext} from './ProfilerContext';
12
-import {ModalDialogContext} from '../ModalDialog';
13
-import Button from '../Button';
14
-import ButtonIcon from '../ButtonIcon';
15
-import {StoreContext} from '../context';
16
-import {
17
- prepareProfilingDataExport,
18
- prepareProfilingDataFrontendFromExport,
19
-} from './utils';
20
-import {downloadFile} from '../utils';
21
-
22
-import styles from './ProfilingImportExportButtons.css';
23
-
24
-import type {ProfilingDataExport} from './types';
25
-
26
-export default function ProfilingImportExportButtons() {
27
- const {isProfiling, profilingData, rootID} = useContext(ProfilerContext);
28
- const store = useContext(StoreContext);
29
- const {profilerStore} = store;
30
-
31
- const inputRef = useRef<HTMLInputElement | null>(null);
32
-
33
- const {dispatch: modalDialogDispatch} = useContext(ModalDialogContext);
34
-
35
- const downloadData = useCallback(
36
- () => {
37
- if (rootID === null) {
38
- return;
39
- }
40
-
41
- if (profilingData !== null) {
42
- const profilingDataExport = prepareProfilingDataExport(profilingData);
43
- const date = new Date();
44
- const dateString = date
45
- .toLocaleDateString(undefined, {
46
- year: 'numeric',
47
- month: '2-digit',
48
- day: '2-digit',
49
- })
50
- .replace(/\//g, '-');
51
- const timeString = date
52
- .toLocaleTimeString(undefined, {
53
- hour12: false,
54
- })
55
- .replace(/:/g, '-');
56
- downloadFile(
57
- `profiling-data.${dateString}.${timeString}.json`,
58
- JSON.stringify(profilingDataExport, null, 2),
59
- );
60
- }
61
- },
62
- [rootID, profilingData],
63
- );
64
-
65
- const uploadData = useCallback(() => {
66
- if (inputRef.current !== null) {
67
- inputRef.current.click();
68
- }
69
- }, []);
70
-
71
- const handleFiles = useCallback(
72
- () => {
73
- const input = inputRef.current;
74
- if (input !== null && input.files.length > 0) {
75
- const fileReader = new FileReader();
76
- fileReader.addEventListener('load', () => {
77
- try {
78
- const raw = ((fileReader.result: any): string);
79
- const profilingDataExport = ((JSON.parse(
80
- raw,
81
- ): any): ProfilingDataExport);
82
- profilerStore.profilingData = prepareProfilingDataFrontendFromExport(
83
- profilingDataExport,
84
- );
85
- } catch (error) {
86
- modalDialogDispatch({
87
- type: 'SHOW',
88
- title: 'Import failed',
89
- content: (
90
- <Fragment>
91
- <div>The profiling data you selected cannot be imported.</div>
92
- {error !== null && (
93
- <div className={styles.ErrorMessage}>{error.message}</div>
94
- )}
95
- </Fragment>
96
- ),
97
- });
98
- }
99
- });
100
- // TODO (profiling) Handle fileReader errors.
101
- fileReader.readAsText(input.files[0]);
102
- }
103
- },
104
- [modalDialogDispatch, profilerStore],
105
- );
106
-
107
- return (
108
- <Fragment>
109
- <div className={styles.VRule} />
110
- <input
111
- ref={inputRef}
112
- className={styles.Input}
113
- type="file"
114
- onChange={handleFiles}
115
- tabIndex={-1}
116
- />
117
- <Button
118
- disabled={isProfiling}
119
- onClick={uploadData}
120
- title="Load profile...">
121
- <ButtonIcon type="import" />
122
- </Button>
123
- <Button
124
- disabled={isProfiling || !profilerStore.didRecordCommits}
125
- onClick={downloadData}
126
- title="Save profile...">
127
- <ButtonIcon type="export" />
128
- </Button>
129
- </Fragment>
130
- );
131
-}
packages/react-devtools-shared/src/devtools/views/Profiler/RankedChartBuilder.js
deleted
-106
@@ -1,106 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {
11
- ElementTypeForwardRef,
12
- ElementTypeMemo,
13
-} from 'react-devtools-shared/src/types';
14
-import {formatDuration} from './utils';
15
-import ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore';
16
-
17
-import type {CommitTree} from './types';
18
-
19
-export type ChartNode = {|
20
- id: number,
21
- label: string,
22
- name: string,
23
- value: number,
24
-|};
25
-
26
-export type ChartData = {|
27
- maxValue: number,
28
- nodes: Array<ChartNode>,
29
-|};
30
-
31
-const cachedChartData: Map<string, ChartData> = new Map();
32
-
33
-export function getChartData({
34
- commitIndex,
35
- commitTree,
36
- profilerStore,
37
- rootID,
38
-}: {|
39
- commitIndex: number,
40
- commitTree: CommitTree,
41
- profilerStore: ProfilerStore,
42
- rootID: number,
43
-|}): ChartData {
44
- const commitDatum = profilerStore.getCommitData(rootID, commitIndex);
45
-
46
- const {fiberActualDurations, fiberSelfDurations} = commitDatum;
47
- const {nodes} = commitTree;
48
-
49
- const chartDataKey = `${rootID}-${commitIndex}`;
50
- if (cachedChartData.has(chartDataKey)) {
51
- return ((cachedChartData.get(chartDataKey): any): ChartData);
52
- }
53
-
54
- let maxSelfDuration = 0;
55
-
56
- const chartNodes: Array<ChartNode> = [];
57
- fiberActualDurations.forEach((actualDuration, id) => {
58
- const node = nodes.get(id);
59
-
60
- if (node == null) {
61
- throw Error(`Could not find node with id "${id}" in commit tree`);
62
- }
63
-
64
- const {displayName, key, parentID, type} = node;
65
-
66
- // Don't show the root node in this chart.
67
- if (parentID === 0) {
68
- return;
69
- }
70
- const selfDuration = fiberSelfDurations.get(id) || 0;
71
- maxSelfDuration = Math.max(maxSelfDuration, selfDuration);
72
-
73
- const name = displayName || 'Anonymous';
74
- const maybeKey = key !== null ? ` key="${key}"` : '';
75
-
76
- let maybeBadge = '';
77
- if (type === ElementTypeForwardRef) {
78
- maybeBadge = ' (ForwardRef)';
79
- } else if (type === ElementTypeMemo) {
80
- maybeBadge = ' (Memo)';
81
- }
82
-
83
- const label = `${name}${maybeBadge}${maybeKey} (${formatDuration(
84
- selfDuration,
85
- )}ms)`;
86
- chartNodes.push({
87
- id,
88
- label,
89
- name,
90
- value: selfDuration,
91
- });
92
- });
93
-
94
- const chartData = {
95
- maxValue: maxSelfDuration,
96
- nodes: chartNodes.sort((a, b) => b.value - a.value),
97
- };
98
-
99
- cachedChartData.set(chartDataKey, chartData);
100
-
101
- return chartData;
102
-}
103
-
104
-export function invalidateChartData(): void {
105
- cachedChartData.clear();
106
-}
packages/react-devtools-shared/src/devtools/views/Profiler/RecordToggle.css
deleted
-38
@@ -1,38 +0,0 @@
1
-.ActiveRecordToggle {
2
- color: var(--color-record-active);
3
-}
4
-.ActiveRecordToggle:hover {
5
- color: var(--color-record-active);
6
-}
7
-.ActiveRecordToggle:focus {
8
- color: var(--color-record-active);
9
-}
10
-.ActiveRecordToggle:active {
11
- color: var(--color-record-hover);
12
-}
13
-
14
-.InactiveRecordToggle {
15
- color: var(--color-record-inactive);
16
-}
17
-.InactiveRecordToggle:hover {
18
- color: var(--color-record-hover);
19
-}
20
-.InactiveRecordToggle:focus {
21
- color: var(--color-record-inactive);
22
-}
23
-.InactiveRecordToggle:active {
24
- color: var(--color-record-hover);
25
-}
26
-
27
-.DisabledRecordToggle {
28
- color: var(--color-button-disabled);
29
-}
30
-.DisabledRecordToggle:hover {
31
- color: var(--color-button-disabled);
32
-}
33
-.DisabledRecordToggle:focus {
34
- color: var(--color-button-disabled);
35
-}
36
-.DisabledRecordToggle:active {
37
- color: var(--color-button-disabled);
38
-}
packages/react-devtools-shared/src/devtools/views/Profiler/RecordToggle.js
deleted
-42
@@ -1,42 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useContext} from 'react';
11
-import Button from '../Button';
12
-import ButtonIcon from '../ButtonIcon';
13
-import {ProfilerContext} from './ProfilerContext';
14
-
15
-import styles from './RecordToggle.css';
16
-
17
-export type Props = {|
18
- disabled?: boolean,
19
-|};
20
-
21
-export default function RecordToggle({disabled}: Props) {
22
- const {isProfiling, startProfiling, stopProfiling} = useContext(
23
- ProfilerContext,
24
- );
25
-
26
- let className = styles.InactiveRecordToggle;
27
- if (disabled) {
28
- className = styles.DisabledRecordToggle;
29
- } else if (isProfiling) {
30
- className = styles.ActiveRecordToggle;
31
- }
32
-
33
- return (
34
- <Button
35
- className={className}
36
- disabled={disabled}
37
- onClick={isProfiling ? stopProfiling : startProfiling}
38
- title={isProfiling ? 'Stop profiling' : 'Start profiling'}>
39
- <ButtonIcon type="record" />
40
- </Button>
41
- );
42
-}
packages/react-devtools-shared/src/devtools/views/Profiler/ReloadAndProfileButton.js
deleted
-71
@@ -1,71 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useContext, useMemo} from 'react';
11
-import Button from '../Button';
12
-import ButtonIcon from '../ButtonIcon';
13
-import {BridgeContext, StoreContext} from '../context';
14
-import {useSubscription} from '../hooks';
15
-
16
-type SubscriptionData = {|
17
- recordChangeDescriptions: boolean,
18
- supportsReloadAndProfile: boolean,
19
-|};
20
-
21
-export default function ReloadAndProfileButton() {
22
- const bridge = useContext(BridgeContext);
23
- const store = useContext(StoreContext);
24
-
25
- const subscription = useMemo(
26
- () => ({
27
- getCurrentValue: () => ({
28
- recordChangeDescriptions: store.recordChangeDescriptions,
29
- supportsReloadAndProfile: store.supportsReloadAndProfile,
30
- }),
31
- subscribe: (callback: Function) => {
32
- store.addListener('recordChangeDescriptions', callback);
33
- store.addListener('supportsReloadAndProfile', callback);
34
- return () => {
35
- store.removeListener('recordChangeDescriptions', callback);
36
- store.removeListener('supportsReloadAndProfile', callback);
37
- };
38
- },
39
- }),
40
- [store],
41
- );
42
- const {recordChangeDescriptions, supportsReloadAndProfile} = useSubscription<
43
- SubscriptionData,
44
- >(subscription);
45
-
46
- const reloadAndProfile = useCallback(
47
- () => {
48
- // TODO If we want to support reload-and-profile for e.g. React Native,
49
- // we might need to also start profiling here before reloading the app (since DevTools itself isn't reloaded).
50
- // We'd probably want to do this before reloading though, to avoid sending a message on a disconnected port in the browser.
51
- // For now, let's just skip doing it entirely to avoid paying snapshot costs for data we don't need.
52
- // startProfiling();
53
-
54
- bridge.send('reloadAndProfile', recordChangeDescriptions);
55
- },
56
- [bridge, recordChangeDescriptions],
57
- );
58
-
59
- if (!supportsReloadAndProfile) {
60
- return null;
61
- }
62
-
63
- return (
64
- <Button
65
- disabled={!store.supportsProfiling}
66
- onClick={reloadAndProfile}
67
- title="Reload and start profiling">
68
- <ButtonIcon type="reload" />
69
- </Button>
70
- );
71
-}
packages/react-devtools-shared/src/devtools/views/Profiler/RootSelector.css
deleted
-3
@@ -1,3 +0,0 @@
1
-.Spacer {
2
- flex: 1;
3
-}
packages/react-devtools-shared/src/devtools/views/Profiler/RootSelector.js
deleted
-49
@@ -1,49 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useCallback, useContext} from 'react';
11
-import {ProfilerContext} from './ProfilerContext';
12
-
13
-import styles from './RootSelector.css';
14
-
15
-export default function RootSelector(_: {||}) {
16
- const {profilingData, rootID, setRootID} = useContext(ProfilerContext);
17
-
18
- const options = [];
19
- if (profilingData !== null) {
20
- profilingData.dataForRoots.forEach((dataForRoot, id) => {
21
- options.push(
22
- <option key={id} value={id}>
23
- {dataForRoot.displayName}
24
- </option>,
25
- );
26
- });
27
- }
28
-
29
- const handleChange = useCallback(
30
- ({currentTarget}) => {
31
- setRootID(parseInt(currentTarget.value, 10));
32
- },
33
- [setRootID],
34
- );
35
-
36
- if (profilingData === null || profilingData.dataForRoots.size <= 1) {
37
- // Don't take up visual space if there's only one root.
38
- return null;
39
- }
40
-
41
- return (
42
- <Fragment>
43
- <div className={styles.Spacer} />
44
- <select value={rootID} onChange={handleChange}>
45
- {options}
46
- </select>
47
- </Fragment>
48
- );
49
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarCommitInfo.css
deleted
-65
@@ -1,65 +0,0 @@
1
-.Toolbar {
2
- height: 2.25rem;
3
- padding: 0 0.5rem;
4
- flex: 0 0 auto;
5
- display: flex;
6
- align-items: center;
7
- border-bottom: 1px solid var(--color-border);
8
-}
9
-
10
-.Content {
11
- padding: 0.5rem;
12
- user-select: none;
13
- overflow: auto;
14
-}
15
-
16
-.List {
17
- list-style: none;
18
- margin: 0;
19
- padding: 0;
20
-}
21
-
22
-.ListItem {
23
- margin: 0 0 0.5rem;
24
-}
25
-
26
-.NoInteractions {
27
- color: var(--color-dim);
28
-}
29
-
30
-.Interactions {
31
- margin: 0 0 0.5rem;
32
-}
33
-.Interaction {
34
- display: block;
35
- width: 100%;
36
- text-align: left;
37
- background: none;
38
- border: none;
39
- padding: 0.25rem 0.5rem;
40
- color: var(--color-text);
41
-}
42
-.Interaction:focus,
43
-.Interaction:hover {
44
- outline: none;
45
- background-color: var(--color-background-hover);
46
-}
47
-
48
-.Label {
49
- overflow: hidden;
50
- text-overflow: ellipsis;
51
- font-weight: bold;
52
-}
53
-
54
-.Value {
55
- font-family: var(--font-family-monospace);
56
- font-size: var(--font-size-monospace-normal);
57
-}
58
-
59
-.NothingSelected {
60
- display: flex;
61
- align-items: center;
62
- justify-content: center;
63
- height: 100%;
64
- color: var(--color-dim);
65
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarCommitInfo.js
deleted
-91
@@ -1,91 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useContext} from 'react';
11
-import {ProfilerContext} from './ProfilerContext';
12
-import {formatDuration, formatTime} from './utils';
13
-import {StoreContext} from '../context';
14
-
15
-import styles from './SidebarCommitInfo.css';
16
-
17
-export type Props = {||};
18
-
19
-export default function SidebarCommitInfo(_: Props) {
20
- const {
21
- selectedCommitIndex,
22
- rootID,
23
- selectInteraction,
24
- selectTab,
25
- } = useContext(ProfilerContext);
26
-
27
- const {profilerStore} = useContext(StoreContext);
28
-
29
- if (rootID === null || selectedCommitIndex === null) {
30
- return <div className={styles.NothingSelected}>Nothing selected</div>;
31
- }
32
-
33
- const {interactions} = profilerStore.getDataForRoot(rootID);
34
- const {
35
- duration,
36
- interactionIDs,
37
- priorityLevel,
38
- timestamp,
39
- } = profilerStore.getCommitData(rootID, selectedCommitIndex);
40
-
41
- const viewInteraction = interactionID => {
42
- selectTab('interactions');
43
- selectInteraction(interactionID);
44
- };
45
-
46
- return (
47
- <Fragment>
48
- <div className={styles.Toolbar}>Commit information</div>
49
- <div className={styles.Content}>
50
- <ul className={styles.List}>
51
- {priorityLevel !== null && (
52
- <li className={styles.ListItem}>
53
- <label className={styles.Label}>Priority</label>:{' '}
54
- <span className={styles.Value}>{priorityLevel}</span>
55
- </li>
56
- )}
57
- <li className={styles.ListItem}>
58
- <label className={styles.Label}>Committed at</label>:{' '}
59
- <span className={styles.Value}>{formatTime(timestamp)}s</span>
60
- </li>
61
- <li className={styles.ListItem}>
62
- <label className={styles.Label}>Render duration</label>:{' '}
63
- <span className={styles.Value}>{formatDuration(duration)}ms</span>
64
- </li>
65
- <li className={styles.Interactions}>
66
- <label className={styles.Label}>Interactions</label>:
67
- <div className={styles.InteractionList}>
68
- {interactionIDs.length === 0 ? (
69
- <div className={styles.NoInteractions}>None</div>
70
- ) : null}
71
- {interactionIDs.map(interactionID => {
72
- const interaction = interactions.get(interactionID);
73
- if (interaction == null) {
74
- throw Error(`Invalid interaction "${interactionID}"`);
75
- }
76
- return (
77
- <button
78
- key={interactionID}
79
- className={styles.Interaction}
80
- onClick={() => viewInteraction(interactionID)}>
81
- {interaction.name}
82
- </button>
83
- );
84
- })}
85
- </div>
86
- </li>
87
- </ul>
88
- </div>
89
- </Fragment>
90
- );
91
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarInteractions.css
deleted
-55
@@ -1,55 +0,0 @@
1
-.Toolbar {
2
- height: 2.25rem;
3
- padding: 0 0.5rem;
4
- flex: 0 0 auto;
5
- display: flex;
6
- align-items: center;
7
-}
8
-
9
-.Content {
10
- padding: 0.5rem;
11
- user-select: none;
12
- border-top: 1px solid var(--color-border);
13
- overflow: auto;
14
-}
15
-
16
-.Name {
17
- font-size: var(--font-size-sans-large);
18
- white-space: nowrap;
19
- overflow-x: hidden;
20
- text-overflow: ellipsis;
21
-}
22
-
23
-.NothingSelected {
24
- display: flex;
25
- align-items: center;
26
- justify-content: center;
27
- height: 100%;
28
- color: var(--color-dim);
29
-}
30
-
31
-.Commits {
32
- font-weight: bold;
33
-}
34
-
35
-.List {
36
- list-style: none;
37
- margin: 0;
38
- padding: 0;
39
-}
40
-
41
-.ListItem {
42
- display: flex;
43
- flex-direction: row;
44
- align-items: center;
45
- padding: 0.25rem 0.5rem;
46
-}
47
-.ListItem:hover {
48
- background-color: var(--color-background-hover);
49
-}
50
-
51
-.CommitBox {
52
- width: 20px;
53
- height: 20px;
54
- margin-right: 0.5rem;
55
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarInteractions.js
deleted
-97
@@ -1,97 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useContext} from 'react';
11
-import {ProfilerContext} from './ProfilerContext';
12
-import {formatDuration, formatTime} from './utils';
13
-import {StoreContext} from '../context';
14
-import {getGradientColor} from './utils';
15
-
16
-import styles from './SidebarInteractions.css';
17
-
18
-export type Props = {||};
19
-
20
-export default function SidebarInteractions(_: Props) {
21
- const {
22
- selectedInteractionID,
23
- rootID,
24
- selectCommitIndex,
25
- selectTab,
26
- } = useContext(ProfilerContext);
27
-
28
- const {profilerStore} = useContext(StoreContext);
29
- const {profilingCache} = profilerStore;
30
-
31
- if (selectedInteractionID === null) {
32
- return <div className={styles.NothingSelected}>Nothing selected</div>;
33
- }
34
-
35
- const {interactionCommits, interactions} = profilerStore.getDataForRoot(
36
- ((rootID: any): number),
37
- );
38
- const interaction = interactions.get(selectedInteractionID);
39
- if (interaction == null) {
40
- throw Error(
41
- `Could not find interaction by selected interaction id "${selectedInteractionID}"`,
42
- );
43
- }
44
-
45
- const {maxCommitDuration} = profilingCache.getInteractionsChartData({
46
- rootID: ((rootID: any): number),
47
- });
48
-
49
- const viewCommit = (commitIndex: number) => {
50
- selectTab('flame-chart');
51
- selectCommitIndex(commitIndex);
52
- };
53
-
54
- const listItems: Array<React$Node> = [];
55
- const commitIndices = interactionCommits.get(selectedInteractionID);
56
- if (commitIndices != null) {
57
- commitIndices.forEach(commitIndex => {
58
- const {duration, timestamp} = profilerStore.getCommitData(
59
- ((rootID: any): number),
60
- commitIndex,
61
- );
62
-
63
- listItems.push(
64
- <li
65
- key={commitIndex}
66
- className={styles.ListItem}
67
- onClick={() => viewCommit(commitIndex)}>
68
- <div
69
- className={styles.CommitBox}
70
- style={{
71
- backgroundColor: getGradientColor(
72
- Math.min(1, Math.max(0, duration / maxCommitDuration)) || 0,
73
- ),
74
- }}
75
- />
76
- <div>
77
- timestamp: {formatTime(timestamp)}s
78
- <br />
79
- duration: {formatDuration(duration)}ms
80
- </div>
81
- </li>,
82
- );
83
- });
84
- }
85
-
86
- return (
87
- <Fragment>
88
- <div className={styles.Toolbar}>
89
- <div className={styles.Name}>{interaction.name}</div>
90
- </div>
91
- <div className={styles.Content}>
92
- <div className={styles.Commits}>Commits:</div>
93
- <ul className={styles.List}>{listItems}</ul>
94
- </div>
95
- </Fragment>
96
- );
97
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarSelectedFiberInfo.css
deleted
-76
@@ -1,76 +0,0 @@
1
-.Toolbar {
2
- height: 2.25rem;
3
- padding: 0 0.5rem;
4
- flex: 0 0 auto;
5
- display: flex;
6
- align-items: center;
7
- border-bottom: 1px solid var(--color-border);
8
-}
9
-
10
-.Content {
11
- padding: 0.5rem;
12
- user-select: none;
13
- overflow-y: auto;
14
-}
15
-
16
-.WhatChanged {
17
- margin-bottom: 1rem;
18
-}
19
-
20
-.Component {
21
- flex: 1;
22
- color: var(--color-component-name);
23
- font-family: var(--font-family-monospace);
24
- font-size: var(--font-size-monospace-normal);
25
- white-space: nowrap;
26
- overflow-x: hidden;
27
- text-overflow: ellipsis;
28
-}
29
-
30
-.Label {
31
- font-weight: bold;
32
- margin-bottom: 0.5rem;
33
-}
34
-
35
-.CurrentCommit,
36
-.Commit {
37
- display: block;
38
- width: 100%;
39
- text-align: left;
40
- background: none;
41
- border: none;
42
- padding: 0.25rem 0.5rem;
43
- color: var(--color-text);
44
-}
45
-.Commit:focus,
46
-.Commit:hover {
47
- outline: none;
48
- background-color: var(--color-background-hover);
49
-}
50
-
51
-.CurrentCommit {
52
- background-color: var(--color-background-selected);
53
- color: var(--color-text-selected);
54
-}
55
-.CurrentCommit:focus {
56
- outline: none;
57
-}
58
-
59
-.WhatChangedItem {
60
- margin-top: 0.25rem;
61
-}
62
-
63
-.WhatChangedKey {
64
- font-family: var(--font-family-monospace);
65
- font-size: var(--font-size-monospace-small);
66
- line-height: 1;
67
-}
68
-.WhatChangedKey:first-of-type::before {
69
- content: ' (';
70
-}
71
-.WhatChangedKey::after {
72
- content: ', ';
73
-}
74
-.WhatChangedKey:last-of-type::after {
75
- content: ')';
76
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarSelectedFiberInfo.js
deleted
-221
@@ -1,221 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useContext} from 'react';
11
-import ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore';
12
-import {ProfilerContext} from './ProfilerContext';
13
-import {formatDuration, formatTime} from './utils';
14
-import {StoreContext} from '../context';
15
-import Button from '../Button';
16
-import ButtonIcon from '../ButtonIcon';
17
-
18
-import styles from './SidebarSelectedFiberInfo.css';
19
-
20
-export type Props = {||};
21
-
22
-export default function SidebarSelectedFiberInfo(_: Props) {
23
- const {profilerStore} = useContext(StoreContext);
24
- const {
25
- rootID,
26
- selectCommitIndex,
27
- selectedCommitIndex,
28
- selectedFiberID,
29
- selectedFiberName,
30
- selectFiber,
31
- } = useContext(ProfilerContext);
32
- const {profilingCache} = profilerStore;
33
-
34
- const commitIndices = profilingCache.getFiberCommits({
35
- fiberID: ((selectedFiberID: any): number),
36
- rootID: ((rootID: any): number),
37
- });
38
-
39
- const listItems = [];
40
- let i = 0;
41
- for (i = 0; i < commitIndices.length; i++) {
42
- const commitIndex = commitIndices[i];
43
-
44
- const {duration, timestamp} = profilerStore.getCommitData(
45
- ((rootID: any): number),
46
- commitIndex,
47
- );
48
-
49
- listItems.push(
50
- <button
51
- key={commitIndex}
52
- className={
53
- selectedCommitIndex === commitIndex
54
- ? styles.CurrentCommit
55
- : styles.Commit
56
- }
57
- onClick={() => selectCommitIndex(commitIndex)}>
58
- {formatTime(timestamp)}s for {formatDuration(duration)}ms
59
- </button>,
60
- );
61
- }
62
-
63
- return (
64
- <Fragment>
65
- <div className={styles.Toolbar}>
66
- <div className={styles.Component}>
67
- {selectedFiberName || 'Selected component'}
68
- </div>
69
-
70
- <Button
71
- className={styles.IconButton}
72
- onClick={() => selectFiber(null, null)}
73
- title="Back to commit view">
74
- <ButtonIcon type="close" />
75
- </Button>
76
- </div>
77
- <div className={styles.Content}>
78
- <WhatChanged
79
- commitIndex={((selectedCommitIndex: any): number)}
80
- fiberID={((selectedFiberID: any): number)}
81
- profilerStore={profilerStore}
82
- rootID={((rootID: any): number)}
83
- />
84
- {listItems.length > 0 && (
85
- <Fragment>
86
- <label className={styles.Label}>Rendered at</label>: {listItems}
87
- </Fragment>
88
- )}
89
- {listItems.length === 0 && (
90
- <div>Did not render during this profiling session.</div>
91
- )}
92
- </div>
93
- </Fragment>
94
- );
95
-}
96
-
97
-type WhatChangedProps = {|
98
- commitIndex: number | null,
99
- fiberID: number,
100
- profilerStore: ProfilerStore,
101
- rootID: number,
102
-|};
103
-
104
-function WhatChanged({
105
- commitIndex,
106
- fiberID,
107
- profilerStore,
108
- rootID,
109
-}: WhatChangedProps) {
110
- // TRICKY
111
- // Handle edge case where no commit is selected because of a min-duration filter update.
112
- // If the commit index is null, suspending for data below would throw an error.
113
- // TODO (ProfilerContext) This check should not be necessary.
114
- if (commitIndex === null) {
115
- return null;
116
- }
117
-
118
- const {changeDescriptions} = profilerStore.getCommitData(
119
- ((rootID: any): number),
120
- commitIndex,
121
- );
122
- if (changeDescriptions === null) {
123
- return null;
124
- }
125
-
126
- const changeDescription = changeDescriptions.get(fiberID);
127
- if (changeDescription == null) {
128
- return null;
129
- }
130
-
131
- if (changeDescription.isFirstMount) {
132
- return (
133
- <div className={styles.WhatChanged}>
134
- <label className={styles.Label}>Why did this render?</label>
135
- <div className={styles.WhatChangedItem}>
136
- This is the first time the component rendered.
137
- </div>
138
- </div>
139
- );
140
- }
141
-
142
- const changes = [];
143
-
144
- if (changeDescription.context === true) {
145
- changes.push(
146
- <div key="context" className={styles.WhatChangedItem}>
147
- • Context changed
148
- </div>,
149
- );
150
- } else if (
151
- typeof changeDescription.context === 'object' &&
152
- changeDescription.context !== null &&
153
- changeDescription.context.length !== 0
154
- ) {
155
- changes.push(
156
- <div key="context" className={styles.WhatChangedItem}>
157
- • Context changed:
158
- {changeDescription.context.map(key => (
159
- <span key={key} className={styles.WhatChangedKey}>
160
- {key}
161
- </span>
162
- ))}
163
- </div>,
164
- );
165
- }
166
-
167
- if (changeDescription.didHooksChange) {
168
- changes.push(
169
- <div key="hooks" className={styles.WhatChangedItem}>
170
- • Hooks changed
171
- </div>,
172
- );
173
- }
174
-
175
- if (
176
- changeDescription.props !== null &&
177
- changeDescription.props.length !== 0
178
- ) {
179
- changes.push(
180
- <div key="props" className={styles.WhatChangedItem}>
181
- • Props changed:
182
- {changeDescription.props.map(key => (
183
- <span key={key} className={styles.WhatChangedKey}>
184
- {key}
185
- </span>
186
- ))}
187
- </div>,
188
- );
189
- }
190
-
191
- if (
192
- changeDescription.state !== null &&
193
- changeDescription.state.length !== 0
194
- ) {
195
- changes.push(
196
- <div key="state" className={styles.WhatChangedItem}>
197
- • State changed:
198
- {changeDescription.state.map(key => (
199
- <span key={key} className={styles.WhatChangedKey}>
200
- {key}
201
- </span>
202
- ))}
203
- </div>,
204
- );
205
- }
206
-
207
- if (changes.length === 0) {
208
- changes.push(
209
- <div key="nothing" className={styles.WhatChangedItem}>
210
- The parent component rendered.
211
- </div>,
212
- );
213
- }
214
-
215
- return (
216
- <div className={styles.WhatChanged}>
217
- <label className={styles.Label}>Why did this render?</label>
218
- {changes}
219
- </div>
220
- );
221
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.css
deleted
-9
@@ -1,9 +0,0 @@
1
-.List {
2
- /**
3
- * The decision to suppress the default (horizontal) scroll bars is intentional.
4
- * The snapshot selector is small enough that the scrollbar renders it essentially useless.
5
- * There are two alternative navigation mechanisms (arrow keys and arrow buttons).
6
- * If necessary, we could also expand the click-and-drag mechanism to scroll.
7
- */
8
- overflow-x: hidden !important;
9
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js
deleted
-179
@@ -1,179 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
11
-import AutoSizer from 'react-virtualized-auto-sizer';
12
-import {FixedSizeList} from 'react-window';
13
-import SnapshotCommitListItem from './SnapshotCommitListItem';
14
-import {minBarWidth} from './constants';
15
-
16
-import styles from './SnapshotCommitList.css';
17
-
18
-export type ItemData = {|
19
- commitDurations: Array<number>,
20
- commitTimes: Array<number>,
21
- filteredCommitIndices: Array<number>,
22
- isMouseDown: boolean,
23
- maxDuration: number,
24
- selectedCommitIndex: number | null,
25
- selectedFilteredCommitIndex: number | null,
26
- selectCommitIndex: (index: number) => void,
27
-|};
28
-
29
-type Props = {|
30
- commitDurations: Array<number>,
31
- commitTimes: Array<number>,
32
- filteredCommitIndices: Array<number>,
33
- selectedCommitIndex: number | null,
34
- selectedFilteredCommitIndex: number | null,
35
- selectCommitIndex: (index: number) => void,
36
-|};
37
-
38
-export default function SnapshotCommitList({
39
- commitDurations,
40
- commitTimes,
41
- filteredCommitIndices,
42
- selectedCommitIndex,
43
- selectedFilteredCommitIndex,
44
- selectCommitIndex,
45
-}: Props) {
46
- return (
47
- <AutoSizer>
48
- {({height, width}) => (
49
- <List
50
- commitDurations={commitDurations}
51
- commitTimes={commitTimes}
52
- height={height}
53
- filteredCommitIndices={filteredCommitIndices}
54
- selectedCommitIndex={selectedCommitIndex}
55
- selectedFilteredCommitIndex={selectedFilteredCommitIndex}
56
- selectCommitIndex={selectCommitIndex}
57
- width={width}
58
- />
59
- )}
60
- </AutoSizer>
61
- );
62
-}
63
-
64
-type ListProps = {|
65
- commitDurations: Array<number>,
66
- commitTimes: Array<number>,
67
- height: number,
68
- filteredCommitIndices: Array<number>,
69
- selectedCommitIndex: number | null,
70
- selectedFilteredCommitIndex: number | null,
71
- selectCommitIndex: (index: number) => void,
72
- width: number,
73
-|};
74
-
75
-function List({
76
- commitDurations,
77
- selectedCommitIndex,
78
- commitTimes,
79
- height,
80
- filteredCommitIndices,
81
- selectedFilteredCommitIndex,
82
- selectCommitIndex,
83
- width,
84
-}: ListProps) {
85
- const listRef = useRef<FixedSizeList<ItemData> | null>(null);
86
- const divRef = useRef<HTMLDivElement | null>(null);
87
- const prevCommitIndexRef = useRef<number | null>(null);
88
-
89
- // Make sure a newly selected snapshot is fully visible within the list.
90
- useEffect(
91
- () => {
92
- if (selectedFilteredCommitIndex !== prevCommitIndexRef.current) {
93
- prevCommitIndexRef.current = selectedFilteredCommitIndex;
94
- if (selectedFilteredCommitIndex !== null && listRef.current !== null) {
95
- listRef.current.scrollToItem(selectedFilteredCommitIndex);
96
- }
97
- }
98
- },
99
- [listRef, selectedFilteredCommitIndex],
100
- );
101
-
102
- // When the mouse is down, dragging over a commit should auto-select it.
103
- // This provides a nice way for users to swipe across a range of commits to compare them.
104
- const [isMouseDown, setIsMouseDown] = useState(false);
105
- const handleMouseDown = useCallback(() => {
106
- setIsMouseDown(true);
107
- }, []);
108
- const handleMouseUp = useCallback(() => {
109
- setIsMouseDown(false);
110
- }, []);
111
- useEffect(
112
- () => {
113
- if (divRef.current === null) {
114
- return () => {};
115
- }
116
-
117
- // It's important to listen to the ownerDocument to support the browser extension.
118
- // Here we use portals to render individual tabs (e.g. Profiler),
119
- // and the root document might belong to a different window.
120
- const ownerDocument = divRef.current.ownerDocument;
121
- ownerDocument.addEventListener('mouseup', handleMouseUp);
122
- return () => ownerDocument.removeEventListener('mouseup', handleMouseUp);
123
- },
124
- [divRef, handleMouseUp],
125
- );
126
-
127
- const itemSize = useMemo(
128
- () => Math.max(minBarWidth, width / filteredCommitIndices.length),
129
- [filteredCommitIndices, width],
130
- );
131
- const maxDuration = useMemo(
132
- () => commitDurations.reduce((max, duration) => Math.max(max, duration), 0),
133
- [commitDurations],
134
- );
135
-
136
- // Pass required contextual data down to the ListItem renderer.
137
- const itemData = useMemo<ItemData>(
138
- () => ({
139
- commitDurations,
140
- commitTimes,
141
- filteredCommitIndices,
142
- isMouseDown,
143
- maxDuration,
144
- selectedCommitIndex,
145
- selectedFilteredCommitIndex,
146
- selectCommitIndex,
147
- }),
148
- [
149
- commitDurations,
150
- commitTimes,
151
- filteredCommitIndices,
152
- isMouseDown,
153
- maxDuration,
154
- selectedCommitIndex,
155
- selectedFilteredCommitIndex,
156
- selectCommitIndex,
157
- ],
158
- );
159
-
160
- return (
161
- <div
162
- onMouseDown={handleMouseDown}
163
- onMouseUp={handleMouseUp}
164
- ref={divRef}
165
- style={{height, width}}>
166
- <FixedSizeList
167
- className={styles.List}
168
- layout="horizontal"
169
- height={height}
170
- itemCount={filteredCommitIndices.length}
171
- itemData={itemData}
172
- itemSize={itemSize}
173
- ref={(listRef: any) /* Flow bug? */}
174
- width={width}>
175
- {SnapshotCommitListItem}
176
- </FixedSizeList>
177
- </div>
178
- );
179
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.css
deleted
-16
@@ -1,16 +0,0 @@
1
-.Outer {
2
- user-select: none;
3
- cursor: pointer;
4
- border-bottom: 3px solid transparent;
5
- padding-top: 4px;
6
- padding-bottom: 1px;
7
- display: flex;
8
- align-items: flex-end;
9
-}
10
-
11
-.Inner {
12
- width: 100%;
13
- min-height: 5px;
14
- background-color: var(--color-commit-did-not-render-fill);
15
- color: var(--color-commit-did-not-render-fill-text);
16
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js
deleted
-80
@@ -1,80 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {memo, useCallback} from 'react';
11
-import {areEqual} from 'react-window';
12
-import {getGradientColor, formatDuration, formatTime} from './utils';
13
-
14
-import styles from './SnapshotCommitListItem.css';
15
-
16
-import type {ItemData} from './SnapshotCommitList';
17
-
18
-type Props = {
19
- data: ItemData,
20
- index: number,
21
- style: Object,
22
-};
23
-
24
-function SnapshotCommitListItem({data: itemData, index, style}: Props) {
25
- const {
26
- commitDurations,
27
- commitTimes,
28
- filteredCommitIndices,
29
- isMouseDown,
30
- maxDuration,
31
- selectedCommitIndex,
32
- selectCommitIndex,
33
- } = itemData;
34
-
35
- index = filteredCommitIndices[index];
36
-
37
- const commitDuration = commitDurations[index];
38
- const commitTime = commitTimes[index];
39
-
40
- const handleClick = useCallback(() => selectCommitIndex(index), [
41
- index,
42
- selectCommitIndex,
43
- ]);
44
-
45
- // Guard against commits with duration 0
46
- const percentage =
47
- Math.min(1, Math.max(0, commitDuration / maxDuration)) || 0;
48
- const isSelected = selectedCommitIndex === index;
49
-
50
- // Leave a 1px gap between snapshots
51
- const width = parseFloat(style.width) - 1;
52
-
53
- return (
54
- <div
55
- className={styles.Outer}
56
- onClick={handleClick}
57
- onMouseEnter={isMouseDown ? handleClick : null}
58
- style={{
59
- ...style,
60
- width,
61
- borderBottom: isSelected
62
- ? '3px solid var(--color-tab-selected-border)'
63
- : undefined,
64
- }}
65
- title={`Duration ${formatDuration(commitDuration)}ms at ${formatTime(
66
- commitTime,
67
- )}s`}>
68
- <div
69
- className={styles.Inner}
70
- style={{
71
- height: `${Math.round(percentage * 100)}%`,
72
- backgroundColor:
73
- percentage > 0 ? getGradientColor(percentage) : undefined,
74
- }}
75
- />
76
- </div>
77
- );
78
-}
79
-
80
-export default memo<Props>(SnapshotCommitListItem, areEqual);
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotSelector.css
deleted
-30
@@ -1,30 +0,0 @@
1
-.Button {
2
- flex: 0 0 auto;
3
- margin-left: 0.25rem;
4
-}
5
-
6
-.Commits {
7
- height: 100%;
8
- min-width: 30px;
9
- margin-left: 0.25rem;
10
- overflow: hidden;
11
-}
12
-.Commits:focus {
13
- outline: none;
14
- background-color: var(--color-button-background-focus);
15
-}
16
-
17
-.IndexLabel {
18
- flex: 0 0 auto;
19
- white-space: nowrap;
20
- font-family: var(--font-family-monospace);
21
- margin-left: 0.25rem;
22
-}
23
-
24
-.NoCommits {
25
- height: 100%;
26
- display: flex;
27
- align-items: center;
28
- justify-content: center;
29
- color: var(--color-dim);
30
-}
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotSelector.js
deleted
-186
@@ -1,186 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useCallback, useContext, useMemo} from 'react';
11
-import Button from '../Button';
12
-import ButtonIcon from '../ButtonIcon';
13
-import {ProfilerContext} from './ProfilerContext';
14
-import SnapshotCommitList from './SnapshotCommitList';
15
-import {maxBarWidth} from './constants';
16
-import {StoreContext} from '../context';
17
-
18
-import styles from './SnapshotSelector.css';
19
-
20
-export type Props = {||};
21
-
22
-export default function SnapshotSelector(_: Props) {
23
- const {
24
- isCommitFilterEnabled,
25
- minCommitDuration,
26
- rootID,
27
- selectedCommitIndex,
28
- selectCommitIndex,
29
- } = useContext(ProfilerContext);
30
-
31
- const {profilerStore} = useContext(StoreContext);
32
- const {commitData} = profilerStore.getDataForRoot(((rootID: any): number));
33
-
34
- const commitDurations: Array<number> = [];
35
- const commitTimes: Array<number> = [];
36
- commitData.forEach(commitDatum => {
37
- commitDurations.push(commitDatum.duration);
38
- commitTimes.push(commitDatum.timestamp);
39
- });
40
-
41
- const filteredCommitIndices = useMemo(
42
- () =>
43
- commitData.reduce((reduced, commitDatum, index) => {
44
- if (
45
- !isCommitFilterEnabled ||
46
- commitDatum.duration >= minCommitDuration
47
- ) {
48
- reduced.push(index);
49
- }
50
- return reduced;
51
- }, []),
52
- [commitData, isCommitFilterEnabled, minCommitDuration],
53
- );
54
-
55
- const numFilteredCommits = filteredCommitIndices.length;
56
-
57
- // Map the (unfiltered) selected commit index to an index within the filtered data.
58
- const selectedFilteredCommitIndex = useMemo(
59
- () => {
60
- if (selectedCommitIndex !== null) {
61
- for (let i = 0; i < filteredCommitIndices.length; i++) {
62
- if (filteredCommitIndices[i] === selectedCommitIndex) {
63
- return i;
64
- }
65
- }
66
- }
67
- return null;
68
- },
69
- [filteredCommitIndices, selectedCommitIndex],
70
- );
71
-
72
- // TODO (ProfilerContext) This should be managed by the context controller (reducer).
73
- // It doesn't currently know about the filtered commits though (since it doesn't suspend).
74
- // Maybe this component should pass filteredCommitIndices up?
75
- if (selectedFilteredCommitIndex === null) {
76
- if (numFilteredCommits > 0) {
77
- selectCommitIndex(0);
78
- } else {
79
- selectCommitIndex(null);
80
- }
81
- } else if (selectedFilteredCommitIndex >= numFilteredCommits) {
82
- selectCommitIndex(numFilteredCommits === 0 ? null : numFilteredCommits - 1);
83
- }
84
-
85
- let label = null;
86
- if (numFilteredCommits > 0) {
87
- label =
88
- `${selectedFilteredCommitIndex + 1}`.padStart(
89
- `${numFilteredCommits}`.length,
90
- '0',
91
- ) +
92
- ' / ' +
93
- numFilteredCommits;
94
- }
95
-
96
- const viewNextCommit = useCallback(
97
- () => {
98
- const nextCommitIndex = Math.min(
99
- ((selectedFilteredCommitIndex: any): number) + 1,
100
- filteredCommitIndices.length - 1,
101
- );
102
- selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
103
- },
104
- [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex],
105
- );
106
- const viewPrevCommit = useCallback(
107
- () => {
108
- const nextCommitIndex = Math.max(
109
- ((selectedFilteredCommitIndex: any): number) - 1,
110
- 0,
111
- );
112
- selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
113
- },
114
- [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex],
115
- );
116
-
117
- const handleKeyDown = useCallback(
118
- event => {
119
- switch (event.key) {
120
- case 'ArrowLeft':
121
- viewPrevCommit();
122
- event.stopPropagation();
123
- break;
124
- case 'ArrowRight':
125
- viewNextCommit();
126
- event.stopPropagation();
127
- break;
128
- default:
129
- break;
130
- }
131
- },
132
- [viewNextCommit, viewPrevCommit],
133
- );
134
-
135
- if (commitData.length === 0) {
136
- return null;
137
- }
138
-
139
- return (
140
- <Fragment>
141
- <span className={styles.IndexLabel}>{label}</span>
142
- <Button
143
- className={styles.Button}
144
- disabled={selectedFilteredCommitIndex === 0 || numFilteredCommits === 0}
145
- onClick={viewPrevCommit}
146
- title="Select previous commit">
147
- <ButtonIcon type="previous" />
148
- </Button>
149
- <div
150
- className={styles.Commits}
151
- onKeyDown={handleKeyDown}
152
- style={{
153
- flex: numFilteredCommits > 0 ? '1 1 auto' : '0 0 auto',
154
- maxWidth:
155
- numFilteredCommits > 0
156
- ? numFilteredCommits * maxBarWidth
157
- : undefined,
158
- }}
159
- tabIndex={0}>
160
- {numFilteredCommits > 0 && (
161
- <SnapshotCommitList
162
- commitDurations={commitDurations}
163
- commitTimes={commitTimes}
164
- filteredCommitIndices={filteredCommitIndices}
165
- selectedCommitIndex={selectedCommitIndex}
166
- selectedFilteredCommitIndex={selectedFilteredCommitIndex}
167
- selectCommitIndex={selectCommitIndex}
168
- />
169
- )}
170
- {numFilteredCommits === 0 && (
171
- <div className={styles.NoCommits}>No commits</div>
172
- )}
173
- </div>
174
- <Button
175
- className={styles.Button}
176
- disabled={
177
- selectedFilteredCommitIndex === null ||
178
- selectedFilteredCommitIndex >= numFilteredCommits - 1
179
- }
180
- onClick={viewNextCommit}
181
- title="Select next commit">
182
- <ButtonIcon type="next" />
183
- </Button>
184
- </Fragment>
185
- );
186
-}
packages/react-devtools-shared/src/devtools/views/Profiler/constants.js
deleted
-14
@@ -1,14 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-export const barWidthThreshold = 2;
11
-export const interactionCommitSize = 10;
12
-export const interactionLabelWidth = 200;
13
-export const maxBarWidth = 30;
14
-export const minBarWidth = 5;
packages/react-devtools-shared/src/devtools/views/Profiler/types.js
deleted
-139
@@ -1,139 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import type {ElementType} from 'react-devtools-shared/src/types';
11
-
12
-export type CommitTreeNode = {|
13
- id: number,
14
- children: Array<number>,
15
- displayName: string | null,
16
- key: number | string | null,
17
- parentID: number,
18
- treeBaseDuration: number,
19
- type: ElementType,
20
-|};
21
-
22
-export type CommitTree = {|
23
- nodes: Map<number, CommitTreeNode>,
24
- rootID: number,
25
-|};
26
-
27
-export type Interaction = {|
28
- id: number,
29
- name: string,
30
- timestamp: number,
31
-|};
32
-
33
-export type SnapshotNode = {|
34
- id: number,
35
- children: Array<number>,
36
- displayName: string | null,
37
- key: number | string | null,
38
- type: ElementType,
39
-|};
40
-
41
-export type ChangeDescription = {|
42
- context: Array<string> | boolean | null,
43
- didHooksChange: boolean,
44
- isFirstMount: boolean,
45
- props: Array<string> | null,
46
- state: Array<string> | null,
47
-|};
48
-
49
-export type CommitDataFrontend = {|
50
- // Map of Fiber (ID) to a description of what changed in this commit.
51
- changeDescriptions: Map<number, ChangeDescription> | null,
52
-
53
- // How long was this commit?
54
- duration: number,
55
-
56
- // Map of Fiber (ID) to actual duration for this commit;
57
- // Fibers that did not render will not have entries in this Map.
58
- fiberActualDurations: Map<number, number>,
59
-
60
- // Map of Fiber (ID) to "self duration" for this commit;
61
- // Fibers that did not render will not have entries in this Map.
62
- fiberSelfDurations: Map<number, number>,
63
-
64
- // Which interactions (IDs) were associated with this commit.
65
- interactionIDs: Array<number>,
66
-
67
- // Priority level of the commit (if React provided this info)
68
- priorityLevel: string | null,
69
-
70
- // When did this commit occur (relative to the start of profiling)
71
- timestamp: number,
72
-|};
73
-
74
-export type ProfilingDataForRootFrontend = {|
75
- // Timing, duration, and other metadata about each commit.
76
- commitData: Array<CommitDataFrontend>,
77
-
78
- // Display name of the nearest descendant component (ideally a function or class component).
79
- // This value is used by the root selector UI.
80
- displayName: string,
81
-
82
- // Map of fiber id to (initial) tree base duration when Profiling session was started.
83
- // This info can be used along with commitOperations to reconstruct the tree for any commit.
84
- initialTreeBaseDurations: Map<number, number>,
85
-
86
- // All interactions recorded (for this root) during the current session.
87
- interactionCommits: Map<number, Array<number>>,
88
-
89
- // All interactions recorded (for this root) during the current session.
90
- interactions: Map<number, Interaction>,
91
-
92
- // List of tree mutation that occur during profiling.
93
- // These mutations can be used along with initial snapshots to reconstruct the tree for any commit.
94
- operations: Array<Array<number>>,
95
-
96
- // Identifies the root this profiler data corresponds to.
97
- rootID: number,
98
-
99
- // Map of fiber id to node when the Profiling session was started.
100
- // This info can be used along with commitOperations to reconstruct the tree for any commit.
101
- snapshots: Map<number, SnapshotNode>,
102
-|};
103
-
104
-// Combination of profiling data collected by the renderer interface (backend) and Store (frontend).
105
-export type ProfilingDataFrontend = {|
106
- // Profiling data per root.
107
- dataForRoots: Map<number, ProfilingDataForRootFrontend>,
108
-|};
109
-
110
-export type CommitDataExport = {|
111
- changeDescriptions: Array<[number, ChangeDescription]> | null,
112
- duration: number,
113
- // Tuple of fiber ID and actual duration
114
- fiberActualDurations: Array<[number, number]>,
115
- // Tuple of fiber ID and computed "self" duration
116
- fiberSelfDurations: Array<[number, number]>,
117
- interactionIDs: Array<number>,
118
- priorityLevel: string | null,
119
- timestamp: number,
120
-|};
121
-
122
-export type ProfilingDataForRootExport = {|
123
- commitData: Array<CommitDataExport>,
124
- displayName: string,
125
- // Tuple of Fiber ID and base duration
126
- initialTreeBaseDurations: Array<[number, number]>,
127
- // Tuple of Interaction ID and commit indices
128
- interactionCommits: Array<[number, Array<number>]>,
129
- interactions: Array<[number, Interaction]>,
130
- operations: Array<Array<number>>,
131
- rootID: number,
132
- snapshots: Array<[number, SnapshotNode]>,
133
-|};
134
-
135
-// Serializable vefrsion of ProfilingDataFrontend data.
136
-export type ProfilingDataExport = {|
137
- version: 4,
138
- dataForRoots: Array<ProfilingDataForRootExport>,
139
-|};
packages/react-devtools-shared/src/devtools/views/Profiler/utils.js
deleted
-236
@@ -1,236 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {PROFILER_EXPORT_VERSION} from 'react-devtools-shared/src/constants';
11
-
12
-import type {ProfilingDataBackend} from 'react-devtools-shared/src/backend/types';
13
-import type {
14
- ProfilingDataExport,
15
- ProfilingDataForRootExport,
16
- ProfilingDataForRootFrontend,
17
- ProfilingDataFrontend,
18
- SnapshotNode,
19
-} from './types';
20
-
21
-const commitGradient = [
22
- 'var(--color-commit-gradient-0)',
23
- 'var(--color-commit-gradient-1)',
24
- 'var(--color-commit-gradient-2)',
25
- 'var(--color-commit-gradient-3)',
26
- 'var(--color-commit-gradient-4)',
27
- 'var(--color-commit-gradient-5)',
28
- 'var(--color-commit-gradient-6)',
29
- 'var(--color-commit-gradient-7)',
30
- 'var(--color-commit-gradient-8)',
31
- 'var(--color-commit-gradient-9)',
32
-];
33
-
34
-// Combines info from the Store (frontend) and renderer interfaces (backend) into the format required by the Profiler UI.
35
-// This format can then be quickly exported (and re-imported).
36
-export function prepareProfilingDataFrontendFromBackendAndStore(
37
- dataBackends: Array<ProfilingDataBackend>,
38
- operationsByRootID: Map<number, Array<Array<number>>>,
39
- snapshotsByRootID: Map<number, Map<number, SnapshotNode>>,
40
-): ProfilingDataFrontend {
41
- const dataForRoots: Map<number, ProfilingDataForRootFrontend> = new Map();
42
-
43
- dataBackends.forEach(dataBackend => {
44
- dataBackend.dataForRoots.forEach(
45
- ({
46
- commitData,
47
- displayName,
48
- initialTreeBaseDurations,
49
- interactionCommits,
50
- interactions,
51
- rootID,
52
- }) => {
53
- const operations = operationsByRootID.get(rootID);
54
- if (operations == null) {
55
- throw Error(`Could not find profiling operations for root ${rootID}`);
56
- }
57
-
58
- const snapshots = snapshotsByRootID.get(rootID);
59
- if (snapshots == null) {
60
- throw Error(`Could not find profiling snapshots for root ${rootID}`);
61
- }
62
-
63
- dataForRoots.set(rootID, {
64
- commitData: commitData.map((commitDataBackend, commitIndex) => ({
65
- changeDescriptions:
66
- commitDataBackend.changeDescriptions != null
67
- ? new Map(commitDataBackend.changeDescriptions)
68
- : null,
69
- duration: commitDataBackend.duration,
70
- fiberActualDurations: new Map(
71
- commitDataBackend.fiberActualDurations,
72
- ),
73
- fiberSelfDurations: new Map(commitDataBackend.fiberSelfDurations),
74
- interactionIDs: commitDataBackend.interactionIDs,
75
- priorityLevel: commitDataBackend.priorityLevel,
76
- timestamp: commitDataBackend.timestamp,
77
- })),
78
- displayName,
79
- initialTreeBaseDurations: new Map(initialTreeBaseDurations),
80
- interactionCommits: new Map(interactionCommits),
81
- interactions: new Map(interactions),
82
- operations,
83
- rootID,
84
- snapshots,
85
- });
86
- },
87
- );
88
- });
89
-
90
- return {dataForRoots};
91
-}
92
-
93
-// Converts a Profiling data export into the format required by the Store.
94
-export function prepareProfilingDataFrontendFromExport(
95
- profilingDataExport: ProfilingDataExport,
96
-): ProfilingDataFrontend {
97
- const {version} = profilingDataExport;
98
-
99
- if (version !== PROFILER_EXPORT_VERSION) {
100
- throw Error(`Unsupported profiler export version "${version}"`);
101
- }
102
-
103
- const dataForRoots: Map<number, ProfilingDataForRootFrontend> = new Map();
104
- profilingDataExport.dataForRoots.forEach(
105
- ({
106
- commitData,
107
- displayName,
108
- initialTreeBaseDurations,
109
- interactionCommits,
110
- interactions,
111
- operations,
112
- rootID,
113
- snapshots,
114
- }) => {
115
- dataForRoots.set(rootID, {
116
- commitData: commitData.map(
117
- ({
118
- changeDescriptions,
119
- duration,
120
- fiberActualDurations,
121
- fiberSelfDurations,
122
- interactionIDs,
123
- priorityLevel,
124
- timestamp,
125
- }) => ({
126
- changeDescriptions:
127
- changeDescriptions != null ? new Map(changeDescriptions) : null,
128
- duration,
129
- fiberActualDurations: new Map(fiberActualDurations),
130
- fiberSelfDurations: new Map(fiberSelfDurations),
131
- interactionIDs,
132
- priorityLevel,
133
- timestamp,
134
- }),
135
- ),
136
- displayName,
137
- initialTreeBaseDurations: new Map(initialTreeBaseDurations),
138
- interactionCommits: new Map(interactionCommits),
139
- interactions: new Map(interactions),
140
- operations,
141
- rootID,
142
- snapshots: new Map(snapshots),
143
- });
144
- },
145
- );
146
-
147
- return {dataForRoots};
148
-}
149
-
150
-// Converts a Store Profiling data into a format that can be safely (JSON) serialized for export.
151
-export function prepareProfilingDataExport(
152
- profilingDataFrontend: ProfilingDataFrontend,
153
-): ProfilingDataExport {
154
- const dataForRoots: Array<ProfilingDataForRootExport> = [];
155
- profilingDataFrontend.dataForRoots.forEach(
156
- ({
157
- commitData,
158
- displayName,
159
- initialTreeBaseDurations,
160
- interactionCommits,
161
- interactions,
162
- operations,
163
- rootID,
164
- snapshots,
165
- }) => {
166
- dataForRoots.push({
167
- commitData: commitData.map(
168
- ({
169
- changeDescriptions,
170
- duration,
171
- fiberActualDurations,
172
- fiberSelfDurations,
173
- interactionIDs,
174
- priorityLevel,
175
- timestamp,
176
- }) => ({
177
- changeDescriptions:
178
- changeDescriptions != null
179
- ? Array.from(changeDescriptions.entries())
180
- : null,
181
- duration,
182
- fiberActualDurations: Array.from(fiberActualDurations.entries()),
183
- fiberSelfDurations: Array.from(fiberSelfDurations.entries()),
184
- interactionIDs,
185
- priorityLevel,
186
- timestamp,
187
- }),
188
- ),
189
- displayName,
190
- initialTreeBaseDurations: Array.from(
191
- initialTreeBaseDurations.entries(),
192
- ),
193
- interactionCommits: Array.from(interactionCommits.entries()),
194
- interactions: Array.from(interactions.entries()),
195
- operations,
196
- rootID,
197
- snapshots: Array.from(snapshots.entries()),
198
- });
199
- },
200
- );
201
-
202
- return {
203
- version: PROFILER_EXPORT_VERSION,
204
- dataForRoots,
205
- };
206
-}
207
-
208
-export const getGradientColor = (value: number) => {
209
- const maxIndex = commitGradient.length - 1;
210
- let index;
211
- if (Number.isNaN(value)) {
212
- index = 0;
213
- } else if (!Number.isFinite(value)) {
214
- index = maxIndex;
215
- } else {
216
- index = Math.max(0, Math.min(maxIndex, value)) * maxIndex;
217
- }
218
- return commitGradient[Math.round(index)];
219
-};
220
-
221
-export const formatDuration = (duration: number) =>
222
- Math.round(duration * 10) / 10 || '<0.1';
223
-export const formatPercentage = (percentage: number) =>
224
- Math.round(percentage * 100);
225
-export const formatTime = (timestamp: number) =>
226
- Math.round(Math.round(timestamp) / 100) / 10;
227
-
228
-export const scale = (
229
- minValue: number,
230
- maxValue: number,
231
- minRange: number,
232
- maxRange: number,
233
-) => (value: number, fallbackValue: number) =>
234
- maxValue - minValue === 0
235
- ? fallbackValue
236
- : ((value - minValue) / (maxValue - minValue)) * (maxRange - minRange);
packages/react-devtools-shared/src/devtools/views/ReactLogo.css
deleted
-6
@@ -1,6 +0,0 @@
1
-.ReactLogo {
2
- width: 1.75rem;
3
- height: 1.75rem;
4
- margin: 0 0.75rem 0 0.25rem;
5
- color: var(--color-button-active);
6
-}
packages/react-devtools-shared/src/devtools/views/ReactLogo.js
deleted
-32
@@ -1,32 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-
12
-import styles from './ReactLogo.css';
13
-
14
-type Props = {|
15
- className?: string,
16
-|};
17
-
18
-export default function ReactLogo({className}: Props) {
19
- return (
20
- <svg
21
- xmlns="http://www.w3.org/2000/svg"
22
- className={`${styles.ReactLogo} ${className || ''}`}
23
- viewBox="-11.5 -10.23174 23 20.46348">
24
- <circle cx="0" cy="0" r="2.05" fill="currentColor" />
25
- <g stroke="currentColor" strokeWidth="1" fill="none">
26
- <ellipse rx="11" ry="4.2" />
27
- <ellipse rx="11" ry="4.2" transform="rotate(60)" />
28
- <ellipse rx="11" ry="4.2" transform="rotate(120)" />
29
- </g>
30
- </svg>
31
- );
32
-}
packages/react-devtools-shared/src/devtools/views/Settings/ComponentsSettings.js
deleted
-401
@@ -1,401 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- useCallback,
12
- useContext,
13
- useEffect,
14
- useMemo,
15
- useRef,
16
- useState,
17
-} from 'react';
18
-import {useSubscription} from '../hooks';
19
-import {StoreContext} from '../context';
20
-import Button from '../Button';
21
-import ButtonIcon from '../ButtonIcon';
22
-import Toggle from '../Toggle';
23
-import {
24
- ComponentFilterDisplayName,
25
- ComponentFilterElementType,
26
- ComponentFilterHOC,
27
- ComponentFilterLocation,
28
- ElementTypeClass,
29
- ElementTypeContext,
30
- ElementTypeFunction,
31
- ElementTypeForwardRef,
32
- ElementTypeHostComponent,
33
- ElementTypeMemo,
34
- ElementTypeOtherOrUnknown,
35
- ElementTypeProfiler,
36
- ElementTypeSuspense,
37
-} from 'react-devtools-shared/src/types';
38
-
39
-import styles from './SettingsShared.css';
40
-
41
-import type {
42
- BooleanComponentFilter,
43
- ComponentFilter,
44
- ComponentFilterType,
45
- ElementType,
46
- ElementTypeComponentFilter,
47
- RegExpComponentFilter,
48
-} from 'react-devtools-shared/src/types';
49
-
50
-export default function ComponentsSettings(_: {||}) {
51
- const store = useContext(StoreContext);
52
-
53
- const collapseNodesByDefaultSubscription = useMemo(
54
- () => ({
55
- getCurrentValue: () => store.collapseNodesByDefault,
56
- subscribe: (callback: Function) => {
57
- store.addListener('collapseNodesByDefault', callback);
58
- return () => store.removeListener('collapseNodesByDefault', callback);
59
- },
60
- }),
61
- [store],
62
- );
63
- const collapseNodesByDefault = useSubscription<boolean>(
64
- collapseNodesByDefaultSubscription,
65
- );
66
-
67
- const updateCollapseNodesByDefault = useCallback(
68
- ({currentTarget}) => {
69
- store.collapseNodesByDefault = !currentTarget.checked;
70
- },
71
- [store],
72
- );
73
-
74
- const [componentFilters, setComponentFilters] = useState<
75
- Array<ComponentFilter>,
76
- >(() => [...store.componentFilters]);
77
-
78
- const addFilter = useCallback(() => {
79
- setComponentFilters(prevComponentFilters => {
80
- return [
81
- ...prevComponentFilters,
82
- {
83
- type: ComponentFilterElementType,
84
- value: ElementTypeHostComponent,
85
- isEnabled: true,
86
- },
87
- ];
88
- });
89
- }, []);
90
-
91
- const changeFilterType = useCallback(
92
- (componentFilter: ComponentFilter, type: ComponentFilterType) => {
93
- setComponentFilters(prevComponentFilters => {
94
- const cloned: Array<ComponentFilter> = [...prevComponentFilters];
95
- const index = prevComponentFilters.indexOf(componentFilter);
96
- if (index >= 0) {
97
- if (type === ComponentFilterElementType) {
98
- cloned[index] = {
99
- type: ComponentFilterElementType,
100
- isEnabled: componentFilter.isEnabled,
101
- value: ElementTypeHostComponent,
102
- };
103
- } else if (type === ComponentFilterDisplayName) {
104
- cloned[index] = {
105
- type: ComponentFilterDisplayName,
106
- isEnabled: componentFilter.isEnabled,
107
- isValid: true,
108
- value: '',
109
- };
110
- } else if (type === ComponentFilterLocation) {
111
- cloned[index] = {
112
- type: ComponentFilterLocation,
113
- isEnabled: componentFilter.isEnabled,
114
- isValid: true,
115
- value: '',
116
- };
117
- } else if (type === ComponentFilterHOC) {
118
- cloned[index] = {
119
- type: ComponentFilterHOC,
120
- isEnabled: componentFilter.isEnabled,
121
- isValid: true,
122
- };
123
- }
124
- }
125
- return cloned;
126
- });
127
- },
128
- [],
129
- );
130
-
131
- const updateFilterValueElementType = useCallback(
132
- (componentFilter: ComponentFilter, value: ElementType) => {
133
- if (componentFilter.type !== ComponentFilterElementType) {
134
- throw Error('Invalid value for element type filter');
135
- }
136
-
137
- setComponentFilters(prevComponentFilters => {
138
- const cloned: Array<ComponentFilter> = [...prevComponentFilters];
139
- if (componentFilter.type === ComponentFilterElementType) {
140
- const index = prevComponentFilters.indexOf(componentFilter);
141
- if (index >= 0) {
142
- cloned[index] = {
143
- ...componentFilter,
144
- value,
145
- };
146
- }
147
- }
148
- return cloned;
149
- });
150
- },
151
- [],
152
- );
153
-
154
- const updateFilterValueRegExp = useCallback(
155
- (componentFilter: ComponentFilter, value: string) => {
156
- if (componentFilter.type === ComponentFilterElementType) {
157
- throw Error('Invalid value for element type filter');
158
- }
159
-
160
- setComponentFilters(prevComponentFilters => {
161
- const cloned: Array<ComponentFilter> = [...prevComponentFilters];
162
- if (
163
- componentFilter.type === ComponentFilterDisplayName ||
164
- componentFilter.type === ComponentFilterLocation
165
- ) {
166
- const index = prevComponentFilters.indexOf(componentFilter);
167
- if (index >= 0) {
168
- let isValid = true;
169
- try {
170
- new RegExp(value); // eslint-disable-line no-new
171
- } catch (error) {
172
- isValid = false;
173
- }
174
- cloned[index] = {
175
- ...componentFilter,
176
- isValid,
177
- value,
178
- };
179
- }
180
- }
181
- return cloned;
182
- });
183
- },
184
- [],
185
- );
186
-
187
- const removeFilter = useCallback((index: number) => {
188
- setComponentFilters(prevComponentFilters => {
189
- const cloned: Array<ComponentFilter> = [...prevComponentFilters];
190
- cloned.splice(index, 1);
191
- return cloned;
192
- });
193
- }, []);
194
-
195
- const toggleFilterIsEnabled = useCallback(
196
- (componentFilter: ComponentFilter, isEnabled: boolean) => {
197
- setComponentFilters(prevComponentFilters => {
198
- const cloned: Array<ComponentFilter> = [...prevComponentFilters];
199
- const index = prevComponentFilters.indexOf(componentFilter);
200
- if (index >= 0) {
201
- if (componentFilter.type === ComponentFilterElementType) {
202
- cloned[index] = {
203
- ...((cloned[index]: any): ElementTypeComponentFilter),
204
- isEnabled,
205
- };
206
- } else if (
207
- componentFilter.type === ComponentFilterDisplayName ||
208
- componentFilter.type === ComponentFilterLocation
209
- ) {
210
- cloned[index] = {
211
- ...((cloned[index]: any): RegExpComponentFilter),
212
- isEnabled,
213
- };
214
- } else if (componentFilter.type === ComponentFilterHOC) {
215
- cloned[index] = {
216
- ...((cloned[index]: any): BooleanComponentFilter),
217
- isEnabled,
218
- };
219
- }
220
- }
221
- return cloned;
222
- });
223
- },
224
- [],
225
- );
226
-
227
- // Filter updates are expensive to apply (since they impact the entire tree).
228
- // Only apply them on unmount.
229
- // The Store will avoid doing any expensive work unless they've changed.
230
- // We just want to batch the work in the event that they do change.
231
- const componentFiltersRef = useRef<Array<ComponentFilter>>(componentFilters);
232
- useEffect(
233
- () => {
234
- componentFiltersRef.current = componentFilters;
235
- return () => {};
236
- },
237
- [componentFilters],
238
- );
239
- useEffect(
240
- () => () => {
241
- store.componentFilters = [...componentFiltersRef.current];
242
- },
243
- [store],
244
- );
245
-
246
- return (
247
- <div className={styles.Settings}>
248
- <label className={styles.Setting}>
249
- <input
250
- type="checkbox"
251
- checked={!collapseNodesByDefault}
252
- onChange={updateCollapseNodesByDefault}
253
- />{' '}
254
- Expand component tree by default
255
- </label>
256
-
257
- <div className={styles.Header}>Hide components where...</div>
258
-
259
- <table className={styles.Table}>
260
- <tbody>
261
- {componentFilters.length === 0 && (
262
- <tr className={styles.TableRow}>
263
- <td className={styles.NoFiltersCell}>
264
- No filters have been added.
265
- </td>
266
- </tr>
267
- )}
268
- {componentFilters.map((componentFilter, index) => (
269
- <tr className={styles.TableRow} key={index}>
270
- <td className={styles.TableCell}>
271
- <Toggle
272
- className={
273
- componentFilter.isValid !== false
274
- ? ''
275
- : styles.InvalidRegExp
276
- }
277
- isChecked={componentFilter.isEnabled}
278
- onChange={isEnabled =>
279
- toggleFilterIsEnabled(componentFilter, isEnabled)
280
- }
281
- title={
282
- componentFilter.isValid === false
283
- ? 'Filter invalid'
284
- : componentFilter.isEnabled
285
- ? 'Filter enabled'
286
- : 'Filter disabled'
287
- }>
288
- <ToggleIcon
289
- isEnabled={componentFilter.isEnabled}
290
- isValid={
291
- componentFilter.isValid == null ||
292
- componentFilter.isValid === true
293
- }
294
- />
295
- </Toggle>
296
- </td>
297
- <td className={styles.TableCell}>
298
- <select
299
- className={styles.Select}
300
- value={componentFilter.type}
301
- onChange={({currentTarget}) =>
302
- changeFilterType(
303
- componentFilter,
304
- ((parseInt(
305
- currentTarget.value,
306
- 10,
307
- ): any): ComponentFilterType),
308
- )
309
- }>
310
- <option value={ComponentFilterLocation}>location</option>
311
- <option value={ComponentFilterDisplayName}>name</option>
312
- <option value={ComponentFilterElementType}>type</option>
313
- <option value={ComponentFilterHOC}>hoc</option>
314
- </select>
315
- </td>
316
- <td className={styles.TableCell}>
317
- {componentFilter.type === ComponentFilterElementType &&
318
- 'equals'}
319
- {(componentFilter.type === ComponentFilterLocation ||
320
- componentFilter.type === ComponentFilterDisplayName) &&
321
- 'matches'}
322
- </td>
323
- <td className={styles.TableCell}>
324
- {componentFilter.type === ComponentFilterElementType && (
325
- <select
326
- className={styles.Select}
327
- value={componentFilter.value}
328
- onChange={({currentTarget}) =>
329
- updateFilterValueElementType(
330
- componentFilter,
331
- ((parseInt(currentTarget.value, 10): any): ElementType),
332
- )
333
- }>
334
- <option value={ElementTypeClass}>class</option>
335
- <option value={ElementTypeContext}>context</option>
336
- <option value={ElementTypeFunction}>function</option>
337
- <option value={ElementTypeForwardRef}>forward ref</option>
338
- <option value={ElementTypeHostComponent}>
339
- host (e.g. <div>)
340
- </option>
341
- <option value={ElementTypeMemo}>memo</option>
342
- <option value={ElementTypeOtherOrUnknown}>other</option>
343
- <option value={ElementTypeProfiler}>profiler</option>
344
- <option value={ElementTypeSuspense}>suspense</option>
345
- </select>
346
- )}
347
- {(componentFilter.type === ComponentFilterLocation ||
348
- componentFilter.type === ComponentFilterDisplayName) && (
349
- <input
350
- className={styles.Input}
351
- type="text"
352
- placeholder="Regular expression"
353
- onChange={({currentTarget}) =>
354
- updateFilterValueRegExp(
355
- componentFilter,
356
- currentTarget.value,
357
- )
358
- }
359
- value={componentFilter.value}
360
- />
361
- )}
362
- </td>
363
- <td className={styles.TableCell}>
364
- <Button
365
- onClick={() => removeFilter(index)}
366
- title="Delete filter">
367
- <ButtonIcon type="delete" />
368
- </Button>
369
- </td>
370
- </tr>
371
- ))}
372
- </tbody>
373
- </table>
374
-
375
- <Button onClick={addFilter}>
376
- <ButtonIcon className={styles.ButtonIcon} type="add" />
377
- Add filter
378
- </Button>
379
- </div>
380
- );
381
-}
382
-
383
-type ToggleIconProps = {|
384
- isEnabled: boolean,
385
- isValid: boolean,
386
-|};
387
-function ToggleIcon({isEnabled, isValid}: ToggleIconProps) {
388
- let className;
389
- if (isValid) {
390
- className = isEnabled ? styles.ToggleOn : styles.ToggleOff;
391
- } else {
392
- className = isEnabled ? styles.ToggleOnInvalid : styles.ToggleOffInvalid;
393
- }
394
- return (
395
- <div className={className}>
396
- <div
397
- className={isEnabled ? styles.ToggleInsideOn : styles.ToggleInsideOff}
398
- />
399
- </div>
400
- );
401
-}
packages/react-devtools-shared/src/devtools/views/Settings/GeneralSettings.js
deleted
-77
@@ -1,77 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useContext} from 'react';
11
-import {SettingsContext} from './SettingsContext';
12
-import {CHANGE_LOG_URL} from 'react-devtools-shared/src/constants';
13
-
14
-import styles from './SettingsShared.css';
15
-
16
-export default function GeneralSettings(_: {||}) {
17
- const {
18
- displayDensity,
19
- setDisplayDensity,
20
- theme,
21
- setTheme,
22
- appendComponentStack,
23
- setAppendComponentStack,
24
- } = useContext(SettingsContext);
25
-
26
- const updateDisplayDensity = ({currentTarget}) =>
27
- setDisplayDensity(currentTarget.value);
28
- const updateTheme = ({currentTarget}) => setTheme(currentTarget.value);
29
- const updateappendComponentStack = ({currentTarget}) =>
30
- setAppendComponentStack(currentTarget.checked);
31
-
32
- return (
33
- <div className={styles.Settings}>
34
- <div className={styles.Setting}>
35
- <div className={styles.RadioLabel}>Theme</div>
36
- <select className={styles.Select} value={theme} onChange={updateTheme}>
37
- <option value="auto">Auto</option>
38
- <option value="light">Light</option>
39
- <option value="dark">Dark</option>
40
- </select>
41
- </div>
42
-
43
- <div className={styles.Setting}>
44
- <div className={styles.RadioLabel}>Display density</div>
45
- <select
46
- className={styles.Select}
47
- value={displayDensity}
48
- onChange={updateDisplayDensity}>
49
- <option value="compact">Compact</option>
50
- <option value="comfortable">Comfortable</option>
51
- </select>
52
- </div>
53
-
54
- <div className={styles.Setting}>
55
- <label>
56
- <input
57
- type="checkbox"
58
- checked={appendComponentStack}
59
- onChange={updateappendComponentStack}
60
- />{' '}
61
- Append component stacks to console warnings and errors.
62
- </label>
63
- </div>
64
-
65
- <div className={styles.ReleaseNotes}>
66
- <a
67
- className={styles.ReleaseNotesLink}
68
- target="_blank"
69
- rel="noopener noreferrer"
70
- href={CHANGE_LOG_URL}>
71
- View release notes
72
- </a>{' '}
73
- for DevTools version {process.env.DEVTOOLS_VERSION}
74
- </div>
75
- </div>
76
- );
77
-}
packages/react-devtools-shared/src/devtools/views/Settings/ProfilerSettings.js
deleted
-103
@@ -1,103 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useContext, useMemo, useRef} from 'react';
11
-import {useSubscription} from '../hooks';
12
-import {StoreContext} from '../context';
13
-import {ProfilerContext} from 'react-devtools-shared/src/devtools/views/Profiler/ProfilerContext';
14
-
15
-import styles from './SettingsShared.css';
16
-
17
-export default function ProfilerSettings(_: {||}) {
18
- const {
19
- isCommitFilterEnabled,
20
- minCommitDuration,
21
- setIsCommitFilterEnabled,
22
- setMinCommitDuration,
23
- } = useContext(ProfilerContext);
24
- const store = useContext(StoreContext);
25
-
26
- const recordChangeDescriptionsSubscription = useMemo(
27
- () => ({
28
- getCurrentValue: () => store.recordChangeDescriptions,
29
- subscribe: (callback: Function) => {
30
- store.addListener('recordChangeDescriptions', callback);
31
- return () => store.removeListener('recordChangeDescriptions', callback);
32
- },
33
- }),
34
- [store],
35
- );
36
- const recordChangeDescriptions = useSubscription<boolean>(
37
- recordChangeDescriptionsSubscription,
38
- );
39
-
40
- const updateRecordChangeDescriptions = useCallback(
41
- ({currentTarget}) => {
42
- store.recordChangeDescriptions = currentTarget.checked;
43
- },
44
- [store],
45
- );
46
- const updateMinCommitDuration = useCallback(
47
- (event: SyntheticEvent<HTMLInputElement>) => {
48
- const newValue = parseFloat(event.currentTarget.value);
49
- setMinCommitDuration(
50
- Number.isNaN(newValue) || newValue <= 0 ? 0 : newValue,
51
- );
52
- },
53
- [setMinCommitDuration],
54
- );
55
- const updateIsCommitFilterEnabled = useCallback(
56
- (event: SyntheticEvent<HTMLInputElement>) => {
57
- const checked = event.currentTarget.checked;
58
- setIsCommitFilterEnabled(checked);
59
- if (checked) {
60
- if (minCommitDurationInputRef.current !== null) {
61
- minCommitDurationInputRef.current.focus();
62
- }
63
- }
64
- },
65
- [setIsCommitFilterEnabled],
66
- );
67
-
68
- const minCommitDurationInputRef = useRef<HTMLInputElement | null>(null);
69
-
70
- return (
71
- <div className={styles.Settings}>
72
- <div className={styles.Setting}>
73
- <label>
74
- <input
75
- type="checkbox"
76
- checked={recordChangeDescriptions}
77
- onChange={updateRecordChangeDescriptions}
78
- />{' '}
79
- Record why each component rendered while profiling.
80
- </label>
81
- </div>
82
-
83
- <div className={styles.Setting}>
84
- <label>
85
- <input
86
- checked={isCommitFilterEnabled}
87
- onChange={updateIsCommitFilterEnabled}
88
- type="checkbox"
89
- />{' '}
90
- Hide commits below
91
- </label>{' '}
92
- <input
93
- className={styles.Input}
94
- onChange={updateMinCommitDuration}
95
- ref={minCommitDurationInputRef}
96
- type="number"
97
- value={minCommitDuration}
98
- />{' '}
99
- (ms)
100
- </div>
101
- </div>
102
- );
103
-}
packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js
deleted
-345
@@ -1,345 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- createContext,
12
- useContext,
13
- useEffect,
14
- useLayoutEffect,
15
- useMemo,
16
-} from 'react';
17
-import {
18
- COMFORTABLE_LINE_HEIGHT,
19
- COMPACT_LINE_HEIGHT,
20
- LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY,
21
-} from 'react-devtools-shared/src/constants';
22
-import {useLocalStorage} from '../hooks';
23
-import {BridgeContext} from '../context';
24
-
25
-import type {BrowserTheme} from '../DevTools';
26
-
27
-export type DisplayDensity = 'comfortable' | 'compact';
28
-export type Theme = 'auto' | 'light' | 'dark';
29
-
30
-type Context = {|
31
- displayDensity: DisplayDensity,
32
- setDisplayDensity(value: DisplayDensity): void,
33
-
34
- // Derived from display density.
35
- // Specified as a separate prop so it can trigger a re-render of FixedSizeList.
36
- lineHeight: number,
37
-
38
- appendComponentStack: boolean,
39
- setAppendComponentStack: (value: boolean) => void,
40
-
41
- theme: Theme,
42
- setTheme(value: Theme): void,
43
-|};
44
-
45
-const SettingsContext = createContext<Context>(((null: any): Context));
46
-SettingsContext.displayName = 'SettingsContext';
47
-
48
-type DocumentElements = Array<HTMLElement>;
49
-
50
-type Props = {|
51
- browserTheme: BrowserTheme,
52
- children: React$Node,
53
- componentsPortalContainer?: Element,
54
- profilerPortalContainer?: Element,
55
-|};
56
-
57
-function SettingsContextController({
58
- browserTheme,
59
- children,
60
- componentsPortalContainer,
61
- profilerPortalContainer,
62
-}: Props) {
63
- const bridge = useContext(BridgeContext);
64
-
65
- const [displayDensity, setDisplayDensity] = useLocalStorage<DisplayDensity>(
66
- 'React::DevTools::displayDensity',
67
- 'compact',
68
- );
69
- const [theme, setTheme] = useLocalStorage<Theme>(
70
- 'React::DevTools::theme',
71
- 'auto',
72
- );
73
- const [appendComponentStack, setAppendComponentStack] = useLocalStorage<
74
- boolean,
75
- >(LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY, true);
76
-
77
- const documentElements = useMemo<DocumentElements>(
78
- () => {
79
- const array: Array<HTMLElement> = [
80
- ((document.documentElement: any): HTMLElement),
81
- ];
82
- if (componentsPortalContainer != null) {
83
- array.push(
84
- ((componentsPortalContainer.ownerDocument
85
- .documentElement: any): HTMLElement),
86
- );
87
- }
88
- if (profilerPortalContainer != null) {
89
- array.push(
90
- ((profilerPortalContainer.ownerDocument
91
- .documentElement: any): HTMLElement),
92
- );
93
- }
94
- return array;
95
- },
96
- [componentsPortalContainer, profilerPortalContainer],
97
- );
98
-
99
- useLayoutEffect(
100
- () => {
101
- switch (displayDensity) {
102
- case 'comfortable':
103
- updateDisplayDensity('comfortable', documentElements);
104
- break;
105
- case 'compact':
106
- updateDisplayDensity('compact', documentElements);
107
- break;
108
- default:
109
- throw Error(`Unsupported displayDensity value "${displayDensity}"`);
110
- }
111
- },
112
- [displayDensity, documentElements],
113
- );
114
-
115
- useLayoutEffect(
116
- () => {
117
- switch (theme) {
118
- case 'light':
119
- updateThemeVariables('light', documentElements);
120
- break;
121
- case 'dark':
122
- updateThemeVariables('dark', documentElements);
123
- break;
124
- case 'auto':
125
- updateThemeVariables(browserTheme, documentElements);
126
- break;
127
- default:
128
- throw Error(`Unsupported theme value "${theme}"`);
129
- }
130
- },
131
- [browserTheme, theme, documentElements],
132
- );
133
-
134
- useEffect(
135
- () => {
136
- bridge.send('updateAppendComponentStack', appendComponentStack);
137
- },
138
- [bridge, appendComponentStack],
139
- );
140
-
141
- const value = useMemo(
142
- () => ({
143
- displayDensity,
144
- setDisplayDensity,
145
- theme,
146
- setTheme,
147
- appendComponentStack,
148
- setAppendComponentStack,
149
- lineHeight:
150
- displayDensity === 'compact'
151
- ? COMPACT_LINE_HEIGHT
152
- : COMFORTABLE_LINE_HEIGHT,
153
- }),
154
- [
155
- displayDensity,
156
- setDisplayDensity,
157
- setTheme,
158
- appendComponentStack,
159
- setAppendComponentStack,
160
- theme,
161
- ],
162
- );
163
-
164
- return (
165
- <SettingsContext.Provider value={value}>
166
- {children}
167
- </SettingsContext.Provider>
168
- );
169
-}
170
-
171
-function setStyleVariable(
172
- name: string,
173
- value: string,
174
- documentElements: DocumentElements,
175
-) {
176
- documentElements.forEach(documentElement =>
177
- documentElement.style.setProperty(name, value),
178
- );
179
-}
180
-
181
-function updateStyleHelper(
182
- themeKey: string,
183
- style: string,
184
- documentElements: DocumentElements,
185
-) {
186
- setStyleVariable(
187
- `--${style}`,
188
- `var(--${themeKey}-${style})`,
189
- documentElements,
190
- );
191
-}
192
-
193
-function updateDisplayDensity(
194
- displayDensity: DisplayDensity,
195
- documentElements: DocumentElements,
196
-): void {
197
- updateStyleHelper(
198
- displayDensity,
199
- 'font-size-monospace-normal',
200
- documentElements,
201
- );
202
- updateStyleHelper(
203
- displayDensity,
204
- 'font-size-monospace-large',
205
- documentElements,
206
- );
207
- updateStyleHelper(
208
- displayDensity,
209
- 'font-size-monospace-small',
210
- documentElements,
211
- );
212
- updateStyleHelper(displayDensity, 'font-size-sans-normal', documentElements);
213
- updateStyleHelper(displayDensity, 'font-size-sans-large', documentElements);
214
- updateStyleHelper(displayDensity, 'font-size-sans-small', documentElements);
215
- updateStyleHelper(displayDensity, 'line-height-data', documentElements);
216
-
217
- // Sizes and paddings/margins are all rem-based,
218
- // so update the root font-size as well when the display preference changes.
219
- const computedStyle = getComputedStyle((document.body: any));
220
- const fontSize = computedStyle.getPropertyValue(
221
- `--${displayDensity}-root-font-size`,
222
- );
223
- const root = ((document.querySelector(':root'): any): HTMLElement);
224
- root.style.fontSize = fontSize;
225
-}
226
-
227
-function updateThemeVariables(
228
- theme: Theme,
229
- documentElements: DocumentElements,
230
-): void {
231
- updateStyleHelper(theme, 'color-attribute-name', documentElements);
232
- updateStyleHelper(theme, 'color-attribute-name-inverted', documentElements);
233
- updateStyleHelper(theme, 'color-attribute-value', documentElements);
234
- updateStyleHelper(theme, 'color-attribute-value-inverted', documentElements);
235
- updateStyleHelper(theme, 'color-attribute-editable-value', documentElements);
236
- updateStyleHelper(theme, 'color-background', documentElements);
237
- updateStyleHelper(theme, 'color-background-hover', documentElements);
238
- updateStyleHelper(theme, 'color-background-inactive', documentElements);
239
- updateStyleHelper(theme, 'color-background-invalid', documentElements);
240
- updateStyleHelper(theme, 'color-background-selected', documentElements);
241
- updateStyleHelper(theme, 'color-border', documentElements);
242
- updateStyleHelper(theme, 'color-button-background', documentElements);
243
- updateStyleHelper(theme, 'color-button-background-focus', documentElements);
244
- updateStyleHelper(theme, 'color-button', documentElements);
245
- updateStyleHelper(theme, 'color-button-active', documentElements);
246
- updateStyleHelper(theme, 'color-button-disabled', documentElements);
247
- updateStyleHelper(theme, 'color-button-focus', documentElements);
248
- updateStyleHelper(theme, 'color-button-hover', documentElements);
249
- updateStyleHelper(
250
- theme,
251
- 'color-commit-did-not-render-fill',
252
- documentElements,
253
- );
254
- updateStyleHelper(
255
- theme,
256
- 'color-commit-did-not-render-fill-text',
257
- documentElements,
258
- );
259
- updateStyleHelper(
260
- theme,
261
- 'color-commit-did-not-render-pattern',
262
- documentElements,
263
- );
264
- updateStyleHelper(
265
- theme,
266
- 'color-commit-did-not-render-pattern-text',
267
- documentElements,
268
- );
269
- updateStyleHelper(theme, 'color-commit-gradient-0', documentElements);
270
- updateStyleHelper(theme, 'color-commit-gradient-1', documentElements);
271
- updateStyleHelper(theme, 'color-commit-gradient-2', documentElements);
272
- updateStyleHelper(theme, 'color-commit-gradient-3', documentElements);
273
- updateStyleHelper(theme, 'color-commit-gradient-4', documentElements);
274
- updateStyleHelper(theme, 'color-commit-gradient-5', documentElements);
275
- updateStyleHelper(theme, 'color-commit-gradient-6', documentElements);
276
- updateStyleHelper(theme, 'color-commit-gradient-7', documentElements);
277
- updateStyleHelper(theme, 'color-commit-gradient-8', documentElements);
278
- updateStyleHelper(theme, 'color-commit-gradient-9', documentElements);
279
- updateStyleHelper(theme, 'color-commit-gradient-text', documentElements);
280
- updateStyleHelper(theme, 'color-component-name', documentElements);
281
- updateStyleHelper(theme, 'color-component-name-inverted', documentElements);
282
- updateStyleHelper(
283
- theme,
284
- 'color-component-badge-background',
285
- documentElements,
286
- );
287
- updateStyleHelper(
288
- theme,
289
- 'color-component-badge-background-inverted',
290
- documentElements,
291
- );
292
- updateStyleHelper(theme, 'color-component-badge-count', documentElements);
293
- updateStyleHelper(
294
- theme,
295
- 'color-component-badge-count-inverted',
296
- documentElements,
297
- );
298
- updateStyleHelper(theme, 'color-dim', documentElements);
299
- updateStyleHelper(theme, 'color-dimmer', documentElements);
300
- updateStyleHelper(theme, 'color-dimmest', documentElements);
301
- updateStyleHelper(theme, 'color-expand-collapse-toggle', documentElements);
302
- updateStyleHelper(theme, 'color-modal-background', documentElements);
303
- updateStyleHelper(theme, 'color-record-active', documentElements);
304
- updateStyleHelper(theme, 'color-record-hover', documentElements);
305
- updateStyleHelper(theme, 'color-record-inactive', documentElements);
306
- updateStyleHelper(theme, 'color-color-scroll-thumb', documentElements);
307
- updateStyleHelper(theme, 'color-color-scroll-track', documentElements);
308
- updateStyleHelper(theme, 'color-search-match', documentElements);
309
- updateStyleHelper(theme, 'color-shadow', documentElements);
310
- updateStyleHelper(theme, 'color-search-match-current', documentElements);
311
- updateStyleHelper(
312
- theme,
313
- 'color-selected-tree-highlight-active',
314
- documentElements,
315
- );
316
- updateStyleHelper(
317
- theme,
318
- 'color-selected-tree-highlight-inactive',
319
- documentElements,
320
- );
321
- updateStyleHelper(theme, 'color-tab-selected-border', documentElements);
322
- updateStyleHelper(theme, 'color-text', documentElements);
323
- updateStyleHelper(theme, 'color-text-invalid', documentElements);
324
- updateStyleHelper(theme, 'color-text-selected', documentElements);
325
- updateStyleHelper(theme, 'color-toggle-background-invalid', documentElements);
326
- updateStyleHelper(theme, 'color-toggle-background-on', documentElements);
327
- updateStyleHelper(theme, 'color-toggle-background-off', documentElements);
328
- updateStyleHelper(theme, 'color-toggle-text', documentElements);
329
- updateStyleHelper(theme, 'color-tooltip-background', documentElements);
330
- updateStyleHelper(theme, 'color-tooltip-text', documentElements);
331
-
332
- // Font smoothing varies based on the theme.
333
- updateStyleHelper(theme, 'font-smoothing', documentElements);
334
-
335
- // Update scrollbar color to match theme.
336
- // this CSS property is currently only supported in Firefox,
337
- // but it makes a significant UI improvement in dark mode.
338
- // https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-color
339
- documentElements.forEach(documentElement => {
340
- // $FlowFixMe scrollbarColor is missing in CSSStyleDeclaration
341
- documentElement.style.scrollbarColor = `var(${`--${theme}-color-scroll-thumb`}) var(${`--${theme}-color-scroll-track`})`;
342
- });
343
-}
344
-
345
-export {SettingsContext, SettingsContextController};
packages/react-devtools-shared/src/devtools/views/Settings/SettingsModal.css
deleted
-45
@@ -1,45 +0,0 @@
1
-.Background {
2
- position: absolute;
3
- z-index: 3;
4
- width: 100%;
5
- top: 0;
6
- bottom: 0;
7
- background-color: var(--color-modal-background);
8
- display: flex;
9
- align-items: flex-start;
10
- justify-content: center;
11
- font-size: var(--font-size-sans-normal);
12
- padding: 1rem;
13
-}
14
-
15
-.Modal {
16
- display: flex;
17
- flex-direction: column;
18
- flex: 0 1 auto;
19
- max-height: 100%;
20
- background-color: var(--color-background);
21
- border: 1px solid var(--color-border);
22
- box-shadow: 0 2px 4px var(--color-shadow);
23
- border-radius: 0.25rem;
24
- overflow: auto;
25
- width: 400px;
26
- max-width: 100%;
27
-}
28
-
29
-.Spacer {
30
- flex: 1;
31
-}
32
-
33
-.Tabs {
34
- display: flex;
35
- flex-direction: row;
36
- border-bottom: 1px solid var(--color-border);
37
- padding-right: 0.25rem;
38
- flex: 0 0 auto;
39
-}
40
-
41
-.Content {
42
- padding: 0.5rem;
43
- flex: 0 1 auto;
44
- overflow: auto;
45
-}
packages/react-devtools-shared/src/devtools/views/Settings/SettingsModal.js
deleted
-140
@@ -1,140 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- useCallback,
12
- useContext,
13
- useEffect,
14
- useMemo,
15
- useRef,
16
-} from 'react';
17
-import {SettingsModalContext} from './SettingsModalContext';
18
-import Button from '../Button';
19
-import ButtonIcon from '../ButtonIcon';
20
-import TabBar from '../TabBar';
21
-import {StoreContext} from '../context';
22
-import {
23
- useLocalStorage,
24
- useModalDismissSignal,
25
- useSubscription,
26
-} from '../hooks';
27
-import ComponentsSettings from './ComponentsSettings';
28
-import GeneralSettings from './GeneralSettings';
29
-import ProfilerSettings from './ProfilerSettings';
30
-
31
-import styles from './SettingsModal.css';
32
-
33
-type TabID = 'general' | 'components' | 'profiler';
34
-
35
-export default function SettingsModal(_: {||}) {
36
- const {isModalShowing, setIsModalShowing} = useContext(SettingsModalContext);
37
- const store = useContext(StoreContext);
38
- const {profilerStore} = store;
39
-
40
- // Updating preferences while profiling is in progress could break things (e.g. filtering)
41
- // Explicitly disallow it for now.
42
- const isProfilingSubscription = useMemo(
43
- () => ({
44
- getCurrentValue: () => profilerStore.isProfiling,
45
- subscribe: (callback: Function) => {
46
- profilerStore.addListener('isProfiling', callback);
47
- return () => profilerStore.removeListener('isProfiling', callback);
48
- },
49
- }),
50
- [profilerStore],
51
- );
52
- const isProfiling = useSubscription<boolean>(isProfilingSubscription);
53
- if (isProfiling && isModalShowing) {
54
- setIsModalShowing(false);
55
- }
56
-
57
- if (!isModalShowing) {
58
- return null;
59
- }
60
-
61
- return <SettingsModalImpl />;
62
-}
63
-
64
-function SettingsModalImpl(_: {||}) {
65
- const {setIsModalShowing} = useContext(SettingsModalContext);
66
- const dismissModal = useCallback(() => setIsModalShowing(false), [
67
- setIsModalShowing,
68
- ]);
69
-
70
- const [selectedTabID, selectTab] = useLocalStorage<TabID>(
71
- 'React::DevTools::selectedSettingsTabID',
72
- 'general',
73
- );
74
-
75
- const modalRef = useRef<HTMLDivElement | null>(null);
76
- useModalDismissSignal(modalRef, dismissModal);
77
-
78
- useEffect(
79
- () => {
80
- if (modalRef.current !== null) {
81
- modalRef.current.focus();
82
- }
83
- },
84
- [modalRef],
85
- );
86
-
87
- let view = null;
88
- switch (selectedTabID) {
89
- case 'general':
90
- view = <GeneralSettings />;
91
- break;
92
- case 'profiler':
93
- view = <ProfilerSettings />;
94
- break;
95
- case 'components':
96
- view = <ComponentsSettings />;
97
- break;
98
- default:
99
- break;
100
- }
101
-
102
- return (
103
- <div className={styles.Background}>
104
- <div className={styles.Modal} ref={modalRef}>
105
- <div className={styles.Tabs}>
106
- <TabBar
107
- currentTab={selectedTabID}
108
- id="Settings"
109
- selectTab={selectTab}
110
- tabs={tabs}
111
- type="settings"
112
- />
113
- <div className={styles.Spacer} />
114
- <Button onClick={dismissModal} title="Close settings dialog">
115
- <ButtonIcon type="close" />
116
- </Button>
117
- </div>
118
- <div className={styles.Content}>{view}</div>
119
- </div>
120
- </div>
121
- );
122
-}
123
-
124
-const tabs = [
125
- {
126
- id: 'general',
127
- icon: 'settings',
128
- label: 'General',
129
- },
130
- {
131
- id: 'components',
132
- icon: 'components',
133
- label: 'Components',
134
- },
135
- {
136
- id: 'profiler',
137
- icon: 'profiler',
138
- label: 'Profiler',
139
- },
140
-];
packages/react-devtools-shared/src/devtools/views/Settings/SettingsModalContext.js
deleted
-38
@@ -1,38 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {createContext, useMemo, useState} from 'react';
11
-
12
-export type DisplayDensity = 'comfortable' | 'compact';
13
-export type Theme = 'auto' | 'light' | 'dark';
14
-
15
-type Context = {
16
- isModalShowing: boolean,
17
- setIsModalShowing: (value: boolean) => void,
18
-};
19
-
20
-const SettingsModalContext = createContext<Context>(((null: any): Context));
21
-SettingsModalContext.displayName = 'SettingsModalContext';
22
-
23
-function SettingsModalContextController({children}: {|children: React$Node|}) {
24
- const [isModalShowing, setIsModalShowing] = useState<boolean>(false);
25
-
26
- const value = useMemo(() => ({isModalShowing, setIsModalShowing}), [
27
- isModalShowing,
28
- setIsModalShowing,
29
- ]);
30
-
31
- return (
32
- <SettingsModalContext.Provider value={value}>
33
- {children}
34
- </SettingsModalContext.Provider>
35
- );
36
-}
37
-
38
-export {SettingsModalContext, SettingsModalContextController};
packages/react-devtools-shared/src/devtools/views/Settings/SettingsModalContextToggle.js
deleted
-48
@@ -1,48 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback, useContext, useMemo} from 'react';
11
-import {SettingsModalContext} from './SettingsModalContext';
12
-import Button from '../Button';
13
-import ButtonIcon from '../ButtonIcon';
14
-import {StoreContext} from '../context';
15
-import {useSubscription} from '../hooks';
16
-
17
-export default function SettingsModalContextToggle() {
18
- const {setIsModalShowing} = useContext(SettingsModalContext);
19
- const store = useContext(StoreContext);
20
- const {profilerStore} = store;
21
-
22
- const showFilterModal = useCallback(() => setIsModalShowing(true), [
23
- setIsModalShowing,
24
- ]);
25
-
26
- // Updating preferences while profiling is in progress could break things (e.g. filtering)
27
- // Explicitly disallow it for now.
28
- const isProfilingSubscription = useMemo(
29
- () => ({
30
- getCurrentValue: () => profilerStore.isProfiling,
31
- subscribe: (callback: Function) => {
32
- profilerStore.addListener('isProfiling', callback);
33
- return () => profilerStore.removeListener('isProfiling', callback);
34
- },
35
- }),
36
- [profilerStore],
37
- );
38
- const isProfiling = useSubscription<boolean>(isProfilingSubscription);
39
-
40
- return (
41
- <Button
42
- disabled={isProfiling}
43
- onClick={showFilterModal}
44
- title="View settings">
45
- <ButtonIcon type="settings" />
46
- </Button>
47
- );
48
-}
packages/react-devtools-shared/src/devtools/views/Settings/SettingsShared.css
deleted
-140
@@ -1,140 +0,0 @@
1
-.Settings {
2
- display: flex;
3
- flex-direction: column;
4
- align-items: flex-start;
5
- justify-content: flex-start;
6
- font-family: var(--font-family-sans);
7
- font-size: var(--font-size-sans-normal);
8
-}
9
-
10
-.Setting {
11
- margin-bottom: 0.5rem;
12
-}
13
-.Setting:last-of-type {
14
- margin-bottom: 0;
15
-}
16
-
17
-.OptionGroup {
18
- display: inline-flex;
19
- flex-direction: row;
20
- align-items: center;
21
- user-select: none;
22
- margin: 0 1rem 0.5rem 0;
23
-}
24
-.OptionGroup:last-of-type {
25
- margin-right: 0;
26
-}
27
-
28
-.RadioLabel {
29
- display: inline;
30
- margin-right: 0.5rem;
31
-}
32
-
33
-.Select {
34
-}
35
-
36
-.CheckboxOption {
37
- display: block;
38
- padding: 0 0 0.5rem;
39
-}
40
-
41
-.HRule {
42
- height: 1px;
43
- background-color: var(--color-border);
44
- width: 100%;
45
- border: none;
46
- margin: 0.5rem 0;
47
-}
48
-
49
-.Header {
50
- font-size: var(--font-size-sans-large);
51
- margin-top: 0.5rem;
52
-}
53
-
54
-.ButtonIcon {
55
- margin-right: 0.25rem;
56
-}
57
-
58
-.NoFiltersCell {
59
- padding: 0.25rem 0;
60
- color: var(--color-dim);
61
-}
62
-
63
-.Table {
64
- min-width: 20rem;
65
- margin-top: 0.5rem;
66
- border-spacing: 0;
67
-}
68
-
69
-.TableRow {
70
- padding-bottom: 0.5rem;
71
-}
72
-
73
-.TableCell {
74
- padding: 0;
75
- padding-right: 0.5rem;
76
-}
77
-.TableCell:last-of-type {
78
- text-align: right;
79
- padding-right: 0;
80
-}
81
-
82
-.Input {
83
- border: 1px solid var(--color-border);
84
- border-radius: 0.125rem;
85
- padding: 0.125rem;
86
-}
87
-
88
-.InvalidRegExp,
89
-.InvalidRegExp:active,
90
-.InvalidRegExp:focus,
91
-.InvalidRegExp:hover {
92
- color: var(--color-value-invalid);
93
-}
94
-
95
-.ToggleOffInvalid,
96
-.ToggleOnInvalid,
97
-.ToggleOff,
98
-.ToggleOn {
99
- border-radius: 0.75rem;
100
- width: 1rem;
101
- height: 0.625rem;
102
- display: flex;
103
- align-items: center;
104
- padding: 0.125rem;
105
-}
106
-.ToggleOffInvalid {
107
- background-color: var(--color-toggle-background-invalid);
108
- justify-content: flex-start;
109
-}
110
-.ToggleOnInvalid {
111
- background-color: var(--color-toggle-background-invalid);
112
- justify-content: flex-end;
113
-}
114
-.ToggleOff {
115
- background-color: var(--color-toggle-background-off);
116
- justify-content: flex-start;
117
-}
118
-.ToggleOn {
119
- background-color: var(--color-toggle-background-on);
120
- justify-content: flex-end;
121
-}
122
-
123
-.ToggleInsideOff,
124
-.ToggleInsideOn {
125
- border-radius: 0.375rem;
126
- width: 0.375rem;
127
- height: 0.375rem;
128
- background-color: var(--color-toggle-text);
129
-}
130
-
131
-.ReleaseNotes {
132
- width: 100%;
133
- background-color: var(--color-background-hover);
134
- padding: 0.25rem 0.5rem;
135
- border-radius: 0.25rem;
136
-}
137
-
138
-.ReleaseNotesLink {
139
- color: var(--color-button-active);
140
-}
packages/react-devtools-shared/src/devtools/views/ShowWelcomeToTheNewDevToolsDialog.css
deleted
-26
@@ -1,26 +0,0 @@
1
-.Row {
2
- display: flex;
3
- flex-direction: row;
4
- align-items: center;
5
-}
6
-
7
-.Column {
8
- display: flex;
9
- flex-direction: column;
10
- align-items: center;
11
-}
12
-
13
-.Logo {
14
- height: 4rem;
15
- width: 4rem;
16
- margin: 1rem;
17
-}
18
-
19
-.Title {
20
- font-size: var(--font-size-sans-large);
21
- margin-bottom: 0.5rem;
22
-}
23
-
24
-.ReleaseNotesLink {
25
- color: var(--color-button-active);
26
-}
packages/react-devtools-shared/src/devtools/views/ShowWelcomeToTheNewDevToolsDialog.js
deleted
-73
@@ -1,73 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useContext, useEffect} from 'react';
11
-import {unstable_batchedUpdates as batchedUpdates} from 'react-dom';
12
-import {useLocalStorage} from './hooks';
13
-import {ModalDialogContext} from './ModalDialog';
14
-import ReactLogo from './ReactLogo';
15
-import {CHANGE_LOG_URL} from 'react-devtools-shared/src/constants';
16
-
17
-import styles from './ShowWelcomeToTheNewDevToolsDialog.css';
18
-
19
-const LOCAL_STORAGE_KEY =
20
- 'React::DevTools::hasShownWelcomeToTheNewDevToolsDialog';
21
-
22
-export default function ShowWelcomeToTheNewDevToolsDialog(_: {||}) {
23
- const {dispatch} = useContext(ModalDialogContext);
24
- const [
25
- hasShownWelcomeToTheNewDevToolsDialog,
26
- setHasShownWelcomeToTheNewDevToolsDialog,
27
- ] = useLocalStorage<boolean>(LOCAL_STORAGE_KEY, false);
28
-
29
- useEffect(
30
- () => {
31
- if (!hasShownWelcomeToTheNewDevToolsDialog) {
32
- batchedUpdates(() => {
33
- setHasShownWelcomeToTheNewDevToolsDialog(true);
34
- dispatch({
35
- canBeDismissed: true,
36
- type: 'SHOW',
37
- content: <DialogContent />,
38
- });
39
- });
40
- }
41
- },
42
- [
43
- dispatch,
44
- hasShownWelcomeToTheNewDevToolsDialog,
45
- setHasShownWelcomeToTheNewDevToolsDialog,
46
- ],
47
- );
48
-
49
- return null;
50
-}
51
-
52
-function DialogContent(_: {||}) {
53
- return (
54
- <Fragment>
55
- <div className={styles.Row}>
56
- <ReactLogo className={styles.Logo} />
57
- <div>
58
- <div className={styles.Title}>Welcome to the new React DevTools!</div>
59
- <div>
60
- <a
61
- className={styles.ReleaseNotesLink}
62
- target="_blank"
63
- rel="noopener noreferrer"
64
- href={CHANGE_LOG_URL}>
65
- Learn more
66
- </a>{' '}
67
- about changes in this version.
68
- </div>
69
- </div>
70
- </div>
71
- </Fragment>
72
- );
73
-}
packages/react-devtools-shared/src/devtools/views/TabBar.css
deleted
-110
@@ -1,110 +0,0 @@
1
-.Tab,
2
-.TabCurrent,
3
-.TabDisabled {
4
- height: 100%;
5
- display: flex;
6
- align-items: center;
7
- cursor: pointer;
8
- border-top: 3px solid transparent;
9
- border-bottom: 3px solid transparent;
10
- user-select: none;
11
- color: var(--color-text);
12
-
13
- /* Electron drag area */
14
- -webkit-app-region: no-drag;
15
-}
16
-.Tab:hover,
17
-.TabCurrent:hover {
18
- background-color: var(--color-background-hover);
19
-}
20
-.Tab:focus-within,
21
-.TabCurrent:focus-within {
22
- background-color: var(--color-background-hover);
23
-}
24
-
25
-.TabCurrent {
26
- border-bottom: 3px solid var(--color-tab-selected-border);
27
-}
28
-
29
-.TabDisabled {
30
- color: var(--color-dim);
31
- cursor: default;
32
-}
33
-
34
-.TabSizeNavigation {
35
- font-size: var(--font-size-sans-large);
36
- padding: 0.5rem 1rem;
37
-}
38
-.TabSizeProfiler {
39
- font-size: var(--font-size-sans-normal);
40
- padding: 0.25rem 0.5rem;
41
-}
42
-.TabSizeSettings {
43
- font-size: var(--font-size-sans-normal);
44
- padding: 0.25rem 0.5rem;
45
-}
46
-
47
-.Input {
48
- width: 0;
49
- margin: 0;
50
- opacity: 0;
51
-}
52
-
53
-.IconSizeNavigation,
54
-.IconSizeProfiler,
55
-.IconSizeSettings {
56
- margin-right: 0.5rem;
57
- color: var(--color-button-active);
58
-}
59
-
60
-.IconDisabled {
61
- color: var(--color-dim);
62
-}
63
-
64
-.IconSizeNavigation {
65
- width: 1.5rem;
66
- height: 1.5rem;
67
-}
68
-.IconSizeProfiler {
69
- width: 1rem;
70
- height: 1rem;
71
-}
72
-.IconSizeSettings {
73
- width: 1rem;
74
- height: 1rem;
75
-}
76
-
77
-.TabLabelNavigation,
78
-.TabLabelProfiler,
79
-.TabLabelSettings {
80
-}
81
-
82
-@media screen and (max-width: 525px) {
83
- .IconSizeNavigation {
84
- margin-right: 0;
85
- }
86
-
87
- .TabLabelNavigation {
88
- display: none;
89
- }
90
-}
91
-
92
-@media screen and (max-width: 900px) {
93
- .TabLabelProfiler {
94
- display: none;
95
- }
96
-
97
- .IconSizeProfiler {
98
- margin-right: 0;
99
- }
100
-}
101
-
102
-@media screen and (max-width: 400px) {
103
- .TabLabelSettings {
104
- display: none;
105
- }
106
-
107
- .IconSizeSettings {
108
- margin-right: 0;
109
- }
110
-}
packages/react-devtools-shared/src/devtools/views/TabBar.js
deleted
-132
@@ -1,132 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useCallback} from 'react';
11
-import Tooltip from '@reach/tooltip';
12
-import Icon from './Icon';
13
-
14
-import styles from './TabBar.css';
15
-import tooltipStyles from './Tooltip.css';
16
-
17
-import type {IconType} from './Icon';
18
-
19
-type TabInfo = {|
20
- icon: IconType,
21
- id: string,
22
- label: string,
23
- title?: string,
24
-|};
25
-
26
-export type Props = {|
27
- currentTab: any,
28
- disabled?: boolean,
29
- id: string,
30
- selectTab: (tabID: any) => void,
31
- tabs: Array<TabInfo>,
32
- type: 'navigation' | 'profiler' | 'settings',
33
-|};
34
-
35
-export default function TabBar({
36
- currentTab,
37
- disabled = false,
38
- id: groupName,
39
- selectTab,
40
- tabs,
41
- type,
42
-}: Props) {
43
- if (!tabs.some(tab => tab.id === currentTab)) {
44
- selectTab(tabs[0].id);
45
- }
46
-
47
- const onChange = useCallback(
48
- ({currentTarget}) => selectTab(currentTarget.value),
49
- [selectTab],
50
- );
51
-
52
- const handleKeyDown = useCallback(event => {
53
- switch (event.key) {
54
- case 'ArrowDown':
55
- case 'ArrowLeft':
56
- case 'ArrowRight':
57
- case 'ArrowUp':
58
- event.stopPropagation();
59
- break;
60
- default:
61
- break;
62
- }
63
- }, []);
64
-
65
- let iconSizeClassName;
66
- let tabLabelClassName;
67
- let tabSizeClassName;
68
- switch (type) {
69
- case 'navigation':
70
- iconSizeClassName = styles.IconSizeNavigation;
71
- tabLabelClassName = styles.TabLabelNavigation;
72
- tabSizeClassName = styles.TabSizeNavigation;
73
- break;
74
- case 'profiler':
75
- iconSizeClassName = styles.IconSizeProfiler;
76
- tabLabelClassName = styles.TabLabelProfiler;
77
- tabSizeClassName = styles.TabSizeProfiler;
78
- break;
79
- case 'settings':
80
- iconSizeClassName = styles.IconSizeSettings;
81
- tabLabelClassName = styles.TabLabelSettings;
82
- tabSizeClassName = styles.TabSizeSettings;
83
- break;
84
- default:
85
- throw Error(`Unsupported type "${type}"`);
86
- }
87
-
88
- return (
89
- <Fragment>
90
- {tabs.map(({icon, id, label, title}) => {
91
- let button = (
92
- <label
93
- className={[
94
- tabSizeClassName,
95
- disabled ? styles.TabDisabled : styles.Tab,
96
- !disabled && currentTab === id ? styles.TabCurrent : '',
97
- ].join(' ')}
98
- key={id}
99
- onKeyDown={handleKeyDown}
100
- onMouseDown={() => selectTab(id)}>
101
- <input
102
- type="radio"
103
- className={styles.Input}
104
- checked={currentTab === id}
105
- disabled={disabled}
106
- name={groupName}
107
- value={id}
108
- onChange={onChange}
109
- />
110
- <Icon
111
- className={`${
112
- disabled ? styles.IconDisabled : ''
113
- } ${iconSizeClassName}`}
114
- type={icon}
115
- />
116
- <span className={tabLabelClassName}>{label}</span>
117
- </label>
118
- );
119
-
120
- if (title) {
121
- button = (
122
- <Tooltip key={id} className={tooltipStyles.Tooltip} label={title}>
123
- {button}
124
- </Tooltip>
125
- );
126
- }
127
-
128
- return button;
129
- })}
130
- </Fragment>
131
- );
132
-}
packages/react-devtools-shared/src/devtools/views/Toggle.css
deleted
-54
@@ -1,54 +0,0 @@
1
-.ToggleDisabled,
2
-.ToggleOn,
3
-.ToggleOff {
4
- background: var(--color-button-background);
5
- border: none;
6
- border-radius: 0.25rem;
7
- padding: 0;
8
- flex: 0 0 auto;
9
-}
10
-
11
-.ToggleContent {
12
- display: inline-flex;
13
- align-items: center;
14
- border-radius: 0.25rem;
15
- padding: 0.25rem;
16
-}
17
-
18
-.ToggleOff {
19
- border: none;
20
- background: var(--color-button-background);
21
- color: var(--color-button);
22
-}
23
-.ToggleOff:hover {
24
- color: var(--color-button-hover);
25
-}
26
-
27
-.ToggleOn,
28
-.ToggleOn:active {
29
- color: var(--color-button-active);
30
- outline: none;
31
-}
32
-
33
-.ToggleOn:focus,
34
-.ToggleOff:focus,
35
-.ToggleContent:focus {
36
- outline: none;
37
-}
38
-
39
-.ToggleOn:focus > .ToggleContent,
40
-.ToggleOff:focus > .ToggleContent {
41
- background: var(--color-button-background-focus);
42
-}
43
-
44
-.ToggleDisabled {
45
- background: var(--color-button-background);
46
- color: var(--color-button-disabled);
47
- cursor: default;
48
-}
49
-
50
-.Input {
51
- width: 0;
52
- margin: 0;
53
- opacity: 0;
54
-}
packages/react-devtools-shared/src/devtools/views/Toggle.js
deleted
-67
@@ -1,67 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {useCallback} from 'react';
11
-import Tooltip from '@reach/tooltip';
12
-
13
-import styles from './Toggle.css';
14
-import tooltipStyles from './Tooltip.css';
15
-
16
-type Props = {
17
- children: React$Node,
18
- className?: string,
19
- isChecked: boolean,
20
- isDisabled?: boolean,
21
- onChange: (isChecked: boolean) => void,
22
- title?: string,
23
-};
24
-
25
-export default function Toggle({
26
- children,
27
- className = '',
28
- isDisabled = false,
29
- isChecked,
30
- onChange,
31
- title,
32
-}: Props) {
33
- let defaultClassName;
34
- if (isDisabled) {
35
- defaultClassName = styles.ToggleDisabled;
36
- } else if (isChecked) {
37
- defaultClassName = styles.ToggleOn;
38
- } else {
39
- defaultClassName = styles.ToggleOff;
40
- }
41
-
42
- const handleClick = useCallback(() => onChange(!isChecked), [
43
- isChecked,
44
- onChange,
45
- ]);
46
-
47
- let toggle = (
48
- <button
49
- className={`${defaultClassName} ${className}`}
50
- disabled={isDisabled}
51
- onClick={handleClick}>
52
- <span className={styles.ToggleContent} tabIndex={-1}>
53
- {children}
54
- </span>
55
- </button>
56
- );
57
-
58
- if (title) {
59
- toggle = (
60
- <Tooltip className={tooltipStyles.Tooltip} label={title}>
61
- {toggle}
62
- </Tooltip>
63
- );
64
- }
65
-
66
- return toggle;
67
-}
packages/react-devtools-shared/src/devtools/views/Tooltip.css
deleted
-11
@@ -1,11 +0,0 @@
1
-.Tooltip {
2
- border: none;
3
- border-radius: 0.25rem;
4
- padding: 0.25rem 0.5rem;
5
- font-size: 12px;
6
- background-color: var(--color-tooltip-background);
7
- color: var(--color-tooltip-text);
8
-
9
- /* Make sure this is above the DevTools, which are above the Overlay */
10
- z-index: 10000002;
11
-}
packages/react-devtools-shared/src/devtools/views/WarnIfLegacyBackendDetected.css
deleted
-6
@@ -1,6 +0,0 @@
1
-.Command {
2
- background-color: var(--color-dimmest);
3
- padding: 0.25rem 0.5rem;
4
- display: block;
5
- border-radius: 0.125rem;
6
-}
packages/react-devtools-shared/src/devtools/views/WarnIfLegacyBackendDetected.js
deleted
-86
@@ -1,86 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useContext, useEffect} from 'react';
11
-import {BridgeContext} from './context';
12
-import {ModalDialogContext} from './ModalDialog';
13
-
14
-import styles from './WarnIfLegacyBackendDetected.css';
15
-
16
-export default function WarnIfLegacyBackendDetected(_: {||}) {
17
- const bridge = useContext(BridgeContext);
18
- const {dispatch} = useContext(ModalDialogContext);
19
-
20
- // Detect pairing with legacy v3 backend.
21
- // We do this by listening to a message that it broadcasts but the v4 backend doesn't.
22
- // In this case the frontend should show upgrade instructions.
23
- useEffect(
24
- () => {
25
- // Wall.listen returns a cleanup function
26
- let unlisten = bridge.wall.listen(message => {
27
- switch (message.type) {
28
- case 'call':
29
- case 'event':
30
- case 'many-events':
31
- // Any of these types indicate the v3 backend.
32
- dispatch({
33
- canBeDismissed: false,
34
- type: 'SHOW',
35
- title: 'DevTools v4 is incompatible with this version of React',
36
- content: <InvalidBackendDetected />,
37
- });
38
-
39
- // Once we've identified the backend version, it's safe to unsubscribe.
40
- if (typeof unlisten === 'function') {
41
- unlisten();
42
- unlisten = null;
43
- }
44
- break;
45
- default:
46
- break;
47
- }
48
-
49
- switch (message.event) {
50
- case 'isBackendStorageAPISupported':
51
- case 'isNativeStyleEditorSupported':
52
- case 'operations':
53
- case 'overrideComponentFilters':
54
- // Any of these is sufficient to indicate a v4 backend.
55
- // Once we've identified the backend version, it's safe to unsubscribe.
56
- if (typeof unlisten === 'function') {
57
- unlisten();
58
- unlisten = null;
59
- }
60
- break;
61
- default:
62
- break;
63
- }
64
- });
65
-
66
- return () => {
67
- if (typeof unlisten === 'function') {
68
- unlisten();
69
- unlisten = null;
70
- }
71
- };
72
- },
73
- [bridge, dispatch],
74
- );
75
-
76
- return null;
77
-}
78
-
79
-function InvalidBackendDetected(_: {||}) {
80
- return (
81
- <Fragment>
82
- <p>Either upgrade React or install React DevTools v3:</p>
83
- <code className={styles.Command}>npm install -d react-devtools@^3</code>
84
- </Fragment>
85
- );
86
-}
packages/react-devtools-shared/src/devtools/views/context.js
deleted
-21
@@ -1,21 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {createContext} from 'react';
11
-import Store from '../store';
12
-
13
-import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
14
-
15
-export const BridgeContext = createContext<FrontendBridge>(
16
- ((null: any): FrontendBridge),
17
-);
18
-BridgeContext.displayName = 'BridgeContext';
19
-
20
-export const StoreContext = createContext<Store>(((null: any): Store));
21
-StoreContext.displayName = 'StoreContext';
packages/react-devtools-shared/src/devtools/views/hooks.js
deleted
-226
@@ -1,226 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import throttle from 'lodash.throttle';
11
-import {useCallback, useEffect, useLayoutEffect, useState} from 'react';
12
-import {
13
- localStorageGetItem,
14
- localStorageSetItem,
15
-} from 'react-devtools-shared/src/storage';
16
-
17
-export function useIsOverflowing(
18
- containerRef: {current: HTMLDivElement | null},
19
- totalChildWidth: number,
20
-): boolean {
21
- const [isOverflowing, setIsOverflowing] = useState<boolean>(false);
22
-
23
- // It's important to use a layout effect, so that we avoid showing a flash of overflowed content.
24
- useLayoutEffect(
25
- () => {
26
- if (containerRef.current === null) {
27
- return () => {};
28
- }
29
-
30
- const container = ((containerRef.current: any): HTMLDivElement);
31
-
32
- const handleResize = throttle(
33
- () => setIsOverflowing(container.clientWidth <= totalChildWidth),
34
- 100,
35
- );
36
-
37
- handleResize();
38
-
39
- // It's important to listen to the ownerDocument.defaultView to support the browser extension.
40
- // Here we use portals to render individual tabs (e.g. Profiler),
41
- // and the root document might belong to a different window.
42
- const ownerWindow = container.ownerDocument.defaultView;
43
- ownerWindow.addEventListener('resize', handleResize);
44
- return () => ownerWindow.removeEventListener('resize', handleResize);
45
- },
46
- [containerRef, totalChildWidth],
47
- );
48
-
49
- return isOverflowing;
50
-}
51
-
52
-// Forked from https://usehooks.com/useLocalStorage/
53
-export function useLocalStorage<T>(
54
- key: string,
55
- initialValue: T | (() => T),
56
-): [T, (value: T | (() => T)) => void] {
57
- const getValueFromLocalStorage = useCallback(
58
- () => {
59
- try {
60
- const item = localStorageGetItem(key);
61
- if (item != null) {
62
- return JSON.parse(item);
63
- }
64
- } catch (error) {
65
- console.log(error);
66
- }
67
- if (typeof initialValue === 'function') {
68
- return ((initialValue: any): () => T)();
69
- } else {
70
- return initialValue;
71
- }
72
- },
73
- [initialValue, key],
74
- );
75
-
76
- const [storedValue, setStoredValue] = useState(getValueFromLocalStorage);
77
-
78
- const setValue = useCallback(
79
- value => {
80
- try {
81
- const valueToStore =
82
- value instanceof Function ? (value: any)(storedValue) : value;
83
- setStoredValue(valueToStore);
84
- localStorageSetItem(key, JSON.stringify(valueToStore));
85
- } catch (error) {
86
- console.log(error);
87
- }
88
- },
89
- [key, storedValue],
90
- );
91
-
92
- // Listen for changes to this local storage value made from other windows.
93
- // This enables the e.g. "⚛️ Elements" tab to update in response to changes from "⚛️ Settings".
94
- useLayoutEffect(
95
- () => {
96
- const onStorage = event => {
97
- const newValue = getValueFromLocalStorage();
98
- if (key === event.key && storedValue !== newValue) {
99
- setValue(newValue);
100
- }
101
- };
102
-
103
- window.addEventListener('storage', onStorage);
104
-
105
- return () => {
106
- window.removeEventListener('storage', onStorage);
107
- };
108
- },
109
- [getValueFromLocalStorage, key, storedValue, setValue],
110
- );
111
-
112
- return [storedValue, setValue];
113
-}
114
-
115
-export function useModalDismissSignal(
116
- modalRef: {current: HTMLDivElement | null},
117
- dismissCallback: () => void,
118
- dismissOnClickOutside?: boolean = true,
119
-): void {
120
- useEffect(
121
- () => {
122
- if (modalRef.current === null) {
123
- return () => {};
124
- }
125
-
126
- const handleDocumentKeyDown = ({key}: any) => {
127
- if (key === 'Escape') {
128
- dismissCallback();
129
- }
130
- };
131
-
132
- const handleDocumentClick = (event: any) => {
133
- // $FlowFixMe
134
- if (
135
- modalRef.current !== null &&
136
- !modalRef.current.contains(event.target)
137
- ) {
138
- event.stopPropagation();
139
- event.preventDefault();
140
-
141
- dismissCallback();
142
- }
143
- };
144
-
145
- // It's important to listen to the ownerDocument to support the browser extension.
146
- // Here we use portals to render individual tabs (e.g. Profiler),
147
- // and the root document might belong to a different window.
148
- const ownerDocument = modalRef.current.ownerDocument;
149
- ownerDocument.addEventListener('keydown', handleDocumentKeyDown);
150
- if (dismissOnClickOutside) {
151
- ownerDocument.addEventListener('click', handleDocumentClick);
152
- }
153
-
154
- return () => {
155
- ownerDocument.removeEventListener('keydown', handleDocumentKeyDown);
156
- ownerDocument.removeEventListener('click', handleDocumentClick);
157
- };
158
- },
159
- [modalRef, dismissCallback, dismissOnClickOutside],
160
- );
161
-}
162
-
163
-// Copied from https://github.com/facebook/react/pull/15022
164
-export function useSubscription<Value>({
165
- getCurrentValue,
166
- subscribe,
167
-}: {|
168
- getCurrentValue: () => Value,
169
- subscribe: (callback: Function) => () => void,
170
-|}): Value {
171
- const [state, setState] = useState({
172
- getCurrentValue,
173
- subscribe,
174
- value: getCurrentValue(),
175
- });
176
-
177
- if (
178
- state.getCurrentValue !== getCurrentValue ||
179
- state.subscribe !== subscribe
180
- ) {
181
- setState({
182
- getCurrentValue,
183
- subscribe,
184
- value: getCurrentValue(),
185
- });
186
- }
187
-
188
- useEffect(
189
- () => {
190
- let didUnsubscribe = false;
191
-
192
- const checkForUpdates = () => {
193
- if (didUnsubscribe) {
194
- return;
195
- }
196
-
197
- setState(prevState => {
198
- if (
199
- prevState.getCurrentValue !== getCurrentValue ||
200
- prevState.subscribe !== subscribe
201
- ) {
202
- return prevState;
203
- }
204
-
205
- const value = getCurrentValue();
206
- if (prevState.value === value) {
207
- return prevState;
208
- }
209
-
210
- return {...prevState, value};
211
- });
212
- };
213
- const unsubscribe = subscribe(checkForUpdates);
214
-
215
- checkForUpdates();
216
-
217
- return () => {
218
- didUnsubscribe = true;
219
- unsubscribe();
220
- };
221
- },
222
- [getCurrentValue, subscribe],
223
- );
224
-
225
- return state.value;
226
-}
packages/react-devtools-shared/src/devtools/views/portaledContent.js
deleted
-32
@@ -1,32 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-import {createPortal} from 'react-dom';
12
-import ErrorBoundary from './ErrorBoundary';
13
-
14
-export type Props = {
15
- portalContainer?: Element,
16
-};
17
-
18
-export default function portaledContent(
19
- Component: React$StatelessFunctionalComponent<any>,
20
-): React$StatelessFunctionalComponent<any> {
21
- return function PortaledContent({portalContainer, ...rest}: Props) {
22
- const children = (
23
- <ErrorBoundary>
24
- <Component {...rest} />
25
- </ErrorBoundary>
26
- );
27
-
28
- return portalContainer != null
29
- ? createPortal(children, portalContainer)
30
- : children;
31
- };
32
-}
packages/react-devtools-shared/src/devtools/views/root.css
deleted
-178
@@ -1,178 +0,0 @@
1
-:root {
2
- /**
3
- * IMPORTANT: When new theme variables are added below– also add them to SettingsContext updateThemeVariables()
4
- */
5
-
6
- /* Light theme */
7
- --light-color-attribute-name: #ef6632;
8
- --light-color-attribute-name-inverted: rgba(255, 255, 255, 0.7);
9
- --light-color-attribute-value: #1a1aa6;
10
- --light-color-attribute-value-inverted: #ffffff;
11
- --light-color-attribute-editable-value: #1a1aa6;
12
- --light-color-background: #ffffff;
13
- --light-color-background-hover: rgba(0, 136, 250, 0.1);
14
- --light-color-background-inactive: #e5e5e5;
15
- --light-color-background-invalid: #fff0f0;
16
- --light-color-background-selected: #0088fa;
17
- --light-color-button-background: #ffffff;
18
- --light-color-button-background-focus: #ededed;
19
- --light-color-button: #5f6673;
20
- --light-color-button-disabled: #cfd1d5;
21
- --light-color-button-active: #0088fa;
22
- --light-color-button-focus: #23272f;
23
- --light-color-button-hover: #23272f;
24
- --light-color-border: #eeeeee;
25
- --light-color-commit-did-not-render-fill: #cfd1d5;
26
- --light-color-commit-did-not-render-fill-text: #000000;
27
- --light-color-commit-did-not-render-pattern: #cfd1d5;
28
- --light-color-commit-did-not-render-pattern-text: #333333;
29
- --light-color-commit-gradient-0: #37afa9;
30
- --light-color-commit-gradient-1: #63b19e;
31
- --light-color-commit-gradient-2: #80b393;
32
- --light-color-commit-gradient-3: #97b488;
33
- --light-color-commit-gradient-4: #abb67d;
34
- --light-color-commit-gradient-5: #beb771;
35
- --light-color-commit-gradient-6: #cfb965;
36
- --light-color-commit-gradient-7: #dfba57;
37
- --light-color-commit-gradient-8: #efbb49;
38
- --light-color-commit-gradient-9: #febc38;
39
- --light-color-commit-gradient-text: #000000;
40
- --light-color-component-name: #6a51b2;
41
- --light-color-component-name-inverted: #ffffff;
42
- --light-color-component-badge-background: rgba(0, 0, 0, 0.1);
43
- --light-color-component-badge-background-inverted: rgba(255, 255, 255, 0.25);
44
- --light-color-component-badge-count: #777d88;
45
- --light-color-component-badge-count-inverted: rgba(255, 255, 255, 0.7);
46
- --light-color-dim: #777d88;
47
- --light-color-dimmer: #cfd1d5;
48
- --light-color-dimmest: #eff0f1;
49
- --light-color-expand-collapse-toggle: #777d88;
50
- --light-color-modal-background: rgba(255, 255, 255, 0.75);
51
- --light-color-record-active: #fc3a4b;
52
- --light-color-record-hover: #3578e5;
53
- --light-color-record-inactive: #0088fa;
54
- --light-color-scroll-thumb: #c2c2c2;
55
- --light-color-scroll-track: #fafafa;
56
- --light-color-search-match: yellow;
57
- --light-color-search-match-current: #f7923b;
58
- --light-color-selected-tree-highlight-active: rgba(0, 136, 250, 0.1);
59
- --light-color-selected-tree-highlight-inactive: rgba(0, 0, 0, 0.05);
60
- --light-color-shadow: rgba(0, 0, 0, 0.25);
61
- --light-color-tab-selected-border: #0088fa;
62
- --light-color-text: #000000;
63
- --light-color-text-invalid: #ff0000;
64
- --light-color-text-selected: #ffffff;
65
- --light-color-toggle-background-invalid: #fc3a4b;
66
- --light-color-toggle-background-on: #0088fa;
67
- --light-color-toggle-background-off: #cfd1d5;
68
- --light-color-toggle-text: #ffffff;
69
- --light-color-tooltip-background: rgba(0, 0, 0, 0.9);
70
- --light-color-tooltip-text: #ffffff;
71
-
72
- /* Dark theme */
73
- --dark-color-attribute-name: #9d87d2;
74
- --dark-color-attribute-name-inverted: #282828;
75
- --dark-color-attribute-value: #cedae0;
76
- --dark-color-attribute-value-inverted: #ffffff;
77
- --dark-color-attribute-editable-value: yellow;
78
- --dark-color-background: #282c34;
79
- --dark-color-background-hover: rgba(255, 255, 255, 0.1);
80
- --dark-color-background-inactive: #3d424a;
81
- --dark-color-background-invalid: #5c0000;
82
- --dark-color-background-selected: #178fb9;
83
- --dark-color-button-background: #282c34;
84
- --dark-color-button-background-focus: #3d424a;
85
- --dark-color-button: #afb3b9;
86
- --dark-color-button-active: #61dafb;
87
- --dark-color-button-disabled: #4f5766;
88
- --dark-color-button-focus: #a2e9fc;
89
- --dark-color-button-hover: #ededed;
90
- --dark-color-border: #3d424a;
91
- --dark-color-commit-did-not-render-fill: #777d88;
92
- --dark-color-commit-did-not-render-fill-text: #000000;
93
- --dark-color-commit-did-not-render-pattern: #666c77;
94
- --dark-color-commit-did-not-render-pattern-text: #ffffff;
95
- --dark-color-commit-gradient-0: #37afa9;
96
- --dark-color-commit-gradient-1: #63b19e;
97
- --dark-color-commit-gradient-2: #80b393;
98
- --dark-color-commit-gradient-3: #97b488;
99
- --dark-color-commit-gradient-4: #abb67d;
100
- --dark-color-commit-gradient-5: #beb771;
101
- --dark-color-commit-gradient-6: #cfb965;
102
- --dark-color-commit-gradient-7: #dfba57;
103
- --dark-color-commit-gradient-8: #efbb49;
104
- --dark-color-commit-gradient-9: #febc38;
105
- --dark-color-commit-gradient-text: #000000;
106
- --dark-color-component-name: #61dafb;
107
- --dark-color-component-name-inverted: #282828;
108
- --dark-color-component-badge-background: rgba(255, 255, 255, 0.25);
109
- --dark-color-component-badge-background-inverted: rgba(0, 0, 0, 0.25);
110
- --dark-color-component-badge-count: #8f949d;
111
- --dark-color-component-badge-count-inverted: rgba(255, 255, 255, 0.7);
112
- --dark-color-dim: #8f949d;
113
- --dark-color-dimmer: #777d88;
114
- --dark-color-dimmest: #4f5766;
115
- --dark-color-expand-collapse-toggle: #8f949d;
116
- --dark-color-modal-background: rgba(0, 0, 0, 0.75);
117
- --dark-color-record-active: #fc3a4b;
118
- --dark-color-record-hover: #a2e9fc;
119
- --dark-color-record-inactive: #61dafb;
120
- --dark-color-scroll-thumb: #afb3b9;
121
- --dark-color-scroll-track: #313640;
122
- --dark-color-search-match: yellow;
123
- --dark-color-search-match-current: #f7923b;
124
- --dark-color-selected-tree-highlight-active: rgba(23, 143, 185, 0.15);
125
- --dark-color-selected-tree-highlight-inactive: rgba(255, 255, 255, 0.05);
126
- --dark-color-shadow: rgba(0, 0, 0, 0.5);
127
- --dark-color-tab-selected-border: #178fb9;
128
- --dark-color-text: #ffffff;
129
- --dark-color-text-invalid: #ff8080;
130
- --dark-color-text-selected: #ffffff;
131
- --dark-color-toggle-background-invalid: #fc3a4b;
132
- --dark-color-toggle-background-on: #178fb9;
133
- --dark-color-toggle-background-off: #777d88;
134
- --dark-color-toggle-text: #ffffff;
135
- --dark-color-tooltip-background: rgba(255, 255, 255, 0.9);
136
- --dark-color-tooltip-text: #000000;
137
-
138
- /* Font smoothing */
139
- --light-font-smoothing: auto;
140
- --dark-font-smoothing: antialiased;
141
- --font-smoothing: auto;
142
-
143
- /* Compact density */
144
- --compact-font-size-monospace-small: 9px;
145
- --compact-font-size-monospace-normal: 11px;
146
- --compact-font-size-monospace-large: 15px;
147
- --compact-font-size-sans-small: 10px;
148
- --compact-font-size-sans-normal: 12px;
149
- --compact-font-size-sans-large: 14px;
150
- --compact-line-height-data: 18px;
151
- --compact-root-font-size: 16px;
152
-
153
- /* Comfortable density */
154
- --comfortable-font-size-monospace-small: 10px;
155
- --comfortable-font-size-monospace-normal: 13px;
156
- --comfortable-font-size-monospace-large: 17px;
157
- --comfortable-font-size-sans-small: 12px;
158
- --comfortable-font-size-sans-normal: 14px;
159
- --comfortable-font-size-sans-large: 16px;
160
- --comfortable-line-height-data: 22px;
161
- --comfortable-root-font-size: 20px;
162
-
163
- /* GitHub.com system fonts */
164
- --font-family-monospace: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo,
165
- Courier, monospace;
166
- --font-family-sans: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica,
167
- Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
168
-
169
- /* Constant values shared between JS and CSS */
170
- --interaction-commit-size: 10px;
171
- --interaction-label-width: 200px;
172
-}
173
-
174
-* {
175
- box-sizing: border-box;
176
-
177
- -webkit-font-smoothing: var(--font-smoothing);
178
-}
packages/react-devtools-shared/src/devtools/views/utils.js
deleted
-212
@@ -1,212 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import escapeStringRegExp from 'escape-string-regexp';
11
-import {meta} from '../../hydration';
12
-
13
-import type {HooksTree} from 'react-debug-tools/src/ReactDebugHooks';
14
-
15
-export function alphaSortEntries(
16
- entryA: [string, mixed],
17
- entryB: [string, mixed],
18
-): number {
19
- const a = entryA[0];
20
- const b = entryB[0];
21
- if ('' + +a === a) {
22
- if ('' + +b !== b) {
23
- return -1;
24
- }
25
- return +a < +b ? -1 : 1;
26
- }
27
- return a < b ? -1 : 1;
28
-}
29
-
30
-export function createRegExp(string: string): RegExp {
31
- // Allow /regex/ syntax with optional last /
32
- if (string[0] === '/') {
33
- // Cut off first slash
34
- string = string.substring(1);
35
- // Cut off last slash, but only if it's there
36
- if (string[string.length - 1] === '/') {
37
- string = string.substring(0, string.length - 1);
38
- }
39
- try {
40
- return new RegExp(string, 'i');
41
- } catch (err) {
42
- // Bad regex. Make it not match anything.
43
- // TODO: maybe warn in console?
44
- return new RegExp('.^');
45
- }
46
- }
47
-
48
- function isLetter(char: string) {
49
- return char.toLowerCase() !== char.toUpperCase();
50
- }
51
-
52
- function matchAnyCase(char: string) {
53
- if (!isLetter(char)) {
54
- // Don't mess with special characters like [.
55
- return char;
56
- }
57
- return '[' + char.toLowerCase() + char.toUpperCase() + ']';
58
- }
59
-
60
- // 'item' should match 'Item' and 'ListItem', but not 'InviteMom'.
61
- // To do this, we'll slice off 'tem' and check first letter separately.
62
- const escaped = escapeStringRegExp(string);
63
- const firstChar = escaped[0];
64
- let restRegex = '';
65
- // For 'item' input, restRegex becomes '[tT][eE][mM]'
66
- // We can't simply make it case-insensitive because first letter case matters.
67
- for (let i = 1; i < escaped.length; i++) {
68
- restRegex += matchAnyCase(escaped[i]);
69
- }
70
-
71
- if (!isLetter(firstChar)) {
72
- // We can't put a non-character like [ in a group
73
- // so we fall back to the simple case.
74
- return new RegExp(firstChar + restRegex);
75
- }
76
-
77
- // Construct a smarter regex.
78
- return new RegExp(
79
- // For example:
80
- // (^[iI]|I)[tT][eE][mM]
81
- // Matches:
82
- // 'Item'
83
- // 'ListItem'
84
- // but not 'InviteMom'
85
- '(^' +
86
- matchAnyCase(firstChar) +
87
- '|' +
88
- firstChar.toUpperCase() +
89
- ')' +
90
- restRegex,
91
- );
92
-}
93
-
94
-export function getMetaValueLabel(data: Object): string | null {
95
- const name = data[meta.name];
96
- const type = data[meta.type];
97
-
98
- switch (type) {
99
- case 'html_element':
100
- return name ? `<${name.toLowerCase()} />` : '';
101
- case 'react_element':
102
- return `<${name} />`;
103
- case 'function':
104
- return `${name || 'fn'}()`;
105
- case 'object':
106
- return 'Object';
107
- case 'date':
108
- case 'symbol':
109
- return name;
110
- case 'iterator':
111
- return `${name}(…)`;
112
- case 'array_buffer':
113
- case 'data_view':
114
- case 'array':
115
- case 'typed_array':
116
- return `${name}[${data[meta.size]}]`;
117
- default:
118
- return null;
119
- }
120
-}
121
-
122
-function sanitize(data: Object): void {
123
- for (const key in data) {
124
- const value = data[key];
125
-
126
- if (value && value[meta.type]) {
127
- data[key] = getMetaValueLabel(value);
128
- } else if (value != null) {
129
- if (Array.isArray(value)) {
130
- sanitize(value);
131
- } else if (typeof value === 'object') {
132
- sanitize(value);
133
- }
134
- }
135
- }
136
-}
137
-
138
-export function serializeDataForCopy(props: Object): string {
139
- const cloned = Object.assign({}, props);
140
-
141
- sanitize(cloned);
142
-
143
- try {
144
- return JSON.stringify(cloned, null, 2);
145
- } catch (error) {
146
- return '';
147
- }
148
-}
149
-
150
-export function serializeHooksForCopy(hooks: HooksTree | null): string {
151
- // $FlowFixMe "HooksTree is not an object"
152
- const cloned = Object.assign([], hooks);
153
-
154
- const queue = [...cloned];
155
-
156
- while (queue.length > 0) {
157
- const current = queue.pop();
158
-
159
- // These aren't meaningful
160
- delete current.id;
161
- delete current.isStateEditable;
162
-
163
- if (current.subHooks.length > 0) {
164
- queue.push(...current.subHooks);
165
- }
166
- }
167
-
168
- sanitize(cloned);
169
-
170
- try {
171
- return JSON.stringify(cloned, null, 2);
172
- } catch (error) {
173
- return '';
174
- }
175
-}
176
-
177
-// Keeping this in memory seems to be enough to enable the browser to download larger profiles.
178
-// Without this, we would see a "Download failed: network error" failure.
179
-let downloadUrl = null;
180
-
181
-export function downloadFile(filename: string, text: string): void {
182
- const blob = new Blob([text], {type: 'text/plain;charset=utf-8'});
183
-
184
- if (downloadUrl !== null) {
185
- URL.revokeObjectURL(downloadUrl);
186
- }
187
-
188
- downloadUrl = URL.createObjectURL(blob);
189
-
190
- const element = document.createElement('a');
191
- element.setAttribute('href', downloadUrl);
192
- element.setAttribute('download', filename);
193
- element.style.display = 'none';
194
- ((document.body: any): HTMLBodyElement).appendChild(element);
195
-
196
- element.click();
197
-
198
- ((document.body: any): HTMLBodyElement).removeChild(element);
199
-}
200
-
201
-export function truncateText(text: string, maxLength: number): string {
202
- const {length} = text;
203
- if (length > maxLength) {
204
- return (
205
- text.substr(0, Math.floor(maxLength / 2)) +
206
- '…' +
207
- text.substr(length - Math.ceil(maxLength / 2) - 1)
208
- );
209
- } else {
210
- return text;
211
- }
212
-}
packages/react-devtools-shared/src/hook.js
deleted
-314
@@ -1,314 +0,0 @@
1
-/**
2
- * Install the hook on window, which is an event emitter.
3
- * Note because Chrome content scripts cannot directly modify the window object,
4
- * we are evaling this function by inserting a script tag.
5
- * That's why we have to inline the whole event emitter implementation here.
6
- *
7
- * @flow
8
- */
9
-
10
-import {
11
- patch as patchConsole,
12
- registerRenderer as registerRendererWithConsole,
13
-} from './backend/console';
14
-
15
-import type {DevToolsHook} from 'react-devtools-shared/src/backend/types';
16
-
17
-declare var window: any;
18
-
19
-export function installHook(target: any): DevToolsHook | null {
20
- if (target.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')) {
21
- return null;
22
- }
23
-
24
- function detectReactBuildType(renderer) {
25
- try {
26
- if (typeof renderer.version === 'string') {
27
- // React DOM Fiber (16+)
28
- if (renderer.bundleType > 0) {
29
- // This is not a production build.
30
- // We are currently only using 0 (PROD) and 1 (DEV)
31
- // but might add 2 (PROFILE) in the future.
32
- return 'development';
33
- }
34
-
35
- // React 16 uses flat bundles. If we report the bundle as production
36
- // version, it means we also minified and envified it ourselves.
37
- return 'production';
38
- // Note: There is still a risk that the CommonJS entry point has not
39
- // been envified or uglified. In this case the user would have *both*
40
- // development and production bundle, but only the prod one would run.
41
- // This would be really bad. We have a separate check for this because
42
- // it happens *outside* of the renderer injection. See `checkDCE` below.
43
- }
44
-
45
- const toString = Function.prototype.toString;
46
- if (renderer.Mount && renderer.Mount._renderNewRootComponent) {
47
- // React DOM Stack
48
- const renderRootCode = toString.call(
49
- renderer.Mount._renderNewRootComponent,
50
- );
51
- // Filter out bad results (if that is even possible):
52
- if (renderRootCode.indexOf('function') !== 0) {
53
- // Hope for the best if we're not sure.
54
- return 'production';
55
- }
56
- // Check for React DOM Stack < 15.1.0 in development.
57
- // If it contains "storedMeasure" call, it's wrapped in ReactPerf (DEV only).
58
- // This would be true even if it's minified, as method name still matches.
59
- if (renderRootCode.indexOf('storedMeasure') !== -1) {
60
- return 'development';
61
- }
62
- // For other versions (and configurations) it's not so easy.
63
- // Let's quickly exclude proper production builds.
64
- // If it contains a warning message, it's either a DEV build,
65
- // or an PROD build without proper dead code elimination.
66
- if (renderRootCode.indexOf('should be a pure function') !== -1) {
67
- // Now how do we tell a DEV build from a bad PROD build?
68
- // If we see NODE_ENV, we're going to assume this is a dev build
69
- // because most likely it is referring to an empty shim.
70
- if (renderRootCode.indexOf('NODE_ENV') !== -1) {
71
- return 'development';
72
- }
73
- // If we see "development", we're dealing with an envified DEV build
74
- // (such as the official React DEV UMD).
75
- if (renderRootCode.indexOf('development') !== -1) {
76
- return 'development';
77
- }
78
- // I've seen process.env.NODE_ENV !== 'production' being smartly
79
- // replaced by `true` in DEV by Webpack. I don't know how that
80
- // works but we can safely guard against it because `true` was
81
- // never used in the function source since it was written.
82
- if (renderRootCode.indexOf('true') !== -1) {
83
- return 'development';
84
- }
85
- // By now either it is a production build that has not been minified,
86
- // or (worse) this is a minified development build using non-standard
87
- // environment (e.g. "staging"). We're going to look at whether
88
- // the function argument name is mangled:
89
- if (
90
- // 0.13 to 15
91
- renderRootCode.indexOf('nextElement') !== -1 ||
92
- // 0.12
93
- renderRootCode.indexOf('nextComponent') !== -1
94
- ) {
95
- // We can't be certain whether this is a development build or not,
96
- // but it is definitely unminified.
97
- return 'unminified';
98
- } else {
99
- // This is likely a minified development build.
100
- return 'development';
101
- }
102
- }
103
- // By now we know that it's envified and dead code elimination worked,
104
- // but what if it's still not minified? (Is this even possible?)
105
- // Let's check matches for the first argument name.
106
- if (
107
- // 0.13 to 15
108
- renderRootCode.indexOf('nextElement') !== -1 ||
109
- // 0.12
110
- renderRootCode.indexOf('nextComponent') !== -1
111
- ) {
112
- return 'unminified';
113
- }
114
- // Seems like we're using the production version.
115
- // However, the branch above is Stack-only so this is 15 or earlier.
116
- return 'outdated';
117
- }
118
- } catch (err) {
119
- // Weird environments may exist.
120
- // This code needs a higher fault tolerance
121
- // because it runs even with closed DevTools.
122
- // TODO: should we catch errors in all injected code, and not just this part?
123
- }
124
- return 'production';
125
- }
126
-
127
- function checkDCE(fn: Function) {
128
- // This runs for production versions of React.
129
- // Needs to be super safe.
130
- try {
131
- const toString = Function.prototype.toString;
132
- const code = toString.call(fn);
133
-
134
- // This is a string embedded in the passed function under DEV-only
135
- // condition. However the function executes only in PROD. Therefore,
136
- // if we see it, dead code elimination did not work.
137
- if (code.indexOf('^_^') > -1) {
138
- // Remember to report during next injection.
139
- hasDetectedBadDCE = true;
140
-
141
- // Bonus: throw an exception hoping that it gets picked up by a reporting system.
142
- // Not synchronously so that it doesn't break the calling code.
143
- setTimeout(function() {
144
- throw new Error(
145
- 'React is running in production mode, but dead code ' +
146
- 'elimination has not been applied. Read how to correctly ' +
147
- 'configure React for production: ' +
148
- 'https://fb.me/react-perf-use-the-production-build',
149
- );
150
- });
151
- }
152
- } catch (err) {}
153
- }
154
-
155
- let uidCounter = 0;
156
-
157
- function inject(renderer) {
158
- const id = ++uidCounter;
159
- renderers.set(id, renderer);
160
-
161
- const reactBuildType = hasDetectedBadDCE
162
- ? 'deadcode'
163
- : detectReactBuildType(renderer);
164
-
165
- // Patching the console enables DevTools to do a few useful things:
166
- // * Append component stacks to warnings and error messages
167
- // * Disable logging during re-renders to inspect hooks (see inspectHooksOfFiber)
168
- //
169
- // For React Native, we intentionally patch early (during injection).
170
- // This provides React Native developers with components stacks even if they don't run DevTools.
171
- // This won't work for DOM though, since this entire file is eval'ed and inserted as a script tag.
172
- // In that case, we'll patch later (when the frontend attaches).
173
- //
174
- // Don't patch in test environments because we don't want to interfere with Jest's own console overrides.
175
- if (process.env.NODE_ENV !== 'test') {
176
- try {
177
- // The installHook() function is injected by being stringified in the browser,
178
- // so imports outside of this function do not get included.
179
- //
180
- // Normally we could check "typeof patchConsole === 'function'",
181
- // but Webpack wraps imports with an object (e.g. _backend_console__WEBPACK_IMPORTED_MODULE_0__)
182
- // and the object itself will be undefined as well for the reasons mentioned above,
183
- // so we use try/catch instead.
184
- if (window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ !== false) {
185
- registerRendererWithConsole(renderer);
186
- patchConsole();
187
- }
188
- } catch (error) {}
189
- }
190
-
191
- // If we have just reloaded to profile, we need to inject the renderer interface before the app loads.
192
- // Otherwise the renderer won't yet exist and we can skip this step.
193
- const attach = target.__REACT_DEVTOOLS_ATTACH__;
194
- if (typeof attach === 'function') {
195
- const rendererInterface = attach(hook, id, renderer, target);
196
- hook.rendererInterfaces.set(id, rendererInterface);
197
- }
198
-
199
- hook.emit('renderer', {id, renderer, reactBuildType});
200
-
201
- return id;
202
- }
203
-
204
- let hasDetectedBadDCE = false;
205
-
206
- function sub(event, fn) {
207
- hook.on(event, fn);
208
- return () => hook.off(event, fn);
209
- }
210
-
211
- function on(event, fn) {
212
- if (!listeners[event]) {
213
- listeners[event] = [];
214
- }
215
- listeners[event].push(fn);
216
- }
217
-
218
- function off(event, fn) {
219
- if (!listeners[event]) {
220
- return;
221
- }
222
- const index = listeners[event].indexOf(fn);
223
- if (index !== -1) {
224
- listeners[event].splice(index, 1);
225
- }
226
- if (!listeners[event].length) {
227
- delete listeners[event];
228
- }
229
- }
230
-
231
- function emit(event, data) {
232
- if (listeners[event]) {
233
- listeners[event].map(fn => fn(data));
234
- }
235
- }
236
-
237
- function getFiberRoots(rendererID) {
238
- const roots = fiberRoots;
239
- if (!roots[rendererID]) {
240
- roots[rendererID] = new Set();
241
- }
242
- return roots[rendererID];
243
- }
244
-
245
- function onCommitFiberUnmount(rendererID, fiber) {
246
- const rendererInterface = rendererInterfaces.get(rendererID);
247
- if (rendererInterface != null) {
248
- rendererInterface.handleCommitFiberUnmount(fiber);
249
- }
250
- }
251
-
252
- function onCommitFiberRoot(rendererID, root, priorityLevel) {
253
- const mountedRoots = hook.getFiberRoots(rendererID);
254
- const current = root.current;
255
- const isKnownRoot = mountedRoots.has(root);
256
- const isUnmounting =
257
- current.memoizedState == null || current.memoizedState.element == null;
258
-
259
- // Keep track of mounted roots so we can hydrate when DevTools connect.
260
- if (!isKnownRoot && !isUnmounting) {
261
- mountedRoots.add(root);
262
- } else if (isKnownRoot && isUnmounting) {
263
- mountedRoots.delete(root);
264
- }
265
- const rendererInterface = rendererInterfaces.get(rendererID);
266
- if (rendererInterface != null) {
267
- rendererInterface.handleCommitFiberRoot(root, priorityLevel);
268
- }
269
- }
270
-
271
- // TODO: More meaningful names for "rendererInterfaces" and "renderers".
272
- const fiberRoots = {};
273
- const rendererInterfaces = new Map();
274
- const listeners = {};
275
- const renderers = new Map();
276
-
277
- const hook: DevToolsHook = {
278
- rendererInterfaces,
279
- listeners,
280
- renderers,
281
-
282
- emit,
283
- getFiberRoots,
284
- inject,
285
- on,
286
- off,
287
- sub,
288
-
289
- // This is a legacy flag.
290
- // React v16 checks the hook for this to ensure DevTools is new enough.
291
- supportsFiber: true,
292
-
293
- // React calls these methods.
294
- checkDCE,
295
- onCommitFiberUnmount,
296
- onCommitFiberRoot,
297
- };
298
-
299
- Object.defineProperty(
300
- target,
301
- '__REACT_DEVTOOLS_GLOBAL_HOOK__',
302
- ({
303
- // This property needs to be configurable for the test environment,
304
- // else we won't be able to delete and recreate it beween tests.
305
- configurable: __DEV__,
306
- enumerable: false,
307
- get() {
308
- return hook;
309
- },
310
- }: Object),
311
- );
312
-
313
- return hook;
314
-}
packages/react-devtools-shared/src/hydration.js
deleted
-531
@@ -1,531 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import Symbol from 'es6-symbol';
11
-import {
12
- isElement,
13
- typeOf,
14
- AsyncMode,
15
- ConcurrentMode,
16
- ContextConsumer,
17
- ContextProvider,
18
- ForwardRef,
19
- Fragment,
20
- Lazy,
21
- Memo,
22
- Portal,
23
- Profiler,
24
- StrictMode,
25
- Suspense,
26
-} from 'react-is';
27
-import {getDisplayName, getInObject, setInObject} from './utils';
28
-
29
-import type {DehydratedData} from 'react-devtools-shared/src/devtools/views/Components/types';
30
-
31
-export const meta = {
32
- inspectable: Symbol('inspectable'),
33
- inspected: Symbol('inspected'),
34
- name: Symbol('name'),
35
- readonly: Symbol('readonly'),
36
- size: Symbol('size'),
37
- type: Symbol('type'),
38
- unserializable: Symbol('unserializable'),
39
-};
40
-
41
-export type Dehydrated = {|
42
- inspectable: boolean,
43
- name: string | null,
44
- readonly?: boolean,
45
- size?: number,
46
- type: string,
47
-|};
48
-
49
-// Typed arrays and other complex iteratable objects (e.g. Map, Set, ImmutableJS) need special handling.
50
-// These objects can't be serialized without losing type information,
51
-// so a "Unserializable" type wrapper is used (with meta-data keys) to send nested values-
52
-// while preserving the original type and name.
53
-export type Unserializable = {
54
- name: string | null,
55
- readonly?: boolean,
56
- size?: number,
57
- type: string,
58
- unserializable: boolean,
59
-};
60
-
61
-// This threshold determines the depth at which the bridge "dehydrates" nested data.
62
-// Dehydration means that we don't serialize the data for e.g. postMessage or stringify,
63
-// unless the frontend explicitly requests it (e.g. a user clicks to expand a props object).
64
-//
65
-// Reducing this threshold will improve the speed of initial component inspection,
66
-// but may decrease the responsiveness of expanding objects/arrays to inspect further.
67
-const LEVEL_THRESHOLD = 2;
68
-
69
-type PropType =
70
- | 'array'
71
- | 'array_buffer'
72
- | 'boolean'
73
- | 'data_view'
74
- | 'date'
75
- | 'function'
76
- | 'html_element'
77
- | 'infinity'
78
- | 'iterator'
79
- | 'nan'
80
- | 'null'
81
- | 'number'
82
- | 'object'
83
- | 'react_element'
84
- | 'string'
85
- | 'symbol'
86
- | 'typed_array'
87
- | 'undefined'
88
- | 'unknown';
89
-
90
-/**
91
- * Get a enhanced/artificial type string based on the object instance
92
- */
93
-function getDataType(data: Object): PropType {
94
- if (data === null) {
95
- return 'null';
96
- } else if (data === undefined) {
97
- return 'undefined';
98
- }
99
-
100
- if (isElement(data)) {
101
- return 'react_element';
102
- }
103
-
104
- if (typeof HTMLElement !== 'undefined' && data instanceof HTMLElement) {
105
- return 'html_element';
106
- }
107
-
108
- const type = typeof data;
109
- switch (type) {
110
- case 'boolean':
111
- return 'boolean';
112
- case 'function':
113
- return 'function';
114
- case 'number':
115
- if (Number.isNaN(data)) {
116
- return 'nan';
117
- } else if (!Number.isFinite(data)) {
118
- return 'infinity';
119
- } else {
120
- return 'number';
121
- }
122
- case 'object':
123
- if (Array.isArray(data)) {
124
- return 'array';
125
- } else if (ArrayBuffer.isView(data)) {
126
- return data instanceof DataView ? 'data_view' : 'typed_array';
127
- } else if (data instanceof ArrayBuffer) {
128
- return 'array_buffer';
129
- } else if (typeof data[Symbol.iterator] === 'function') {
130
- return 'iterator';
131
- } else if (Object.prototype.toString.call(data) === '[object Date]') {
132
- return 'date';
133
- }
134
- return 'object';
135
- case 'string':
136
- return 'string';
137
- case 'symbol':
138
- return 'symbol';
139
- default:
140
- return 'unknown';
141
- }
142
-}
143
-
144
-/**
145
- * Generate the dehydrated metadata for complex object instances
146
- */
147
-function createDehydrated(
148
- type: string,
149
- inspectable: boolean,
150
- data: Object,
151
- cleaned: Array<Array<string | number>>,
152
- path: Array<string | number>,
153
-): Dehydrated {
154
- cleaned.push(path);
155
-
156
- const dehydrated: Dehydrated = {
157
- inspectable,
158
- type,
159
- name:
160
- !data.constructor || data.constructor.name === 'Object'
161
- ? ''
162
- : data.constructor.name,
163
- };
164
-
165
- if (type === 'array' || type === 'typed_array') {
166
- dehydrated.size = data.length;
167
- } else if (type === 'object') {
168
- dehydrated.size = Object.keys(data).length;
169
- }
170
-
171
- if (type === 'iterator' || type === 'typed_array') {
172
- dehydrated.readonly = true;
173
- }
174
-
175
- return dehydrated;
176
-}
177
-
178
-/**
179
- * Strip out complex data (instances, functions, and data nested > LEVEL_THRESHOLD levels deep).
180
- * The paths of the stripped out objects are appended to the `cleaned` list.
181
- * On the other side of the barrier, the cleaned list is used to "re-hydrate" the cleaned representation into
182
- * an object with symbols as attributes, so that a sanitized object can be distinguished from a normal object.
183
- *
184
- * Input: {"some": {"attr": fn()}, "other": AnInstance}
185
- * Output: {
186
- * "some": {
187
- * "attr": {"name": the fn.name, type: "function"}
188
- * },
189
- * "other": {
190
- * "name": "AnInstance",
191
- * "type": "object",
192
- * },
193
- * }
194
- * and cleaned = [["some", "attr"], ["other"]]
195
- */
196
-export function dehydrate(
197
- data: Object,
198
- cleaned: Array<Array<string | number>>,
199
- unserializable: Array<Array<string | number>>,
200
- path: Array<string | number>,
201
- isPathWhitelisted: (path: Array<string | number>) => boolean,
202
- level?: number = 0,
203
-):
204
- | string
205
- | Dehydrated
206
- | Unserializable
207
- | Array<Dehydrated>
208
- | Array<Unserializable>
209
- | {[key: string]: string | Dehydrated | Unserializable} {
210
- const type = getDataType(data);
211
-
212
- let isPathWhitelistedCheck;
213
-
214
- switch (type) {
215
- case 'html_element':
216
- cleaned.push(path);
217
- return {
218
- inspectable: false,
219
- name: data.tagName,
220
- type,
221
- };
222
-
223
- case 'function':
224
- cleaned.push(path);
225
- return {
226
- inspectable: false,
227
- name: data.name,
228
- type,
229
- };
230
-
231
- case 'string':
232
- return data.length <= 500 ? data : data.slice(0, 500) + '...';
233
-
234
- case 'symbol':
235
- cleaned.push(path);
236
- return {
237
- inspectable: false,
238
- name: data.toString(),
239
- type,
240
- };
241
-
242
- // React Elements aren't very inspector-friendly,
243
- // and often contain private fields or circular references.
244
- case 'react_element':
245
- cleaned.push(path);
246
- return {
247
- inspectable: false,
248
- name: getDisplayNameForReactElement(data),
249
- type,
250
- };
251
-
252
- // ArrayBuffers error if you try to inspect them.
253
- case 'array_buffer':
254
- case 'data_view':
255
- cleaned.push(path);
256
- return {
257
- inspectable: false,
258
- name: type === 'data_view' ? 'DataView' : 'ArrayBuffer',
259
- size: data.byteLength,
260
- type,
261
- };
262
-
263
- case 'array':
264
- isPathWhitelistedCheck = isPathWhitelisted(path);
265
- if (level >= LEVEL_THRESHOLD && !isPathWhitelistedCheck) {
266
- return createDehydrated(type, true, data, cleaned, path);
267
- }
268
- return data.map((item, i) =>
269
- dehydrate(
270
- item,
271
- cleaned,
272
- unserializable,
273
- path.concat([i]),
274
- isPathWhitelisted,
275
- isPathWhitelistedCheck ? 1 : level + 1,
276
- ),
277
- );
278
-
279
- case 'typed_array':
280
- case 'iterator':
281
- isPathWhitelistedCheck = isPathWhitelisted(path);
282
- if (level >= LEVEL_THRESHOLD && !isPathWhitelistedCheck) {
283
- return createDehydrated(type, true, data, cleaned, path);
284
- } else {
285
- const unserializableValue: Unserializable = {
286
- unserializable: true,
287
- type: type,
288
- readonly: true,
289
- size: type === 'typed_array' ? data.length : undefined,
290
- name:
291
- !data.constructor || data.constructor.name === 'Object'
292
- ? ''
293
- : data.constructor.name,
294
- };
295
-
296
- if (typeof data[Symbol.iterator]) {
297
- // TRICKY
298
- // Don't use [...spread] syntax for this purpose.
299
- // This project uses @babel/plugin-transform-spread in "loose" mode which only works with Array values.
300
- // Other types (e.g. typed arrays, Sets) will not spread correctly.
301
- Array.from(data).forEach(
302
- (item, i) =>
303
- (unserializableValue[i] = dehydrate(
304
- item,
305
- cleaned,
306
- unserializable,
307
- path.concat([i]),
308
- isPathWhitelisted,
309
- isPathWhitelistedCheck ? 1 : level + 1,
310
- )),
311
- );
312
- }
313
-
314
- unserializable.push(path);
315
-
316
- return unserializableValue;
317
- }
318
-
319
- case 'date':
320
- cleaned.push(path);
321
- return {
322
- inspectable: false,
323
- name: data.toString(),
324
- type,
325
- };
326
-
327
- case 'object':
328
- isPathWhitelistedCheck = isPathWhitelisted(path);
329
- if (level >= LEVEL_THRESHOLD && !isPathWhitelistedCheck) {
330
- return createDehydrated(type, true, data, cleaned, path);
331
- } else {
332
- const object = {};
333
- for (let name in data) {
334
- object[name] = dehydrate(
335
- data[name],
336
- cleaned,
337
- unserializable,
338
- path.concat([name]),
339
- isPathWhitelisted,
340
- isPathWhitelistedCheck ? 1 : level + 1,
341
- );
342
- }
343
- return object;
344
- }
345
-
346
- case 'infinity':
347
- case 'nan':
348
- case 'undefined':
349
- // Some values are lossy when sent through a WebSocket.
350
- // We dehydrate+rehydrate them to preserve their type.
351
- cleaned.push(path);
352
- return {
353
- type,
354
- };
355
-
356
- default:
357
- return data;
358
- }
359
-}
360
-
361
-export function fillInPath(
362
- object: Object,
363
- data: DehydratedData,
364
- path: Array<string | number>,
365
- value: any,
366
-) {
367
- const target = getInObject(object, path);
368
- if (target != null) {
369
- if (!target[meta.unserializable]) {
370
- delete target[meta.inspectable];
371
- delete target[meta.inspected];
372
- delete target[meta.name];
373
- delete target[meta.readonly];
374
- delete target[meta.size];
375
- delete target[meta.type];
376
- }
377
- }
378
-
379
- if (value !== null && data.unserializable.length > 0) {
380
- const unserializablePath = data.unserializable[0];
381
- let isMatch = unserializablePath.length === path.length;
382
- for (let i = 0; i < path.length; i++) {
383
- if (path[i] !== unserializablePath[i]) {
384
- isMatch = false;
385
- break;
386
- }
387
- }
388
- if (isMatch) {
389
- upgradeUnserializable(value, value);
390
- }
391
- }
392
-
393
- setInObject(object, path, value);
394
-}
395
-
396
-export function hydrate(
397
- object: any,
398
- cleaned: Array<Array<string | number>>,
399
- unserializable: Array<Array<string | number>>,
400
-): Object {
401
- cleaned.forEach((path: Array<string | number>) => {
402
- const length = path.length;
403
- const last = path[length - 1];
404
- const parent = getInObject(object, path.slice(0, length - 1));
405
- if (!parent || !parent.hasOwnProperty(last)) {
406
- return;
407
- }
408
-
409
- const value = parent[last];
410
-
411
- if (value.type === 'infinity') {
412
- parent[last] = Infinity;
413
- } else if (value.type === 'nan') {
414
- parent[last] = NaN;
415
- } else if (value.type === 'undefined') {
416
- parent[last] = undefined;
417
- } else {
418
- // Replace the string keys with Symbols so they're non-enumerable.
419
- const replaced: {[key: Symbol]: boolean | string} = {};
420
- replaced[meta.inspectable] = !!value.inspectable;
421
- replaced[meta.inspected] = false;
422
- replaced[meta.name] = value.name;
423
- replaced[meta.size] = value.size;
424
- replaced[meta.readonly] = !!value.readonly;
425
- replaced[meta.type] = value.type;
426
-
427
- parent[last] = replaced;
428
- }
429
- });
430
- unserializable.forEach((path: Array<string | number>) => {
431
- const length = path.length;
432
- const last = path[length - 1];
433
- const parent = getInObject(object, path.slice(0, length - 1));
434
- if (!parent || !parent.hasOwnProperty(last)) {
435
- return;
436
- }
437
-
438
- const node = parent[last];
439
-
440
- const replacement = {
441
- ...node,
442
- };
443
-
444
- upgradeUnserializable(replacement, node);
445
-
446
- parent[last] = replacement;
447
- });
448
- return object;
449
-}
450
-
451
-function upgradeUnserializable(destination: Object, source: Object) {
452
- Object.defineProperties(destination, {
453
- [meta.inspected]: {
454
- configurable: true,
455
- enumerable: false,
456
- value: !!source.inspected,
457
- },
458
- [meta.name]: {
459
- configurable: true,
460
- enumerable: false,
461
- value: source.name,
462
- },
463
- [meta.size]: {
464
- configurable: true,
465
- enumerable: false,
466
- value: source.size,
467
- },
468
- [meta.readonly]: {
469
- configurable: true,
470
- enumerable: false,
471
- value: !!source.readonly,
472
- },
473
- [meta.type]: {
474
- configurable: true,
475
- enumerable: false,
476
- value: source.type,
477
- },
478
- [meta.unserializable]: {
479
- configurable: true,
480
- enumerable: false,
481
- value: !!source.unserializable,
482
- },
483
- });
484
-
485
- delete destination.inspected;
486
- delete destination.name;
487
- delete destination.size;
488
- delete destination.readonly;
489
- delete destination.type;
490
- delete destination.unserializable;
491
-}
492
-
493
-export function getDisplayNameForReactElement(
494
- element: React$Element<any>,
495
-): string | null {
496
- const elementType = typeOf(element);
497
- switch (elementType) {
498
- case AsyncMode:
499
- case ConcurrentMode:
500
- return 'ConcurrentMode';
501
- case ContextConsumer:
502
- return 'ContextConsumer';
503
- case ContextProvider:
504
- return 'ContextProvider';
505
- case ForwardRef:
506
- return 'ForwardRef';
507
- case Fragment:
508
- return 'Fragment';
509
- case Lazy:
510
- return 'Lazy';
511
- case Memo:
512
- return 'Memo';
513
- case Portal:
514
- return 'Portal';
515
- case Profiler:
516
- return 'Profiler';
517
- case StrictMode:
518
- return 'StrictMode';
519
- case Suspense:
520
- return 'Suspense';
521
- default:
522
- const {type} = element;
523
- if (typeof type === 'string') {
524
- return type;
525
- } else if (type != null) {
526
- return getDisplayName(type, 'Anonymous');
527
- } else {
528
- return 'Element';
529
- }
530
- }
531
-}
packages/react-devtools-shared/src/node_modules/react-window/CHANGELOG.md
deleted
-96
@@ -1,96 +0,0 @@
1
-Changelog
2
-------------
3
-
4
-### 1.8.0
5
-* 🎉 Added new "smart" align option for grid and list scroll-to-item methods ([gaearon](https://github.com/gaearon) - [#209](https://github.com/bvaughn/react-window/pull/209))
6
-
7
-### 1.7.2
8
-* 🐛 Add guards to avoid invalid scroll offsets when `scrollTo()` is called with a negative offset or when `scrollToItem` is called with invalid indices (negative or too large).
9
-
10
-### 1.7.1
11
-* 🐛 Fix SSR regression introduced in 1.7.0 - ([Betree](https://github.com/Betree) - [#185](https://github.com/bvaughn/react-window/pull/185))
12
-
13
-### 1.7.0
14
-* 🎉 Grid `scrollToItem` supports optional `rowIndex` and `columnIndex` params ([jgoz](https://github.com/jgoz) - [#174](https://github.com/bvaughn/react-window/pull/174))
15
-* DEV mode checks for `WeakSet` support before using it to avoid requiring a polyfill for IE11 - ([jgoz](https://github.com/jgoz) - [#167](https://github.com/bvaughn/react-window/pull/167))
16
-
17
-### 1.6.2
18
-* 🐛 Bugfix for RTL when scrolling back towards the beginning (right) of the list.
19
-
20
-### 1.6.1
21
-* 🐛 Bugfix to account for differences between Chrome and non-Chrome browsers with regard to RTL and "scroll" events.
22
-
23
-### 1.6.0
24
-* 🎉 RTL support added for lists and grids. Special thanks to [davidgarsan](https://github.com/davidgarsan) for his support. - [#156](https://github.com/bvaughn/react-window/pull/156)
25
-* 🐛 Grid `scrollToItem` methods take scrollbar size into account when aligning items - [#153](https://github.com/bvaughn/react-window/issues/153)
26
-
27
-### 1.5.2
28
-* 🐛 Edge case bug fix for `VariableSizeList` and `VariableSizeGrid` when the number of items decreases while a scroll is in progress. - ([iamsolankiamit](https://github.com/iamsolankiamit) - [#138](https://github.com/bvaughn/react-window/pull/138))
29
-
30
-### 1.5.1
31
-* 🐛 Updated `getDerivedState` Flow annotations to address a warning in a newer version of Flow.
32
-
33
-### 1.5.0
34
-* 🎉 Added advanced memoization helpers methods `areEqual` and `shouldComponentUpdate` for item renderers. - [#114](https://github.com/bvaughn/react-window/issues/114)
35
-
36
-### 1.4.0
37
-* 🎉 List and Grid components now "overscan" (pre-render) in both directions when scrolling is not active. When scrolling is in progress, cells are only pre-rendered in the direction being scrolled. This change has been made in an effort to reduce visible flicker when scrolling starts without adding additional overhead during scroll (which is the most performance sensitive time).
38
-* 🎉 Grid components now support separate `overscanColumnsCount` and `overscanRowsCount` props. Legacy `overscanCount` prop will continue to work, but with a deprecation warning in DEV mode.
39
-* 🐛 Replaced `setTimeout` with `requestAnimationFrame` based timer, to avoid starvation issue for `isScrolling` reset. - [#106](https://github.com/bvaughn/react-window/issues/106)
40
-* 🎉 Renamed List and Grid `innerTagName` and `outerTagName` props to `innerElementType` and `outerElementType` to formalize support for attaching arbitrary props (e.g. test ids) to List and Grid inner and outer DOM elements. Legacy `innerTagName` and `outerTagName` props will continue to work, but with a deprecation warning in DEV mode.
41
-* 🐛 List re-renders items if `direction` prop changes. - [#104](https://github.com/bvaughn/react-window/issues/104)
42
-
43
-### 1.3.1
44
-* 🎉 Pass `itemData` value to custom `itemKey` callbacks when present - [#90](https://github.com/bvaughn/react-window/issues/90))
45
-
46
-### 1.3.0
47
-* (Skipped)
48
-
49
-### 1.2.4
50
-* 🐛 Added Flow annotations to memoized methods to avoid a Flow warning for newer versions of Flow
51
-
52
-### 1.2.3
53
-* 🐛 Relaxed `children` validation checks. They were too strict and didn't support new React APIs like `memo`.
54
-
55
-### 1.2.2
56
-* 🐛 Improved Flow types for class component item renderers - ([nicholas-l](https://github.com/nicholas-l) - [#77](https://github.com/bvaughn/react-window/pull/77))
57
-
58
-### 1.2.1
59
-* 🎉 Improved Flow types to include optional `itemData` parameter. ([TrySound](https://github.com/TrySound) - [#66](https://github.com/bvaughn/react-window/pull/66))
60
-* 🐛 `VariableSizeList` and `VariableSizeGrid` no longer call size getter functions with invalid index when item count is zero.
61
-
62
-### 1.2.0
63
-* 🎉 Flow types added to NPM package. ([TrySound](https://github.com/TrySound) - [#40](https://github.com/bvaughn/react-window/pull/40))
64
-* 🎉 Relaxed grid `scrollTo` method to make `scrollLeft` and `scrollTop` params _optional_ (so you can only update one axis if desired). - [#63](https://github.com/bvaughn/react-window/pull/63))
65
-* 🐛 Fixed invalid `this` pointer in `VariableSizeGrid` that broke the `resetAfter*` methods - [#58](https://github.com/bvaughn/react-window/pull/58))
66
-* Upgraded to babel 7 and used shared runtime helpers to reduce package size slightly. ([TrySound](https://github.com/TrySound) - [#48](https://github.com/bvaughn/react-window/pull/48))
67
-* Remove `overflow:hidden` from inner container ([souporserious](https://github.com/souporserious) - [#56](https://github.com/bvaughn/react-window/pull/56))
68
-
69
-### 1.1.2
70
-* 🐛 Fixed edge case `scrollToItem` bug that caused lists/grids with very few items to have negative scroll offsets.
71
-
72
-### 1.1.1
73
-* 🐛 `FixedSizeGrid` and `FixedSizeList` automatically clear style cache when item size props change.
74
-
75
-### 1.1.0
76
-* 🎉 Use explicit `constructor` and `super` to generate cleaner component code. ([Andarist](https://github.com/Andarist) - [#26](https://github.com/bvaughn/react-window/pull/26))
77
-* 🎉 Add optional `shouldForceUpdate` param reset-index methods to specify `forceUpdate` behavior. ([nihgwu](https://github.com/nihgwu) - [#32](https://github.com/bvaughn/react-window/pull/32))
78
-
79
-### 1.0.3
80
-* 🐛 Avoid unnecessary scrollbars for lists (e.g. no horizontal scrollbar for a vertical list) unless content requires them.
81
-
82
-### 1.0.2
83
-
84
-* 🎉 Enable Babel `annotate-pure-calls` option so that classes compiled by "transform-es2015-classes" are annotated with `#__PURE__`. This enables [UglifyJS to remove them if they are not referenced](https://github.com/mishoo/UglifyJS2/pull/1448), improving dead code elimination in application code. ([Andarist](https://github.com/Andarist) - [#20](https://github.com/bvaughn/react-window/pull/20))
85
-* 🎉 Update "rollup-plugin-peer-deps-external" and use new `includeDependencies` flag so that the "memoize-one" dependency does not get inlined into the Rollup bundle. ([Andarist](https://github.com/Andarist) - [#19](https://github.com/bvaughn/react-window/pull/19))
86
-* 🎉 Enable [Babel "loose" mode](https://babeljs.io/docs/en/babel-preset-env#loose) to reduce package size (-8%). ([Andarist](https://github.com/Andarist) - [#18](https://github.com/bvaughn/react-window/pull/18))
87
-
88
-### 1.0.1
89
-Updated `README.md` file to remove `@alpha` tag from NPM installation instructions.
90
-
91
-# 1.0.0
92
-Initial release of library. Includes the following components:
93
-* `FixedSizeGrid`
94
-* `FixedSizeList`
95
-* `VariableSizeGrid`
96
-* `VariableSizeList`
packages/react-devtools-shared/src/node_modules/react-window/LICENSE.md
deleted
-21
@@ -1,21 +0,0 @@
1
-The MIT License (MIT)
2
-
3
-Copyright (c) 2018 Brian Vaughn
4
-
5
-Permission is hereby granted, free of charge, to any person obtaining a copy
6
-of this software and associated documentation files (the "Software"), to deal
7
-in the Software without restriction, including without limitation the rights
8
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
-copies of the Software, and to permit persons to whom the Software is
10
-furnished to do so, subject to the following conditions:
11
-
12
-The above copyright notice and this permission notice shall be included in all
13
-copies or substantial portions of the Software.
14
-
15
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
-SOFTWARE.
packages/react-devtools-shared/src/node_modules/react-window/README.md
deleted
-88
@@ -1,88 +0,0 @@
1
-# react-window
2
-
3
-> React components for efficiently rendering large lists and tabular data
4
-
5
-[](https://yarnpkg.com/en/package/react-window) [](https://travis-ci.org/bvaughn/react-window) [](LICENSE.md)
6
-
7
-## Install
8
-
9
-```bash
10
-# Yarn
11
-yarn add react-window
12
-
13
-# NPM
14
-npm install --save react-window
15
-```
16
-
17
-## Usage
18
-
19
-Learn more at [react-window.now.sh](https://react-window.now.sh/):
20
-
21
-## Related libraries
22
-
23
-* [`react-virtualized-auto-sizer`](https://npmjs.com/package/react-virtualized-auto-sizer): HOC that grows to fit all of the available space and passes the width and height values to its child.
24
-* [`react-window-infinite-loader`](https://npmjs.com/package/react-window-infinite-loader): Helps break large data sets down into chunks that can be just-in-time loaded as they are scrolled into view. It can also be used to create infinite loading lists (e.g. Facebook or Twitter).
25
-
26
-## Frequently asked questions
27
-
28
-### How is `react-window` different from `react-virtualized`?
29
-I wrote `react-virtualized` several years ago. At the time, I was new to both React and the concept of windowing. Because of this, I made a few API decisions that I later came to regret. One of these was adding too many non-essential features and components. Once you add something to an open source project, removing it is pretty painful for users.
30
-
31
-`react-window` is a complete rewrite of `react-virtualized`. I didn't try to solve as many problems or support as many use cases. Instead I focused on making the package **smaller**<sup>1</sup> and **faster**. I also put a lot of thought into making the API (and documentation) as beginner-friendly as possible (with the caveat that windowing is still kind of an advanced use case).
32
-
33
-If `react-window` provides the functionality your project needs, I would strongly recommend using it instead of `react-virtualized`. However if you need features that only `react-virtualized` provides, you have two options:
34
-
35
-1. Use `react-virtualized`. (It's still widely used by a lot of successful projects!)
36
-2. Create a component that decorates one of the `react-window` primitives and adds the functionality you need. You may even want to release this component to NPM (as its own, standalone package)! 🙂
37
-
38
-<sup>1 - Adding a `react-virtualized` list to a CRA project increases the (gzipped) build size by ~33.5 KB. Adding a `react-window` list to a CRA project increases the (gzipped) build size by <2 KB.</sup>
39
-
40
-### Can a list or a grid fill 100% the width or height of a page?
41
-
42
-Yes. I recommend using the [`react-virtualized-auto-sizer` package](https://npmjs.com/package/react-virtualized-auto-sizer):
43
-
44
-<img width="336" alt="screen shot 2019-03-07 at 7 29 08 pm" src="https://user-images.githubusercontent.com/29597/54005716-50f41880-410f-11e9-864f-a65bbdf49e07.png">
45
-
46
-Here's a [Code Sandbox demo](https://codesandbox.io/s/3vnx878jk5).
47
-
48
-### Why is my list blank when I scroll?
49
-
50
-If your list looks something like this...
51
-
52
-<img src="https://user-images.githubusercontent.com/29597/54005352-eb535c80-410d-11e9-80b2-d3d02db1f599.gif" width="302" height="152">
53
-
54
-...then you probably forgot to use the `style` parameter! Libraries like react-window work by absolutely positioning the list items (via an inline style), so don't forget to attach it to the DOM element you render!
55
-
56
-<img width="257" alt="screen shot 2019-03-07 at 7 21 48 pm" src="https://user-images.githubusercontent.com/29597/54005433-45ecb880-410e-11e9-8721-420ff1a153da.png">
57
-
58
-### Can I lazy load data for my list?
59
-
60
-Yes. I recommend using the [`react-window-infinite-loader` package](https://npmjs.com/package/react-window-infinite-loader):
61
-
62
-<img width="368" alt="screen shot 2019-03-07 at 7 32 32 pm" src="https://user-images.githubusercontent.com/29597/54006733-653a1480-4113-11e9-907b-08ca5e27b3f9.png">
63
-
64
-Here's a [Code Sandbox demo](https://codesandbox.io/s/5wqo7z2np4).
65
-
66
-### Can I attach custom properties or event handlers?
67
-
68
-Yes, using the `outerElementType` prop.
69
-
70
-<img width="412" alt="Screen Shot 2019-03-12 at 8 58 09 AM" src="https://user-images.githubusercontent.com/29597/54215333-f9ee9a80-44a4-11e9-9142-34c67026d950.png">
71
-
72
-Here's a [Code Sandbox demo](https://codesandbox.io/s/4zqx79nww0).
73
-
74
-### Can I add gutter or padding between items?
75
-
76
-Yes, although it requires a bit of inline styling.
77
-
78
-<img width="416" alt="Screen Shot 2019-03-26 at 6 33 56 PM" src="https://user-images.githubusercontent.com/29597/55043972-c14ad700-4ff5-11e9-9caa-2e9f4d85f96c.png">
79
-
80
-Here's a [Code Sandbox demo](https://codesandbox.io/s/2w8wmlm89p).
81
-
82
-### Does this library support "sticky" items?
83
-
84
-Yes, although it requires a small amount of user code. Here's a [Code Sandbox demo](https://codesandbox.io/s/0mk3qwpl4l).
85
-
86
-## License
87
-
88
-MIT © [bvaughn](https://github.com/bvaughn)
packages/react-devtools-shared/src/node_modules/react-window/dist/index-dev.umd.js
deleted
-2
@@ -1,2 +0,0 @@
1
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e=e||self).ReactWindow={},e.React)}(this,function(e,t){"use strict";function r(){return(r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}function n(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var i=function(e,t){return e.length===t.length&&e.every(function(e,r){return n=e,o=t[r],n===o;var n,o})};function a(e,t){var r;void 0===t&&(t=i);var n,o=[],a=!1;return function(){for(var i=arguments.length,l=new Array(i),s=0;s<i;s++)l[s]=arguments[s];return a&&r===this&&t(l,o)?n:(n=e.apply(this,l),a=!0,r=this,o=l,n)}}var l="object"==typeof performance&&"function"==typeof performance.now?function(){return performance.now()}:function(){return Date.now()};function s(e){cancelAnimationFrame(e.id)}function c(e,t){var r=l();var n={id:requestAnimationFrame(function o(){l()-r>=t?e.call(null):n.id=requestAnimationFrame(o)})};return n}var u=-1;var d=null;function f(e){if(void 0===e&&(e=!1),null===d||e){var t=document.createElement("div"),r=t.style;r.width="50px",r.height="50px",r.overflow="scroll",r.direction="rtl";var n=document.createElement("div"),o=n.style;return o.width="100px",o.height="100px",t.appendChild(n),document.body.appendChild(t),t.scrollLeft>0?d="positive-descending":(t.scrollLeft=1,d=0===t.scrollLeft?"negative":"positive-ascending"),document.body.removeChild(t),d}return d}var h=150,p=function(e){var t=e.columnIndex;e.data;return e.rowIndex+":"+t},m=null,v=null,g=null;function w(e){var i,l,d=e.getColumnOffset,m=e.getColumnStartIndexForOffset,v=e.getColumnStopIndexForStartIndex,g=e.getColumnWidth,w=e.getEstimatedTotalHeight,I=e.getEstimatedTotalWidth,M=e.getOffsetForColumnAndAlignment,y=e.getOffsetForRowAndAlignment,x=e.getRowHeight,C=e.getRowOffset,_=e.getRowStartIndexForOffset,b=e.getRowStopIndexForStartIndex,R=e.initInstanceProps,T=e.shouldResetStyleCacheOnItemSizeChange,z=e.validateProps;return l=i=function(e){function i(t){var r;return(r=e.call(this,t)||this)._instanceProps=R(r.props,o(o(r))),r._resetIsScrollingTimeoutId=null,r._outerRef=void 0,r.state={instance:o(o(r)),isScrolling:!1,horizontalScrollDirection:"forward",scrollLeft:"number"==typeof r.props.initialScrollLeft?r.props.initialScrollLeft:0,scrollTop:"number"==typeof r.props.initialScrollTop?r.props.initialScrollTop:0,scrollUpdateWasRequested:!1,verticalScrollDirection:"forward"},r._callOnItemsRendered=void 0,r._callOnItemsRendered=a(function(e,t,n,o,i,a,l,s){return r.props.onItemsRendered({overscanColumnStartIndex:e,overscanColumnStopIndex:t,overscanRowStartIndex:n,overscanRowStopIndex:o,visibleColumnStartIndex:i,visibleColumnStopIndex:a,visibleRowStartIndex:l,visibleRowStopIndex:s})}),r._callOnScroll=void 0,r._callOnScroll=a(function(e,t,n,o,i){return r.props.onScroll({horizontalScrollDirection:n,scrollLeft:e,scrollTop:t,verticalScrollDirection:o,scrollUpdateWasRequested:i})}),r._getItemStyle=void 0,r._getItemStyle=function(e,t){var n,o,i=r.props,a=i.columnWidth,l=i.direction,s=i.rowHeight,c=r._getItemStyleCache(T&&a,T&&l,T&&s),u=e+":"+t;c.hasOwnProperty(u)?n=c[u]:c[u]=((o={position:"absolute"})["rtl"===l?"right":"left"]=d(r.props,t,r._instanceProps),o.top=C(r.props,e,r._instanceProps),o.height=x(r.props,e,r._instanceProps),o.width=g(r.props,t,r._instanceProps),n=o);return n},r._getItemStyleCache=void 0,r._getItemStyleCache=a(function(e,t,r){return{}}),r._onScroll=function(e){var t=e.currentTarget,n=t.clientHeight,o=t.clientWidth,i=t.scrollLeft,a=t.scrollTop,l=t.scrollHeight,s=t.scrollWidth;r.setState(function(e){if(e.scrollLeft===i&&e.scrollTop===a)return null;var t=r.props.direction,c=i;if("rtl"===t)switch(f()){case"negative":c=-i;break;case"positive-descending":c=s-o-i}c=Math.max(0,Math.min(c,s-o));var u=Math.max(0,Math.min(a,l-n));return{isScrolling:!0,horizontalScrollDirection:e.scrollLeft<i?"forward":"backward",scrollLeft:c,scrollTop:u,verticalScrollDirection:e.scrollTop<a?"forward":"backward",scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._outerRefSetter=function(e){var t=r.props.outerRef;r._outerRef=e,"function"==typeof t?t(e):null!=t&&"object"==typeof t&&t.hasOwnProperty("current")&&(t.current=e)},r._resetIsScrollingDebounced=function(){null!==r._resetIsScrollingTimeoutId&&s(r._resetIsScrollingTimeoutId),r._resetIsScrollingTimeoutId=c(r._resetIsScrolling,h)},r._resetIsScrolling=function(){r._resetIsScrollingTimeoutId=null,r.setState({isScrolling:!1},function(){r._getItemStyleCache(-1)})},r}n(i,e),i.getDerivedStateFromProps=function(e,t){return S(e,t),z(e),null};var l=i.prototype;return l.scrollTo=function(e){var t=e.scrollLeft,r=e.scrollTop;void 0!==t&&(t=Math.max(0,t)),void 0!==r&&(r=Math.max(0,r)),this.setState(function(e){return void 0===t&&(t=e.scrollLeft),void 0===r&&(r=e.scrollTop),e.scrollLeft===t&&e.scrollTop===r?null:{horizontalScrollDirection:e.scrollLeft<t?"forward":"backward",scrollLeft:t,scrollTop:r,scrollUpdateWasRequested:!0,verticalScrollDirection:e.scrollTop<r?"forward":"backward"}},this._resetIsScrollingDebounced)},l.scrollToItem=function(e){var t=e.align,r=void 0===t?"auto":t,n=e.columnIndex,o=e.rowIndex,i=this.props,a=i.columnCount,l=i.height,s=i.rowCount,c=i.width,d=this.state,f=d.scrollLeft,h=d.scrollTop,p=function(e){if(void 0===e&&(e=!1),-1===u||e){var t=document.createElement("div"),r=t.style;r.width="50px",r.height="50px",r.overflow="scroll",document.body.appendChild(t),u=t.offsetWidth-t.clientWidth,document.body.removeChild(t)}return u}();void 0!==n&&(n=Math.max(0,Math.min(n,a-1))),void 0!==o&&(o=Math.max(0,Math.min(o,s-1)));var m=w(this.props,this._instanceProps),v=I(this.props,this._instanceProps)>c?p:0,g=m>l?p:0;this.scrollTo({scrollLeft:void 0!==n?M(this.props,n,r,f,this._instanceProps,g):f,scrollTop:void 0!==o?y(this.props,o,r,h,this._instanceProps,v):h})},l.componentDidMount=function(){var e=this.props,t=e.initialScrollLeft,r=e.initialScrollTop;if(null!=this._outerRef){var n=this._outerRef;"number"==typeof t&&(n.scrollLeft=t),"number"==typeof r&&(n.scrollTop=r)}this._callPropsCallbacks()},l.componentDidUpdate=function(){var e=this.props.direction,t=this.state,r=t.scrollLeft,n=t.scrollTop;if(t.scrollUpdateWasRequested&&null!=this._outerRef){var o=this._outerRef;if("rtl"===e)switch(f()){case"negative":o.scrollLeft=-r;break;case"positive-ascending":o.scrollLeft=r;break;default:var i=o.clientWidth,a=o.scrollWidth;o.scrollLeft=a-i-r}else o.scrollLeft=Math.max(0,r);o.scrollTop=Math.max(0,n)}this._callPropsCallbacks()},l.componentWillUnmount=function(){null!==this._resetIsScrollingTimeoutId&&s(this._resetIsScrollingTimeoutId)},l.render=function(){var e=this.props,n=e.children,o=e.className,i=e.columnCount,a=e.direction,l=e.height,s=e.innerRef,c=e.innerElementType,u=e.innerTagName,d=e.itemData,f=e.itemKey,h=void 0===f?p:f,m=e.outerElementType,v=e.outerTagName,g=e.rowCount,S=e.style,M=e.useIsScrolling,y=e.width,x=this.state.isScrolling,C=this._getHorizontalRangeToRender(),_=C[0],b=C[1],R=this._getVerticalRangeToRender(),T=R[0],z=R[1],O=[];if(i>0&&g)for(var P=T;P<=z;P++)for(var W=_;W<=b;W++)O.push(t.createElement(n,{columnIndex:W,data:d,isScrolling:M?x:void 0,key:h({columnIndex:W,data:d,rowIndex:P}),rowIndex:P,style:this._getItemStyle(P,W)}));var E=w(this.props,this._instanceProps),A=I(this.props,this._instanceProps);return t.createElement(m||v||"div",{className:o,onScroll:this._onScroll,ref:this._outerRefSetter,style:r({position:"relative",height:l,width:y,overflow:"auto",WebkitOverflowScrolling:"touch",willChange:"transform",direction:a},S)},t.createElement(c||u||"div",{children:O,ref:s,style:{height:E,pointerEvents:x?"none":void 0,width:A}}))},l._callPropsCallbacks=function(){var e=this.props,t=e.columnCount,r=e.onItemsRendered,n=e.onScroll,o=e.rowCount;if("function"==typeof r&&t>0&&o>0){var i=this._getHorizontalRangeToRender(),a=i[0],l=i[1],s=i[2],c=i[3],u=this._getVerticalRangeToRender(),d=u[0],f=u[1],h=u[2],p=u[3];this._callOnItemsRendered(a,l,d,f,s,c,h,p)}if("function"==typeof n){var m=this.state,v=m.horizontalScrollDirection,g=m.scrollLeft,w=m.scrollTop,S=m.scrollUpdateWasRequested,I=m.verticalScrollDirection;this._callOnScroll(g,w,v,I,S)}},l._getHorizontalRangeToRender=function(){var e=this.props,t=e.columnCount,r=e.overscanColumnCount,n=e.overscanColumnsCount,o=e.overscanCount,i=e.rowCount,a=this.state,l=a.horizontalScrollDirection,s=a.isScrolling,c=a.scrollLeft,u=r||n||o||1;if(0===t||0===i)return[0,0,0,0];var d=m(this.props,c,this._instanceProps),f=v(this.props,d,c,this._instanceProps),h=s&&"backward"!==l?1:Math.max(1,u),p=s&&"forward"!==l?1:Math.max(1,u);return[Math.max(0,d-h),Math.max(0,Math.min(t-1,f+p)),d,f]},l._getVerticalRangeToRender=function(){var e=this.props,t=e.columnCount,r=e.overscanCount,n=e.overscanRowCount,o=e.overscanRowsCount,i=e.rowCount,a=this.state,l=a.isScrolling,s=a.verticalScrollDirection,c=a.scrollTop,u=n||o||r||1;if(0===t||0===i)return[0,0,0,0];var d=_(this.props,c,this._instanceProps),f=b(this.props,d,c,this._instanceProps),h=l&&"backward"!==s?1:Math.max(1,u),p=l&&"forward"!==s?1:Math.max(1,u);return[Math.max(0,d-h),Math.max(0,Math.min(i-1,f+p)),d,f]},i}(t.PureComponent),i.defaultProps={direction:"ltr",itemData:void 0,useIsScrolling:!1},l}"undefined"!=typeof window&&void 0!==window.WeakSet&&(m=new WeakSet,v=new WeakSet,g=new WeakSet);var S=function(e,t){var r=e.children,n=e.direction,o=e.height,i=e.innerTagName,a=e.outerTagName,l=e.overscanColumnsCount,s=e.overscanCount,c=e.overscanRowsCount,u=e.width,d=t.instance;if("number"==typeof s&&m&&!m.has(d)&&(m.add(d),console.warn("The overscanCount prop has been deprecated. Please use the overscanColumnCount and overscanRowCount props instead.")),"number"!=typeof l&&"number"!=typeof c||v&&!v.has(d)&&(v.add(d),console.warn("The overscanColumnsCount and overscanRowsCount props have been deprecated. Please use the overscanColumnCount and overscanRowCount props instead.")),null==i&&null==a||g&&!g.has(d)&&(g.add(d),console.warn("The innerTagName and outerTagName props have been deprecated. Please use the innerElementType and outerElementType props instead.")),null==r)throw Error('An invalid "children" prop has been specified. Value should be a React component. "'+(null===r?"null":typeof r)+'" was specified.');switch(n){case"ltr":case"rtl":break;default:throw Error('An invalid "direction" prop has been specified. Value should be either "ltr" or "rtl". "'+n+'" was specified.')}if("number"!=typeof u)throw Error('An invalid "width" prop has been specified. Grids must specify a number for width. "'+(null===u?"null":typeof u)+'" was specified.');if("number"!=typeof o)throw Error('An invalid "height" prop has been specified. Grids must specify a number for height. "'+(null===o?"null":typeof o)+'" was specified.')},I=function(e,t){var r=e.rowCount,n=t.rowMetadataMap,o=t.estimatedRowHeight,i=t.lastMeasuredRowIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=n[i];a=l.offset+l.size}return a+(r-i-1)*o},M=function(e,t){var r=e.columnCount,n=t.columnMetadataMap,o=t.estimatedColumnWidth,i=t.lastMeasuredColumnIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=n[i];a=l.offset+l.size}return a+(r-i-1)*o},y=function(e,t,r,n){var o,i,a;if("column"===e?(o=n.columnMetadataMap,i=t.columnWidth,a=n.lastMeasuredColumnIndex):(o=n.rowMetadataMap,i=t.rowHeight,a=n.lastMeasuredRowIndex),r>a){var l=0;if(a>=0){var s=o[a];l=s.offset+s.size}for(var c=a+1;c<=r;c++){var u=i(c);o[c]={offset:l,size:u},l+=u}"column"===e?n.lastMeasuredColumnIndex=r:n.lastMeasuredRowIndex=r}return o[r]},x=function(e,t,r,n){var o,i;return"column"===e?(o=r.columnMetadataMap,i=r.lastMeasuredColumnIndex):(o=r.rowMetadataMap,i=r.lastMeasuredRowIndex),(i>0?o[i].offset:0)>=n?C(e,t,r,i,0,n):_(e,t,r,Math.max(0,i),n)},C=function(e,t,r,n,o,i){for(;o<=n;){var a=o+Math.floor((n-o)/2),l=y(e,t,a,r).offset;if(l===i)return a;l<i?o=a+1:l>i&&(n=a-1)}return o>0?o-1:0},_=function(e,t,r,n,o){for(var i="column"===e?t.columnCount:t.rowCount,a=1;n<i&&y(e,t,n,r).offset<o;)n+=a,a*=2;return C(e,t,r,Math.min(n,i-1),Math.floor(n/2),o)},b=function(e,t,r,n,o,i,a){var l="column"===e?t.width:t.height,s=y(e,t,r,i),c="column"===e?M(t,i):I(t,i),u=Math.max(0,Math.min(c-l,s.offset)),d=Math.max(0,s.offset-l+a+s.size);switch("smart"===n&&(n=o>=d-l&&o<=u+l?"auto":"center"),n){case"start":return u;case"end":return d;case"center":return Math.round(d+(u-d)/2);case"auto":default:return o>=d&&o<=u?o:d>u?d:o<d?d:u}},R=w({getColumnOffset:function(e,t,r){return y("column",e,t,r).offset},getColumnStartIndexForOffset:function(e,t,r){return x("column",e,r,t)},getColumnStopIndexForStartIndex:function(e,t,r,n){for(var o=e.columnCount,i=e.width,a=y("column",e,t,n),l=r+i,s=a.offset+a.size,c=t;c<o-1&&s<l;)s+=y("column",e,++c,n).size;return c},getColumnWidth:function(e,t,r){return r.columnMetadataMap[t].size},getEstimatedTotalHeight:I,getEstimatedTotalWidth:M,getOffsetForColumnAndAlignment:function(e,t,r,n,o,i){return b("column",e,t,r,n,o,i)},getOffsetForRowAndAlignment:function(e,t,r,n,o,i){return b("row",e,t,r,n,o,i)},getRowOffset:function(e,t,r){return y("row",e,t,r).offset},getRowHeight:function(e,t,r){return r.rowMetadataMap[t].size},getRowStartIndexForOffset:function(e,t,r){return x("row",e,r,t)},getRowStopIndexForStartIndex:function(e,t,r,n){for(var o=e.rowCount,i=e.height,a=y("row",e,t,n),l=r+i,s=a.offset+a.size,c=t;c<o-1&&s<l;)s+=y("row",e,++c,n).size;return c},initInstanceProps:function(e,t){var r=e,n={columnMetadataMap:{},estimatedColumnWidth:r.estimatedColumnWidth||50,estimatedRowHeight:r.estimatedRowHeight||50,lastMeasuredColumnIndex:-1,lastMeasuredRowIndex:-1,rowMetadataMap:{}};return t.resetAfterColumnIndex=function(e,r){void 0===r&&(r=!0),t.resetAfterIndices({columnIndex:e,shouldForceUpdate:r})},t.resetAfterRowIndex=function(e,r){void 0===r&&(r=!0),t.resetAfterIndices({rowIndex:e,shouldForceUpdate:r})},t.resetAfterIndices=function(e){var r=e.columnIndex,o=e.rowIndex,i=e.shouldForceUpdate,a=void 0===i||i;"number"==typeof r&&(n.lastMeasuredColumnIndex=Math.min(n.lastMeasuredColumnIndex,r-1)),"number"==typeof o&&(n.lastMeasuredRowIndex=Math.min(n.lastMeasuredRowIndex,o-1)),t._getItemStyleCache(-1),a&&t.forceUpdate()},n},shouldResetStyleCacheOnItemSizeChange:!1,validateProps:function(e){var t=e.columnWidth,r=e.rowHeight;if("function"!=typeof t)throw Error('An invalid "columnWidth" prop has been specified. Value should be a function. "'+(null===t?"null":typeof t)+'" was specified.');if("function"!=typeof r)throw Error('An invalid "rowHeight" prop has been specified. Value should be a function. "'+(null===r?"null":typeof r)+'" was specified.')}}),T=150,z=function(e,t){return e},O=null,P=null;function W(e){var i,l,u=e.getItemOffset,d=e.getEstimatedTotalSize,h=e.getItemSize,p=e.getOffsetForIndexAndAlignment,m=e.getStartIndexForOffset,v=e.getStopIndexForStartIndex,g=e.initInstanceProps,w=e.shouldResetStyleCacheOnItemSizeChange,S=e.validateProps;return l=i=function(e){function i(t){var r;return(r=e.call(this,t)||this)._instanceProps=g(r.props,o(o(r))),r._outerRef=void 0,r._resetIsScrollingTimeoutId=null,r.state={instance:o(o(r)),isScrolling:!1,scrollDirection:"forward",scrollOffset:"number"==typeof r.props.initialScrollOffset?r.props.initialScrollOffset:0,scrollUpdateWasRequested:!1},r._callOnItemsRendered=void 0,r._callOnItemsRendered=a(function(e,t,n,o){return r.props.onItemsRendered({overscanStartIndex:e,overscanStopIndex:t,visibleStartIndex:n,visibleStopIndex:o})}),r._callOnScroll=void 0,r._callOnScroll=a(function(e,t,n){return r.props.onScroll({scrollDirection:e,scrollOffset:t,scrollUpdateWasRequested:n})}),r._getItemStyle=void 0,r._getItemStyle=function(e){var t,n=r.props,o=n.direction,i=n.itemSize,a=n.layout,l=r._getItemStyleCache(w&&i,w&&a,w&&o);if(l.hasOwnProperty(e))t=l[e];else{var s,c=u(r.props,e,r._instanceProps),d=h(r.props,e,r._instanceProps),f="horizontal"===o||"horizontal"===a;l[e]=((s={position:"absolute"})["rtl"===o?"right":"left"]=f?c:0,s.top=f?0:c,s.height=f?"100%":d,s.width=f?d:"100%",t=s)}return t},r._getItemStyleCache=void 0,r._getItemStyleCache=a(function(e,t,r){return{}}),r._onScrollHorizontal=function(e){var t=e.currentTarget,n=t.clientWidth,o=t.scrollLeft,i=t.scrollWidth;r.setState(function(e){if(e.scrollOffset===o)return null;var t=r.props.direction,a=o;if("rtl"===t)switch(f()){case"negative":a=-o;break;case"positive-descending":a=i-n-o}return a=Math.max(0,Math.min(a,i-n)),{isScrolling:!0,scrollDirection:e.scrollOffset<o?"forward":"backward",scrollOffset:a,scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._onScrollVertical=function(e){var t=e.currentTarget,n=t.clientHeight,o=t.scrollHeight,i=t.scrollTop;r.setState(function(e){if(e.scrollOffset===i)return null;var t=Math.max(0,Math.min(i,o-n));return{isScrolling:!0,scrollDirection:e.scrollOffset<t?"forward":"backward",scrollOffset:t,scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._outerRefSetter=function(e){var t=r.props.outerRef;r._outerRef=e,"function"==typeof t?t(e):null!=t&&"object"==typeof t&&t.hasOwnProperty("current")&&(t.current=e)},r._resetIsScrollingDebounced=function(){null!==r._resetIsScrollingTimeoutId&&s(r._resetIsScrollingTimeoutId),r._resetIsScrollingTimeoutId=c(r._resetIsScrolling,T)},r._resetIsScrolling=function(){r._resetIsScrollingTimeoutId=null,r.setState({isScrolling:!1},function(){r._getItemStyleCache(-1,null)})},r}n(i,e),i.getDerivedStateFromProps=function(e,t){return E(e,t),S(e),null};var l=i.prototype;return l.scrollTo=function(e){e=Math.max(0,e),this.setState(function(t){return t.scrollOffset===e?null:{scrollDirection:t.scrollOffset<e?"forward":"backward",scrollOffset:e,scrollUpdateWasRequested:!0}},this._resetIsScrollingDebounced)},l.scrollToItem=function(e,t){void 0===t&&(t="auto");var r=this.props.itemCount,n=this.state.scrollOffset;e=Math.max(0,Math.min(e,r-1)),this.scrollTo(p(this.props,e,t,n,this._instanceProps))},l.componentDidMount=function(){var e=this.props,t=e.direction,r=e.initialScrollOffset,n=e.layout;if("number"==typeof r&&null!=this._outerRef){var o=this._outerRef;"horizontal"===t||"horizontal"===n?o.scrollLeft=r:o.scrollTop=r}this._callPropsCallbacks()},l.componentDidUpdate=function(){var e=this.props,t=e.direction,r=e.layout,n=this.state,o=n.scrollOffset;if(n.scrollUpdateWasRequested&&null!=this._outerRef){var i=this._outerRef;if("horizontal"===t||"horizontal"===r)if("rtl"===t)switch(f()){case"negative":i.scrollLeft=-o;break;case"positive-ascending":i.scrollLeft=o;break;default:var a=i.clientWidth,l=i.scrollWidth;i.scrollLeft=l-a-o}else i.scrollLeft=o;else i.scrollTop=o}this._callPropsCallbacks()},l.componentWillUnmount=function(){null!==this._resetIsScrollingTimeoutId&&s(this._resetIsScrollingTimeoutId)},l.render=function(){var e=this.props,n=e.children,o=e.className,i=e.direction,a=e.height,l=e.innerRef,s=e.innerElementType,c=e.innerTagName,u=e.itemCount,f=e.itemData,h=e.itemKey,p=void 0===h?z:h,m=e.layout,v=e.outerElementType,g=e.outerTagName,w=e.style,S=e.useIsScrolling,I=e.width,M=this.state.isScrolling,y="horizontal"===i||"horizontal"===m,x=y?this._onScrollHorizontal:this._onScrollVertical,C=this._getRangeToRender(),_=C[0],b=C[1],R=[];if(u>0)for(var T=_;T<=b;T++)R.push(t.createElement(n,{data:f,key:p(T,f),index:T,isScrolling:S?M:void 0,style:this._getItemStyle(T)}));var O=d(this.props,this._instanceProps);return t.createElement(v||g||"div",{className:o,onScroll:x,ref:this._outerRefSetter,style:r({position:"relative",height:a,width:I,overflow:"auto",WebkitOverflowScrolling:"touch",willChange:"transform",direction:i},w)},t.createElement(s||c||"div",{children:R,ref:l,style:{height:y?"100%":O,pointerEvents:M?"none":void 0,width:y?O:"100%"}}))},l._callPropsCallbacks=function(){if("function"==typeof this.props.onItemsRendered&&this.props.itemCount>0){var e=this._getRangeToRender(),t=e[0],r=e[1],n=e[2],o=e[3];this._callOnItemsRendered(t,r,n,o)}if("function"==typeof this.props.onScroll){var i=this.state,a=i.scrollDirection,l=i.scrollOffset,s=i.scrollUpdateWasRequested;this._callOnScroll(a,l,s)}},l._getRangeToRender=function(){var e=this.props,t=e.itemCount,r=e.overscanCount,n=this.state,o=n.isScrolling,i=n.scrollDirection,a=n.scrollOffset;if(0===t)return[0,0,0,0];var l=m(this.props,a,this._instanceProps),s=v(this.props,l,a,this._instanceProps),c=o&&"backward"!==i?1:Math.max(1,r),u=o&&"forward"!==i?1:Math.max(1,r);return[Math.max(0,l-c),Math.max(0,Math.min(t-1,s+u)),l,s]},i}(t.PureComponent),i.defaultProps={direction:"ltr",itemData:void 0,layout:"vertical",overscanCount:2,useIsScrolling:!1},l}"undefined"!=typeof window&&void 0!==window.WeakSet&&(O=new WeakSet,P=new WeakSet);var E=function(e,t){var r=e.children,n=e.direction,o=e.height,i=e.layout,a=e.innerTagName,l=e.outerTagName,s=e.width,c=t.instance;null==a&&null==l||P&&!P.has(c)&&(P.add(c),console.warn("The innerTagName and outerTagName props have been deprecated. Please use the innerElementType and outerElementType props instead."));var u="horizontal"===n||"horizontal"===i;switch(n){case"horizontal":case"vertical":O&&!O.has(c)&&(O.add(c),console.warn('The direction prop should be either "ltr" (default) or "rtl". Please use the layout prop to specify "vertical" (default) or "horizontal" orientation.'));break;case"ltr":case"rtl":break;default:throw Error('An invalid "direction" prop has been specified. Value should be either "ltr" or "rtl". "'+n+'" was specified.')}switch(i){case"horizontal":case"vertical":break;default:throw Error('An invalid "layout" prop has been specified. Value should be either "horizontal" or "vertical". "'+i+'" was specified.')}if(null==r)throw Error('An invalid "children" prop has been specified. Value should be a React component. "'+(null===r?"null":typeof r)+'" was specified.');if(u&&"number"!=typeof s)throw Error('An invalid "width" prop has been specified. Horizontal lists must specify a number for width. "'+(null===s?"null":typeof s)+'" was specified.');if(!u&&"number"!=typeof o)throw Error('An invalid "height" prop has been specified. Vertical lists must specify a number for height. "'+(null===o?"null":typeof o)+'" was specified.')},A=function(e,t,r){var n=e.itemSize,o=r.itemMetadataMap,i=r.lastMeasuredIndex;if(t>i){var a=0;if(i>=0){var l=o[i];a=l.offset+l.size}for(var s=i+1;s<=t;s++){var c=n(s);o[s]={offset:a,size:c},a+=c}r.lastMeasuredIndex=t}return o[t]},k=function(e,t,r,n,o){for(;n<=r;){var i=n+Math.floor((r-n)/2),a=A(e,i,t).offset;if(a===o)return i;a<o?n=i+1:a>o&&(r=i-1)}return n>0?n-1:0},D=function(e,t,r,n){for(var o=e.itemCount,i=1;r<o&&A(e,r,t).offset<n;)r+=i,i*=2;return k(e,t,Math.min(r,o-1),Math.floor(r/2),n)},F=function(e,t){var r=e.itemCount,n=t.itemMetadataMap,o=t.estimatedItemSize,i=t.lastMeasuredIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=n[i];a=l.offset+l.size}return a+(r-i-1)*o},L=W({getItemOffset:function(e,t,r){return A(e,t,r).offset},getItemSize:function(e,t,r){return r.itemMetadataMap[t].size},getEstimatedTotalSize:F,getOffsetForIndexAndAlignment:function(e,t,r,n,o){var i=e.direction,a=e.height,l=e.layout,s=e.width,c="horizontal"===i||"horizontal"===l?s:a,u=A(e,t,o),d=F(e,o),f=Math.max(0,Math.min(d-c,u.offset)),h=Math.max(0,u.offset-c+u.size);switch("smart"===r&&(r=n>=h-c&&n<=f+c?"auto":"center"),r){case"start":return f;case"end":return h;case"center":return Math.round(h+(f-h)/2);case"auto":default:return n>=h&&n<=f?n:n<h?h:f}},getStartIndexForOffset:function(e,t,r){return function(e,t,r){var n=t.itemMetadataMap,o=t.lastMeasuredIndex;return(o>0?n[o].offset:0)>=r?k(e,t,o,0,r):D(e,t,Math.max(0,o),r)}(e,r,t)},getStopIndexForStartIndex:function(e,t,r,n){for(var o=e.direction,i=e.height,a=e.itemCount,l=e.layout,s=e.width,c="horizontal"===o||"horizontal"===l?s:i,u=A(e,t,n),d=r+c,f=u.offset+u.size,h=t;h<a-1&&f<d;)f+=A(e,++h,n).size;return h},initInstanceProps:function(e,t){var r={itemMetadataMap:{},estimatedItemSize:e.estimatedItemSize||50,lastMeasuredIndex:-1};return t.resetAfterIndex=function(e,n){void 0===n&&(n=!0),r.lastMeasuredIndex=Math.min(r.lastMeasuredIndex,e-1),t._getItemStyleCache(-1),n&&t.forceUpdate()},r},shouldResetStyleCacheOnItemSizeChange:!1,validateProps:function(e){var t=e.itemSize;if("function"!=typeof t)throw Error('An invalid "itemSize" prop has been specified. Value should be a function. "'+(null===t?"null":typeof t)+'" was specified.')}}),H=w({getColumnOffset:function(e,t){return t*e.columnWidth},getColumnWidth:function(e,t){return e.columnWidth},getRowOffset:function(e,t){return t*e.rowHeight},getRowHeight:function(e,t){return e.rowHeight},getEstimatedTotalHeight:function(e){var t=e.rowCount;return e.rowHeight*t},getEstimatedTotalWidth:function(e){var t=e.columnCount;return e.columnWidth*t},getOffsetForColumnAndAlignment:function(e,t,r,n,o,i){var a=e.columnCount,l=e.columnWidth,s=e.width,c=Math.max(0,a*l-s),u=Math.min(c,t*l),d=Math.max(0,t*l-s+i+l);switch("smart"===r&&(r=n>=d-s&&n<=u+s?"auto":"center"),r){case"start":return u;case"end":return d;case"center":var f=Math.round(d+(u-d)/2);return f<Math.ceil(s/2)?0:f>c+Math.floor(s/2)?c:f;case"auto":default:return n>=d&&n<=u?n:d>u?d:n<d?d:u}},getOffsetForRowAndAlignment:function(e,t,r,n,o,i){var a=e.rowHeight,l=e.height,s=e.rowCount,c=Math.max(0,s*a-l),u=Math.min(c,t*a),d=Math.max(0,t*a-l+i+a);switch("smart"===r&&(r=n>=d-l&&n<=u+l?"auto":"center"),r){case"start":return u;case"end":return d;case"center":var f=Math.round(d+(u-d)/2);return f<Math.ceil(l/2)?0:f>c+Math.floor(l/2)?c:f;case"auto":default:return n>=d&&n<=u?n:d>u?d:n<d?d:u}},getColumnStartIndexForOffset:function(e,t){var r=e.columnWidth,n=e.columnCount;return Math.max(0,Math.min(n-1,Math.floor(t/r)))},getColumnStopIndexForStartIndex:function(e,t,r){var n=e.columnWidth,o=e.columnCount,i=e.width,a=t*n,l=Math.ceil((i+r-a)/n);return Math.max(0,Math.min(o-1,t+l-1))},getRowStartIndexForOffset:function(e,t){var r=e.rowHeight,n=e.rowCount;return Math.max(0,Math.min(n-1,Math.floor(t/r)))},getRowStopIndexForStartIndex:function(e,t,r){var n=e.rowHeight,o=e.rowCount,i=e.height,a=t*n,l=Math.ceil((i+r-a)/n);return Math.max(0,Math.min(o-1,t+l-1))},initInstanceProps:function(e){},shouldResetStyleCacheOnItemSizeChange:!0,validateProps:function(e){var t=e.columnWidth,r=e.rowHeight;if("number"!=typeof t)throw Error('An invalid "columnWidth" prop has been specified. Value should be a number. "'+(null===t?"null":typeof t)+'" was specified.');if("number"!=typeof r)throw Error('An invalid "rowHeight" prop has been specified. Value should be a number. "'+(null===r?"null":typeof r)+'" was specified.')}}),U=W({getItemOffset:function(e,t){return t*e.itemSize},getItemSize:function(e,t){return e.itemSize},getEstimatedTotalSize:function(e){var t=e.itemCount;return e.itemSize*t},getOffsetForIndexAndAlignment:function(e,t,r,n){var o=e.direction,i=e.height,a=e.itemCount,l=e.itemSize,s=e.layout,c=e.width,u="horizontal"===o||"horizontal"===s?c:i,d=Math.max(0,a*l-u),f=Math.min(d,t*l),h=Math.max(0,t*l-u+l);switch("smart"===r&&(r=n>=h-u&&n<=f+u?"auto":"center"),r){case"start":return f;case"end":return h;case"center":var p=Math.round(h+(f-h)/2);return p<Math.ceil(u/2)?0:p>d+Math.floor(u/2)?d:p;case"auto":default:return n>=h&&n<=f?n:n<h?h:f}},getStartIndexForOffset:function(e,t){var r=e.itemCount,n=e.itemSize;return Math.max(0,Math.min(r-1,Math.floor(t/n)))},getStopIndexForStartIndex:function(e,t,r){var n=e.direction,o=e.height,i=e.itemCount,a=e.itemSize,l=e.layout,s=e.width,c=t*a,u="horizontal"===n||"horizontal"===l?s:o,d=Math.ceil((u+r-c)/a);return Math.max(0,Math.min(i-1,t+d-1))},initInstanceProps:function(e){},shouldResetStyleCacheOnItemSizeChange:!0,validateProps:function(e){var t=e.itemSize;if("number"!=typeof t)throw Error('An invalid "itemSize" prop has been specified. Value should be a number. "'+(null===t?"null":typeof t)+'" was specified.')}});function V(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}function q(e,t){for(var r in e)if(!(r in t))return!0;for(var n in t)if(e[n]!==t[n])return!0;return!1}function N(e,t){var r=e.style,n=V(e,["style"]),o=t.style,i=V(t,["style"]);return!q(r,o)&&!q(n,i)}e.VariableSizeGrid=R,e.VariableSizeList=L,e.FixedSizeGrid=H,e.FixedSizeList=U,e.areEqual=N,e.shouldComponentUpdate=function(e,t){return!N(this.props,e)||q(this.state,t)},Object.defineProperty(e,"__esModule",{value:!0})});
2
-//# sourceMappingURL=index-dev.umd.js.map
packages/react-devtools-shared/src/node_modules/react-window/dist/index-prod.umd.js
deleted
-2
@@ -1,2 +0,0 @@
1
-!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],e):e((t=t||self).ReactWindow={},t.React)}(this,function(t,e){"use strict";function r(){return(r=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(t[o]=r[o])}return t}).apply(this,arguments)}function o(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,t.__proto__=e}function n(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}var i=function(t,e){return t.length===e.length&&t.every(function(t,r){return o=t,n=e[r],o===n;var o,n})};function a(t,e){var r;void 0===e&&(e=i);var o,n=[],a=!1;return function(){for(var i=arguments.length,l=new Array(i),s=0;s<i;s++)l[s]=arguments[s];return a&&r===this&&e(l,n)?o:(o=t.apply(this,l),a=!0,r=this,n=l,o)}}var l="object"==typeof performance&&"function"==typeof performance.now?function(){return performance.now()}:function(){return Date.now()};function s(t){cancelAnimationFrame(t.id)}function c(t,e){var r=l();var o={id:requestAnimationFrame(function n(){l()-r>=e?t.call(null):o.id=requestAnimationFrame(n)})};return o}var u=-1;var f=null;function d(t){if(void 0===t&&(t=!1),null===f||t){var e=document.createElement("div"),r=e.style;r.width="50px",r.height="50px",r.overflow="scroll",r.direction="rtl";var o=document.createElement("div"),n=o.style;return n.width="100px",n.height="100px",e.appendChild(o),document.body.appendChild(e),e.scrollLeft>0?f="positive-descending":(e.scrollLeft=1,f=0===e.scrollLeft?"negative":"positive-ascending"),document.body.removeChild(e),f}return f}var h=150,m=function(t){var e=t.columnIndex;t.data;return t.rowIndex+":"+e};function p(t){var i,l,f=t.getColumnOffset,p=t.getColumnStartIndexForOffset,v=t.getColumnStopIndexForStartIndex,S=t.getColumnWidth,I=t.getEstimatedTotalHeight,w=t.getEstimatedTotalWidth,M=t.getOffsetForColumnAndAlignment,x=t.getOffsetForRowAndAlignment,_=t.getRowHeight,C=t.getRowOffset,R=t.getRowStartIndexForOffset,y=t.getRowStopIndexForStartIndex,T=t.initInstanceProps,O=t.shouldResetStyleCacheOnItemSizeChange,z=t.validateProps;return l=i=function(t){function i(e){var r;return(r=t.call(this,e)||this)._instanceProps=T(r.props,n(n(r))),r._resetIsScrollingTimeoutId=null,r._outerRef=void 0,r.state={instance:n(n(r)),isScrolling:!1,horizontalScrollDirection:"forward",scrollLeft:"number"==typeof r.props.initialScrollLeft?r.props.initialScrollLeft:0,scrollTop:"number"==typeof r.props.initialScrollTop?r.props.initialScrollTop:0,scrollUpdateWasRequested:!1,verticalScrollDirection:"forward"},r._callOnItemsRendered=void 0,r._callOnItemsRendered=a(function(t,e,o,n,i,a,l,s){return r.props.onItemsRendered({overscanColumnStartIndex:t,overscanColumnStopIndex:e,overscanRowStartIndex:o,overscanRowStopIndex:n,visibleColumnStartIndex:i,visibleColumnStopIndex:a,visibleRowStartIndex:l,visibleRowStopIndex:s})}),r._callOnScroll=void 0,r._callOnScroll=a(function(t,e,o,n,i){return r.props.onScroll({horizontalScrollDirection:o,scrollLeft:t,scrollTop:e,verticalScrollDirection:n,scrollUpdateWasRequested:i})}),r._getItemStyle=void 0,r._getItemStyle=function(t,e){var o,n,i=r.props,a=i.columnWidth,l=i.direction,s=i.rowHeight,c=r._getItemStyleCache(O&&a,O&&l,O&&s),u=t+":"+e;c.hasOwnProperty(u)?o=c[u]:c[u]=((n={position:"absolute"})["rtl"===l?"right":"left"]=f(r.props,e,r._instanceProps),n.top=C(r.props,t,r._instanceProps),n.height=_(r.props,t,r._instanceProps),n.width=S(r.props,e,r._instanceProps),o=n);return o},r._getItemStyleCache=void 0,r._getItemStyleCache=a(function(t,e,r){return{}}),r._onScroll=function(t){var e=t.currentTarget,o=e.clientHeight,n=e.clientWidth,i=e.scrollLeft,a=e.scrollTop,l=e.scrollHeight,s=e.scrollWidth;r.setState(function(t){if(t.scrollLeft===i&&t.scrollTop===a)return null;var e=r.props.direction,c=i;if("rtl"===e)switch(d()){case"negative":c=-i;break;case"positive-descending":c=s-n-i}c=Math.max(0,Math.min(c,s-n));var u=Math.max(0,Math.min(a,l-o));return{isScrolling:!0,horizontalScrollDirection:t.scrollLeft<i?"forward":"backward",scrollLeft:c,scrollTop:u,verticalScrollDirection:t.scrollTop<a?"forward":"backward",scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._outerRefSetter=function(t){var e=r.props.outerRef;r._outerRef=t,"function"==typeof e?e(t):null!=e&&"object"==typeof e&&e.hasOwnProperty("current")&&(e.current=t)},r._resetIsScrollingDebounced=function(){null!==r._resetIsScrollingTimeoutId&&s(r._resetIsScrollingTimeoutId),r._resetIsScrollingTimeoutId=c(r._resetIsScrolling,h)},r._resetIsScrolling=function(){r._resetIsScrollingTimeoutId=null,r.setState({isScrolling:!1},function(){r._getItemStyleCache(-1)})},r}o(i,t),i.getDerivedStateFromProps=function(t,e){return g(t,e),z(t),null};var l=i.prototype;return l.scrollTo=function(t){var e=t.scrollLeft,r=t.scrollTop;void 0!==e&&(e=Math.max(0,e)),void 0!==r&&(r=Math.max(0,r)),this.setState(function(t){return void 0===e&&(e=t.scrollLeft),void 0===r&&(r=t.scrollTop),t.scrollLeft===e&&t.scrollTop===r?null:{horizontalScrollDirection:t.scrollLeft<e?"forward":"backward",scrollLeft:e,scrollTop:r,scrollUpdateWasRequested:!0,verticalScrollDirection:t.scrollTop<r?"forward":"backward"}},this._resetIsScrollingDebounced)},l.scrollToItem=function(t){var e=t.align,r=void 0===e?"auto":e,o=t.columnIndex,n=t.rowIndex,i=this.props,a=i.columnCount,l=i.height,s=i.rowCount,c=i.width,f=this.state,d=f.scrollLeft,h=f.scrollTop,m=function(t){if(void 0===t&&(t=!1),-1===u||t){var e=document.createElement("div"),r=e.style;r.width="50px",r.height="50px",r.overflow="scroll",document.body.appendChild(e),u=e.offsetWidth-e.clientWidth,document.body.removeChild(e)}return u}();void 0!==o&&(o=Math.max(0,Math.min(o,a-1))),void 0!==n&&(n=Math.max(0,Math.min(n,s-1)));var p=I(this.props,this._instanceProps),g=w(this.props,this._instanceProps)>c?m:0,v=p>l?m:0;this.scrollTo({scrollLeft:void 0!==o?M(this.props,o,r,d,this._instanceProps,v):d,scrollTop:void 0!==n?x(this.props,n,r,h,this._instanceProps,g):h})},l.componentDidMount=function(){var t=this.props,e=t.initialScrollLeft,r=t.initialScrollTop;if(null!=this._outerRef){var o=this._outerRef;"number"==typeof e&&(o.scrollLeft=e),"number"==typeof r&&(o.scrollTop=r)}this._callPropsCallbacks()},l.componentDidUpdate=function(){var t=this.props.direction,e=this.state,r=e.scrollLeft,o=e.scrollTop;if(e.scrollUpdateWasRequested&&null!=this._outerRef){var n=this._outerRef;if("rtl"===t)switch(d()){case"negative":n.scrollLeft=-r;break;case"positive-ascending":n.scrollLeft=r;break;default:var i=n.clientWidth,a=n.scrollWidth;n.scrollLeft=a-i-r}else n.scrollLeft=Math.max(0,r);n.scrollTop=Math.max(0,o)}this._callPropsCallbacks()},l.componentWillUnmount=function(){null!==this._resetIsScrollingTimeoutId&&s(this._resetIsScrollingTimeoutId)},l.render=function(){var t=this.props,o=t.children,n=t.className,i=t.columnCount,a=t.direction,l=t.height,s=t.innerRef,c=t.innerElementType,u=t.innerTagName,f=t.itemData,d=t.itemKey,h=void 0===d?m:d,p=t.outerElementType,g=t.outerTagName,v=t.rowCount,S=t.style,M=t.useIsScrolling,x=t.width,_=this.state.isScrolling,C=this._getHorizontalRangeToRender(),R=C[0],y=C[1],T=this._getVerticalRangeToRender(),O=T[0],z=T[1],b=[];if(i>0&&v)for(var P=O;P<=z;P++)for(var W=R;W<=y;W++)b.push(e.createElement(o,{columnIndex:W,data:f,isScrolling:M?_:void 0,key:h({columnIndex:W,data:f,rowIndex:P}),rowIndex:P,style:this._getItemStyle(P,W)}));var D=I(this.props,this._instanceProps),F=w(this.props,this._instanceProps);return e.createElement(p||g||"div",{className:n,onScroll:this._onScroll,ref:this._outerRefSetter,style:r({position:"relative",height:l,width:x,overflow:"auto",WebkitOverflowScrolling:"touch",willChange:"transform",direction:a},S)},e.createElement(c||u||"div",{children:b,ref:s,style:{height:D,pointerEvents:_?"none":void 0,width:F}}))},l._callPropsCallbacks=function(){var t=this.props,e=t.columnCount,r=t.onItemsRendered,o=t.onScroll,n=t.rowCount;if("function"==typeof r&&e>0&&n>0){var i=this._getHorizontalRangeToRender(),a=i[0],l=i[1],s=i[2],c=i[3],u=this._getVerticalRangeToRender(),f=u[0],d=u[1],h=u[2],m=u[3];this._callOnItemsRendered(a,l,f,d,s,c,h,m)}if("function"==typeof o){var p=this.state,g=p.horizontalScrollDirection,v=p.scrollLeft,S=p.scrollTop,I=p.scrollUpdateWasRequested,w=p.verticalScrollDirection;this._callOnScroll(v,S,g,w,I)}},l._getHorizontalRangeToRender=function(){var t=this.props,e=t.columnCount,r=t.overscanColumnCount,o=t.overscanColumnsCount,n=t.overscanCount,i=t.rowCount,a=this.state,l=a.horizontalScrollDirection,s=a.isScrolling,c=a.scrollLeft,u=r||o||n||1;if(0===e||0===i)return[0,0,0,0];var f=p(this.props,c,this._instanceProps),d=v(this.props,f,c,this._instanceProps),h=s&&"backward"!==l?1:Math.max(1,u),m=s&&"forward"!==l?1:Math.max(1,u);return[Math.max(0,f-h),Math.max(0,Math.min(e-1,d+m)),f,d]},l._getVerticalRangeToRender=function(){var t=this.props,e=t.columnCount,r=t.overscanCount,o=t.overscanRowCount,n=t.overscanRowsCount,i=t.rowCount,a=this.state,l=a.isScrolling,s=a.verticalScrollDirection,c=a.scrollTop,u=o||n||r||1;if(0===e||0===i)return[0,0,0,0];var f=R(this.props,c,this._instanceProps),d=y(this.props,f,c,this._instanceProps),h=l&&"backward"!==s?1:Math.max(1,u),m=l&&"forward"!==s?1:Math.max(1,u);return[Math.max(0,f-h),Math.max(0,Math.min(i-1,d+m)),f,d]},i}(e.PureComponent),i.defaultProps={direction:"ltr",itemData:void 0,useIsScrolling:!1},l}var g=function(t,e){t.children,t.direction,t.height,t.innerTagName,t.outerTagName,t.overscanColumnsCount,t.overscanCount,t.overscanRowsCount,t.width,e.instance},v=function(t,e){var r=t.rowCount,o=e.rowMetadataMap,n=e.estimatedRowHeight,i=e.lastMeasuredRowIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=o[i];a=l.offset+l.size}return a+(r-i-1)*n},S=function(t,e){var r=t.columnCount,o=e.columnMetadataMap,n=e.estimatedColumnWidth,i=e.lastMeasuredColumnIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=o[i];a=l.offset+l.size}return a+(r-i-1)*n},I=function(t,e,r,o){var n,i,a;if("column"===t?(n=o.columnMetadataMap,i=e.columnWidth,a=o.lastMeasuredColumnIndex):(n=o.rowMetadataMap,i=e.rowHeight,a=o.lastMeasuredRowIndex),r>a){var l=0;if(a>=0){var s=n[a];l=s.offset+s.size}for(var c=a+1;c<=r;c++){var u=i(c);n[c]={offset:l,size:u},l+=u}"column"===t?o.lastMeasuredColumnIndex=r:o.lastMeasuredRowIndex=r}return n[r]},w=function(t,e,r,o){var n,i;return"column"===t?(n=r.columnMetadataMap,i=r.lastMeasuredColumnIndex):(n=r.rowMetadataMap,i=r.lastMeasuredRowIndex),(i>0?n[i].offset:0)>=o?M(t,e,r,i,0,o):x(t,e,r,Math.max(0,i),o)},M=function(t,e,r,o,n,i){for(;n<=o;){var a=n+Math.floor((o-n)/2),l=I(t,e,a,r).offset;if(l===i)return a;l<i?n=a+1:l>i&&(o=a-1)}return n>0?n-1:0},x=function(t,e,r,o,n){for(var i="column"===t?e.columnCount:e.rowCount,a=1;o<i&&I(t,e,o,r).offset<n;)o+=a,a*=2;return M(t,e,r,Math.min(o,i-1),Math.floor(o/2),n)},_=function(t,e,r,o,n,i,a){var l="column"===t?e.width:e.height,s=I(t,e,r,i),c="column"===t?S(e,i):v(e,i),u=Math.max(0,Math.min(c-l,s.offset)),f=Math.max(0,s.offset-l+a+s.size);switch("smart"===o&&(o=n>=f-l&&n<=u+l?"auto":"center"),o){case"start":return u;case"end":return f;case"center":return Math.round(f+(u-f)/2);case"auto":default:return n>=f&&n<=u?n:f>u?f:n<f?f:u}},C=p({getColumnOffset:function(t,e,r){return I("column",t,e,r).offset},getColumnStartIndexForOffset:function(t,e,r){return w("column",t,r,e)},getColumnStopIndexForStartIndex:function(t,e,r,o){for(var n=t.columnCount,i=t.width,a=I("column",t,e,o),l=r+i,s=a.offset+a.size,c=e;c<n-1&&s<l;)s+=I("column",t,++c,o).size;return c},getColumnWidth:function(t,e,r){return r.columnMetadataMap[e].size},getEstimatedTotalHeight:v,getEstimatedTotalWidth:S,getOffsetForColumnAndAlignment:function(t,e,r,o,n,i){return _("column",t,e,r,o,n,i)},getOffsetForRowAndAlignment:function(t,e,r,o,n,i){return _("row",t,e,r,o,n,i)},getRowOffset:function(t,e,r){return I("row",t,e,r).offset},getRowHeight:function(t,e,r){return r.rowMetadataMap[e].size},getRowStartIndexForOffset:function(t,e,r){return w("row",t,r,e)},getRowStopIndexForStartIndex:function(t,e,r,o){for(var n=t.rowCount,i=t.height,a=I("row",t,e,o),l=r+i,s=a.offset+a.size,c=e;c<n-1&&s<l;)s+=I("row",t,++c,o).size;return c},initInstanceProps:function(t,e){var r=t,o={columnMetadataMap:{},estimatedColumnWidth:r.estimatedColumnWidth||50,estimatedRowHeight:r.estimatedRowHeight||50,lastMeasuredColumnIndex:-1,lastMeasuredRowIndex:-1,rowMetadataMap:{}};return e.resetAfterColumnIndex=function(t,r){void 0===r&&(r=!0),e.resetAfterIndices({columnIndex:t,shouldForceUpdate:r})},e.resetAfterRowIndex=function(t,r){void 0===r&&(r=!0),e.resetAfterIndices({rowIndex:t,shouldForceUpdate:r})},e.resetAfterIndices=function(t){var r=t.columnIndex,n=t.rowIndex,i=t.shouldForceUpdate,a=void 0===i||i;"number"==typeof r&&(o.lastMeasuredColumnIndex=Math.min(o.lastMeasuredColumnIndex,r-1)),"number"==typeof n&&(o.lastMeasuredRowIndex=Math.min(o.lastMeasuredRowIndex,n-1)),e._getItemStyleCache(-1),a&&e.forceUpdate()},o},shouldResetStyleCacheOnItemSizeChange:!1,validateProps:function(t){t.columnWidth,t.rowHeight}}),R=150,y=function(t,e){return t};function T(t){var i,l,u=t.getItemOffset,f=t.getEstimatedTotalSize,h=t.getItemSize,m=t.getOffsetForIndexAndAlignment,p=t.getStartIndexForOffset,g=t.getStopIndexForStartIndex,v=t.initInstanceProps,S=t.shouldResetStyleCacheOnItemSizeChange,I=t.validateProps;return l=i=function(t){function i(e){var r;return(r=t.call(this,e)||this)._instanceProps=v(r.props,n(n(r))),r._outerRef=void 0,r._resetIsScrollingTimeoutId=null,r.state={instance:n(n(r)),isScrolling:!1,scrollDirection:"forward",scrollOffset:"number"==typeof r.props.initialScrollOffset?r.props.initialScrollOffset:0,scrollUpdateWasRequested:!1},r._callOnItemsRendered=void 0,r._callOnItemsRendered=a(function(t,e,o,n){return r.props.onItemsRendered({overscanStartIndex:t,overscanStopIndex:e,visibleStartIndex:o,visibleStopIndex:n})}),r._callOnScroll=void 0,r._callOnScroll=a(function(t,e,o){return r.props.onScroll({scrollDirection:t,scrollOffset:e,scrollUpdateWasRequested:o})}),r._getItemStyle=void 0,r._getItemStyle=function(t){var e,o=r.props,n=o.direction,i=o.itemSize,a=o.layout,l=r._getItemStyleCache(S&&i,S&&a,S&&n);if(l.hasOwnProperty(t))e=l[t];else{var s,c=u(r.props,t,r._instanceProps),f=h(r.props,t,r._instanceProps),d="horizontal"===n||"horizontal"===a;l[t]=((s={position:"absolute"})["rtl"===n?"right":"left"]=d?c:0,s.top=d?0:c,s.height=d?"100%":f,s.width=d?f:"100%",e=s)}return e},r._getItemStyleCache=void 0,r._getItemStyleCache=a(function(t,e,r){return{}}),r._onScrollHorizontal=function(t){var e=t.currentTarget,o=e.clientWidth,n=e.scrollLeft,i=e.scrollWidth;r.setState(function(t){if(t.scrollOffset===n)return null;var e=r.props.direction,a=n;if("rtl"===e)switch(d()){case"negative":a=-n;break;case"positive-descending":a=i-o-n}return a=Math.max(0,Math.min(a,i-o)),{isScrolling:!0,scrollDirection:t.scrollOffset<n?"forward":"backward",scrollOffset:a,scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._onScrollVertical=function(t){var e=t.currentTarget,o=e.clientHeight,n=e.scrollHeight,i=e.scrollTop;r.setState(function(t){if(t.scrollOffset===i)return null;var e=Math.max(0,Math.min(i,n-o));return{isScrolling:!0,scrollDirection:t.scrollOffset<e?"forward":"backward",scrollOffset:e,scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._outerRefSetter=function(t){var e=r.props.outerRef;r._outerRef=t,"function"==typeof e?e(t):null!=e&&"object"==typeof e&&e.hasOwnProperty("current")&&(e.current=t)},r._resetIsScrollingDebounced=function(){null!==r._resetIsScrollingTimeoutId&&s(r._resetIsScrollingTimeoutId),r._resetIsScrollingTimeoutId=c(r._resetIsScrolling,R)},r._resetIsScrolling=function(){r._resetIsScrollingTimeoutId=null,r.setState({isScrolling:!1},function(){r._getItemStyleCache(-1,null)})},r}o(i,t),i.getDerivedStateFromProps=function(t,e){return O(t,e),I(t),null};var l=i.prototype;return l.scrollTo=function(t){t=Math.max(0,t),this.setState(function(e){return e.scrollOffset===t?null:{scrollDirection:e.scrollOffset<t?"forward":"backward",scrollOffset:t,scrollUpdateWasRequested:!0}},this._resetIsScrollingDebounced)},l.scrollToItem=function(t,e){void 0===e&&(e="auto");var r=this.props.itemCount,o=this.state.scrollOffset;t=Math.max(0,Math.min(t,r-1)),this.scrollTo(m(this.props,t,e,o,this._instanceProps))},l.componentDidMount=function(){var t=this.props,e=t.direction,r=t.initialScrollOffset,o=t.layout;if("number"==typeof r&&null!=this._outerRef){var n=this._outerRef;"horizontal"===e||"horizontal"===o?n.scrollLeft=r:n.scrollTop=r}this._callPropsCallbacks()},l.componentDidUpdate=function(){var t=this.props,e=t.direction,r=t.layout,o=this.state,n=o.scrollOffset;if(o.scrollUpdateWasRequested&&null!=this._outerRef){var i=this._outerRef;if("horizontal"===e||"horizontal"===r)if("rtl"===e)switch(d()){case"negative":i.scrollLeft=-n;break;case"positive-ascending":i.scrollLeft=n;break;default:var a=i.clientWidth,l=i.scrollWidth;i.scrollLeft=l-a-n}else i.scrollLeft=n;else i.scrollTop=n}this._callPropsCallbacks()},l.componentWillUnmount=function(){null!==this._resetIsScrollingTimeoutId&&s(this._resetIsScrollingTimeoutId)},l.render=function(){var t=this.props,o=t.children,n=t.className,i=t.direction,a=t.height,l=t.innerRef,s=t.innerElementType,c=t.innerTagName,u=t.itemCount,d=t.itemData,h=t.itemKey,m=void 0===h?y:h,p=t.layout,g=t.outerElementType,v=t.outerTagName,S=t.style,I=t.useIsScrolling,w=t.width,M=this.state.isScrolling,x="horizontal"===i||"horizontal"===p,_=x?this._onScrollHorizontal:this._onScrollVertical,C=this._getRangeToRender(),R=C[0],T=C[1],O=[];if(u>0)for(var z=R;z<=T;z++)O.push(e.createElement(o,{data:d,key:m(z,d),index:z,isScrolling:I?M:void 0,style:this._getItemStyle(z)}));var b=f(this.props,this._instanceProps);return e.createElement(g||v||"div",{className:n,onScroll:_,ref:this._outerRefSetter,style:r({position:"relative",height:a,width:w,overflow:"auto",WebkitOverflowScrolling:"touch",willChange:"transform",direction:i},S)},e.createElement(s||c||"div",{children:O,ref:l,style:{height:x?"100%":b,pointerEvents:M?"none":void 0,width:x?b:"100%"}}))},l._callPropsCallbacks=function(){if("function"==typeof this.props.onItemsRendered&&this.props.itemCount>0){var t=this._getRangeToRender(),e=t[0],r=t[1],o=t[2],n=t[3];this._callOnItemsRendered(e,r,o,n)}if("function"==typeof this.props.onScroll){var i=this.state,a=i.scrollDirection,l=i.scrollOffset,s=i.scrollUpdateWasRequested;this._callOnScroll(a,l,s)}},l._getRangeToRender=function(){var t=this.props,e=t.itemCount,r=t.overscanCount,o=this.state,n=o.isScrolling,i=o.scrollDirection,a=o.scrollOffset;if(0===e)return[0,0,0,0];var l=p(this.props,a,this._instanceProps),s=g(this.props,l,a,this._instanceProps),c=n&&"backward"!==i?1:Math.max(1,r),u=n&&"forward"!==i?1:Math.max(1,r);return[Math.max(0,l-c),Math.max(0,Math.min(e-1,s+u)),l,s]},i}(e.PureComponent),i.defaultProps={direction:"ltr",itemData:void 0,layout:"vertical",overscanCount:2,useIsScrolling:!1},l}var O=function(t,e){t.children,t.direction,t.height,t.layout,t.innerTagName,t.outerTagName,t.width,e.instance},z=function(t,e,r){var o=t.itemSize,n=r.itemMetadataMap,i=r.lastMeasuredIndex;if(e>i){var a=0;if(i>=0){var l=n[i];a=l.offset+l.size}for(var s=i+1;s<=e;s++){var c=o(s);n[s]={offset:a,size:c},a+=c}r.lastMeasuredIndex=e}return n[e]},b=function(t,e,r,o,n){for(;o<=r;){var i=o+Math.floor((r-o)/2),a=z(t,i,e).offset;if(a===n)return i;a<n?o=i+1:a>n&&(r=i-1)}return o>0?o-1:0},P=function(t,e,r,o){for(var n=t.itemCount,i=1;r<n&&z(t,r,e).offset<o;)r+=i,i*=2;return b(t,e,Math.min(r,n-1),Math.floor(r/2),o)},W=function(t,e){var r=t.itemCount,o=e.itemMetadataMap,n=e.estimatedItemSize,i=e.lastMeasuredIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=o[i];a=l.offset+l.size}return a+(r-i-1)*n},D=T({getItemOffset:function(t,e,r){return z(t,e,r).offset},getItemSize:function(t,e,r){return r.itemMetadataMap[e].size},getEstimatedTotalSize:W,getOffsetForIndexAndAlignment:function(t,e,r,o,n){var i=t.direction,a=t.height,l=t.layout,s=t.width,c="horizontal"===i||"horizontal"===l?s:a,u=z(t,e,n),f=W(t,n),d=Math.max(0,Math.min(f-c,u.offset)),h=Math.max(0,u.offset-c+u.size);switch("smart"===r&&(r=o>=h-c&&o<=d+c?"auto":"center"),r){case"start":return d;case"end":return h;case"center":return Math.round(h+(d-h)/2);case"auto":default:return o>=h&&o<=d?o:o<h?h:d}},getStartIndexForOffset:function(t,e,r){return function(t,e,r){var o=e.itemMetadataMap,n=e.lastMeasuredIndex;return(n>0?o[n].offset:0)>=r?b(t,e,n,0,r):P(t,e,Math.max(0,n),r)}(t,r,e)},getStopIndexForStartIndex:function(t,e,r,o){for(var n=t.direction,i=t.height,a=t.itemCount,l=t.layout,s=t.width,c="horizontal"===n||"horizontal"===l?s:i,u=z(t,e,o),f=r+c,d=u.offset+u.size,h=e;h<a-1&&d<f;)d+=z(t,++h,o).size;return h},initInstanceProps:function(t,e){var r={itemMetadataMap:{},estimatedItemSize:t.estimatedItemSize||50,lastMeasuredIndex:-1};return e.resetAfterIndex=function(t,o){void 0===o&&(o=!0),r.lastMeasuredIndex=Math.min(r.lastMeasuredIndex,t-1),e._getItemStyleCache(-1),o&&e.forceUpdate()},r},shouldResetStyleCacheOnItemSizeChange:!1,validateProps:function(t){t.itemSize}}),F=p({getColumnOffset:function(t,e){return e*t.columnWidth},getColumnWidth:function(t,e){return t.columnWidth},getRowOffset:function(t,e){return e*t.rowHeight},getRowHeight:function(t,e){return t.rowHeight},getEstimatedTotalHeight:function(t){var e=t.rowCount;return t.rowHeight*e},getEstimatedTotalWidth:function(t){var e=t.columnCount;return t.columnWidth*e},getOffsetForColumnAndAlignment:function(t,e,r,o,n,i){var a=t.columnCount,l=t.columnWidth,s=t.width,c=Math.max(0,a*l-s),u=Math.min(c,e*l),f=Math.max(0,e*l-s+i+l);switch("smart"===r&&(r=o>=f-s&&o<=u+s?"auto":"center"),r){case"start":return u;case"end":return f;case"center":var d=Math.round(f+(u-f)/2);return d<Math.ceil(s/2)?0:d>c+Math.floor(s/2)?c:d;case"auto":default:return o>=f&&o<=u?o:f>u?f:o<f?f:u}},getOffsetForRowAndAlignment:function(t,e,r,o,n,i){var a=t.rowHeight,l=t.height,s=t.rowCount,c=Math.max(0,s*a-l),u=Math.min(c,e*a),f=Math.max(0,e*a-l+i+a);switch("smart"===r&&(r=o>=f-l&&o<=u+l?"auto":"center"),r){case"start":return u;case"end":return f;case"center":var d=Math.round(f+(u-f)/2);return d<Math.ceil(l/2)?0:d>c+Math.floor(l/2)?c:d;case"auto":default:return o>=f&&o<=u?o:f>u?f:o<f?f:u}},getColumnStartIndexForOffset:function(t,e){var r=t.columnWidth,o=t.columnCount;return Math.max(0,Math.min(o-1,Math.floor(e/r)))},getColumnStopIndexForStartIndex:function(t,e,r){var o=t.columnWidth,n=t.columnCount,i=t.width,a=e*o,l=Math.ceil((i+r-a)/o);return Math.max(0,Math.min(n-1,e+l-1))},getRowStartIndexForOffset:function(t,e){var r=t.rowHeight,o=t.rowCount;return Math.max(0,Math.min(o-1,Math.floor(e/r)))},getRowStopIndexForStartIndex:function(t,e,r){var o=t.rowHeight,n=t.rowCount,i=t.height,a=e*o,l=Math.ceil((i+r-a)/o);return Math.max(0,Math.min(n-1,e+l-1))},initInstanceProps:function(t){},shouldResetStyleCacheOnItemSizeChange:!0,validateProps:function(t){t.columnWidth,t.rowHeight}}),L=T({getItemOffset:function(t,e){return e*t.itemSize},getItemSize:function(t,e){return t.itemSize},getEstimatedTotalSize:function(t){var e=t.itemCount;return t.itemSize*e},getOffsetForIndexAndAlignment:function(t,e,r,o){var n=t.direction,i=t.height,a=t.itemCount,l=t.itemSize,s=t.layout,c=t.width,u="horizontal"===n||"horizontal"===s?c:i,f=Math.max(0,a*l-u),d=Math.min(f,e*l),h=Math.max(0,e*l-u+l);switch("smart"===r&&(r=o>=h-u&&o<=d+u?"auto":"center"),r){case"start":return d;case"end":return h;case"center":var m=Math.round(h+(d-h)/2);return m<Math.ceil(u/2)?0:m>f+Math.floor(u/2)?f:m;case"auto":default:return o>=h&&o<=d?o:o<h?h:d}},getStartIndexForOffset:function(t,e){var r=t.itemCount,o=t.itemSize;return Math.max(0,Math.min(r-1,Math.floor(e/o)))},getStopIndexForStartIndex:function(t,e,r){var o=t.direction,n=t.height,i=t.itemCount,a=t.itemSize,l=t.layout,s=t.width,c=e*a,u="horizontal"===o||"horizontal"===l?s:n,f=Math.ceil((u+r-c)/a);return Math.max(0,Math.min(i-1,e+f-1))},initInstanceProps:function(t){},shouldResetStyleCacheOnItemSizeChange:!0,validateProps:function(t){t.itemSize}});function A(t,e){if(null==t)return{};var r,o,n={},i=Object.keys(t);for(o=0;o<i.length;o++)r=i[o],e.indexOf(r)>=0||(n[r]=t[r]);return n}function H(t,e){for(var r in t)if(!(r in e))return!0;for(var o in e)if(t[o]!==e[o])return!0;return!1}function k(t,e){var r=t.style,o=A(t,["style"]),n=e.style,i=A(e,["style"]);return!H(r,n)&&!H(o,i)}t.VariableSizeGrid=C,t.VariableSizeList=D,t.FixedSizeGrid=F,t.FixedSizeList=L,t.areEqual=k,t.shouldComponentUpdate=function(t,e){return!k(this.props,t)||H(this.state,e)},Object.defineProperty(t,"__esModule",{value:!0})});
2
-//# sourceMappingURL=index-prod.umd.js.map
packages/react-devtools-shared/src/node_modules/react-window/dist/index.cjs.js
deleted
-2079
@@ -1,2079 +0,0 @@
1
-'use strict';
2
-
3
-Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
-function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
-
7
-var _extends = _interopDefault(require('@babel/runtime/helpers/extends'));
8
-var _inheritsLoose = _interopDefault(require('@babel/runtime/helpers/inheritsLoose'));
9
-var _assertThisInitialized = _interopDefault(require('@babel/runtime/helpers/assertThisInitialized'));
10
-var memoizeOne = _interopDefault(require('memoize-one'));
11
-var react = require('react');
12
-var _objectWithoutPropertiesLoose = _interopDefault(require('@babel/runtime/helpers/objectWithoutPropertiesLoose'));
13
-
14
-// Animation frame based implementation of setTimeout.
15
-// Inspired by Joe Lambert, https://gist.github.com/joelambert/1002116#file-requesttimeout-js
16
-var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
17
-var now = hasNativePerformanceNow ? function () {
18
- return performance.now();
19
-} : function () {
20
- return Date.now();
21
-};
22
-function cancelTimeout(timeoutID) {
23
- cancelAnimationFrame(timeoutID.id);
24
-}
25
-function requestTimeout(callback, delay) {
26
- var start = now();
27
-
28
- function tick() {
29
- if (now() - start >= delay) {
30
- callback.call(null);
31
- } else {
32
- timeoutID.id = requestAnimationFrame(tick);
33
- }
34
- }
35
-
36
- var timeoutID = {
37
- id: requestAnimationFrame(tick)
38
- };
39
- return timeoutID;
40
-}
41
-
42
-var size = -1; // This utility copied from "dom-helpers" package.
43
-
44
-function getScrollbarSize(recalculate) {
45
- if (recalculate === void 0) {
46
- recalculate = false;
47
- }
48
-
49
- if (size === -1 || recalculate) {
50
- var div = document.createElement('div');
51
- var style = div.style;
52
- style.width = '50px';
53
- style.height = '50px';
54
- style.overflow = 'scroll';
55
- document.body.appendChild(div);
56
- size = div.offsetWidth - div.clientWidth;
57
- document.body.removeChild(div);
58
- }
59
-
60
- return size;
61
-}
62
-var cachedRTLResult = null; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
63
-// Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
64
-// Safari's elastic bounce makes detecting this even more complicated wrt potential false positives.
65
-// The safest way to check this is to intentionally set a negative offset,
66
-// and then verify that the subsequent "scroll" event matches the negative offset.
67
-// If it does not match, then we can assume a non-standard RTL scroll implementation.
68
-
69
-function getRTLOffsetType(recalculate) {
70
- if (recalculate === void 0) {
71
- recalculate = false;
72
- }
73
-
74
- if (cachedRTLResult === null || recalculate) {
75
- var outerDiv = document.createElement('div');
76
- var outerStyle = outerDiv.style;
77
- outerStyle.width = '50px';
78
- outerStyle.height = '50px';
79
- outerStyle.overflow = 'scroll';
80
- outerStyle.direction = 'rtl';
81
- var innerDiv = document.createElement('div');
82
- var innerStyle = innerDiv.style;
83
- innerStyle.width = '100px';
84
- innerStyle.height = '100px';
85
- outerDiv.appendChild(innerDiv);
86
- document.body.appendChild(outerDiv);
87
-
88
- if (outerDiv.scrollLeft > 0) {
89
- cachedRTLResult = 'positive-descending';
90
- } else {
91
- outerDiv.scrollLeft = 1;
92
-
93
- if (outerDiv.scrollLeft === 0) {
94
- cachedRTLResult = 'negative';
95
- } else {
96
- cachedRTLResult = 'positive-ascending';
97
- }
98
- }
99
-
100
- document.body.removeChild(outerDiv);
101
- return cachedRTLResult;
102
- }
103
-
104
- return cachedRTLResult;
105
-}
106
-
107
-var IS_SCROLLING_DEBOUNCE_INTERVAL = 150;
108
-
109
-var defaultItemKey = function defaultItemKey(_ref) {
110
- var columnIndex = _ref.columnIndex,
111
- data = _ref.data,
112
- rowIndex = _ref.rowIndex;
113
- return rowIndex + ":" + columnIndex;
114
-}; // In DEV mode, this Set helps us only log a warning once per component instance.
115
-// This avoids spamming the console every time a render happens.
116
-
117
-
118
-var devWarningsOverscanCount = null;
119
-var devWarningsOverscanRowsColumnsCount = null;
120
-var devWarningsTagName = null;
121
-
122
-if (process.env.NODE_ENV !== 'production') {
123
- if (typeof window !== 'undefined' && typeof window.WeakSet !== 'undefined') {
124
- devWarningsOverscanCount =
125
- /*#__PURE__*/
126
- new WeakSet();
127
- devWarningsOverscanRowsColumnsCount =
128
- /*#__PURE__*/
129
- new WeakSet();
130
- devWarningsTagName =
131
- /*#__PURE__*/
132
- new WeakSet();
133
- }
134
-}
135
-
136
-function createGridComponent(_ref2) {
137
- var _class, _temp;
138
-
139
- var getColumnOffset = _ref2.getColumnOffset,
140
- getColumnStartIndexForOffset = _ref2.getColumnStartIndexForOffset,
141
- getColumnStopIndexForStartIndex = _ref2.getColumnStopIndexForStartIndex,
142
- getColumnWidth = _ref2.getColumnWidth,
143
- getEstimatedTotalHeight = _ref2.getEstimatedTotalHeight,
144
- getEstimatedTotalWidth = _ref2.getEstimatedTotalWidth,
145
- getOffsetForColumnAndAlignment = _ref2.getOffsetForColumnAndAlignment,
146
- getOffsetForRowAndAlignment = _ref2.getOffsetForRowAndAlignment,
147
- getRowHeight = _ref2.getRowHeight,
148
- getRowOffset = _ref2.getRowOffset,
149
- getRowStartIndexForOffset = _ref2.getRowStartIndexForOffset,
150
- getRowStopIndexForStartIndex = _ref2.getRowStopIndexForStartIndex,
151
- initInstanceProps = _ref2.initInstanceProps,
152
- shouldResetStyleCacheOnItemSizeChange = _ref2.shouldResetStyleCacheOnItemSizeChange,
153
- validateProps = _ref2.validateProps;
154
- return _temp = _class =
155
- /*#__PURE__*/
156
- function (_PureComponent) {
157
- _inheritsLoose(Grid, _PureComponent);
158
-
159
- // Always use explicit constructor for React components.
160
- // It produces less code after transpilation. (#26)
161
- // eslint-disable-next-line no-useless-constructor
162
- function Grid(props) {
163
- var _this;
164
-
165
- _this = _PureComponent.call(this, props) || this;
166
- _this._instanceProps = initInstanceProps(_this.props, _assertThisInitialized(_assertThisInitialized(_this)));
167
- _this._resetIsScrollingTimeoutId = null;
168
- _this._outerRef = void 0;
169
- _this.state = {
170
- instance: _assertThisInitialized(_assertThisInitialized(_this)),
171
- isScrolling: false,
172
- horizontalScrollDirection: 'forward',
173
- scrollLeft: typeof _this.props.initialScrollLeft === 'number' ? _this.props.initialScrollLeft : 0,
174
- scrollTop: typeof _this.props.initialScrollTop === 'number' ? _this.props.initialScrollTop : 0,
175
- scrollUpdateWasRequested: false,
176
- verticalScrollDirection: 'forward'
177
- };
178
- _this._callOnItemsRendered = void 0;
179
- _this._callOnItemsRendered = memoizeOne(function (overscanColumnStartIndex, overscanColumnStopIndex, overscanRowStartIndex, overscanRowStopIndex, visibleColumnStartIndex, visibleColumnStopIndex, visibleRowStartIndex, visibleRowStopIndex) {
180
- return _this.props.onItemsRendered({
181
- overscanColumnStartIndex: overscanColumnStartIndex,
182
- overscanColumnStopIndex: overscanColumnStopIndex,
183
- overscanRowStartIndex: overscanRowStartIndex,
184
- overscanRowStopIndex: overscanRowStopIndex,
185
- visibleColumnStartIndex: visibleColumnStartIndex,
186
- visibleColumnStopIndex: visibleColumnStopIndex,
187
- visibleRowStartIndex: visibleRowStartIndex,
188
- visibleRowStopIndex: visibleRowStopIndex
189
- });
190
- });
191
- _this._callOnScroll = void 0;
192
- _this._callOnScroll = memoizeOne(function (scrollLeft, scrollTop, horizontalScrollDirection, verticalScrollDirection, scrollUpdateWasRequested) {
193
- return _this.props.onScroll({
194
- horizontalScrollDirection: horizontalScrollDirection,
195
- scrollLeft: scrollLeft,
196
- scrollTop: scrollTop,
197
- verticalScrollDirection: verticalScrollDirection,
198
- scrollUpdateWasRequested: scrollUpdateWasRequested
199
- });
200
- });
201
- _this._getItemStyle = void 0;
202
-
203
- _this._getItemStyle = function (rowIndex, columnIndex) {
204
- var _this$props = _this.props,
205
- columnWidth = _this$props.columnWidth,
206
- direction = _this$props.direction,
207
- rowHeight = _this$props.rowHeight;
208
-
209
- var itemStyleCache = _this._getItemStyleCache(shouldResetStyleCacheOnItemSizeChange && columnWidth, shouldResetStyleCacheOnItemSizeChange && direction, shouldResetStyleCacheOnItemSizeChange && rowHeight);
210
-
211
- var key = rowIndex + ":" + columnIndex;
212
- var style;
213
-
214
- if (itemStyleCache.hasOwnProperty(key)) {
215
- style = itemStyleCache[key];
216
- } else {
217
- var _style;
218
-
219
- itemStyleCache[key] = style = (_style = {
220
- position: 'absolute'
221
- }, _style[direction === 'rtl' ? 'right' : 'left'] = getColumnOffset(_this.props, columnIndex, _this._instanceProps), _style.top = getRowOffset(_this.props, rowIndex, _this._instanceProps), _style.height = getRowHeight(_this.props, rowIndex, _this._instanceProps), _style.width = getColumnWidth(_this.props, columnIndex, _this._instanceProps), _style);
222
- }
223
-
224
- return style;
225
- };
226
-
227
- _this._getItemStyleCache = void 0;
228
- _this._getItemStyleCache = memoizeOne(function (_, __, ___) {
229
- return {};
230
- });
231
-
232
- _this._onScroll = function (event) {
233
- var _event$currentTarget = event.currentTarget,
234
- clientHeight = _event$currentTarget.clientHeight,
235
- clientWidth = _event$currentTarget.clientWidth,
236
- scrollLeft = _event$currentTarget.scrollLeft,
237
- scrollTop = _event$currentTarget.scrollTop,
238
- scrollHeight = _event$currentTarget.scrollHeight,
239
- scrollWidth = _event$currentTarget.scrollWidth;
240
-
241
- _this.setState(function (prevState) {
242
- if (prevState.scrollLeft === scrollLeft && prevState.scrollTop === scrollTop) {
243
- // Scroll position may have been updated by cDM/cDU,
244
- // In which case we don't need to trigger another render,
245
- // And we don't want to update state.isScrolling.
246
- return null;
247
- }
248
-
249
- var direction = _this.props.direction; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
250
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
251
- // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
252
- // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
253
-
254
- var calculatedScrollLeft = scrollLeft;
255
-
256
- if (direction === 'rtl') {
257
- switch (getRTLOffsetType()) {
258
- case 'negative':
259
- calculatedScrollLeft = -scrollLeft;
260
- break;
261
-
262
- case 'positive-descending':
263
- calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
264
- break;
265
- }
266
- } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
267
-
268
-
269
- calculatedScrollLeft = Math.max(0, Math.min(calculatedScrollLeft, scrollWidth - clientWidth));
270
- var calculatedScrollTop = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
271
- return {
272
- isScrolling: true,
273
- horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
274
- scrollLeft: calculatedScrollLeft,
275
- scrollTop: calculatedScrollTop,
276
- verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward',
277
- scrollUpdateWasRequested: false
278
- };
279
- }, _this._resetIsScrollingDebounced);
280
- };
281
-
282
- _this._outerRefSetter = function (ref) {
283
- var outerRef = _this.props.outerRef;
284
- _this._outerRef = ref;
285
-
286
- if (typeof outerRef === 'function') {
287
- outerRef(ref);
288
- } else if (outerRef != null && typeof outerRef === 'object' && outerRef.hasOwnProperty('current')) {
289
- outerRef.current = ref;
290
- }
291
- };
292
-
293
- _this._resetIsScrollingDebounced = function () {
294
- if (_this._resetIsScrollingTimeoutId !== null) {
295
- cancelTimeout(_this._resetIsScrollingTimeoutId);
296
- }
297
-
298
- _this._resetIsScrollingTimeoutId = requestTimeout(_this._resetIsScrolling, IS_SCROLLING_DEBOUNCE_INTERVAL);
299
- };
300
-
301
- _this._resetIsScrolling = function () {
302
- _this._resetIsScrollingTimeoutId = null;
303
-
304
- _this.setState({
305
- isScrolling: false
306
- }, function () {
307
- // Clear style cache after state update has been committed.
308
- // This way we don't break pure sCU for items that don't use isScrolling param.
309
- _this._getItemStyleCache(-1);
310
- });
311
- };
312
-
313
- return _this;
314
- }
315
-
316
- Grid.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
317
- validateSharedProps(nextProps, prevState);
318
- validateProps(nextProps);
319
- return null;
320
- };
321
-
322
- var _proto = Grid.prototype;
323
-
324
- _proto.scrollTo = function scrollTo(_ref3) {
325
- var scrollLeft = _ref3.scrollLeft,
326
- scrollTop = _ref3.scrollTop;
327
-
328
- if (scrollLeft !== undefined) {
329
- scrollLeft = Math.max(0, scrollLeft);
330
- }
331
-
332
- if (scrollTop !== undefined) {
333
- scrollTop = Math.max(0, scrollTop);
334
- }
335
-
336
- this.setState(function (prevState) {
337
- if (scrollLeft === undefined) {
338
- scrollLeft = prevState.scrollLeft;
339
- }
340
-
341
- if (scrollTop === undefined) {
342
- scrollTop = prevState.scrollTop;
343
- }
344
-
345
- if (prevState.scrollLeft === scrollLeft && prevState.scrollTop === scrollTop) {
346
- return null;
347
- }
348
-
349
- return {
350
- horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
351
- scrollLeft: scrollLeft,
352
- scrollTop: scrollTop,
353
- scrollUpdateWasRequested: true,
354
- verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward'
355
- };
356
- }, this._resetIsScrollingDebounced);
357
- };
358
-
359
- _proto.scrollToItem = function scrollToItem(_ref4) {
360
- var _ref4$align = _ref4.align,
361
- align = _ref4$align === void 0 ? 'auto' : _ref4$align,
362
- columnIndex = _ref4.columnIndex,
363
- rowIndex = _ref4.rowIndex;
364
- var _this$props2 = this.props,
365
- columnCount = _this$props2.columnCount,
366
- height = _this$props2.height,
367
- rowCount = _this$props2.rowCount,
368
- width = _this$props2.width;
369
- var _this$state = this.state,
370
- scrollLeft = _this$state.scrollLeft,
371
- scrollTop = _this$state.scrollTop;
372
- var scrollbarSize = getScrollbarSize();
373
-
374
- if (columnIndex !== undefined) {
375
- columnIndex = Math.max(0, Math.min(columnIndex, columnCount - 1));
376
- }
377
-
378
- if (rowIndex !== undefined) {
379
- rowIndex = Math.max(0, Math.min(rowIndex, rowCount - 1));
380
- }
381
-
382
- var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps);
383
- var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps); // The scrollbar size should be considered when scrolling an item into view,
384
- // to ensure it's fully visible.
385
- // But we only need to account for its size when it's actually visible.
386
-
387
- var horizontalScrollbarSize = estimatedTotalWidth > width ? scrollbarSize : 0;
388
- var verticalScrollbarSize = estimatedTotalHeight > height ? scrollbarSize : 0;
389
- this.scrollTo({
390
- scrollLeft: columnIndex !== undefined ? getOffsetForColumnAndAlignment(this.props, columnIndex, align, scrollLeft, this._instanceProps, verticalScrollbarSize) : scrollLeft,
391
- scrollTop: rowIndex !== undefined ? getOffsetForRowAndAlignment(this.props, rowIndex, align, scrollTop, this._instanceProps, horizontalScrollbarSize) : scrollTop
392
- });
393
- };
394
-
395
- _proto.componentDidMount = function componentDidMount() {
396
- var _this$props3 = this.props,
397
- initialScrollLeft = _this$props3.initialScrollLeft,
398
- initialScrollTop = _this$props3.initialScrollTop;
399
-
400
- if (this._outerRef != null) {
401
- var outerRef = this._outerRef;
402
-
403
- if (typeof initialScrollLeft === 'number') {
404
- outerRef.scrollLeft = initialScrollLeft;
405
- }
406
-
407
- if (typeof initialScrollTop === 'number') {
408
- outerRef.scrollTop = initialScrollTop;
409
- }
410
- }
411
-
412
- this._callPropsCallbacks();
413
- };
414
-
415
- _proto.componentDidUpdate = function componentDidUpdate() {
416
- var direction = this.props.direction;
417
- var _this$state2 = this.state,
418
- scrollLeft = _this$state2.scrollLeft,
419
- scrollTop = _this$state2.scrollTop,
420
- scrollUpdateWasRequested = _this$state2.scrollUpdateWasRequested;
421
-
422
- if (scrollUpdateWasRequested && this._outerRef != null) {
423
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
424
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
425
- // So we need to determine which browser behavior we're dealing with, and mimic it.
426
- var outerRef = this._outerRef;
427
-
428
- if (direction === 'rtl') {
429
- switch (getRTLOffsetType()) {
430
- case 'negative':
431
- outerRef.scrollLeft = -scrollLeft;
432
- break;
433
-
434
- case 'positive-ascending':
435
- outerRef.scrollLeft = scrollLeft;
436
- break;
437
-
438
- default:
439
- var clientWidth = outerRef.clientWidth,
440
- scrollWidth = outerRef.scrollWidth;
441
- outerRef.scrollLeft = scrollWidth - clientWidth - scrollLeft;
442
- break;
443
- }
444
- } else {
445
- outerRef.scrollLeft = Math.max(0, scrollLeft);
446
- }
447
-
448
- outerRef.scrollTop = Math.max(0, scrollTop);
449
- }
450
-
451
- this._callPropsCallbacks();
452
- };
453
-
454
- _proto.componentWillUnmount = function componentWillUnmount() {
455
- if (this._resetIsScrollingTimeoutId !== null) {
456
- cancelTimeout(this._resetIsScrollingTimeoutId);
457
- }
458
- };
459
-
460
- _proto.render = function render() {
461
- var _this$props4 = this.props,
462
- children = _this$props4.children,
463
- className = _this$props4.className,
464
- columnCount = _this$props4.columnCount,
465
- direction = _this$props4.direction,
466
- height = _this$props4.height,
467
- innerRef = _this$props4.innerRef,
468
- innerElementType = _this$props4.innerElementType,
469
- innerTagName = _this$props4.innerTagName,
470
- itemData = _this$props4.itemData,
471
- _this$props4$itemKey = _this$props4.itemKey,
472
- itemKey = _this$props4$itemKey === void 0 ? defaultItemKey : _this$props4$itemKey,
473
- outerElementType = _this$props4.outerElementType,
474
- outerTagName = _this$props4.outerTagName,
475
- rowCount = _this$props4.rowCount,
476
- style = _this$props4.style,
477
- useIsScrolling = _this$props4.useIsScrolling,
478
- width = _this$props4.width;
479
- var isScrolling = this.state.isScrolling;
480
-
481
- var _this$_getHorizontalR = this._getHorizontalRangeToRender(),
482
- columnStartIndex = _this$_getHorizontalR[0],
483
- columnStopIndex = _this$_getHorizontalR[1];
484
-
485
- var _this$_getVerticalRan = this._getVerticalRangeToRender(),
486
- rowStartIndex = _this$_getVerticalRan[0],
487
- rowStopIndex = _this$_getVerticalRan[1];
488
-
489
- var items = [];
490
-
491
- if (columnCount > 0 && rowCount) {
492
- for (var _rowIndex = rowStartIndex; _rowIndex <= rowStopIndex; _rowIndex++) {
493
- for (var _columnIndex = columnStartIndex; _columnIndex <= columnStopIndex; _columnIndex++) {
494
- items.push(react.createElement(children, {
495
- columnIndex: _columnIndex,
496
- data: itemData,
497
- isScrolling: useIsScrolling ? isScrolling : undefined,
498
- key: itemKey({
499
- columnIndex: _columnIndex,
500
- data: itemData,
501
- rowIndex: _rowIndex
502
- }),
503
- rowIndex: _rowIndex,
504
- style: this._getItemStyle(_rowIndex, _columnIndex)
505
- }));
506
- }
507
- }
508
- } // Read this value AFTER items have been created,
509
- // So their actual sizes (if variable) are taken into consideration.
510
-
511
-
512
- var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps);
513
- var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps);
514
- return react.createElement(outerElementType || outerTagName || 'div', {
515
- className: className,
516
- onScroll: this._onScroll,
517
- ref: this._outerRefSetter,
518
- style: _extends({
519
- position: 'relative',
520
- height: height,
521
- width: width,
522
- overflow: 'auto',
523
- WebkitOverflowScrolling: 'touch',
524
- willChange: 'transform',
525
- direction: direction
526
- }, style)
527
- }, react.createElement(innerElementType || innerTagName || 'div', {
528
- children: items,
529
- ref: innerRef,
530
- style: {
531
- height: estimatedTotalHeight,
532
- pointerEvents: isScrolling ? 'none' : undefined,
533
- width: estimatedTotalWidth
534
- }
535
- }));
536
- };
537
-
538
- _proto._callPropsCallbacks = function _callPropsCallbacks() {
539
- var _this$props5 = this.props,
540
- columnCount = _this$props5.columnCount,
541
- onItemsRendered = _this$props5.onItemsRendered,
542
- onScroll = _this$props5.onScroll,
543
- rowCount = _this$props5.rowCount;
544
-
545
- if (typeof onItemsRendered === 'function') {
546
- if (columnCount > 0 && rowCount > 0) {
547
- var _this$_getHorizontalR2 = this._getHorizontalRangeToRender(),
548
- _overscanColumnStartIndex = _this$_getHorizontalR2[0],
549
- _overscanColumnStopIndex = _this$_getHorizontalR2[1],
550
- _visibleColumnStartIndex = _this$_getHorizontalR2[2],
551
- _visibleColumnStopIndex = _this$_getHorizontalR2[3];
552
-
553
- var _this$_getVerticalRan2 = this._getVerticalRangeToRender(),
554
- _overscanRowStartIndex = _this$_getVerticalRan2[0],
555
- _overscanRowStopIndex = _this$_getVerticalRan2[1],
556
- _visibleRowStartIndex = _this$_getVerticalRan2[2],
557
- _visibleRowStopIndex = _this$_getVerticalRan2[3];
558
-
559
- this._callOnItemsRendered(_overscanColumnStartIndex, _overscanColumnStopIndex, _overscanRowStartIndex, _overscanRowStopIndex, _visibleColumnStartIndex, _visibleColumnStopIndex, _visibleRowStartIndex, _visibleRowStopIndex);
560
- }
561
- }
562
-
563
- if (typeof onScroll === 'function') {
564
- var _this$state3 = this.state,
565
- _horizontalScrollDirection = _this$state3.horizontalScrollDirection,
566
- _scrollLeft = _this$state3.scrollLeft,
567
- _scrollTop = _this$state3.scrollTop,
568
- _scrollUpdateWasRequested = _this$state3.scrollUpdateWasRequested,
569
- _verticalScrollDirection = _this$state3.verticalScrollDirection;
570
-
571
- this._callOnScroll(_scrollLeft, _scrollTop, _horizontalScrollDirection, _verticalScrollDirection, _scrollUpdateWasRequested);
572
- }
573
- }; // Lazily create and cache item styles while scrolling,
574
- // So that pure component sCU will prevent re-renders.
575
- // We maintain this cache, and pass a style prop rather than index,
576
- // So that List can clear cached styles and force item re-render if necessary.
577
-
578
-
579
- _proto._getHorizontalRangeToRender = function _getHorizontalRangeToRender() {
580
- var _this$props6 = this.props,
581
- columnCount = _this$props6.columnCount,
582
- overscanColumnCount = _this$props6.overscanColumnCount,
583
- overscanColumnsCount = _this$props6.overscanColumnsCount,
584
- overscanCount = _this$props6.overscanCount,
585
- rowCount = _this$props6.rowCount;
586
- var _this$state4 = this.state,
587
- horizontalScrollDirection = _this$state4.horizontalScrollDirection,
588
- isScrolling = _this$state4.isScrolling,
589
- scrollLeft = _this$state4.scrollLeft;
590
- var overscanCountResolved = overscanColumnCount || overscanColumnsCount || overscanCount || 1;
591
-
592
- if (columnCount === 0 || rowCount === 0) {
593
- return [0, 0, 0, 0];
594
- }
595
-
596
- var startIndex = getColumnStartIndexForOffset(this.props, scrollLeft, this._instanceProps);
597
- var stopIndex = getColumnStopIndexForStartIndex(this.props, startIndex, scrollLeft, this._instanceProps); // Overscan by one item in each direction so that tab/focus works.
598
- // If there isn't at least one extra item, tab loops back around.
599
-
600
- var overscanBackward = !isScrolling || horizontalScrollDirection === 'backward' ? Math.max(1, overscanCountResolved) : 1;
601
- var overscanForward = !isScrolling || horizontalScrollDirection === 'forward' ? Math.max(1, overscanCountResolved) : 1;
602
- return [Math.max(0, startIndex - overscanBackward), Math.max(0, Math.min(columnCount - 1, stopIndex + overscanForward)), startIndex, stopIndex];
603
- };
604
-
605
- _proto._getVerticalRangeToRender = function _getVerticalRangeToRender() {
606
- var _this$props7 = this.props,
607
- columnCount = _this$props7.columnCount,
608
- overscanCount = _this$props7.overscanCount,
609
- overscanRowCount = _this$props7.overscanRowCount,
610
- overscanRowsCount = _this$props7.overscanRowsCount,
611
- rowCount = _this$props7.rowCount;
612
- var _this$state5 = this.state,
613
- isScrolling = _this$state5.isScrolling,
614
- verticalScrollDirection = _this$state5.verticalScrollDirection,
615
- scrollTop = _this$state5.scrollTop;
616
- var overscanCountResolved = overscanRowCount || overscanRowsCount || overscanCount || 1;
617
-
618
- if (columnCount === 0 || rowCount === 0) {
619
- return [0, 0, 0, 0];
620
- }
621
-
622
- var startIndex = getRowStartIndexForOffset(this.props, scrollTop, this._instanceProps);
623
- var stopIndex = getRowStopIndexForStartIndex(this.props, startIndex, scrollTop, this._instanceProps); // Overscan by one item in each direction so that tab/focus works.
624
- // If there isn't at least one extra item, tab loops back around.
625
-
626
- var overscanBackward = !isScrolling || verticalScrollDirection === 'backward' ? Math.max(1, overscanCountResolved) : 1;
627
- var overscanForward = !isScrolling || verticalScrollDirection === 'forward' ? Math.max(1, overscanCountResolved) : 1;
628
- return [Math.max(0, startIndex - overscanBackward), Math.max(0, Math.min(rowCount - 1, stopIndex + overscanForward)), startIndex, stopIndex];
629
- };
630
-
631
- return Grid;
632
- }(react.PureComponent), _class.defaultProps = {
633
- direction: 'ltr',
634
- itemData: undefined,
635
- useIsScrolling: false
636
- }, _temp;
637
-}
638
-
639
-var validateSharedProps = function validateSharedProps(_ref5, _ref6) {
640
- var children = _ref5.children,
641
- direction = _ref5.direction,
642
- height = _ref5.height,
643
- innerTagName = _ref5.innerTagName,
644
- outerTagName = _ref5.outerTagName,
645
- overscanColumnsCount = _ref5.overscanColumnsCount,
646
- overscanCount = _ref5.overscanCount,
647
- overscanRowsCount = _ref5.overscanRowsCount,
648
- width = _ref5.width;
649
- var instance = _ref6.instance;
650
-
651
- if (process.env.NODE_ENV !== 'production') {
652
- if (typeof overscanCount === 'number') {
653
- if (devWarningsOverscanCount && !devWarningsOverscanCount.has(instance)) {
654
- devWarningsOverscanCount.add(instance);
655
- console.warn('The overscanCount prop has been deprecated. ' + 'Please use the overscanColumnCount and overscanRowCount props instead.');
656
- }
657
- }
658
-
659
- if (typeof overscanColumnsCount === 'number' || typeof overscanRowsCount === 'number') {
660
- if (devWarningsOverscanRowsColumnsCount && !devWarningsOverscanRowsColumnsCount.has(instance)) {
661
- devWarningsOverscanRowsColumnsCount.add(instance);
662
- console.warn('The overscanColumnsCount and overscanRowsCount props have been deprecated. ' + 'Please use the overscanColumnCount and overscanRowCount props instead.');
663
- }
664
- }
665
-
666
- if (innerTagName != null || outerTagName != null) {
667
- if (devWarningsTagName && !devWarningsTagName.has(instance)) {
668
- devWarningsTagName.add(instance);
669
- console.warn('The innerTagName and outerTagName props have been deprecated. ' + 'Please use the innerElementType and outerElementType props instead.');
670
- }
671
- }
672
-
673
- if (children == null) {
674
- throw Error('An invalid "children" prop has been specified. ' + 'Value should be a React component. ' + ("\"" + (children === null ? 'null' : typeof children) + "\" was specified."));
675
- }
676
-
677
- switch (direction) {
678
- case 'ltr':
679
- case 'rtl':
680
- // Valid values
681
- break;
682
-
683
- default:
684
- throw Error('An invalid "direction" prop has been specified. ' + 'Value should be either "ltr" or "rtl". ' + ("\"" + direction + "\" was specified."));
685
- }
686
-
687
- if (typeof width !== 'number') {
688
- throw Error('An invalid "width" prop has been specified. ' + 'Grids must specify a number for width. ' + ("\"" + (width === null ? 'null' : typeof width) + "\" was specified."));
689
- }
690
-
691
- if (typeof height !== 'number') {
692
- throw Error('An invalid "height" prop has been specified. ' + 'Grids must specify a number for height. ' + ("\"" + (height === null ? 'null' : typeof height) + "\" was specified."));
693
- }
694
- }
695
-};
696
-
697
-var DEFAULT_ESTIMATED_ITEM_SIZE = 50;
698
-
699
-var getEstimatedTotalHeight = function getEstimatedTotalHeight(_ref, _ref2) {
700
- var rowCount = _ref.rowCount;
701
- var rowMetadataMap = _ref2.rowMetadataMap,
702
- estimatedRowHeight = _ref2.estimatedRowHeight,
703
- lastMeasuredRowIndex = _ref2.lastMeasuredRowIndex;
704
- var totalSizeOfMeasuredRows = 0; // Edge case check for when the number of items decreases while a scroll is in progress.
705
- // https://github.com/bvaughn/react-window/pull/138
706
-
707
- if (lastMeasuredRowIndex >= rowCount) {
708
- lastMeasuredRowIndex = rowCount - 1;
709
- }
710
-
711
- if (lastMeasuredRowIndex >= 0) {
712
- var itemMetadata = rowMetadataMap[lastMeasuredRowIndex];
713
- totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size;
714
- }
715
-
716
- var numUnmeasuredItems = rowCount - lastMeasuredRowIndex - 1;
717
- var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedRowHeight;
718
- return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems;
719
-};
720
-
721
-var getEstimatedTotalWidth = function getEstimatedTotalWidth(_ref3, _ref4) {
722
- var columnCount = _ref3.columnCount;
723
- var columnMetadataMap = _ref4.columnMetadataMap,
724
- estimatedColumnWidth = _ref4.estimatedColumnWidth,
725
- lastMeasuredColumnIndex = _ref4.lastMeasuredColumnIndex;
726
- var totalSizeOfMeasuredRows = 0; // Edge case check for when the number of items decreases while a scroll is in progress.
727
- // https://github.com/bvaughn/react-window/pull/138
728
-
729
- if (lastMeasuredColumnIndex >= columnCount) {
730
- lastMeasuredColumnIndex = columnCount - 1;
731
- }
732
-
733
- if (lastMeasuredColumnIndex >= 0) {
734
- var itemMetadata = columnMetadataMap[lastMeasuredColumnIndex];
735
- totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size;
736
- }
737
-
738
- var numUnmeasuredItems = columnCount - lastMeasuredColumnIndex - 1;
739
- var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedColumnWidth;
740
- return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems;
741
-};
742
-
743
-var getItemMetadata = function getItemMetadata(itemType, props, index, instanceProps) {
744
- var itemMetadataMap, itemSize, lastMeasuredIndex;
745
-
746
- if (itemType === 'column') {
747
- itemMetadataMap = instanceProps.columnMetadataMap;
748
- itemSize = props.columnWidth;
749
- lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex;
750
- } else {
751
- itemMetadataMap = instanceProps.rowMetadataMap;
752
- itemSize = props.rowHeight;
753
- lastMeasuredIndex = instanceProps.lastMeasuredRowIndex;
754
- }
755
-
756
- if (index > lastMeasuredIndex) {
757
- var offset = 0;
758
-
759
- if (lastMeasuredIndex >= 0) {
760
- var itemMetadata = itemMetadataMap[lastMeasuredIndex];
761
- offset = itemMetadata.offset + itemMetadata.size;
762
- }
763
-
764
- for (var i = lastMeasuredIndex + 1; i <= index; i++) {
765
- var size = itemSize(i);
766
- itemMetadataMap[i] = {
767
- offset: offset,
768
- size: size
769
- };
770
- offset += size;
771
- }
772
-
773
- if (itemType === 'column') {
774
- instanceProps.lastMeasuredColumnIndex = index;
775
- } else {
776
- instanceProps.lastMeasuredRowIndex = index;
777
- }
778
- }
779
-
780
- return itemMetadataMap[index];
781
-};
782
-
783
-var findNearestItem = function findNearestItem(itemType, props, instanceProps, offset) {
784
- var itemMetadataMap, lastMeasuredIndex;
785
-
786
- if (itemType === 'column') {
787
- itemMetadataMap = instanceProps.columnMetadataMap;
788
- lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex;
789
- } else {
790
- itemMetadataMap = instanceProps.rowMetadataMap;
791
- lastMeasuredIndex = instanceProps.lastMeasuredRowIndex;
792
- }
793
-
794
- var lastMeasuredItemOffset = lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0;
795
-
796
- if (lastMeasuredItemOffset >= offset) {
797
- // If we've already measured items within this range just use a binary search as it's faster.
798
- return findNearestItemBinarySearch(itemType, props, instanceProps, lastMeasuredIndex, 0, offset);
799
- } else {
800
- // If we haven't yet measured this high, fallback to an exponential search with an inner binary search.
801
- // The exponential search avoids pre-computing sizes for the full set of items as a binary search would.
802
- // The overall complexity for this approach is O(log n).
803
- return findNearestItemExponentialSearch(itemType, props, instanceProps, Math.max(0, lastMeasuredIndex), offset);
804
- }
805
-};
806
-
807
-var findNearestItemBinarySearch = function findNearestItemBinarySearch(itemType, props, instanceProps, high, low, offset) {
808
- while (low <= high) {
809
- var middle = low + Math.floor((high - low) / 2);
810
- var currentOffset = getItemMetadata(itemType, props, middle, instanceProps).offset;
811
-
812
- if (currentOffset === offset) {
813
- return middle;
814
- } else if (currentOffset < offset) {
815
- low = middle + 1;
816
- } else if (currentOffset > offset) {
817
- high = middle - 1;
818
- }
819
- }
820
-
821
- if (low > 0) {
822
- return low - 1;
823
- } else {
824
- return 0;
825
- }
826
-};
827
-
828
-var findNearestItemExponentialSearch = function findNearestItemExponentialSearch(itemType, props, instanceProps, index, offset) {
829
- var itemCount = itemType === 'column' ? props.columnCount : props.rowCount;
830
- var interval = 1;
831
-
832
- while (index < itemCount && getItemMetadata(itemType, props, index, instanceProps).offset < offset) {
833
- index += interval;
834
- interval *= 2;
835
- }
836
-
837
- return findNearestItemBinarySearch(itemType, props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset);
838
-};
839
-
840
-var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(itemType, props, index, align, scrollOffset, instanceProps, scrollbarSize) {
841
- var size = itemType === 'column' ? props.width : props.height;
842
- var itemMetadata = getItemMetadata(itemType, props, index, instanceProps); // Get estimated total size after ItemMetadata is computed,
843
- // To ensure it reflects actual measurements instead of just estimates.
844
-
845
- var estimatedTotalSize = itemType === 'column' ? getEstimatedTotalWidth(props, instanceProps) : getEstimatedTotalHeight(props, instanceProps);
846
- var maxOffset = Math.max(0, Math.min(estimatedTotalSize - size, itemMetadata.offset));
847
- var minOffset = Math.max(0, itemMetadata.offset - size + scrollbarSize + itemMetadata.size);
848
-
849
- if (align === 'smart') {
850
- if (scrollOffset >= minOffset - size && scrollOffset <= maxOffset + size) {
851
- align = 'auto';
852
- } else {
853
- align = 'center';
854
- }
855
- }
856
-
857
- switch (align) {
858
- case 'start':
859
- return maxOffset;
860
-
861
- case 'end':
862
- return minOffset;
863
-
864
- case 'center':
865
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
866
-
867
- case 'auto':
868
- default:
869
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
870
- return scrollOffset;
871
- } else if (minOffset > maxOffset) {
872
- // Because we only take into account the scrollbar size when calculating minOffset
873
- // this value can be larger than maxOffset when at the end of the list
874
- return minOffset;
875
- } else if (scrollOffset < minOffset) {
876
- return minOffset;
877
- } else {
878
- return maxOffset;
879
- }
880
-
881
- }
882
-};
883
-
884
-var VariableSizeGrid =
885
-/*#__PURE__*/
886
-createGridComponent({
887
- getColumnOffset: function getColumnOffset(props, index, instanceProps) {
888
- return getItemMetadata('column', props, index, instanceProps).offset;
889
- },
890
- getColumnStartIndexForOffset: function getColumnStartIndexForOffset(props, scrollLeft, instanceProps) {
891
- return findNearestItem('column', props, instanceProps, scrollLeft);
892
- },
893
- getColumnStopIndexForStartIndex: function getColumnStopIndexForStartIndex(props, startIndex, scrollLeft, instanceProps) {
894
- var columnCount = props.columnCount,
895
- width = props.width;
896
- var itemMetadata = getItemMetadata('column', props, startIndex, instanceProps);
897
- var maxOffset = scrollLeft + width;
898
- var offset = itemMetadata.offset + itemMetadata.size;
899
- var stopIndex = startIndex;
900
-
901
- while (stopIndex < columnCount - 1 && offset < maxOffset) {
902
- stopIndex++;
903
- offset += getItemMetadata('column', props, stopIndex, instanceProps).size;
904
- }
905
-
906
- return stopIndex;
907
- },
908
- getColumnWidth: function getColumnWidth(props, index, instanceProps) {
909
- return instanceProps.columnMetadataMap[index].size;
910
- },
911
- getEstimatedTotalHeight: getEstimatedTotalHeight,
912
- getEstimatedTotalWidth: getEstimatedTotalWidth,
913
- getOffsetForColumnAndAlignment: function getOffsetForColumnAndAlignment(props, index, align, scrollOffset, instanceProps, scrollbarSize) {
914
- return getOffsetForIndexAndAlignment('column', props, index, align, scrollOffset, instanceProps, scrollbarSize);
915
- },
916
- getOffsetForRowAndAlignment: function getOffsetForRowAndAlignment(props, index, align, scrollOffset, instanceProps, scrollbarSize) {
917
- return getOffsetForIndexAndAlignment('row', props, index, align, scrollOffset, instanceProps, scrollbarSize);
918
- },
919
- getRowOffset: function getRowOffset(props, index, instanceProps) {
920
- return getItemMetadata('row', props, index, instanceProps).offset;
921
- },
922
- getRowHeight: function getRowHeight(props, index, instanceProps) {
923
- return instanceProps.rowMetadataMap[index].size;
924
- },
925
- getRowStartIndexForOffset: function getRowStartIndexForOffset(props, scrollTop, instanceProps) {
926
- return findNearestItem('row', props, instanceProps, scrollTop);
927
- },
928
- getRowStopIndexForStartIndex: function getRowStopIndexForStartIndex(props, startIndex, scrollTop, instanceProps) {
929
- var rowCount = props.rowCount,
930
- height = props.height;
931
- var itemMetadata = getItemMetadata('row', props, startIndex, instanceProps);
932
- var maxOffset = scrollTop + height;
933
- var offset = itemMetadata.offset + itemMetadata.size;
934
- var stopIndex = startIndex;
935
-
936
- while (stopIndex < rowCount - 1 && offset < maxOffset) {
937
- stopIndex++;
938
- offset += getItemMetadata('row', props, stopIndex, instanceProps).size;
939
- }
940
-
941
- return stopIndex;
942
- },
943
- initInstanceProps: function initInstanceProps(props, instance) {
944
- var _ref5 = props,
945
- estimatedColumnWidth = _ref5.estimatedColumnWidth,
946
- estimatedRowHeight = _ref5.estimatedRowHeight;
947
- var instanceProps = {
948
- columnMetadataMap: {},
949
- estimatedColumnWidth: estimatedColumnWidth || DEFAULT_ESTIMATED_ITEM_SIZE,
950
- estimatedRowHeight: estimatedRowHeight || DEFAULT_ESTIMATED_ITEM_SIZE,
951
- lastMeasuredColumnIndex: -1,
952
- lastMeasuredRowIndex: -1,
953
- rowMetadataMap: {}
954
- };
955
-
956
- instance.resetAfterColumnIndex = function (columnIndex, shouldForceUpdate) {
957
- if (shouldForceUpdate === void 0) {
958
- shouldForceUpdate = true;
959
- }
960
-
961
- instance.resetAfterIndices({
962
- columnIndex: columnIndex,
963
- shouldForceUpdate: shouldForceUpdate
964
- });
965
- };
966
-
967
- instance.resetAfterRowIndex = function (rowIndex, shouldForceUpdate) {
968
- if (shouldForceUpdate === void 0) {
969
- shouldForceUpdate = true;
970
- }
971
-
972
- instance.resetAfterIndices({
973
- rowIndex: rowIndex,
974
- shouldForceUpdate: shouldForceUpdate
975
- });
976
- };
977
-
978
- instance.resetAfterIndices = function (_ref6) {
979
- var columnIndex = _ref6.columnIndex,
980
- rowIndex = _ref6.rowIndex,
981
- _ref6$shouldForceUpda = _ref6.shouldForceUpdate,
982
- shouldForceUpdate = _ref6$shouldForceUpda === void 0 ? true : _ref6$shouldForceUpda;
983
-
984
- if (typeof columnIndex === 'number') {
985
- instanceProps.lastMeasuredColumnIndex = Math.min(instanceProps.lastMeasuredColumnIndex, columnIndex - 1);
986
- }
987
-
988
- if (typeof rowIndex === 'number') {
989
- instanceProps.lastMeasuredRowIndex = Math.min(instanceProps.lastMeasuredRowIndex, rowIndex - 1);
990
- } // We could potentially optimize further by only evicting styles after this index,
991
- // But since styles are only cached while scrolling is in progress-
992
- // It seems an unnecessary optimization.
993
- // It's unlikely that resetAfterIndex() will be called while a user is scrolling.
994
-
995
-
996
- instance._getItemStyleCache(-1);
997
-
998
- if (shouldForceUpdate) {
999
- instance.forceUpdate();
1000
- }
1001
- };
1002
-
1003
- return instanceProps;
1004
- },
1005
- shouldResetStyleCacheOnItemSizeChange: false,
1006
- validateProps: function validateProps(_ref7) {
1007
- var columnWidth = _ref7.columnWidth,
1008
- rowHeight = _ref7.rowHeight;
1009
-
1010
- if (process.env.NODE_ENV !== 'production') {
1011
- if (typeof columnWidth !== 'function') {
1012
- throw Error('An invalid "columnWidth" prop has been specified. ' + 'Value should be a function. ' + ("\"" + (columnWidth === null ? 'null' : typeof columnWidth) + "\" was specified."));
1013
- } else if (typeof rowHeight !== 'function') {
1014
- throw Error('An invalid "rowHeight" prop has been specified. ' + 'Value should be a function. ' + ("\"" + (rowHeight === null ? 'null' : typeof rowHeight) + "\" was specified."));
1015
- }
1016
- }
1017
- }
1018
-});
1019
-
1020
-var IS_SCROLLING_DEBOUNCE_INTERVAL$1 = 150;
1021
-
1022
-var defaultItemKey$1 = function defaultItemKey(index, data) {
1023
- return index;
1024
-}; // In DEV mode, this Set helps us only log a warning once per component instance.
1025
-// This avoids spamming the console every time a render happens.
1026
-
1027
-
1028
-var devWarningsDirection = null;
1029
-var devWarningsTagName$1 = null;
1030
-
1031
-if (process.env.NODE_ENV !== 'production') {
1032
- if (typeof window !== 'undefined' && typeof window.WeakSet !== 'undefined') {
1033
- devWarningsDirection =
1034
- /*#__PURE__*/
1035
- new WeakSet();
1036
- devWarningsTagName$1 =
1037
- /*#__PURE__*/
1038
- new WeakSet();
1039
- }
1040
-}
1041
-
1042
-function createListComponent(_ref) {
1043
- var _class, _temp;
1044
-
1045
- var getItemOffset = _ref.getItemOffset,
1046
- getEstimatedTotalSize = _ref.getEstimatedTotalSize,
1047
- getItemSize = _ref.getItemSize,
1048
- getOffsetForIndexAndAlignment = _ref.getOffsetForIndexAndAlignment,
1049
- getStartIndexForOffset = _ref.getStartIndexForOffset,
1050
- getStopIndexForStartIndex = _ref.getStopIndexForStartIndex,
1051
- initInstanceProps = _ref.initInstanceProps,
1052
- shouldResetStyleCacheOnItemSizeChange = _ref.shouldResetStyleCacheOnItemSizeChange,
1053
- validateProps = _ref.validateProps;
1054
- return _temp = _class =
1055
- /*#__PURE__*/
1056
- function (_PureComponent) {
1057
- _inheritsLoose(List, _PureComponent);
1058
-
1059
- // Always use explicit constructor for React components.
1060
- // It produces less code after transpilation. (#26)
1061
- // eslint-disable-next-line no-useless-constructor
1062
- function List(props) {
1063
- var _this;
1064
-
1065
- _this = _PureComponent.call(this, props) || this;
1066
- _this._instanceProps = initInstanceProps(_this.props, _assertThisInitialized(_assertThisInitialized(_this)));
1067
- _this._outerRef = void 0;
1068
- _this._resetIsScrollingTimeoutId = null;
1069
- _this.state = {
1070
- instance: _assertThisInitialized(_assertThisInitialized(_this)),
1071
- isScrolling: false,
1072
- scrollDirection: 'forward',
1073
- scrollOffset: typeof _this.props.initialScrollOffset === 'number' ? _this.props.initialScrollOffset : 0,
1074
- scrollUpdateWasRequested: false
1075
- };
1076
- _this._callOnItemsRendered = void 0;
1077
- _this._callOnItemsRendered = memoizeOne(function (overscanStartIndex, overscanStopIndex, visibleStartIndex, visibleStopIndex) {
1078
- return _this.props.onItemsRendered({
1079
- overscanStartIndex: overscanStartIndex,
1080
- overscanStopIndex: overscanStopIndex,
1081
- visibleStartIndex: visibleStartIndex,
1082
- visibleStopIndex: visibleStopIndex
1083
- });
1084
- });
1085
- _this._callOnScroll = void 0;
1086
- _this._callOnScroll = memoizeOne(function (scrollDirection, scrollOffset, scrollUpdateWasRequested) {
1087
- return _this.props.onScroll({
1088
- scrollDirection: scrollDirection,
1089
- scrollOffset: scrollOffset,
1090
- scrollUpdateWasRequested: scrollUpdateWasRequested
1091
- });
1092
- });
1093
- _this._getItemStyle = void 0;
1094
-
1095
- _this._getItemStyle = function (index) {
1096
- var _this$props = _this.props,
1097
- direction = _this$props.direction,
1098
- itemSize = _this$props.itemSize,
1099
- layout = _this$props.layout;
1100
-
1101
- var itemStyleCache = _this._getItemStyleCache(shouldResetStyleCacheOnItemSizeChange && itemSize, shouldResetStyleCacheOnItemSizeChange && layout, shouldResetStyleCacheOnItemSizeChange && direction);
1102
-
1103
- var style;
1104
-
1105
- if (itemStyleCache.hasOwnProperty(index)) {
1106
- style = itemStyleCache[index];
1107
- } else {
1108
- var _style;
1109
-
1110
- var _offset = getItemOffset(_this.props, index, _this._instanceProps);
1111
-
1112
- var size = getItemSize(_this.props, index, _this._instanceProps); // TODO Deprecate direction "horizontal"
1113
-
1114
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1115
- itemStyleCache[index] = style = (_style = {
1116
- position: 'absolute'
1117
- }, _style[direction === 'rtl' ? 'right' : 'left'] = isHorizontal ? _offset : 0, _style.top = !isHorizontal ? _offset : 0, _style.height = !isHorizontal ? size : '100%', _style.width = isHorizontal ? size : '100%', _style);
1118
- }
1119
-
1120
- return style;
1121
- };
1122
-
1123
- _this._getItemStyleCache = void 0;
1124
- _this._getItemStyleCache = memoizeOne(function (_, __, ___) {
1125
- return {};
1126
- });
1127
-
1128
- _this._onScrollHorizontal = function (event) {
1129
- var _event$currentTarget = event.currentTarget,
1130
- clientWidth = _event$currentTarget.clientWidth,
1131
- scrollLeft = _event$currentTarget.scrollLeft,
1132
- scrollWidth = _event$currentTarget.scrollWidth;
1133
-
1134
- _this.setState(function (prevState) {
1135
- if (prevState.scrollOffset === scrollLeft) {
1136
- // Scroll position may have been updated by cDM/cDU,
1137
- // In which case we don't need to trigger another render,
1138
- // And we don't want to update state.isScrolling.
1139
- return null;
1140
- }
1141
-
1142
- var direction = _this.props.direction;
1143
- var scrollOffset = scrollLeft;
1144
-
1145
- if (direction === 'rtl') {
1146
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1147
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1148
- // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
1149
- // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
1150
- switch (getRTLOffsetType()) {
1151
- case 'negative':
1152
- scrollOffset = -scrollLeft;
1153
- break;
1154
-
1155
- case 'positive-descending':
1156
- scrollOffset = scrollWidth - clientWidth - scrollLeft;
1157
- break;
1158
- }
1159
- } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
1160
-
1161
-
1162
- scrollOffset = Math.max(0, Math.min(scrollOffset, scrollWidth - clientWidth));
1163
- return {
1164
- isScrolling: true,
1165
- scrollDirection: prevState.scrollOffset < scrollLeft ? 'forward' : 'backward',
1166
- scrollOffset: scrollOffset,
1167
- scrollUpdateWasRequested: false
1168
- };
1169
- }, _this._resetIsScrollingDebounced);
1170
- };
1171
-
1172
- _this._onScrollVertical = function (event) {
1173
- var _event$currentTarget2 = event.currentTarget,
1174
- clientHeight = _event$currentTarget2.clientHeight,
1175
- scrollHeight = _event$currentTarget2.scrollHeight,
1176
- scrollTop = _event$currentTarget2.scrollTop;
1177
-
1178
- _this.setState(function (prevState) {
1179
- if (prevState.scrollOffset === scrollTop) {
1180
- // Scroll position may have been updated by cDM/cDU,
1181
- // In which case we don't need to trigger another render,
1182
- // And we don't want to update state.isScrolling.
1183
- return null;
1184
- } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
1185
-
1186
-
1187
- var scrollOffset = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
1188
- return {
1189
- isScrolling: true,
1190
- scrollDirection: prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
1191
- scrollOffset: scrollOffset,
1192
- scrollUpdateWasRequested: false
1193
- };
1194
- }, _this._resetIsScrollingDebounced);
1195
- };
1196
-
1197
- _this._outerRefSetter = function (ref) {
1198
- var outerRef = _this.props.outerRef;
1199
- _this._outerRef = ref;
1200
-
1201
- if (typeof outerRef === 'function') {
1202
- outerRef(ref);
1203
- } else if (outerRef != null && typeof outerRef === 'object' && outerRef.hasOwnProperty('current')) {
1204
- outerRef.current = ref;
1205
- }
1206
- };
1207
-
1208
- _this._resetIsScrollingDebounced = function () {
1209
- if (_this._resetIsScrollingTimeoutId !== null) {
1210
- cancelTimeout(_this._resetIsScrollingTimeoutId);
1211
- }
1212
-
1213
- _this._resetIsScrollingTimeoutId = requestTimeout(_this._resetIsScrolling, IS_SCROLLING_DEBOUNCE_INTERVAL$1);
1214
- };
1215
-
1216
- _this._resetIsScrolling = function () {
1217
- _this._resetIsScrollingTimeoutId = null;
1218
-
1219
- _this.setState({
1220
- isScrolling: false
1221
- }, function () {
1222
- // Clear style cache after state update has been committed.
1223
- // This way we don't break pure sCU for items that don't use isScrolling param.
1224
- _this._getItemStyleCache(-1, null);
1225
- });
1226
- };
1227
-
1228
- return _this;
1229
- }
1230
-
1231
- List.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
1232
- validateSharedProps$1(nextProps, prevState);
1233
- validateProps(nextProps);
1234
- return null;
1235
- };
1236
-
1237
- var _proto = List.prototype;
1238
-
1239
- _proto.scrollTo = function scrollTo(scrollOffset) {
1240
- scrollOffset = Math.max(0, scrollOffset);
1241
- this.setState(function (prevState) {
1242
- if (prevState.scrollOffset === scrollOffset) {
1243
- return null;
1244
- }
1245
-
1246
- return {
1247
- scrollDirection: prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
1248
- scrollOffset: scrollOffset,
1249
- scrollUpdateWasRequested: true
1250
- };
1251
- }, this._resetIsScrollingDebounced);
1252
- };
1253
-
1254
- _proto.scrollToItem = function scrollToItem(index, align) {
1255
- if (align === void 0) {
1256
- align = 'auto';
1257
- }
1258
-
1259
- var itemCount = this.props.itemCount;
1260
- var scrollOffset = this.state.scrollOffset;
1261
- index = Math.max(0, Math.min(index, itemCount - 1));
1262
- this.scrollTo(getOffsetForIndexAndAlignment(this.props, index, align, scrollOffset, this._instanceProps));
1263
- };
1264
-
1265
- _proto.componentDidMount = function componentDidMount() {
1266
- var _this$props2 = this.props,
1267
- direction = _this$props2.direction,
1268
- initialScrollOffset = _this$props2.initialScrollOffset,
1269
- layout = _this$props2.layout;
1270
-
1271
- if (typeof initialScrollOffset === 'number' && this._outerRef != null) {
1272
- var outerRef = this._outerRef; // TODO Deprecate direction "horizontal"
1273
-
1274
- if (direction === 'horizontal' || layout === 'horizontal') {
1275
- outerRef.scrollLeft = initialScrollOffset;
1276
- } else {
1277
- outerRef.scrollTop = initialScrollOffset;
1278
- }
1279
- }
1280
-
1281
- this._callPropsCallbacks();
1282
- };
1283
-
1284
- _proto.componentDidUpdate = function componentDidUpdate() {
1285
- var _this$props3 = this.props,
1286
- direction = _this$props3.direction,
1287
- layout = _this$props3.layout;
1288
- var _this$state = this.state,
1289
- scrollOffset = _this$state.scrollOffset,
1290
- scrollUpdateWasRequested = _this$state.scrollUpdateWasRequested;
1291
-
1292
- if (scrollUpdateWasRequested && this._outerRef != null) {
1293
- var outerRef = this._outerRef; // TODO Deprecate direction "horizontal"
1294
-
1295
- if (direction === 'horizontal' || layout === 'horizontal') {
1296
- if (direction === 'rtl') {
1297
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1298
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1299
- // So we need to determine which browser behavior we're dealing with, and mimic it.
1300
- switch (getRTLOffsetType()) {
1301
- case 'negative':
1302
- outerRef.scrollLeft = -scrollOffset;
1303
- break;
1304
-
1305
- case 'positive-ascending':
1306
- outerRef.scrollLeft = scrollOffset;
1307
- break;
1308
-
1309
- default:
1310
- var clientWidth = outerRef.clientWidth,
1311
- scrollWidth = outerRef.scrollWidth;
1312
- outerRef.scrollLeft = scrollWidth - clientWidth - scrollOffset;
1313
- break;
1314
- }
1315
- } else {
1316
- outerRef.scrollLeft = scrollOffset;
1317
- }
1318
- } else {
1319
- outerRef.scrollTop = scrollOffset;
1320
- }
1321
- }
1322
-
1323
- this._callPropsCallbacks();
1324
- };
1325
-
1326
- _proto.componentWillUnmount = function componentWillUnmount() {
1327
- if (this._resetIsScrollingTimeoutId !== null) {
1328
- cancelTimeout(this._resetIsScrollingTimeoutId);
1329
- }
1330
- };
1331
-
1332
- _proto.render = function render() {
1333
- var _this$props4 = this.props,
1334
- children = _this$props4.children,
1335
- className = _this$props4.className,
1336
- direction = _this$props4.direction,
1337
- height = _this$props4.height,
1338
- innerRef = _this$props4.innerRef,
1339
- innerElementType = _this$props4.innerElementType,
1340
- innerTagName = _this$props4.innerTagName,
1341
- itemCount = _this$props4.itemCount,
1342
- itemData = _this$props4.itemData,
1343
- _this$props4$itemKey = _this$props4.itemKey,
1344
- itemKey = _this$props4$itemKey === void 0 ? defaultItemKey$1 : _this$props4$itemKey,
1345
- layout = _this$props4.layout,
1346
- outerElementType = _this$props4.outerElementType,
1347
- outerTagName = _this$props4.outerTagName,
1348
- style = _this$props4.style,
1349
- useIsScrolling = _this$props4.useIsScrolling,
1350
- width = _this$props4.width;
1351
- var isScrolling = this.state.isScrolling; // TODO Deprecate direction "horizontal"
1352
-
1353
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1354
- var onScroll = isHorizontal ? this._onScrollHorizontal : this._onScrollVertical;
1355
-
1356
- var _this$_getRangeToRend = this._getRangeToRender(),
1357
- startIndex = _this$_getRangeToRend[0],
1358
- stopIndex = _this$_getRangeToRend[1];
1359
-
1360
- var items = [];
1361
-
1362
- if (itemCount > 0) {
1363
- for (var _index = startIndex; _index <= stopIndex; _index++) {
1364
- items.push(react.createElement(children, {
1365
- data: itemData,
1366
- key: itemKey(_index, itemData),
1367
- index: _index,
1368
- isScrolling: useIsScrolling ? isScrolling : undefined,
1369
- style: this._getItemStyle(_index)
1370
- }));
1371
- }
1372
- } // Read this value AFTER items have been created,
1373
- // So their actual sizes (if variable) are taken into consideration.
1374
-
1375
-
1376
- var estimatedTotalSize = getEstimatedTotalSize(this.props, this._instanceProps);
1377
- return react.createElement(outerElementType || outerTagName || 'div', {
1378
- className: className,
1379
- onScroll: onScroll,
1380
- ref: this._outerRefSetter,
1381
- style: _extends({
1382
- position: 'relative',
1383
- height: height,
1384
- width: width,
1385
- overflow: 'auto',
1386
- WebkitOverflowScrolling: 'touch',
1387
- willChange: 'transform',
1388
- direction: direction
1389
- }, style)
1390
- }, react.createElement(innerElementType || innerTagName || 'div', {
1391
- children: items,
1392
- ref: innerRef,
1393
- style: {
1394
- height: isHorizontal ? '100%' : estimatedTotalSize,
1395
- pointerEvents: isScrolling ? 'none' : undefined,
1396
- width: isHorizontal ? estimatedTotalSize : '100%'
1397
- }
1398
- }));
1399
- };
1400
-
1401
- _proto._callPropsCallbacks = function _callPropsCallbacks() {
1402
- if (typeof this.props.onItemsRendered === 'function') {
1403
- var itemCount = this.props.itemCount;
1404
-
1405
- if (itemCount > 0) {
1406
- var _this$_getRangeToRend2 = this._getRangeToRender(),
1407
- _overscanStartIndex = _this$_getRangeToRend2[0],
1408
- _overscanStopIndex = _this$_getRangeToRend2[1],
1409
- _visibleStartIndex = _this$_getRangeToRend2[2],
1410
- _visibleStopIndex = _this$_getRangeToRend2[3];
1411
-
1412
- this._callOnItemsRendered(_overscanStartIndex, _overscanStopIndex, _visibleStartIndex, _visibleStopIndex);
1413
- }
1414
- }
1415
-
1416
- if (typeof this.props.onScroll === 'function') {
1417
- var _this$state2 = this.state,
1418
- _scrollDirection = _this$state2.scrollDirection,
1419
- _scrollOffset = _this$state2.scrollOffset,
1420
- _scrollUpdateWasRequested = _this$state2.scrollUpdateWasRequested;
1421
-
1422
- this._callOnScroll(_scrollDirection, _scrollOffset, _scrollUpdateWasRequested);
1423
- }
1424
- }; // Lazily create and cache item styles while scrolling,
1425
- // So that pure component sCU will prevent re-renders.
1426
- // We maintain this cache, and pass a style prop rather than index,
1427
- // So that List can clear cached styles and force item re-render if necessary.
1428
-
1429
-
1430
- _proto._getRangeToRender = function _getRangeToRender() {
1431
- var _this$props5 = this.props,
1432
- itemCount = _this$props5.itemCount,
1433
- overscanCount = _this$props5.overscanCount;
1434
- var _this$state3 = this.state,
1435
- isScrolling = _this$state3.isScrolling,
1436
- scrollDirection = _this$state3.scrollDirection,
1437
- scrollOffset = _this$state3.scrollOffset;
1438
-
1439
- if (itemCount === 0) {
1440
- return [0, 0, 0, 0];
1441
- }
1442
-
1443
- var startIndex = getStartIndexForOffset(this.props, scrollOffset, this._instanceProps);
1444
- var stopIndex = getStopIndexForStartIndex(this.props, startIndex, scrollOffset, this._instanceProps); // Overscan by one item in each direction so that tab/focus works.
1445
- // If there isn't at least one extra item, tab loops back around.
1446
-
1447
- var overscanBackward = !isScrolling || scrollDirection === 'backward' ? Math.max(1, overscanCount) : 1;
1448
- var overscanForward = !isScrolling || scrollDirection === 'forward' ? Math.max(1, overscanCount) : 1;
1449
- return [Math.max(0, startIndex - overscanBackward), Math.max(0, Math.min(itemCount - 1, stopIndex + overscanForward)), startIndex, stopIndex];
1450
- };
1451
-
1452
- return List;
1453
- }(react.PureComponent), _class.defaultProps = {
1454
- direction: 'ltr',
1455
- itemData: undefined,
1456
- layout: 'vertical',
1457
- overscanCount: 2,
1458
- useIsScrolling: false
1459
- }, _temp;
1460
-} // NOTE: I considered further wrapping individual items with a pure ListItem component.
1461
-// This would avoid ever calling the render function for the same index more than once,
1462
-// But it would also add the overhead of a lot of components/fibers.
1463
-// I assume people already do this (render function returning a class component),
1464
-// So my doing it would just unnecessarily double the wrappers.
1465
-
1466
-var validateSharedProps$1 = function validateSharedProps(_ref2, _ref3) {
1467
- var children = _ref2.children,
1468
- direction = _ref2.direction,
1469
- height = _ref2.height,
1470
- layout = _ref2.layout,
1471
- innerTagName = _ref2.innerTagName,
1472
- outerTagName = _ref2.outerTagName,
1473
- width = _ref2.width;
1474
- var instance = _ref3.instance;
1475
-
1476
- if (process.env.NODE_ENV !== 'production') {
1477
- if (innerTagName != null || outerTagName != null) {
1478
- if (devWarningsTagName$1 && !devWarningsTagName$1.has(instance)) {
1479
- devWarningsTagName$1.add(instance);
1480
- console.warn('The innerTagName and outerTagName props have been deprecated. ' + 'Please use the innerElementType and outerElementType props instead.');
1481
- }
1482
- } // TODO Deprecate direction "horizontal"
1483
-
1484
-
1485
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1486
-
1487
- switch (direction) {
1488
- case 'horizontal':
1489
- case 'vertical':
1490
- if (devWarningsDirection && !devWarningsDirection.has(instance)) {
1491
- devWarningsDirection.add(instance);
1492
- console.warn('The direction prop should be either "ltr" (default) or "rtl". ' + 'Please use the layout prop to specify "vertical" (default) or "horizontal" orientation.');
1493
- }
1494
-
1495
- break;
1496
-
1497
- case 'ltr':
1498
- case 'rtl':
1499
- // Valid values
1500
- break;
1501
-
1502
- default:
1503
- throw Error('An invalid "direction" prop has been specified. ' + 'Value should be either "ltr" or "rtl". ' + ("\"" + direction + "\" was specified."));
1504
- }
1505
-
1506
- switch (layout) {
1507
- case 'horizontal':
1508
- case 'vertical':
1509
- // Valid values
1510
- break;
1511
-
1512
- default:
1513
- throw Error('An invalid "layout" prop has been specified. ' + 'Value should be either "horizontal" or "vertical". ' + ("\"" + layout + "\" was specified."));
1514
- }
1515
-
1516
- if (children == null) {
1517
- throw Error('An invalid "children" prop has been specified. ' + 'Value should be a React component. ' + ("\"" + (children === null ? 'null' : typeof children) + "\" was specified."));
1518
- }
1519
-
1520
- if (isHorizontal && typeof width !== 'number') {
1521
- throw Error('An invalid "width" prop has been specified. ' + 'Horizontal lists must specify a number for width. ' + ("\"" + (width === null ? 'null' : typeof width) + "\" was specified."));
1522
- } else if (!isHorizontal && typeof height !== 'number') {
1523
- throw Error('An invalid "height" prop has been specified. ' + 'Vertical lists must specify a number for height. ' + ("\"" + (height === null ? 'null' : typeof height) + "\" was specified."));
1524
- }
1525
- }
1526
-};
1527
-
1528
-var DEFAULT_ESTIMATED_ITEM_SIZE$1 = 50;
1529
-
1530
-var getItemMetadata$1 = function getItemMetadata(props, index, instanceProps) {
1531
- var _ref = props,
1532
- itemSize = _ref.itemSize;
1533
- var itemMetadataMap = instanceProps.itemMetadataMap,
1534
- lastMeasuredIndex = instanceProps.lastMeasuredIndex;
1535
-
1536
- if (index > lastMeasuredIndex) {
1537
- var offset = 0;
1538
-
1539
- if (lastMeasuredIndex >= 0) {
1540
- var itemMetadata = itemMetadataMap[lastMeasuredIndex];
1541
- offset = itemMetadata.offset + itemMetadata.size;
1542
- }
1543
-
1544
- for (var i = lastMeasuredIndex + 1; i <= index; i++) {
1545
- var size = itemSize(i);
1546
- itemMetadataMap[i] = {
1547
- offset: offset,
1548
- size: size
1549
- };
1550
- offset += size;
1551
- }
1552
-
1553
- instanceProps.lastMeasuredIndex = index;
1554
- }
1555
-
1556
- return itemMetadataMap[index];
1557
-};
1558
-
1559
-var findNearestItem$1 = function findNearestItem(props, instanceProps, offset) {
1560
- var itemMetadataMap = instanceProps.itemMetadataMap,
1561
- lastMeasuredIndex = instanceProps.lastMeasuredIndex;
1562
- var lastMeasuredItemOffset = lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0;
1563
-
1564
- if (lastMeasuredItemOffset >= offset) {
1565
- // If we've already measured items within this range just use a binary search as it's faster.
1566
- return findNearestItemBinarySearch$1(props, instanceProps, lastMeasuredIndex, 0, offset);
1567
- } else {
1568
- // If we haven't yet measured this high, fallback to an exponential search with an inner binary search.
1569
- // The exponential search avoids pre-computing sizes for the full set of items as a binary search would.
1570
- // The overall complexity for this approach is O(log n).
1571
- return findNearestItemExponentialSearch$1(props, instanceProps, Math.max(0, lastMeasuredIndex), offset);
1572
- }
1573
-};
1574
-
1575
-var findNearestItemBinarySearch$1 = function findNearestItemBinarySearch(props, instanceProps, high, low, offset) {
1576
- while (low <= high) {
1577
- var middle = low + Math.floor((high - low) / 2);
1578
- var currentOffset = getItemMetadata$1(props, middle, instanceProps).offset;
1579
-
1580
- if (currentOffset === offset) {
1581
- return middle;
1582
- } else if (currentOffset < offset) {
1583
- low = middle + 1;
1584
- } else if (currentOffset > offset) {
1585
- high = middle - 1;
1586
- }
1587
- }
1588
-
1589
- if (low > 0) {
1590
- return low - 1;
1591
- } else {
1592
- return 0;
1593
- }
1594
-};
1595
-
1596
-var findNearestItemExponentialSearch$1 = function findNearestItemExponentialSearch(props, instanceProps, index, offset) {
1597
- var itemCount = props.itemCount;
1598
- var interval = 1;
1599
-
1600
- while (index < itemCount && getItemMetadata$1(props, index, instanceProps).offset < offset) {
1601
- index += interval;
1602
- interval *= 2;
1603
- }
1604
-
1605
- return findNearestItemBinarySearch$1(props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset);
1606
-};
1607
-
1608
-var getEstimatedTotalSize = function getEstimatedTotalSize(_ref2, _ref3) {
1609
- var itemCount = _ref2.itemCount;
1610
- var itemMetadataMap = _ref3.itemMetadataMap,
1611
- estimatedItemSize = _ref3.estimatedItemSize,
1612
- lastMeasuredIndex = _ref3.lastMeasuredIndex;
1613
- var totalSizeOfMeasuredItems = 0; // Edge case check for when the number of items decreases while a scroll is in progress.
1614
- // https://github.com/bvaughn/react-window/pull/138
1615
-
1616
- if (lastMeasuredIndex >= itemCount) {
1617
- lastMeasuredIndex = itemCount - 1;
1618
- }
1619
-
1620
- if (lastMeasuredIndex >= 0) {
1621
- var itemMetadata = itemMetadataMap[lastMeasuredIndex];
1622
- totalSizeOfMeasuredItems = itemMetadata.offset + itemMetadata.size;
1623
- }
1624
-
1625
- var numUnmeasuredItems = itemCount - lastMeasuredIndex - 1;
1626
- var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedItemSize;
1627
- return totalSizeOfMeasuredItems + totalSizeOfUnmeasuredItems;
1628
-};
1629
-
1630
-var VariableSizeList =
1631
-/*#__PURE__*/
1632
-createListComponent({
1633
- getItemOffset: function getItemOffset(props, index, instanceProps) {
1634
- return getItemMetadata$1(props, index, instanceProps).offset;
1635
- },
1636
- getItemSize: function getItemSize(props, index, instanceProps) {
1637
- return instanceProps.itemMetadataMap[index].size;
1638
- },
1639
- getEstimatedTotalSize: getEstimatedTotalSize,
1640
- getOffsetForIndexAndAlignment: function getOffsetForIndexAndAlignment(props, index, align, scrollOffset, instanceProps) {
1641
- var direction = props.direction,
1642
- height = props.height,
1643
- layout = props.layout,
1644
- width = props.width; // TODO Deprecate direction "horizontal"
1645
-
1646
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1647
- var size = isHorizontal ? width : height;
1648
- var itemMetadata = getItemMetadata$1(props, index, instanceProps); // Get estimated total size after ItemMetadata is computed,
1649
- // To ensure it reflects actual measurements instead of just estimates.
1650
-
1651
- var estimatedTotalSize = getEstimatedTotalSize(props, instanceProps);
1652
- var maxOffset = Math.max(0, Math.min(estimatedTotalSize - size, itemMetadata.offset));
1653
- var minOffset = Math.max(0, itemMetadata.offset - size + itemMetadata.size);
1654
-
1655
- if (align === 'smart') {
1656
- if (scrollOffset >= minOffset - size && scrollOffset <= maxOffset + size) {
1657
- align = 'auto';
1658
- } else {
1659
- align = 'center';
1660
- }
1661
- }
1662
-
1663
- switch (align) {
1664
- case 'start':
1665
- return maxOffset;
1666
-
1667
- case 'end':
1668
- return minOffset;
1669
-
1670
- case 'center':
1671
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1672
-
1673
- case 'auto':
1674
- default:
1675
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1676
- return scrollOffset;
1677
- } else if (scrollOffset < minOffset) {
1678
- return minOffset;
1679
- } else {
1680
- return maxOffset;
1681
- }
1682
-
1683
- }
1684
- },
1685
- getStartIndexForOffset: function getStartIndexForOffset(props, offset, instanceProps) {
1686
- return findNearestItem$1(props, instanceProps, offset);
1687
- },
1688
- getStopIndexForStartIndex: function getStopIndexForStartIndex(props, startIndex, scrollOffset, instanceProps) {
1689
- var direction = props.direction,
1690
- height = props.height,
1691
- itemCount = props.itemCount,
1692
- layout = props.layout,
1693
- width = props.width; // TODO Deprecate direction "horizontal"
1694
-
1695
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1696
- var size = isHorizontal ? width : height;
1697
- var itemMetadata = getItemMetadata$1(props, startIndex, instanceProps);
1698
- var maxOffset = scrollOffset + size;
1699
- var offset = itemMetadata.offset + itemMetadata.size;
1700
- var stopIndex = startIndex;
1701
-
1702
- while (stopIndex < itemCount - 1 && offset < maxOffset) {
1703
- stopIndex++;
1704
- offset += getItemMetadata$1(props, stopIndex, instanceProps).size;
1705
- }
1706
-
1707
- return stopIndex;
1708
- },
1709
- initInstanceProps: function initInstanceProps(props, instance) {
1710
- var _ref4 = props,
1711
- estimatedItemSize = _ref4.estimatedItemSize;
1712
- var instanceProps = {
1713
- itemMetadataMap: {},
1714
- estimatedItemSize: estimatedItemSize || DEFAULT_ESTIMATED_ITEM_SIZE$1,
1715
- lastMeasuredIndex: -1
1716
- };
1717
-
1718
- instance.resetAfterIndex = function (index, shouldForceUpdate) {
1719
- if (shouldForceUpdate === void 0) {
1720
- shouldForceUpdate = true;
1721
- }
1722
-
1723
- instanceProps.lastMeasuredIndex = Math.min(instanceProps.lastMeasuredIndex, index - 1); // We could potentially optimize further by only evicting styles after this index,
1724
- // But since styles are only cached while scrolling is in progress-
1725
- // It seems an unnecessary optimization.
1726
- // It's unlikely that resetAfterIndex() will be called while a user is scrolling.
1727
-
1728
- instance._getItemStyleCache(-1);
1729
-
1730
- if (shouldForceUpdate) {
1731
- instance.forceUpdate();
1732
- }
1733
- };
1734
-
1735
- return instanceProps;
1736
- },
1737
- shouldResetStyleCacheOnItemSizeChange: false,
1738
- validateProps: function validateProps(_ref5) {
1739
- var itemSize = _ref5.itemSize;
1740
-
1741
- if (process.env.NODE_ENV !== 'production') {
1742
- if (typeof itemSize !== 'function') {
1743
- throw Error('An invalid "itemSize" prop has been specified. ' + 'Value should be a function. ' + ("\"" + (itemSize === null ? 'null' : typeof itemSize) + "\" was specified."));
1744
- }
1745
- }
1746
- }
1747
-});
1748
-
1749
-var FixedSizeGrid =
1750
-/*#__PURE__*/
1751
-createGridComponent({
1752
- getColumnOffset: function getColumnOffset(_ref, index) {
1753
- var columnWidth = _ref.columnWidth;
1754
- return index * columnWidth;
1755
- },
1756
- getColumnWidth: function getColumnWidth(_ref2, index) {
1757
- var columnWidth = _ref2.columnWidth;
1758
- return columnWidth;
1759
- },
1760
- getRowOffset: function getRowOffset(_ref3, index) {
1761
- var rowHeight = _ref3.rowHeight;
1762
- return index * rowHeight;
1763
- },
1764
- getRowHeight: function getRowHeight(_ref4, index) {
1765
- var rowHeight = _ref4.rowHeight;
1766
- return rowHeight;
1767
- },
1768
- getEstimatedTotalHeight: function getEstimatedTotalHeight(_ref5) {
1769
- var rowCount = _ref5.rowCount,
1770
- rowHeight = _ref5.rowHeight;
1771
- return rowHeight * rowCount;
1772
- },
1773
- getEstimatedTotalWidth: function getEstimatedTotalWidth(_ref6) {
1774
- var columnCount = _ref6.columnCount,
1775
- columnWidth = _ref6.columnWidth;
1776
- return columnWidth * columnCount;
1777
- },
1778
- getOffsetForColumnAndAlignment: function getOffsetForColumnAndAlignment(_ref7, columnIndex, align, scrollLeft, instanceProps, scrollbarSize) {
1779
- var columnCount = _ref7.columnCount,
1780
- columnWidth = _ref7.columnWidth,
1781
- width = _ref7.width;
1782
- var lastColumnOffset = Math.max(0, columnCount * columnWidth - width);
1783
- var maxOffset = Math.min(lastColumnOffset, columnIndex * columnWidth);
1784
- var minOffset = Math.max(0, columnIndex * columnWidth - width + scrollbarSize + columnWidth);
1785
-
1786
- if (align === 'smart') {
1787
- if (scrollLeft >= minOffset - width && scrollLeft <= maxOffset + width) {
1788
- align = 'auto';
1789
- } else {
1790
- align = 'center';
1791
- }
1792
- }
1793
-
1794
- switch (align) {
1795
- case 'start':
1796
- return maxOffset;
1797
-
1798
- case 'end':
1799
- return minOffset;
1800
-
1801
- case 'center':
1802
- // "Centered" offset is usually the average of the min and max.
1803
- // But near the edges of the list, this doesn't hold true.
1804
- var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1805
-
1806
- if (middleOffset < Math.ceil(width / 2)) {
1807
- return 0; // near the beginning
1808
- } else if (middleOffset > lastColumnOffset + Math.floor(width / 2)) {
1809
- return lastColumnOffset; // near the end
1810
- } else {
1811
- return middleOffset;
1812
- }
1813
-
1814
- case 'auto':
1815
- default:
1816
- if (scrollLeft >= minOffset && scrollLeft <= maxOffset) {
1817
- return scrollLeft;
1818
- } else if (minOffset > maxOffset) {
1819
- // Because we only take into account the scrollbar size when calculating minOffset
1820
- // this value can be larger than maxOffset when at the end of the list
1821
- return minOffset;
1822
- } else if (scrollLeft < minOffset) {
1823
- return minOffset;
1824
- } else {
1825
- return maxOffset;
1826
- }
1827
-
1828
- }
1829
- },
1830
- getOffsetForRowAndAlignment: function getOffsetForRowAndAlignment(_ref8, rowIndex, align, scrollTop, instanceProps, scrollbarSize) {
1831
- var rowHeight = _ref8.rowHeight,
1832
- height = _ref8.height,
1833
- rowCount = _ref8.rowCount;
1834
- var lastRowOffset = Math.max(0, rowCount * rowHeight - height);
1835
- var maxOffset = Math.min(lastRowOffset, rowIndex * rowHeight);
1836
- var minOffset = Math.max(0, rowIndex * rowHeight - height + scrollbarSize + rowHeight);
1837
-
1838
- if (align === 'smart') {
1839
- if (scrollTop >= minOffset - height && scrollTop <= maxOffset + height) {
1840
- align = 'auto';
1841
- } else {
1842
- align = 'center';
1843
- }
1844
- }
1845
-
1846
- switch (align) {
1847
- case 'start':
1848
- return maxOffset;
1849
-
1850
- case 'end':
1851
- return minOffset;
1852
-
1853
- case 'center':
1854
- // "Centered" offset is usually the average of the min and max.
1855
- // But near the edges of the list, this doesn't hold true.
1856
- var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1857
-
1858
- if (middleOffset < Math.ceil(height / 2)) {
1859
- return 0; // near the beginning
1860
- } else if (middleOffset > lastRowOffset + Math.floor(height / 2)) {
1861
- return lastRowOffset; // near the end
1862
- } else {
1863
- return middleOffset;
1864
- }
1865
-
1866
- case 'auto':
1867
- default:
1868
- if (scrollTop >= minOffset && scrollTop <= maxOffset) {
1869
- return scrollTop;
1870
- } else if (minOffset > maxOffset) {
1871
- // Because we only take into account the scrollbar size when calculating minOffset
1872
- // this value can be larger than maxOffset when at the end of the list
1873
- return minOffset;
1874
- } else if (scrollTop < minOffset) {
1875
- return minOffset;
1876
- } else {
1877
- return maxOffset;
1878
- }
1879
-
1880
- }
1881
- },
1882
- getColumnStartIndexForOffset: function getColumnStartIndexForOffset(_ref9, scrollLeft) {
1883
- var columnWidth = _ref9.columnWidth,
1884
- columnCount = _ref9.columnCount;
1885
- return Math.max(0, Math.min(columnCount - 1, Math.floor(scrollLeft / columnWidth)));
1886
- },
1887
- getColumnStopIndexForStartIndex: function getColumnStopIndexForStartIndex(_ref10, startIndex, scrollLeft) {
1888
- var columnWidth = _ref10.columnWidth,
1889
- columnCount = _ref10.columnCount,
1890
- width = _ref10.width;
1891
- var left = startIndex * columnWidth;
1892
- var numVisibleColumns = Math.ceil((width + scrollLeft - left) / columnWidth);
1893
- return Math.max(0, Math.min(columnCount - 1, startIndex + numVisibleColumns - 1 // -1 is because stop index is inclusive
1894
- ));
1895
- },
1896
- getRowStartIndexForOffset: function getRowStartIndexForOffset(_ref11, scrollTop) {
1897
- var rowHeight = _ref11.rowHeight,
1898
- rowCount = _ref11.rowCount;
1899
- return Math.max(0, Math.min(rowCount - 1, Math.floor(scrollTop / rowHeight)));
1900
- },
1901
- getRowStopIndexForStartIndex: function getRowStopIndexForStartIndex(_ref12, startIndex, scrollTop) {
1902
- var rowHeight = _ref12.rowHeight,
1903
- rowCount = _ref12.rowCount,
1904
- height = _ref12.height;
1905
- var top = startIndex * rowHeight;
1906
- var numVisibleRows = Math.ceil((height + scrollTop - top) / rowHeight);
1907
- return Math.max(0, Math.min(rowCount - 1, startIndex + numVisibleRows - 1 // -1 is because stop index is inclusive
1908
- ));
1909
- },
1910
- initInstanceProps: function initInstanceProps(props) {// Noop
1911
- },
1912
- shouldResetStyleCacheOnItemSizeChange: true,
1913
- validateProps: function validateProps(_ref13) {
1914
- var columnWidth = _ref13.columnWidth,
1915
- rowHeight = _ref13.rowHeight;
1916
-
1917
- if (process.env.NODE_ENV !== 'production') {
1918
- if (typeof columnWidth !== 'number') {
1919
- throw Error('An invalid "columnWidth" prop has been specified. ' + 'Value should be a number. ' + ("\"" + (columnWidth === null ? 'null' : typeof columnWidth) + "\" was specified."));
1920
- }
1921
-
1922
- if (typeof rowHeight !== 'number') {
1923
- throw Error('An invalid "rowHeight" prop has been specified. ' + 'Value should be a number. ' + ("\"" + (rowHeight === null ? 'null' : typeof rowHeight) + "\" was specified."));
1924
- }
1925
- }
1926
- }
1927
-});
1928
-
1929
-var FixedSizeList =
1930
-/*#__PURE__*/
1931
-createListComponent({
1932
- getItemOffset: function getItemOffset(_ref, index) {
1933
- var itemSize = _ref.itemSize;
1934
- return index * itemSize;
1935
- },
1936
- getItemSize: function getItemSize(_ref2, index) {
1937
- var itemSize = _ref2.itemSize;
1938
- return itemSize;
1939
- },
1940
- getEstimatedTotalSize: function getEstimatedTotalSize(_ref3) {
1941
- var itemCount = _ref3.itemCount,
1942
- itemSize = _ref3.itemSize;
1943
- return itemSize * itemCount;
1944
- },
1945
- getOffsetForIndexAndAlignment: function getOffsetForIndexAndAlignment(_ref4, index, align, scrollOffset) {
1946
- var direction = _ref4.direction,
1947
- height = _ref4.height,
1948
- itemCount = _ref4.itemCount,
1949
- itemSize = _ref4.itemSize,
1950
- layout = _ref4.layout,
1951
- width = _ref4.width;
1952
- // TODO Deprecate direction "horizontal"
1953
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1954
- var size = isHorizontal ? width : height;
1955
- var lastItemOffset = Math.max(0, itemCount * itemSize - size);
1956
- var maxOffset = Math.min(lastItemOffset, index * itemSize);
1957
- var minOffset = Math.max(0, index * itemSize - size + itemSize);
1958
-
1959
- if (align === 'smart') {
1960
- if (scrollOffset >= minOffset - size && scrollOffset <= maxOffset + size) {
1961
- align = 'auto';
1962
- } else {
1963
- align = 'center';
1964
- }
1965
- }
1966
-
1967
- switch (align) {
1968
- case 'start':
1969
- return maxOffset;
1970
-
1971
- case 'end':
1972
- return minOffset;
1973
-
1974
- case 'center':
1975
- {
1976
- // "Centered" offset is usually the average of the min and max.
1977
- // But near the edges of the list, this doesn't hold true.
1978
- var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1979
-
1980
- if (middleOffset < Math.ceil(size / 2)) {
1981
- return 0; // near the beginning
1982
- } else if (middleOffset > lastItemOffset + Math.floor(size / 2)) {
1983
- return lastItemOffset; // near the end
1984
- } else {
1985
- return middleOffset;
1986
- }
1987
- }
1988
-
1989
- case 'auto':
1990
- default:
1991
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1992
- return scrollOffset;
1993
- } else if (scrollOffset < minOffset) {
1994
- return minOffset;
1995
- } else {
1996
- return maxOffset;
1997
- }
1998
-
1999
- }
2000
- },
2001
- getStartIndexForOffset: function getStartIndexForOffset(_ref5, offset) {
2002
- var itemCount = _ref5.itemCount,
2003
- itemSize = _ref5.itemSize;
2004
- return Math.max(0, Math.min(itemCount - 1, Math.floor(offset / itemSize)));
2005
- },
2006
- getStopIndexForStartIndex: function getStopIndexForStartIndex(_ref6, startIndex, scrollOffset) {
2007
- var direction = _ref6.direction,
2008
- height = _ref6.height,
2009
- itemCount = _ref6.itemCount,
2010
- itemSize = _ref6.itemSize,
2011
- layout = _ref6.layout,
2012
- width = _ref6.width;
2013
- // TODO Deprecate direction "horizontal"
2014
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
2015
- var offset = startIndex * itemSize;
2016
- var size = isHorizontal ? width : height;
2017
- var numVisibleItems = Math.ceil((size + scrollOffset - offset) / itemSize);
2018
- return Math.max(0, Math.min(itemCount - 1, startIndex + numVisibleItems - 1 // -1 is because stop index is inclusive
2019
- ));
2020
- },
2021
- initInstanceProps: function initInstanceProps(props) {// Noop
2022
- },
2023
- shouldResetStyleCacheOnItemSizeChange: true,
2024
- validateProps: function validateProps(_ref7) {
2025
- var itemSize = _ref7.itemSize;
2026
-
2027
- if (process.env.NODE_ENV !== 'production') {
2028
- if (typeof itemSize !== 'number') {
2029
- throw Error('An invalid "itemSize" prop has been specified. ' + 'Value should be a number. ' + ("\"" + (itemSize === null ? 'null' : typeof itemSize) + "\" was specified."));
2030
- }
2031
- }
2032
- }
2033
-});
2034
-
2035
-// Pulled from react-compat
2036
-// https://github.com/developit/preact-compat/blob/7c5de00e7c85e2ffd011bf3af02899b63f699d3a/src/index.js#L349
2037
-function shallowDiffers(prev, next) {
2038
- for (var attribute in prev) {
2039
- if (!(attribute in next)) {
2040
- return true;
2041
- }
2042
- }
2043
-
2044
- for (var _attribute in next) {
2045
- if (prev[_attribute] !== next[_attribute]) {
2046
- return true;
2047
- }
2048
- }
2049
-
2050
- return false;
2051
-}
2052
-
2053
-// It knows to compare individual style props and ignore the wrapper object.
2054
-// See https://reactjs.org/docs/react-api.html#reactmemo
2055
-
2056
-function areEqual(prevProps, nextProps) {
2057
- var prevStyle = prevProps.style,
2058
- prevRest = _objectWithoutPropertiesLoose(prevProps, ["style"]);
2059
-
2060
- var nextStyle = nextProps.style,
2061
- nextRest = _objectWithoutPropertiesLoose(nextProps, ["style"]);
2062
-
2063
- return !shallowDiffers(prevStyle, nextStyle) && !shallowDiffers(prevRest, nextRest);
2064
-}
2065
-
2066
-// It knows to compare individual style props and ignore the wrapper object.
2067
-// See https://reactjs.org/docs/react-component.html#shouldcomponentupdate
2068
-
2069
-function shouldComponentUpdate(nextProps, nextState) {
2070
- return !areEqual(this.props, nextProps) || shallowDiffers(this.state, nextState);
2071
-}
2072
-
2073
-exports.VariableSizeGrid = VariableSizeGrid;
2074
-exports.VariableSizeList = VariableSizeList;
2075
-exports.FixedSizeGrid = FixedSizeGrid;
2076
-exports.FixedSizeList = FixedSizeList;
2077
-exports.areEqual = areEqual;
2078
-exports.shouldComponentUpdate = shouldComponentUpdate;
2079
-//# sourceMappingURL=index.cjs.js.map
packages/react-devtools-shared/src/node_modules/react-window/dist/index.cjs.js.flow
deleted
-3
@@ -1,3 +0,0 @@
1
-// @flow
2
-
3
-export * from '../src';
packages/react-devtools-shared/src/node_modules/react-window/dist/index.esm.js
deleted
-2078
@@ -1,2078 +0,0 @@
1
-import _extends from '@babel/runtime/helpers/esm/extends';
2
-import _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose';
3
-import _assertThisInitialized from '@babel/runtime/helpers/esm/assertThisInitialized';
4
-import memoizeOne from 'memoize-one';
5
-import { createElement, PureComponent } from 'react';
6
-import { flushSync } from 'react-dom';
7
-import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose';
8
-
9
-// Animation frame based implementation of setTimeout.
10
-// Inspired by Joe Lambert, https://gist.github.com/joelambert/1002116#file-requesttimeout-js
11
-var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
12
-var now = hasNativePerformanceNow ? function () {
13
- return performance.now();
14
-} : function () {
15
- return Date.now();
16
-};
17
-function cancelTimeout(timeoutID) {
18
- cancelAnimationFrame(timeoutID.id);
19
-}
20
-function requestTimeout(callback, delay) {
21
- var start = now();
22
-
23
- function tick() {
24
- if (now() - start >= delay) {
25
- callback.call(null);
26
- } else {
27
- timeoutID.id = requestAnimationFrame(tick);
28
- }
29
- }
30
-
31
- var timeoutID = {
32
- id: requestAnimationFrame(tick)
33
- };
34
- return timeoutID;
35
-}
36
-
37
-var size = -1; // This utility copied from "dom-helpers" package.
38
-
39
-function getScrollbarSize(recalculate) {
40
- if (recalculate === void 0) {
41
- recalculate = false;
42
- }
43
-
44
- if (size === -1 || recalculate) {
45
- var div = document.createElement('div');
46
- var style = div.style;
47
- style.width = '50px';
48
- style.height = '50px';
49
- style.overflow = 'scroll';
50
- document.body.appendChild(div);
51
- size = div.offsetWidth - div.clientWidth;
52
- document.body.removeChild(div);
53
- }
54
-
55
- return size;
56
-}
57
-var cachedRTLResult = null; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
58
-// Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
59
-// Safari's elastic bounce makes detecting this even more complicated wrt potential false positives.
60
-// The safest way to check this is to intentionally set a negative offset,
61
-// and then verify that the subsequent "scroll" event matches the negative offset.
62
-// If it does not match, then we can assume a non-standard RTL scroll implementation.
63
-
64
-function getRTLOffsetType(recalculate) {
65
- if (recalculate === void 0) {
66
- recalculate = false;
67
- }
68
-
69
- if (cachedRTLResult === null || recalculate) {
70
- var outerDiv = document.createElement('div');
71
- var outerStyle = outerDiv.style;
72
- outerStyle.width = '50px';
73
- outerStyle.height = '50px';
74
- outerStyle.overflow = 'scroll';
75
- outerStyle.direction = 'rtl';
76
- var innerDiv = document.createElement('div');
77
- var innerStyle = innerDiv.style;
78
- innerStyle.width = '100px';
79
- innerStyle.height = '100px';
80
- outerDiv.appendChild(innerDiv);
81
- document.body.appendChild(outerDiv);
82
-
83
- if (outerDiv.scrollLeft > 0) {
84
- cachedRTLResult = 'positive-descending';
85
- } else {
86
- outerDiv.scrollLeft = 1;
87
-
88
- if (outerDiv.scrollLeft === 0) {
89
- cachedRTLResult = 'negative';
90
- } else {
91
- cachedRTLResult = 'positive-ascending';
92
- }
93
- }
94
-
95
- document.body.removeChild(outerDiv);
96
- return cachedRTLResult;
97
- }
98
-
99
- return cachedRTLResult;
100
-}
101
-
102
-var IS_SCROLLING_DEBOUNCE_INTERVAL = 150;
103
-
104
-var defaultItemKey = function defaultItemKey(_ref) {
105
- var columnIndex = _ref.columnIndex,
106
- data = _ref.data,
107
- rowIndex = _ref.rowIndex;
108
- return rowIndex + ":" + columnIndex;
109
-}; // In DEV mode, this Set helps us only log a warning once per component instance.
110
-// This avoids spamming the console every time a render happens.
111
-
112
-
113
-var devWarningsOverscanCount = null;
114
-var devWarningsOverscanRowsColumnsCount = null;
115
-var devWarningsTagName = null;
116
-
117
-if (process.env.NODE_ENV !== 'production') {
118
- if (typeof window !== 'undefined' && typeof window.WeakSet !== 'undefined') {
119
- devWarningsOverscanCount =
120
- /*#__PURE__*/
121
- new WeakSet();
122
- devWarningsOverscanRowsColumnsCount =
123
- /*#__PURE__*/
124
- new WeakSet();
125
- devWarningsTagName =
126
- /*#__PURE__*/
127
- new WeakSet();
128
- }
129
-}
130
-
131
-function createGridComponent(_ref2) {
132
- var _class, _temp;
133
-
134
- var getColumnOffset = _ref2.getColumnOffset,
135
- getColumnStartIndexForOffset = _ref2.getColumnStartIndexForOffset,
136
- getColumnStopIndexForStartIndex = _ref2.getColumnStopIndexForStartIndex,
137
- getColumnWidth = _ref2.getColumnWidth,
138
- getEstimatedTotalHeight = _ref2.getEstimatedTotalHeight,
139
- getEstimatedTotalWidth = _ref2.getEstimatedTotalWidth,
140
- getOffsetForColumnAndAlignment = _ref2.getOffsetForColumnAndAlignment,
141
- getOffsetForRowAndAlignment = _ref2.getOffsetForRowAndAlignment,
142
- getRowHeight = _ref2.getRowHeight,
143
- getRowOffset = _ref2.getRowOffset,
144
- getRowStartIndexForOffset = _ref2.getRowStartIndexForOffset,
145
- getRowStopIndexForStartIndex = _ref2.getRowStopIndexForStartIndex,
146
- initInstanceProps = _ref2.initInstanceProps,
147
- shouldResetStyleCacheOnItemSizeChange = _ref2.shouldResetStyleCacheOnItemSizeChange,
148
- validateProps = _ref2.validateProps;
149
- return _temp = _class =
150
- /*#__PURE__*/
151
- function (_PureComponent) {
152
- _inheritsLoose(Grid, _PureComponent);
153
-
154
- // Always use explicit constructor for React components.
155
- // It produces less code after transpilation. (#26)
156
- // eslint-disable-next-line no-useless-constructor
157
- function Grid(props) {
158
- var _this;
159
-
160
- _this = _PureComponent.call(this, props) || this;
161
- _this._instanceProps = initInstanceProps(_this.props, _assertThisInitialized(_assertThisInitialized(_this)));
162
- _this._resetIsScrollingTimeoutId = null;
163
- _this._outerRef = void 0;
164
- _this.state = {
165
- instance: _assertThisInitialized(_assertThisInitialized(_this)),
166
- isScrolling: false,
167
- horizontalScrollDirection: 'forward',
168
- scrollLeft: typeof _this.props.initialScrollLeft === 'number' ? _this.props.initialScrollLeft : 0,
169
- scrollTop: typeof _this.props.initialScrollTop === 'number' ? _this.props.initialScrollTop : 0,
170
- scrollUpdateWasRequested: false,
171
- verticalScrollDirection: 'forward'
172
- };
173
- _this._callOnItemsRendered = void 0;
174
- _this._callOnItemsRendered = memoizeOne(function (overscanColumnStartIndex, overscanColumnStopIndex, overscanRowStartIndex, overscanRowStopIndex, visibleColumnStartIndex, visibleColumnStopIndex, visibleRowStartIndex, visibleRowStopIndex) {
175
- return _this.props.onItemsRendered({
176
- overscanColumnStartIndex: overscanColumnStartIndex,
177
- overscanColumnStopIndex: overscanColumnStopIndex,
178
- overscanRowStartIndex: overscanRowStartIndex,
179
- overscanRowStopIndex: overscanRowStopIndex,
180
- visibleColumnStartIndex: visibleColumnStartIndex,
181
- visibleColumnStopIndex: visibleColumnStopIndex,
182
- visibleRowStartIndex: visibleRowStartIndex,
183
- visibleRowStopIndex: visibleRowStopIndex
184
- });
185
- });
186
- _this._callOnScroll = void 0;
187
- _this._callOnScroll = memoizeOne(function (scrollLeft, scrollTop, horizontalScrollDirection, verticalScrollDirection, scrollUpdateWasRequested) {
188
- return _this.props.onScroll({
189
- horizontalScrollDirection: horizontalScrollDirection,
190
- scrollLeft: scrollLeft,
191
- scrollTop: scrollTop,
192
- verticalScrollDirection: verticalScrollDirection,
193
- scrollUpdateWasRequested: scrollUpdateWasRequested
194
- });
195
- });
196
- _this._getItemStyle = void 0;
197
-
198
- _this._getItemStyle = function (rowIndex, columnIndex) {
199
- var _this$props = _this.props,
200
- columnWidth = _this$props.columnWidth,
201
- direction = _this$props.direction,
202
- rowHeight = _this$props.rowHeight;
203
-
204
- var itemStyleCache = _this._getItemStyleCache(shouldResetStyleCacheOnItemSizeChange && columnWidth, shouldResetStyleCacheOnItemSizeChange && direction, shouldResetStyleCacheOnItemSizeChange && rowHeight);
205
-
206
- var key = rowIndex + ":" + columnIndex;
207
- var style;
208
-
209
- if (itemStyleCache.hasOwnProperty(key)) {
210
- style = itemStyleCache[key];
211
- } else {
212
- var _style;
213
-
214
- itemStyleCache[key] = style = (_style = {
215
- position: 'absolute'
216
- }, _style[direction === 'rtl' ? 'right' : 'left'] = getColumnOffset(_this.props, columnIndex, _this._instanceProps), _style.top = getRowOffset(_this.props, rowIndex, _this._instanceProps), _style.height = getRowHeight(_this.props, rowIndex, _this._instanceProps), _style.width = getColumnWidth(_this.props, columnIndex, _this._instanceProps), _style);
217
- }
218
-
219
- return style;
220
- };
221
-
222
- _this._getItemStyleCache = void 0;
223
- _this._getItemStyleCache = memoizeOne(function (_, __, ___) {
224
- return {};
225
- });
226
-
227
- _this._onScroll = function (event) {
228
- var _event$currentTarget = event.currentTarget,
229
- clientHeight = _event$currentTarget.clientHeight,
230
- clientWidth = _event$currentTarget.clientWidth,
231
- scrollLeft = _event$currentTarget.scrollLeft,
232
- scrollTop = _event$currentTarget.scrollTop,
233
- scrollHeight = _event$currentTarget.scrollHeight,
234
- scrollWidth = _event$currentTarget.scrollWidth;
235
-
236
- // Force flush sync for scroll updates to reduce visual checkerboarding.
237
- flushSync(() => {
238
- _this.setState(function (prevState) {
239
- if (prevState.scrollLeft === scrollLeft && prevState.scrollTop === scrollTop) {
240
- // Scroll position may have been updated by cDM/cDU,
241
- // In which case we don't need to trigger another render,
242
- // And we don't want to update state.isScrolling.
243
- return null;
244
- }
245
-
246
- var direction = _this.props.direction; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
247
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
248
- // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
249
- // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
250
-
251
- var calculatedScrollLeft = scrollLeft;
252
-
253
- if (direction === 'rtl') {
254
- switch (getRTLOffsetType()) {
255
- case 'negative':
256
- calculatedScrollLeft = -scrollLeft;
257
- break;
258
-
259
- case 'positive-descending':
260
- calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
261
- break;
262
- }
263
- } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
264
-
265
-
266
- calculatedScrollLeft = Math.max(0, Math.min(calculatedScrollLeft, scrollWidth - clientWidth));
267
- var calculatedScrollTop = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
268
- return {
269
- isScrolling: true,
270
- horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
271
- scrollLeft: calculatedScrollLeft,
272
- scrollTop: calculatedScrollTop,
273
- verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward',
274
- scrollUpdateWasRequested: false
275
- };
276
- }, _this._resetIsScrollingDebounced);
277
- });
278
- };
279
-
280
- _this._outerRefSetter = function (ref) {
281
- var outerRef = _this.props.outerRef;
282
- _this._outerRef = ref;
283
-
284
- if (typeof outerRef === 'function') {
285
- outerRef(ref);
286
- } else if (outerRef != null && typeof outerRef === 'object' && outerRef.hasOwnProperty('current')) {
287
- outerRef.current = ref;
288
- }
289
- };
290
-
291
- _this._resetIsScrollingDebounced = function () {
292
- if (_this._resetIsScrollingTimeoutId !== null) {
293
- cancelTimeout(_this._resetIsScrollingTimeoutId);
294
- }
295
-
296
- _this._resetIsScrollingTimeoutId = requestTimeout(_this._resetIsScrolling, IS_SCROLLING_DEBOUNCE_INTERVAL);
297
- };
298
-
299
- _this._resetIsScrolling = function () {
300
- _this._resetIsScrollingTimeoutId = null;
301
-
302
- _this.setState({
303
- isScrolling: false
304
- }, function () {
305
- // Clear style cache after state update has been committed.
306
- // This way we don't break pure sCU for items that don't use isScrolling param.
307
- _this._getItemStyleCache(-1);
308
- });
309
- };
310
-
311
- return _this;
312
- }
313
-
314
- Grid.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
315
- validateSharedProps(nextProps, prevState);
316
- validateProps(nextProps);
317
- return null;
318
- };
319
-
320
- var _proto = Grid.prototype;
321
-
322
- _proto.scrollTo = function scrollTo(_ref3) {
323
- var scrollLeft = _ref3.scrollLeft,
324
- scrollTop = _ref3.scrollTop;
325
-
326
- if (scrollLeft !== undefined) {
327
- scrollLeft = Math.max(0, scrollLeft);
328
- }
329
-
330
- if (scrollTop !== undefined) {
331
- scrollTop = Math.max(0, scrollTop);
332
- }
333
-
334
- this.setState(function (prevState) {
335
- if (scrollLeft === undefined) {
336
- scrollLeft = prevState.scrollLeft;
337
- }
338
-
339
- if (scrollTop === undefined) {
340
- scrollTop = prevState.scrollTop;
341
- }
342
-
343
- if (prevState.scrollLeft === scrollLeft && prevState.scrollTop === scrollTop) {
344
- return null;
345
- }
346
-
347
- return {
348
- horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
349
- scrollLeft: scrollLeft,
350
- scrollTop: scrollTop,
351
- scrollUpdateWasRequested: true,
352
- verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward'
353
- };
354
- }, this._resetIsScrollingDebounced);
355
- };
356
-
357
- _proto.scrollToItem = function scrollToItem(_ref4) {
358
- var _ref4$align = _ref4.align,
359
- align = _ref4$align === void 0 ? 'auto' : _ref4$align,
360
- columnIndex = _ref4.columnIndex,
361
- rowIndex = _ref4.rowIndex;
362
- var _this$props2 = this.props,
363
- columnCount = _this$props2.columnCount,
364
- height = _this$props2.height,
365
- rowCount = _this$props2.rowCount,
366
- width = _this$props2.width;
367
- var _this$state = this.state,
368
- scrollLeft = _this$state.scrollLeft,
369
- scrollTop = _this$state.scrollTop;
370
- var scrollbarSize = getScrollbarSize();
371
-
372
- if (columnIndex !== undefined) {
373
- columnIndex = Math.max(0, Math.min(columnIndex, columnCount - 1));
374
- }
375
-
376
- if (rowIndex !== undefined) {
377
- rowIndex = Math.max(0, Math.min(rowIndex, rowCount - 1));
378
- }
379
-
380
- var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps);
381
- var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps); // The scrollbar size should be considered when scrolling an item into view,
382
- // to ensure it's fully visible.
383
- // But we only need to account for its size when it's actually visible.
384
-
385
- var horizontalScrollbarSize = estimatedTotalWidth > width ? scrollbarSize : 0;
386
- var verticalScrollbarSize = estimatedTotalHeight > height ? scrollbarSize : 0;
387
- this.scrollTo({
388
- scrollLeft: columnIndex !== undefined ? getOffsetForColumnAndAlignment(this.props, columnIndex, align, scrollLeft, this._instanceProps, verticalScrollbarSize) : scrollLeft,
389
- scrollTop: rowIndex !== undefined ? getOffsetForRowAndAlignment(this.props, rowIndex, align, scrollTop, this._instanceProps, horizontalScrollbarSize) : scrollTop
390
- });
391
- };
392
-
393
- _proto.componentDidMount = function componentDidMount() {
394
- var _this$props3 = this.props,
395
- initialScrollLeft = _this$props3.initialScrollLeft,
396
- initialScrollTop = _this$props3.initialScrollTop;
397
-
398
- if (this._outerRef != null) {
399
- var outerRef = this._outerRef;
400
-
401
- if (typeof initialScrollLeft === 'number') {
402
- outerRef.scrollLeft = initialScrollLeft;
403
- }
404
-
405
- if (typeof initialScrollTop === 'number') {
406
- outerRef.scrollTop = initialScrollTop;
407
- }
408
- }
409
-
410
- this._callPropsCallbacks();
411
- };
412
-
413
- _proto.componentDidUpdate = function componentDidUpdate() {
414
- var direction = this.props.direction;
415
- var _this$state2 = this.state,
416
- scrollLeft = _this$state2.scrollLeft,
417
- scrollTop = _this$state2.scrollTop,
418
- scrollUpdateWasRequested = _this$state2.scrollUpdateWasRequested;
419
-
420
- if (scrollUpdateWasRequested && this._outerRef != null) {
421
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
422
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
423
- // So we need to determine which browser behavior we're dealing with, and mimic it.
424
- var outerRef = this._outerRef;
425
-
426
- if (direction === 'rtl') {
427
- switch (getRTLOffsetType()) {
428
- case 'negative':
429
- outerRef.scrollLeft = -scrollLeft;
430
- break;
431
-
432
- case 'positive-ascending':
433
- outerRef.scrollLeft = scrollLeft;
434
- break;
435
-
436
- default:
437
- var clientWidth = outerRef.clientWidth,
438
- scrollWidth = outerRef.scrollWidth;
439
- outerRef.scrollLeft = scrollWidth - clientWidth - scrollLeft;
440
- break;
441
- }
442
- } else {
443
- outerRef.scrollLeft = Math.max(0, scrollLeft);
444
- }
445
-
446
- outerRef.scrollTop = Math.max(0, scrollTop);
447
- }
448
-
449
- this._callPropsCallbacks();
450
- };
451
-
452
- _proto.componentWillUnmount = function componentWillUnmount() {
453
- if (this._resetIsScrollingTimeoutId !== null) {
454
- cancelTimeout(this._resetIsScrollingTimeoutId);
455
- }
456
- };
457
-
458
- _proto.render = function render() {
459
- var _this$props4 = this.props,
460
- children = _this$props4.children,
461
- className = _this$props4.className,
462
- columnCount = _this$props4.columnCount,
463
- direction = _this$props4.direction,
464
- height = _this$props4.height,
465
- innerRef = _this$props4.innerRef,
466
- innerElementType = _this$props4.innerElementType,
467
- innerTagName = _this$props4.innerTagName,
468
- itemData = _this$props4.itemData,
469
- _this$props4$itemKey = _this$props4.itemKey,
470
- itemKey = _this$props4$itemKey === void 0 ? defaultItemKey : _this$props4$itemKey,
471
- outerElementType = _this$props4.outerElementType,
472
- outerTagName = _this$props4.outerTagName,
473
- rowCount = _this$props4.rowCount,
474
- style = _this$props4.style,
475
- useIsScrolling = _this$props4.useIsScrolling,
476
- width = _this$props4.width;
477
- var isScrolling = this.state.isScrolling;
478
-
479
- var _this$_getHorizontalR = this._getHorizontalRangeToRender(),
480
- columnStartIndex = _this$_getHorizontalR[0],
481
- columnStopIndex = _this$_getHorizontalR[1];
482
-
483
- var _this$_getVerticalRan = this._getVerticalRangeToRender(),
484
- rowStartIndex = _this$_getVerticalRan[0],
485
- rowStopIndex = _this$_getVerticalRan[1];
486
-
487
- var items = [];
488
-
489
- if (columnCount > 0 && rowCount) {
490
- for (var _rowIndex = rowStartIndex; _rowIndex <= rowStopIndex; _rowIndex++) {
491
- for (var _columnIndex = columnStartIndex; _columnIndex <= columnStopIndex; _columnIndex++) {
492
- items.push(createElement(children, {
493
- columnIndex: _columnIndex,
494
- data: itemData,
495
- isScrolling: useIsScrolling ? isScrolling : undefined,
496
- key: itemKey({
497
- columnIndex: _columnIndex,
498
- data: itemData,
499
- rowIndex: _rowIndex
500
- }),
501
- rowIndex: _rowIndex,
502
- style: this._getItemStyle(_rowIndex, _columnIndex)
503
- }));
504
- }
505
- }
506
- } // Read this value AFTER items have been created,
507
- // So their actual sizes (if variable) are taken into consideration.
508
-
509
-
510
- var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps);
511
- var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps);
512
- return createElement(outerElementType || outerTagName || 'div', {
513
- className: className,
514
- onScroll: this._onScroll,
515
- ref: this._outerRefSetter,
516
- style: _extends({
517
- position: 'relative',
518
- height: height,
519
- width: width,
520
- overflow: 'auto',
521
- WebkitOverflowScrolling: 'touch',
522
- willChange: 'transform',
523
- direction: direction
524
- }, style)
525
- }, createElement(innerElementType || innerTagName || 'div', {
526
- children: items,
527
- ref: innerRef,
528
- style: {
529
- height: estimatedTotalHeight,
530
- pointerEvents: isScrolling ? 'none' : undefined,
531
- width: estimatedTotalWidth
532
- }
533
- }));
534
- };
535
-
536
- _proto._callPropsCallbacks = function _callPropsCallbacks() {
537
- var _this$props5 = this.props,
538
- columnCount = _this$props5.columnCount,
539
- onItemsRendered = _this$props5.onItemsRendered,
540
- onScroll = _this$props5.onScroll,
541
- rowCount = _this$props5.rowCount;
542
-
543
- if (typeof onItemsRendered === 'function') {
544
- if (columnCount > 0 && rowCount > 0) {
545
- var _this$_getHorizontalR2 = this._getHorizontalRangeToRender(),
546
- _overscanColumnStartIndex = _this$_getHorizontalR2[0],
547
- _overscanColumnStopIndex = _this$_getHorizontalR2[1],
548
- _visibleColumnStartIndex = _this$_getHorizontalR2[2],
549
- _visibleColumnStopIndex = _this$_getHorizontalR2[3];
550
-
551
- var _this$_getVerticalRan2 = this._getVerticalRangeToRender(),
552
- _overscanRowStartIndex = _this$_getVerticalRan2[0],
553
- _overscanRowStopIndex = _this$_getVerticalRan2[1],
554
- _visibleRowStartIndex = _this$_getVerticalRan2[2],
555
- _visibleRowStopIndex = _this$_getVerticalRan2[3];
556
-
557
- this._callOnItemsRendered(_overscanColumnStartIndex, _overscanColumnStopIndex, _overscanRowStartIndex, _overscanRowStopIndex, _visibleColumnStartIndex, _visibleColumnStopIndex, _visibleRowStartIndex, _visibleRowStopIndex);
558
- }
559
- }
560
-
561
- if (typeof onScroll === 'function') {
562
- var _this$state3 = this.state,
563
- _horizontalScrollDirection = _this$state3.horizontalScrollDirection,
564
- _scrollLeft = _this$state3.scrollLeft,
565
- _scrollTop = _this$state3.scrollTop,
566
- _scrollUpdateWasRequested = _this$state3.scrollUpdateWasRequested,
567
- _verticalScrollDirection = _this$state3.verticalScrollDirection;
568
-
569
- this._callOnScroll(_scrollLeft, _scrollTop, _horizontalScrollDirection, _verticalScrollDirection, _scrollUpdateWasRequested);
570
- }
571
- }; // Lazily create and cache item styles while scrolling,
572
- // So that pure component sCU will prevent re-renders.
573
- // We maintain this cache, and pass a style prop rather than index,
574
- // So that List can clear cached styles and force item re-render if necessary.
575
-
576
-
577
- _proto._getHorizontalRangeToRender = function _getHorizontalRangeToRender() {
578
- var _this$props6 = this.props,
579
- columnCount = _this$props6.columnCount,
580
- overscanColumnCount = _this$props6.overscanColumnCount,
581
- overscanColumnsCount = _this$props6.overscanColumnsCount,
582
- overscanCount = _this$props6.overscanCount,
583
- rowCount = _this$props6.rowCount;
584
- var _this$state4 = this.state,
585
- horizontalScrollDirection = _this$state4.horizontalScrollDirection,
586
- isScrolling = _this$state4.isScrolling,
587
- scrollLeft = _this$state4.scrollLeft;
588
- var overscanCountResolved = overscanColumnCount || overscanColumnsCount || overscanCount || 1;
589
-
590
- if (columnCount === 0 || rowCount === 0) {
591
- return [0, 0, 0, 0];
592
- }
593
-
594
- var startIndex = getColumnStartIndexForOffset(this.props, scrollLeft, this._instanceProps);
595
- var stopIndex = getColumnStopIndexForStartIndex(this.props, startIndex, scrollLeft, this._instanceProps); // Overscan by one item in each direction so that tab/focus works.
596
- // If there isn't at least one extra item, tab loops back around.
597
-
598
- var overscanBackward = !isScrolling || horizontalScrollDirection === 'backward' ? Math.max(1, overscanCountResolved) : 1;
599
- var overscanForward = !isScrolling || horizontalScrollDirection === 'forward' ? Math.max(1, overscanCountResolved) : 1;
600
- return [Math.max(0, startIndex - overscanBackward), Math.max(0, Math.min(columnCount - 1, stopIndex + overscanForward)), startIndex, stopIndex];
601
- };
602
-
603
- _proto._getVerticalRangeToRender = function _getVerticalRangeToRender() {
604
- var _this$props7 = this.props,
605
- columnCount = _this$props7.columnCount,
606
- overscanCount = _this$props7.overscanCount,
607
- overscanRowCount = _this$props7.overscanRowCount,
608
- overscanRowsCount = _this$props7.overscanRowsCount,
609
- rowCount = _this$props7.rowCount;
610
- var _this$state5 = this.state,
611
- isScrolling = _this$state5.isScrolling,
612
- verticalScrollDirection = _this$state5.verticalScrollDirection,
613
- scrollTop = _this$state5.scrollTop;
614
- var overscanCountResolved = overscanRowCount || overscanRowsCount || overscanCount || 1;
615
-
616
- if (columnCount === 0 || rowCount === 0) {
617
- return [0, 0, 0, 0];
618
- }
619
-
620
- var startIndex = getRowStartIndexForOffset(this.props, scrollTop, this._instanceProps);
621
- var stopIndex = getRowStopIndexForStartIndex(this.props, startIndex, scrollTop, this._instanceProps); // Overscan by one item in each direction so that tab/focus works.
622
- // If there isn't at least one extra item, tab loops back around.
623
-
624
- var overscanBackward = !isScrolling || verticalScrollDirection === 'backward' ? Math.max(1, overscanCountResolved) : 1;
625
- var overscanForward = !isScrolling || verticalScrollDirection === 'forward' ? Math.max(1, overscanCountResolved) : 1;
626
- return [Math.max(0, startIndex - overscanBackward), Math.max(0, Math.min(rowCount - 1, stopIndex + overscanForward)), startIndex, stopIndex];
627
- };
628
-
629
- return Grid;
630
- }(PureComponent), _class.defaultProps = {
631
- direction: 'ltr',
632
- itemData: undefined,
633
- useIsScrolling: false
634
- }, _temp;
635
-}
636
-
637
-var validateSharedProps = function validateSharedProps(_ref5, _ref6) {
638
- var children = _ref5.children,
639
- direction = _ref5.direction,
640
- height = _ref5.height,
641
- innerTagName = _ref5.innerTagName,
642
- outerTagName = _ref5.outerTagName,
643
- overscanColumnsCount = _ref5.overscanColumnsCount,
644
- overscanCount = _ref5.overscanCount,
645
- overscanRowsCount = _ref5.overscanRowsCount,
646
- width = _ref5.width;
647
- var instance = _ref6.instance;
648
-
649
- if (process.env.NODE_ENV !== 'production') {
650
- if (typeof overscanCount === 'number') {
651
- if (devWarningsOverscanCount && !devWarningsOverscanCount.has(instance)) {
652
- devWarningsOverscanCount.add(instance);
653
- console.warn('The overscanCount prop has been deprecated. ' + 'Please use the overscanColumnCount and overscanRowCount props instead.');
654
- }
655
- }
656
-
657
- if (typeof overscanColumnsCount === 'number' || typeof overscanRowsCount === 'number') {
658
- if (devWarningsOverscanRowsColumnsCount && !devWarningsOverscanRowsColumnsCount.has(instance)) {
659
- devWarningsOverscanRowsColumnsCount.add(instance);
660
- console.warn('The overscanColumnsCount and overscanRowsCount props have been deprecated. ' + 'Please use the overscanColumnCount and overscanRowCount props instead.');
661
- }
662
- }
663
-
664
- if (innerTagName != null || outerTagName != null) {
665
- if (devWarningsTagName && !devWarningsTagName.has(instance)) {
666
- devWarningsTagName.add(instance);
667
- console.warn('The innerTagName and outerTagName props have been deprecated. ' + 'Please use the innerElementType and outerElementType props instead.');
668
- }
669
- }
670
-
671
- if (children == null) {
672
- throw Error('An invalid "children" prop has been specified. ' + 'Value should be a React component. ' + ("\"" + (children === null ? 'null' : typeof children) + "\" was specified."));
673
- }
674
-
675
- switch (direction) {
676
- case 'ltr':
677
- case 'rtl':
678
- // Valid values
679
- break;
680
-
681
- default:
682
- throw Error('An invalid "direction" prop has been specified. ' + 'Value should be either "ltr" or "rtl". ' + ("\"" + direction + "\" was specified."));
683
- }
684
-
685
- if (typeof width !== 'number') {
686
- throw Error('An invalid "width" prop has been specified. ' + 'Grids must specify a number for width. ' + ("\"" + (width === null ? 'null' : typeof width) + "\" was specified."));
687
- }
688
-
689
- if (typeof height !== 'number') {
690
- throw Error('An invalid "height" prop has been specified. ' + 'Grids must specify a number for height. ' + ("\"" + (height === null ? 'null' : typeof height) + "\" was specified."));
691
- }
692
- }
693
-};
694
-
695
-var DEFAULT_ESTIMATED_ITEM_SIZE = 50;
696
-
697
-var getEstimatedTotalHeight = function getEstimatedTotalHeight(_ref, _ref2) {
698
- var rowCount = _ref.rowCount;
699
- var rowMetadataMap = _ref2.rowMetadataMap,
700
- estimatedRowHeight = _ref2.estimatedRowHeight,
701
- lastMeasuredRowIndex = _ref2.lastMeasuredRowIndex;
702
- var totalSizeOfMeasuredRows = 0; // Edge case check for when the number of items decreases while a scroll is in progress.
703
- // https://github.com/bvaughn/react-window/pull/138
704
-
705
- if (lastMeasuredRowIndex >= rowCount) {
706
- lastMeasuredRowIndex = rowCount - 1;
707
- }
708
-
709
- if (lastMeasuredRowIndex >= 0) {
710
- var itemMetadata = rowMetadataMap[lastMeasuredRowIndex];
711
- totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size;
712
- }
713
-
714
- var numUnmeasuredItems = rowCount - lastMeasuredRowIndex - 1;
715
- var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedRowHeight;
716
- return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems;
717
-};
718
-
719
-var getEstimatedTotalWidth = function getEstimatedTotalWidth(_ref3, _ref4) {
720
- var columnCount = _ref3.columnCount;
721
- var columnMetadataMap = _ref4.columnMetadataMap,
722
- estimatedColumnWidth = _ref4.estimatedColumnWidth,
723
- lastMeasuredColumnIndex = _ref4.lastMeasuredColumnIndex;
724
- var totalSizeOfMeasuredRows = 0; // Edge case check for when the number of items decreases while a scroll is in progress.
725
- // https://github.com/bvaughn/react-window/pull/138
726
-
727
- if (lastMeasuredColumnIndex >= columnCount) {
728
- lastMeasuredColumnIndex = columnCount - 1;
729
- }
730
-
731
- if (lastMeasuredColumnIndex >= 0) {
732
- var itemMetadata = columnMetadataMap[lastMeasuredColumnIndex];
733
- totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size;
734
- }
735
-
736
- var numUnmeasuredItems = columnCount - lastMeasuredColumnIndex - 1;
737
- var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedColumnWidth;
738
- return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems;
739
-};
740
-
741
-var getItemMetadata = function getItemMetadata(itemType, props, index, instanceProps) {
742
- var itemMetadataMap, itemSize, lastMeasuredIndex;
743
-
744
- if (itemType === 'column') {
745
- itemMetadataMap = instanceProps.columnMetadataMap;
746
- itemSize = props.columnWidth;
747
- lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex;
748
- } else {
749
- itemMetadataMap = instanceProps.rowMetadataMap;
750
- itemSize = props.rowHeight;
751
- lastMeasuredIndex = instanceProps.lastMeasuredRowIndex;
752
- }
753
-
754
- if (index > lastMeasuredIndex) {
755
- var offset = 0;
756
-
757
- if (lastMeasuredIndex >= 0) {
758
- var itemMetadata = itemMetadataMap[lastMeasuredIndex];
759
- offset = itemMetadata.offset + itemMetadata.size;
760
- }
761
-
762
- for (var i = lastMeasuredIndex + 1; i <= index; i++) {
763
- var size = itemSize(i);
764
- itemMetadataMap[i] = {
765
- offset: offset,
766
- size: size
767
- };
768
- offset += size;
769
- }
770
-
771
- if (itemType === 'column') {
772
- instanceProps.lastMeasuredColumnIndex = index;
773
- } else {
774
- instanceProps.lastMeasuredRowIndex = index;
775
- }
776
- }
777
-
778
- return itemMetadataMap[index];
779
-};
780
-
781
-var findNearestItem = function findNearestItem(itemType, props, instanceProps, offset) {
782
- var itemMetadataMap, lastMeasuredIndex;
783
-
784
- if (itemType === 'column') {
785
- itemMetadataMap = instanceProps.columnMetadataMap;
786
- lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex;
787
- } else {
788
- itemMetadataMap = instanceProps.rowMetadataMap;
789
- lastMeasuredIndex = instanceProps.lastMeasuredRowIndex;
790
- }
791
-
792
- var lastMeasuredItemOffset = lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0;
793
-
794
- if (lastMeasuredItemOffset >= offset) {
795
- // If we've already measured items within this range just use a binary search as it's faster.
796
- return findNearestItemBinarySearch(itemType, props, instanceProps, lastMeasuredIndex, 0, offset);
797
- } else {
798
- // If we haven't yet measured this high, fallback to an exponential search with an inner binary search.
799
- // The exponential search avoids pre-computing sizes for the full set of items as a binary search would.
800
- // The overall complexity for this approach is O(log n).
801
- return findNearestItemExponentialSearch(itemType, props, instanceProps, Math.max(0, lastMeasuredIndex), offset);
802
- }
803
-};
804
-
805
-var findNearestItemBinarySearch = function findNearestItemBinarySearch(itemType, props, instanceProps, high, low, offset) {
806
- while (low <= high) {
807
- var middle = low + Math.floor((high - low) / 2);
808
- var currentOffset = getItemMetadata(itemType, props, middle, instanceProps).offset;
809
-
810
- if (currentOffset === offset) {
811
- return middle;
812
- } else if (currentOffset < offset) {
813
- low = middle + 1;
814
- } else if (currentOffset > offset) {
815
- high = middle - 1;
816
- }
817
- }
818
-
819
- if (low > 0) {
820
- return low - 1;
821
- } else {
822
- return 0;
823
- }
824
-};
825
-
826
-var findNearestItemExponentialSearch = function findNearestItemExponentialSearch(itemType, props, instanceProps, index, offset) {
827
- var itemCount = itemType === 'column' ? props.columnCount : props.rowCount;
828
- var interval = 1;
829
-
830
- while (index < itemCount && getItemMetadata(itemType, props, index, instanceProps).offset < offset) {
831
- index += interval;
832
- interval *= 2;
833
- }
834
-
835
- return findNearestItemBinarySearch(itemType, props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset);
836
-};
837
-
838
-var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(itemType, props, index, align, scrollOffset, instanceProps, scrollbarSize) {
839
- var size = itemType === 'column' ? props.width : props.height;
840
- var itemMetadata = getItemMetadata(itemType, props, index, instanceProps); // Get estimated total size after ItemMetadata is computed,
841
- // To ensure it reflects actual measurements instead of just estimates.
842
-
843
- var estimatedTotalSize = itemType === 'column' ? getEstimatedTotalWidth(props, instanceProps) : getEstimatedTotalHeight(props, instanceProps);
844
- var maxOffset = Math.max(0, Math.min(estimatedTotalSize - size, itemMetadata.offset));
845
- var minOffset = Math.max(0, itemMetadata.offset - size + scrollbarSize + itemMetadata.size);
846
-
847
- if (align === 'smart') {
848
- if (scrollOffset >= minOffset - size && scrollOffset <= maxOffset + size) {
849
- align = 'auto';
850
- } else {
851
- align = 'center';
852
- }
853
- }
854
-
855
- switch (align) {
856
- case 'start':
857
- return maxOffset;
858
-
859
- case 'end':
860
- return minOffset;
861
-
862
- case 'center':
863
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
864
-
865
- case 'auto':
866
- default:
867
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
868
- return scrollOffset;
869
- } else if (minOffset > maxOffset) {
870
- // Because we only take into account the scrollbar size when calculating minOffset
871
- // this value can be larger than maxOffset when at the end of the list
872
- return minOffset;
873
- } else if (scrollOffset < minOffset) {
874
- return minOffset;
875
- } else {
876
- return maxOffset;
877
- }
878
-
879
- }
880
-};
881
-
882
-var VariableSizeGrid =
883
-/*#__PURE__*/
884
-createGridComponent({
885
- getColumnOffset: function getColumnOffset(props, index, instanceProps) {
886
- return getItemMetadata('column', props, index, instanceProps).offset;
887
- },
888
- getColumnStartIndexForOffset: function getColumnStartIndexForOffset(props, scrollLeft, instanceProps) {
889
- return findNearestItem('column', props, instanceProps, scrollLeft);
890
- },
891
- getColumnStopIndexForStartIndex: function getColumnStopIndexForStartIndex(props, startIndex, scrollLeft, instanceProps) {
892
- var columnCount = props.columnCount,
893
- width = props.width;
894
- var itemMetadata = getItemMetadata('column', props, startIndex, instanceProps);
895
- var maxOffset = scrollLeft + width;
896
- var offset = itemMetadata.offset + itemMetadata.size;
897
- var stopIndex = startIndex;
898
-
899
- while (stopIndex < columnCount - 1 && offset < maxOffset) {
900
- stopIndex++;
901
- offset += getItemMetadata('column', props, stopIndex, instanceProps).size;
902
- }
903
-
904
- return stopIndex;
905
- },
906
- getColumnWidth: function getColumnWidth(props, index, instanceProps) {
907
- return instanceProps.columnMetadataMap[index].size;
908
- },
909
- getEstimatedTotalHeight: getEstimatedTotalHeight,
910
- getEstimatedTotalWidth: getEstimatedTotalWidth,
911
- getOffsetForColumnAndAlignment: function getOffsetForColumnAndAlignment(props, index, align, scrollOffset, instanceProps, scrollbarSize) {
912
- return getOffsetForIndexAndAlignment('column', props, index, align, scrollOffset, instanceProps, scrollbarSize);
913
- },
914
- getOffsetForRowAndAlignment: function getOffsetForRowAndAlignment(props, index, align, scrollOffset, instanceProps, scrollbarSize) {
915
- return getOffsetForIndexAndAlignment('row', props, index, align, scrollOffset, instanceProps, scrollbarSize);
916
- },
917
- getRowOffset: function getRowOffset(props, index, instanceProps) {
918
- return getItemMetadata('row', props, index, instanceProps).offset;
919
- },
920
- getRowHeight: function getRowHeight(props, index, instanceProps) {
921
- return instanceProps.rowMetadataMap[index].size;
922
- },
923
- getRowStartIndexForOffset: function getRowStartIndexForOffset(props, scrollTop, instanceProps) {
924
- return findNearestItem('row', props, instanceProps, scrollTop);
925
- },
926
- getRowStopIndexForStartIndex: function getRowStopIndexForStartIndex(props, startIndex, scrollTop, instanceProps) {
927
- var rowCount = props.rowCount,
928
- height = props.height;
929
- var itemMetadata = getItemMetadata('row', props, startIndex, instanceProps);
930
- var maxOffset = scrollTop + height;
931
- var offset = itemMetadata.offset + itemMetadata.size;
932
- var stopIndex = startIndex;
933
-
934
- while (stopIndex < rowCount - 1 && offset < maxOffset) {
935
- stopIndex++;
936
- offset += getItemMetadata('row', props, stopIndex, instanceProps).size;
937
- }
938
-
939
- return stopIndex;
940
- },
941
- initInstanceProps: function initInstanceProps(props, instance) {
942
- var _ref5 = props,
943
- estimatedColumnWidth = _ref5.estimatedColumnWidth,
944
- estimatedRowHeight = _ref5.estimatedRowHeight;
945
- var instanceProps = {
946
- columnMetadataMap: {},
947
- estimatedColumnWidth: estimatedColumnWidth || DEFAULT_ESTIMATED_ITEM_SIZE,
948
- estimatedRowHeight: estimatedRowHeight || DEFAULT_ESTIMATED_ITEM_SIZE,
949
- lastMeasuredColumnIndex: -1,
950
- lastMeasuredRowIndex: -1,
951
- rowMetadataMap: {}
952
- };
953
-
954
- instance.resetAfterColumnIndex = function (columnIndex, shouldForceUpdate) {
955
- if (shouldForceUpdate === void 0) {
956
- shouldForceUpdate = true;
957
- }
958
-
959
- instance.resetAfterIndices({
960
- columnIndex: columnIndex,
961
- shouldForceUpdate: shouldForceUpdate
962
- });
963
- };
964
-
965
- instance.resetAfterRowIndex = function (rowIndex, shouldForceUpdate) {
966
- if (shouldForceUpdate === void 0) {
967
- shouldForceUpdate = true;
968
- }
969
-
970
- instance.resetAfterIndices({
971
- rowIndex: rowIndex,
972
- shouldForceUpdate: shouldForceUpdate
973
- });
974
- };
975
-
976
- instance.resetAfterIndices = function (_ref6) {
977
- var columnIndex = _ref6.columnIndex,
978
- rowIndex = _ref6.rowIndex,
979
- _ref6$shouldForceUpda = _ref6.shouldForceUpdate,
980
- shouldForceUpdate = _ref6$shouldForceUpda === void 0 ? true : _ref6$shouldForceUpda;
981
-
982
- if (typeof columnIndex === 'number') {
983
- instanceProps.lastMeasuredColumnIndex = Math.min(instanceProps.lastMeasuredColumnIndex, columnIndex - 1);
984
- }
985
-
986
- if (typeof rowIndex === 'number') {
987
- instanceProps.lastMeasuredRowIndex = Math.min(instanceProps.lastMeasuredRowIndex, rowIndex - 1);
988
- } // We could potentially optimize further by only evicting styles after this index,
989
- // But since styles are only cached while scrolling is in progress-
990
- // It seems an unnecessary optimization.
991
- // It's unlikely that resetAfterIndex() will be called while a user is scrolling.
992
-
993
-
994
- instance._getItemStyleCache(-1);
995
-
996
- if (shouldForceUpdate) {
997
- instance.forceUpdate();
998
- }
999
- };
1000
-
1001
- return instanceProps;
1002
- },
1003
- shouldResetStyleCacheOnItemSizeChange: false,
1004
- validateProps: function validateProps(_ref7) {
1005
- var columnWidth = _ref7.columnWidth,
1006
- rowHeight = _ref7.rowHeight;
1007
-
1008
- if (process.env.NODE_ENV !== 'production') {
1009
- if (typeof columnWidth !== 'function') {
1010
- throw Error('An invalid "columnWidth" prop has been specified. ' + 'Value should be a function. ' + ("\"" + (columnWidth === null ? 'null' : typeof columnWidth) + "\" was specified."));
1011
- } else if (typeof rowHeight !== 'function') {
1012
- throw Error('An invalid "rowHeight" prop has been specified. ' + 'Value should be a function. ' + ("\"" + (rowHeight === null ? 'null' : typeof rowHeight) + "\" was specified."));
1013
- }
1014
- }
1015
- }
1016
-});
1017
-
1018
-var IS_SCROLLING_DEBOUNCE_INTERVAL$1 = 150;
1019
-
1020
-var defaultItemKey$1 = function defaultItemKey(index, data) {
1021
- return index;
1022
-}; // In DEV mode, this Set helps us only log a warning once per component instance.
1023
-// This avoids spamming the console every time a render happens.
1024
-
1025
-
1026
-var devWarningsDirection = null;
1027
-var devWarningsTagName$1 = null;
1028
-
1029
-if (process.env.NODE_ENV !== 'production') {
1030
- if (typeof window !== 'undefined' && typeof window.WeakSet !== 'undefined') {
1031
- devWarningsDirection =
1032
- /*#__PURE__*/
1033
- new WeakSet();
1034
- devWarningsTagName$1 =
1035
- /*#__PURE__*/
1036
- new WeakSet();
1037
- }
1038
-}
1039
-
1040
-function createListComponent(_ref) {
1041
- var _class, _temp;
1042
-
1043
- var getItemOffset = _ref.getItemOffset,
1044
- getEstimatedTotalSize = _ref.getEstimatedTotalSize,
1045
- getItemSize = _ref.getItemSize,
1046
- getOffsetForIndexAndAlignment = _ref.getOffsetForIndexAndAlignment,
1047
- getStartIndexForOffset = _ref.getStartIndexForOffset,
1048
- getStopIndexForStartIndex = _ref.getStopIndexForStartIndex,
1049
- initInstanceProps = _ref.initInstanceProps,
1050
- shouldResetStyleCacheOnItemSizeChange = _ref.shouldResetStyleCacheOnItemSizeChange,
1051
- validateProps = _ref.validateProps;
1052
- return _temp = _class =
1053
- /*#__PURE__*/
1054
- function (_PureComponent) {
1055
- _inheritsLoose(List, _PureComponent);
1056
-
1057
- // Always use explicit constructor for React components.
1058
- // It produces less code after transpilation. (#26)
1059
- // eslint-disable-next-line no-useless-constructor
1060
- function List(props) {
1061
- var _this;
1062
-
1063
- _this = _PureComponent.call(this, props) || this;
1064
- _this._instanceProps = initInstanceProps(_this.props, _assertThisInitialized(_assertThisInitialized(_this)));
1065
- _this._outerRef = void 0;
1066
- _this._resetIsScrollingTimeoutId = null;
1067
- _this.state = {
1068
- instance: _assertThisInitialized(_assertThisInitialized(_this)),
1069
- isScrolling: false,
1070
- scrollDirection: 'forward',
1071
- scrollOffset: typeof _this.props.initialScrollOffset === 'number' ? _this.props.initialScrollOffset : 0,
1072
- scrollUpdateWasRequested: false
1073
- };
1074
- _this._callOnItemsRendered = void 0;
1075
- _this._callOnItemsRendered = memoizeOne(function (overscanStartIndex, overscanStopIndex, visibleStartIndex, visibleStopIndex) {
1076
- return _this.props.onItemsRendered({
1077
- overscanStartIndex: overscanStartIndex,
1078
- overscanStopIndex: overscanStopIndex,
1079
- visibleStartIndex: visibleStartIndex,
1080
- visibleStopIndex: visibleStopIndex
1081
- });
1082
- });
1083
- _this._callOnScroll = void 0;
1084
- _this._callOnScroll = memoizeOne(function (scrollDirection, scrollOffset, scrollUpdateWasRequested) {
1085
- return _this.props.onScroll({
1086
- scrollDirection: scrollDirection,
1087
- scrollOffset: scrollOffset,
1088
- scrollUpdateWasRequested: scrollUpdateWasRequested
1089
- });
1090
- });
1091
- _this._getItemStyle = void 0;
1092
-
1093
- _this._getItemStyle = function (index) {
1094
- var _this$props = _this.props,
1095
- direction = _this$props.direction,
1096
- itemSize = _this$props.itemSize,
1097
- layout = _this$props.layout;
1098
-
1099
- var itemStyleCache = _this._getItemStyleCache(shouldResetStyleCacheOnItemSizeChange && itemSize, shouldResetStyleCacheOnItemSizeChange && layout, shouldResetStyleCacheOnItemSizeChange && direction);
1100
-
1101
- var style;
1102
-
1103
- if (itemStyleCache.hasOwnProperty(index)) {
1104
- style = itemStyleCache[index];
1105
- } else {
1106
- var _style;
1107
-
1108
- var _offset = getItemOffset(_this.props, index, _this._instanceProps);
1109
-
1110
- var size = getItemSize(_this.props, index, _this._instanceProps); // TODO Deprecate direction "horizontal"
1111
-
1112
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1113
- itemStyleCache[index] = style = (_style = {
1114
- position: 'absolute'
1115
- }, _style[direction === 'rtl' ? 'right' : 'left'] = isHorizontal ? _offset : 0, _style.top = !isHorizontal ? _offset : 0, _style.height = !isHorizontal ? size : '100%', _style.width = isHorizontal ? size : '100%', _style);
1116
- }
1117
-
1118
- return style;
1119
- };
1120
-
1121
- _this._getItemStyleCache = void 0;
1122
- _this._getItemStyleCache = memoizeOne(function (_, __, ___) {
1123
- return {};
1124
- });
1125
-
1126
- _this._onScrollHorizontal = function (event) {
1127
- var _event$currentTarget = event.currentTarget,
1128
- clientWidth = _event$currentTarget.clientWidth,
1129
- scrollLeft = _event$currentTarget.scrollLeft,
1130
- scrollWidth = _event$currentTarget.scrollWidth;
1131
-
1132
- // Force flush sync for scroll updates to reduce visual checkerboarding.
1133
- flushSync(() => {
1134
- _this.setState(function (prevState) {
1135
- if (prevState.scrollOffset === scrollLeft) {
1136
- // Scroll position may have been updated by cDM/cDU,
1137
- // In which case we don't need to trigger another render,
1138
- // And we don't want to update state.isScrolling.
1139
- return null;
1140
- }
1141
-
1142
- var direction = _this.props.direction;
1143
- var scrollOffset = scrollLeft;
1144
-
1145
- if (direction === 'rtl') {
1146
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1147
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1148
- // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
1149
- // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
1150
- switch (getRTLOffsetType()) {
1151
- case 'negative':
1152
- scrollOffset = -scrollLeft;
1153
- break;
1154
-
1155
- case 'positive-descending':
1156
- scrollOffset = scrollWidth - clientWidth - scrollLeft;
1157
- break;
1158
- }
1159
- } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
1160
-
1161
-
1162
- scrollOffset = Math.max(0, Math.min(scrollOffset, scrollWidth - clientWidth));
1163
- return {
1164
- isScrolling: true,
1165
- scrollDirection: prevState.scrollOffset < scrollLeft ? 'forward' : 'backward',
1166
- scrollOffset: scrollOffset,
1167
- scrollUpdateWasRequested: false
1168
- };
1169
- }, _this._resetIsScrollingDebounced);
1170
- });
1171
- };
1172
-
1173
- _this._onScrollVertical = function (event) {
1174
- var _event$currentTarget2 = event.currentTarget,
1175
- clientHeight = _event$currentTarget2.clientHeight,
1176
- scrollHeight = _event$currentTarget2.scrollHeight,
1177
- scrollTop = _event$currentTarget2.scrollTop;
1178
-
1179
- // Force flush sync for scroll updates to reduce visual checkerboarding.
1180
- flushSync(() => {
1181
- _this.setState(function (prevState) {
1182
- if (prevState.scrollOffset === scrollTop) {
1183
- // Scroll position may have been updated by cDM/cDU,
1184
- // In which case we don't need to trigger another render,
1185
- // And we don't want to update state.isScrolling.
1186
- return null;
1187
- } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
1188
-
1189
-
1190
- var scrollOffset = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
1191
- return {
1192
- isScrolling: true,
1193
- scrollDirection: prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
1194
- scrollOffset: scrollOffset,
1195
- scrollUpdateWasRequested: false
1196
- };
1197
- }, _this._resetIsScrollingDebounced);
1198
- });
1199
- };
1200
-
1201
- _this._outerRefSetter = function (ref) {
1202
- var outerRef = _this.props.outerRef;
1203
- _this._outerRef = ref;
1204
-
1205
- if (typeof outerRef === 'function') {
1206
- outerRef(ref);
1207
- } else if (outerRef != null && typeof outerRef === 'object' && outerRef.hasOwnProperty('current')) {
1208
- outerRef.current = ref;
1209
- }
1210
- };
1211
-
1212
- _this._resetIsScrollingDebounced = function () {
1213
- if (_this._resetIsScrollingTimeoutId !== null) {
1214
- cancelTimeout(_this._resetIsScrollingTimeoutId);
1215
- }
1216
-
1217
- _this._resetIsScrollingTimeoutId = requestTimeout(_this._resetIsScrolling, IS_SCROLLING_DEBOUNCE_INTERVAL$1);
1218
- };
1219
-
1220
- _this._resetIsScrolling = function () {
1221
- _this._resetIsScrollingTimeoutId = null;
1222
-
1223
- _this.setState({
1224
- isScrolling: false
1225
- }, function () {
1226
- // Clear style cache after state update has been committed.
1227
- // This way we don't break pure sCU for items that don't use isScrolling param.
1228
- _this._getItemStyleCache(-1, null);
1229
- });
1230
- };
1231
-
1232
- return _this;
1233
- }
1234
-
1235
- List.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
1236
- validateSharedProps$1(nextProps, prevState);
1237
- validateProps(nextProps);
1238
- return null;
1239
- };
1240
-
1241
- var _proto = List.prototype;
1242
-
1243
- _proto.scrollTo = function scrollTo(scrollOffset) {
1244
- scrollOffset = Math.max(0, scrollOffset);
1245
- this.setState(function (prevState) {
1246
- if (prevState.scrollOffset === scrollOffset) {
1247
- return null;
1248
- }
1249
-
1250
- return {
1251
- scrollDirection: prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
1252
- scrollOffset: scrollOffset,
1253
- scrollUpdateWasRequested: true
1254
- };
1255
- }, this._resetIsScrollingDebounced);
1256
- };
1257
-
1258
- _proto.scrollToItem = function scrollToItem(index, align) {
1259
- if (align === void 0) {
1260
- align = 'auto';
1261
- }
1262
-
1263
- var itemCount = this.props.itemCount;
1264
- var scrollOffset = this.state.scrollOffset;
1265
- index = Math.max(0, Math.min(index, itemCount - 1));
1266
- this.scrollTo(getOffsetForIndexAndAlignment(this.props, index, align, scrollOffset, this._instanceProps));
1267
- };
1268
-
1269
- _proto.componentDidMount = function componentDidMount() {
1270
- var _this$props2 = this.props,
1271
- direction = _this$props2.direction,
1272
- initialScrollOffset = _this$props2.initialScrollOffset,
1273
- layout = _this$props2.layout;
1274
-
1275
- if (typeof initialScrollOffset === 'number' && this._outerRef != null) {
1276
- var outerRef = this._outerRef; // TODO Deprecate direction "horizontal"
1277
-
1278
- if (direction === 'horizontal' || layout === 'horizontal') {
1279
- outerRef.scrollLeft = initialScrollOffset;
1280
- } else {
1281
- outerRef.scrollTop = initialScrollOffset;
1282
- }
1283
- }
1284
-
1285
- this._callPropsCallbacks();
1286
- };
1287
-
1288
- _proto.componentDidUpdate = function componentDidUpdate() {
1289
- var _this$props3 = this.props,
1290
- direction = _this$props3.direction,
1291
- layout = _this$props3.layout;
1292
- var _this$state = this.state,
1293
- scrollOffset = _this$state.scrollOffset,
1294
- scrollUpdateWasRequested = _this$state.scrollUpdateWasRequested;
1295
-
1296
- if (scrollUpdateWasRequested && this._outerRef != null) {
1297
- var outerRef = this._outerRef; // TODO Deprecate direction "horizontal"
1298
-
1299
- if (direction === 'horizontal' || layout === 'horizontal') {
1300
- if (direction === 'rtl') {
1301
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1302
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1303
- // So we need to determine which browser behavior we're dealing with, and mimic it.
1304
- switch (getRTLOffsetType()) {
1305
- case 'negative':
1306
- outerRef.scrollLeft = -scrollOffset;
1307
- break;
1308
-
1309
- case 'positive-ascending':
1310
- outerRef.scrollLeft = scrollOffset;
1311
- break;
1312
-
1313
- default:
1314
- var clientWidth = outerRef.clientWidth,
1315
- scrollWidth = outerRef.scrollWidth;
1316
- outerRef.scrollLeft = scrollWidth - clientWidth - scrollOffset;
1317
- break;
1318
- }
1319
- } else {
1320
- outerRef.scrollLeft = scrollOffset;
1321
- }
1322
- } else {
1323
- outerRef.scrollTop = scrollOffset;
1324
- }
1325
- }
1326
-
1327
- this._callPropsCallbacks();
1328
- };
1329
-
1330
- _proto.componentWillUnmount = function componentWillUnmount() {
1331
- if (this._resetIsScrollingTimeoutId !== null) {
1332
- cancelTimeout(this._resetIsScrollingTimeoutId);
1333
- }
1334
- };
1335
-
1336
- _proto.render = function render() {
1337
- var _this$props4 = this.props,
1338
- children = _this$props4.children,
1339
- className = _this$props4.className,
1340
- direction = _this$props4.direction,
1341
- height = _this$props4.height,
1342
- innerRef = _this$props4.innerRef,
1343
- innerElementType = _this$props4.innerElementType,
1344
- innerTagName = _this$props4.innerTagName,
1345
- itemCount = _this$props4.itemCount,
1346
- itemData = _this$props4.itemData,
1347
- _this$props4$itemKey = _this$props4.itemKey,
1348
- itemKey = _this$props4$itemKey === void 0 ? defaultItemKey$1 : _this$props4$itemKey,
1349
- layout = _this$props4.layout,
1350
- outerElementType = _this$props4.outerElementType,
1351
- outerTagName = _this$props4.outerTagName,
1352
- style = _this$props4.style,
1353
- useIsScrolling = _this$props4.useIsScrolling,
1354
- width = _this$props4.width;
1355
- var isScrolling = this.state.isScrolling; // TODO Deprecate direction "horizontal"
1356
-
1357
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1358
- var onScroll = isHorizontal ? this._onScrollHorizontal : this._onScrollVertical;
1359
-
1360
- var _this$_getRangeToRend = this._getRangeToRender(),
1361
- startIndex = _this$_getRangeToRend[0],
1362
- stopIndex = _this$_getRangeToRend[1];
1363
-
1364
- var items = [];
1365
-
1366
- if (itemCount > 0) {
1367
- for (var _index = startIndex; _index <= stopIndex; _index++) {
1368
- items.push(createElement(children, {
1369
- data: itemData,
1370
- key: itemKey(_index, itemData),
1371
- index: _index,
1372
- isScrolling: useIsScrolling ? isScrolling : undefined,
1373
- style: this._getItemStyle(_index)
1374
- }));
1375
- }
1376
- } // Read this value AFTER items have been created,
1377
- // So their actual sizes (if variable) are taken into consideration.
1378
-
1379
-
1380
- var estimatedTotalSize = getEstimatedTotalSize(this.props, this._instanceProps);
1381
- return createElement(outerElementType || outerTagName || 'div', {
1382
- className: className,
1383
- onScroll: onScroll,
1384
- ref: this._outerRefSetter,
1385
- style: _extends({
1386
- position: 'relative',
1387
- height: height,
1388
- width: width,
1389
- overflow: 'auto',
1390
- WebkitOverflowScrolling: 'touch',
1391
- willChange: 'transform',
1392
- direction: direction
1393
- }, style)
1394
- }, createElement(innerElementType || innerTagName || 'div', {
1395
- children: items,
1396
- ref: innerRef,
1397
- style: {
1398
- height: isHorizontal ? '100%' : estimatedTotalSize,
1399
- pointerEvents: isScrolling ? 'none' : undefined,
1400
- width: isHorizontal ? estimatedTotalSize : '100%'
1401
- }
1402
- }));
1403
- };
1404
-
1405
- _proto._callPropsCallbacks = function _callPropsCallbacks() {
1406
- if (typeof this.props.onItemsRendered === 'function') {
1407
- var itemCount = this.props.itemCount;
1408
-
1409
- if (itemCount > 0) {
1410
- var _this$_getRangeToRend2 = this._getRangeToRender(),
1411
- _overscanStartIndex = _this$_getRangeToRend2[0],
1412
- _overscanStopIndex = _this$_getRangeToRend2[1],
1413
- _visibleStartIndex = _this$_getRangeToRend2[2],
1414
- _visibleStopIndex = _this$_getRangeToRend2[3];
1415
-
1416
- this._callOnItemsRendered(_overscanStartIndex, _overscanStopIndex, _visibleStartIndex, _visibleStopIndex);
1417
- }
1418
- }
1419
-
1420
- if (typeof this.props.onScroll === 'function') {
1421
- var _this$state2 = this.state,
1422
- _scrollDirection = _this$state2.scrollDirection,
1423
- _scrollOffset = _this$state2.scrollOffset,
1424
- _scrollUpdateWasRequested = _this$state2.scrollUpdateWasRequested;
1425
-
1426
- this._callOnScroll(_scrollDirection, _scrollOffset, _scrollUpdateWasRequested);
1427
- }
1428
- }; // Lazily create and cache item styles while scrolling,
1429
- // So that pure component sCU will prevent re-renders.
1430
- // We maintain this cache, and pass a style prop rather than index,
1431
- // So that List can clear cached styles and force item re-render if necessary.
1432
-
1433
-
1434
- _proto._getRangeToRender = function _getRangeToRender() {
1435
- var _this$props5 = this.props,
1436
- itemCount = _this$props5.itemCount,
1437
- overscanCount = _this$props5.overscanCount;
1438
- var _this$state3 = this.state,
1439
- isScrolling = _this$state3.isScrolling,
1440
- scrollDirection = _this$state3.scrollDirection,
1441
- scrollOffset = _this$state3.scrollOffset;
1442
-
1443
- if (itemCount === 0) {
1444
- return [0, 0, 0, 0];
1445
- }
1446
-
1447
- var startIndex = getStartIndexForOffset(this.props, scrollOffset, this._instanceProps);
1448
- var stopIndex = getStopIndexForStartIndex(this.props, startIndex, scrollOffset, this._instanceProps); // Overscan by one item in each direction so that tab/focus works.
1449
- // If there isn't at least one extra item, tab loops back around.
1450
-
1451
- var overscanBackward = !isScrolling || scrollDirection === 'backward' ? Math.max(1, overscanCount) : 1;
1452
- var overscanForward = !isScrolling || scrollDirection === 'forward' ? Math.max(1, overscanCount) : 1;
1453
- return [Math.max(0, startIndex - overscanBackward), Math.max(0, Math.min(itemCount - 1, stopIndex + overscanForward)), startIndex, stopIndex];
1454
- };
1455
-
1456
- return List;
1457
- }(PureComponent), _class.defaultProps = {
1458
- direction: 'ltr',
1459
- itemData: undefined,
1460
- layout: 'vertical',
1461
- overscanCount: 2,
1462
- useIsScrolling: false
1463
- }, _temp;
1464
-} // NOTE: I considered further wrapping individual items with a pure ListItem component.
1465
-// This would avoid ever calling the render function for the same index more than once,
1466
-// But it would also add the overhead of a lot of components/fibers.
1467
-// I assume people already do this (render function returning a class component),
1468
-// So my doing it would just unnecessarily double the wrappers.
1469
-
1470
-var validateSharedProps$1 = function validateSharedProps(_ref2, _ref3) {
1471
- var children = _ref2.children,
1472
- direction = _ref2.direction,
1473
- height = _ref2.height,
1474
- layout = _ref2.layout,
1475
- innerTagName = _ref2.innerTagName,
1476
- outerTagName = _ref2.outerTagName,
1477
- width = _ref2.width;
1478
- var instance = _ref3.instance;
1479
-
1480
- if (process.env.NODE_ENV !== 'production') {
1481
- if (innerTagName != null || outerTagName != null) {
1482
- if (devWarningsTagName$1 && !devWarningsTagName$1.has(instance)) {
1483
- devWarningsTagName$1.add(instance);
1484
- console.warn('The innerTagName and outerTagName props have been deprecated. ' + 'Please use the innerElementType and outerElementType props instead.');
1485
- }
1486
- } // TODO Deprecate direction "horizontal"
1487
-
1488
-
1489
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1490
-
1491
- switch (direction) {
1492
- case 'horizontal':
1493
- case 'vertical':
1494
- if (devWarningsDirection && !devWarningsDirection.has(instance)) {
1495
- devWarningsDirection.add(instance);
1496
- console.warn('The direction prop should be either "ltr" (default) or "rtl". ' + 'Please use the layout prop to specify "vertical" (default) or "horizontal" orientation.');
1497
- }
1498
-
1499
- break;
1500
-
1501
- case 'ltr':
1502
- case 'rtl':
1503
- // Valid values
1504
- break;
1505
-
1506
- default:
1507
- throw Error('An invalid "direction" prop has been specified. ' + 'Value should be either "ltr" or "rtl". ' + ("\"" + direction + "\" was specified."));
1508
- }
1509
-
1510
- switch (layout) {
1511
- case 'horizontal':
1512
- case 'vertical':
1513
- // Valid values
1514
- break;
1515
-
1516
- default:
1517
- throw Error('An invalid "layout" prop has been specified. ' + 'Value should be either "horizontal" or "vertical". ' + ("\"" + layout + "\" was specified."));
1518
- }
1519
-
1520
- if (children == null) {
1521
- throw Error('An invalid "children" prop has been specified. ' + 'Value should be a React component. ' + ("\"" + (children === null ? 'null' : typeof children) + "\" was specified."));
1522
- }
1523
-
1524
- if (isHorizontal && typeof width !== 'number') {
1525
- throw Error('An invalid "width" prop has been specified. ' + 'Horizontal lists must specify a number for width. ' + ("\"" + (width === null ? 'null' : typeof width) + "\" was specified."));
1526
- } else if (!isHorizontal && typeof height !== 'number') {
1527
- throw Error('An invalid "height" prop has been specified. ' + 'Vertical lists must specify a number for height. ' + ("\"" + (height === null ? 'null' : typeof height) + "\" was specified."));
1528
- }
1529
- }
1530
-};
1531
-
1532
-var DEFAULT_ESTIMATED_ITEM_SIZE$1 = 50;
1533
-
1534
-var getItemMetadata$1 = function getItemMetadata(props, index, instanceProps) {
1535
- var _ref = props,
1536
- itemSize = _ref.itemSize;
1537
- var itemMetadataMap = instanceProps.itemMetadataMap,
1538
- lastMeasuredIndex = instanceProps.lastMeasuredIndex;
1539
-
1540
- if (index > lastMeasuredIndex) {
1541
- var offset = 0;
1542
-
1543
- if (lastMeasuredIndex >= 0) {
1544
- var itemMetadata = itemMetadataMap[lastMeasuredIndex];
1545
- offset = itemMetadata.offset + itemMetadata.size;
1546
- }
1547
-
1548
- for (var i = lastMeasuredIndex + 1; i <= index; i++) {
1549
- var size = itemSize(i);
1550
- itemMetadataMap[i] = {
1551
- offset: offset,
1552
- size: size
1553
- };
1554
- offset += size;
1555
- }
1556
-
1557
- instanceProps.lastMeasuredIndex = index;
1558
- }
1559
-
1560
- return itemMetadataMap[index];
1561
-};
1562
-
1563
-var findNearestItem$1 = function findNearestItem(props, instanceProps, offset) {
1564
- var itemMetadataMap = instanceProps.itemMetadataMap,
1565
- lastMeasuredIndex = instanceProps.lastMeasuredIndex;
1566
- var lastMeasuredItemOffset = lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0;
1567
-
1568
- if (lastMeasuredItemOffset >= offset) {
1569
- // If we've already measured items within this range just use a binary search as it's faster.
1570
- return findNearestItemBinarySearch$1(props, instanceProps, lastMeasuredIndex, 0, offset);
1571
- } else {
1572
- // If we haven't yet measured this high, fallback to an exponential search with an inner binary search.
1573
- // The exponential search avoids pre-computing sizes for the full set of items as a binary search would.
1574
- // The overall complexity for this approach is O(log n).
1575
- return findNearestItemExponentialSearch$1(props, instanceProps, Math.max(0, lastMeasuredIndex), offset);
1576
- }
1577
-};
1578
-
1579
-var findNearestItemBinarySearch$1 = function findNearestItemBinarySearch(props, instanceProps, high, low, offset) {
1580
- while (low <= high) {
1581
- var middle = low + Math.floor((high - low) / 2);
1582
- var currentOffset = getItemMetadata$1(props, middle, instanceProps).offset;
1583
-
1584
- if (currentOffset === offset) {
1585
- return middle;
1586
- } else if (currentOffset < offset) {
1587
- low = middle + 1;
1588
- } else if (currentOffset > offset) {
1589
- high = middle - 1;
1590
- }
1591
- }
1592
-
1593
- if (low > 0) {
1594
- return low - 1;
1595
- } else {
1596
- return 0;
1597
- }
1598
-};
1599
-
1600
-var findNearestItemExponentialSearch$1 = function findNearestItemExponentialSearch(props, instanceProps, index, offset) {
1601
- var itemCount = props.itemCount;
1602
- var interval = 1;
1603
-
1604
- while (index < itemCount && getItemMetadata$1(props, index, instanceProps).offset < offset) {
1605
- index += interval;
1606
- interval *= 2;
1607
- }
1608
-
1609
- return findNearestItemBinarySearch$1(props, instanceProps, Math.min(index, itemCount - 1), Math.floor(index / 2), offset);
1610
-};
1611
-
1612
-var getEstimatedTotalSize = function getEstimatedTotalSize(_ref2, _ref3) {
1613
- var itemCount = _ref2.itemCount;
1614
- var itemMetadataMap = _ref3.itemMetadataMap,
1615
- estimatedItemSize = _ref3.estimatedItemSize,
1616
- lastMeasuredIndex = _ref3.lastMeasuredIndex;
1617
- var totalSizeOfMeasuredItems = 0; // Edge case check for when the number of items decreases while a scroll is in progress.
1618
- // https://github.com/bvaughn/react-window/pull/138
1619
-
1620
- if (lastMeasuredIndex >= itemCount) {
1621
- lastMeasuredIndex = itemCount - 1;
1622
- }
1623
-
1624
- if (lastMeasuredIndex >= 0) {
1625
- var itemMetadata = itemMetadataMap[lastMeasuredIndex];
1626
- totalSizeOfMeasuredItems = itemMetadata.offset + itemMetadata.size;
1627
- }
1628
-
1629
- var numUnmeasuredItems = itemCount - lastMeasuredIndex - 1;
1630
- var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedItemSize;
1631
- return totalSizeOfMeasuredItems + totalSizeOfUnmeasuredItems;
1632
-};
1633
-
1634
-var VariableSizeList =
1635
-/*#__PURE__*/
1636
-createListComponent({
1637
- getItemOffset: function getItemOffset(props, index, instanceProps) {
1638
- return getItemMetadata$1(props, index, instanceProps).offset;
1639
- },
1640
- getItemSize: function getItemSize(props, index, instanceProps) {
1641
- return instanceProps.itemMetadataMap[index].size;
1642
- },
1643
- getEstimatedTotalSize: getEstimatedTotalSize,
1644
- getOffsetForIndexAndAlignment: function getOffsetForIndexAndAlignment(props, index, align, scrollOffset, instanceProps) {
1645
- var direction = props.direction,
1646
- height = props.height,
1647
- layout = props.layout,
1648
- width = props.width; // TODO Deprecate direction "horizontal"
1649
-
1650
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1651
- var size = isHorizontal ? width : height;
1652
- var itemMetadata = getItemMetadata$1(props, index, instanceProps); // Get estimated total size after ItemMetadata is computed,
1653
- // To ensure it reflects actual measurements instead of just estimates.
1654
-
1655
- var estimatedTotalSize = getEstimatedTotalSize(props, instanceProps);
1656
- var maxOffset = Math.max(0, Math.min(estimatedTotalSize - size, itemMetadata.offset));
1657
- var minOffset = Math.max(0, itemMetadata.offset - size + itemMetadata.size);
1658
-
1659
- if (align === 'smart') {
1660
- if (scrollOffset >= minOffset - size && scrollOffset <= maxOffset + size) {
1661
- align = 'auto';
1662
- } else {
1663
- align = 'center';
1664
- }
1665
- }
1666
-
1667
- switch (align) {
1668
- case 'start':
1669
- return maxOffset;
1670
-
1671
- case 'end':
1672
- return minOffset;
1673
-
1674
- case 'center':
1675
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1676
-
1677
- case 'auto':
1678
- default:
1679
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1680
- return scrollOffset;
1681
- } else if (scrollOffset < minOffset) {
1682
- return minOffset;
1683
- } else {
1684
- return maxOffset;
1685
- }
1686
-
1687
- }
1688
- },
1689
- getStartIndexForOffset: function getStartIndexForOffset(props, offset, instanceProps) {
1690
- return findNearestItem$1(props, instanceProps, offset);
1691
- },
1692
- getStopIndexForStartIndex: function getStopIndexForStartIndex(props, startIndex, scrollOffset, instanceProps) {
1693
- var direction = props.direction,
1694
- height = props.height,
1695
- itemCount = props.itemCount,
1696
- layout = props.layout,
1697
- width = props.width; // TODO Deprecate direction "horizontal"
1698
-
1699
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1700
- var size = isHorizontal ? width : height;
1701
- var itemMetadata = getItemMetadata$1(props, startIndex, instanceProps);
1702
- var maxOffset = scrollOffset + size;
1703
- var offset = itemMetadata.offset + itemMetadata.size;
1704
- var stopIndex = startIndex;
1705
-
1706
- while (stopIndex < itemCount - 1 && offset < maxOffset) {
1707
- stopIndex++;
1708
- offset += getItemMetadata$1(props, stopIndex, instanceProps).size;
1709
- }
1710
-
1711
- return stopIndex;
1712
- },
1713
- initInstanceProps: function initInstanceProps(props, instance) {
1714
- var _ref4 = props,
1715
- estimatedItemSize = _ref4.estimatedItemSize;
1716
- var instanceProps = {
1717
- itemMetadataMap: {},
1718
- estimatedItemSize: estimatedItemSize || DEFAULT_ESTIMATED_ITEM_SIZE$1,
1719
- lastMeasuredIndex: -1
1720
- };
1721
-
1722
- instance.resetAfterIndex = function (index, shouldForceUpdate) {
1723
- if (shouldForceUpdate === void 0) {
1724
- shouldForceUpdate = true;
1725
- }
1726
-
1727
- instanceProps.lastMeasuredIndex = Math.min(instanceProps.lastMeasuredIndex, index - 1); // We could potentially optimize further by only evicting styles after this index,
1728
- // But since styles are only cached while scrolling is in progress-
1729
- // It seems an unnecessary optimization.
1730
- // It's unlikely that resetAfterIndex() will be called while a user is scrolling.
1731
-
1732
- instance._getItemStyleCache(-1);
1733
-
1734
- if (shouldForceUpdate) {
1735
- instance.forceUpdate();
1736
- }
1737
- };
1738
-
1739
- return instanceProps;
1740
- },
1741
- shouldResetStyleCacheOnItemSizeChange: false,
1742
- validateProps: function validateProps(_ref5) {
1743
- var itemSize = _ref5.itemSize;
1744
-
1745
- if (process.env.NODE_ENV !== 'production') {
1746
- if (typeof itemSize !== 'function') {
1747
- throw Error('An invalid "itemSize" prop has been specified. ' + 'Value should be a function. ' + ("\"" + (itemSize === null ? 'null' : typeof itemSize) + "\" was specified."));
1748
- }
1749
- }
1750
- }
1751
-});
1752
-
1753
-var FixedSizeGrid =
1754
-/*#__PURE__*/
1755
-createGridComponent({
1756
- getColumnOffset: function getColumnOffset(_ref, index) {
1757
- var columnWidth = _ref.columnWidth;
1758
- return index * columnWidth;
1759
- },
1760
- getColumnWidth: function getColumnWidth(_ref2, index) {
1761
- var columnWidth = _ref2.columnWidth;
1762
- return columnWidth;
1763
- },
1764
- getRowOffset: function getRowOffset(_ref3, index) {
1765
- var rowHeight = _ref3.rowHeight;
1766
- return index * rowHeight;
1767
- },
1768
- getRowHeight: function getRowHeight(_ref4, index) {
1769
- var rowHeight = _ref4.rowHeight;
1770
- return rowHeight;
1771
- },
1772
- getEstimatedTotalHeight: function getEstimatedTotalHeight(_ref5) {
1773
- var rowCount = _ref5.rowCount,
1774
- rowHeight = _ref5.rowHeight;
1775
- return rowHeight * rowCount;
1776
- },
1777
- getEstimatedTotalWidth: function getEstimatedTotalWidth(_ref6) {
1778
- var columnCount = _ref6.columnCount,
1779
- columnWidth = _ref6.columnWidth;
1780
- return columnWidth * columnCount;
1781
- },
1782
- getOffsetForColumnAndAlignment: function getOffsetForColumnAndAlignment(_ref7, columnIndex, align, scrollLeft, instanceProps, scrollbarSize) {
1783
- var columnCount = _ref7.columnCount,
1784
- columnWidth = _ref7.columnWidth,
1785
- width = _ref7.width;
1786
- var lastColumnOffset = Math.max(0, columnCount * columnWidth - width);
1787
- var maxOffset = Math.min(lastColumnOffset, columnIndex * columnWidth);
1788
- var minOffset = Math.max(0, columnIndex * columnWidth - width + scrollbarSize + columnWidth);
1789
-
1790
- if (align === 'smart') {
1791
- if (scrollLeft >= minOffset - width && scrollLeft <= maxOffset + width) {
1792
- align = 'auto';
1793
- } else {
1794
- align = 'center';
1795
- }
1796
- }
1797
-
1798
- switch (align) {
1799
- case 'start':
1800
- return maxOffset;
1801
-
1802
- case 'end':
1803
- return minOffset;
1804
-
1805
- case 'center':
1806
- // "Centered" offset is usually the average of the min and max.
1807
- // But near the edges of the list, this doesn't hold true.
1808
- var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1809
-
1810
- if (middleOffset < Math.ceil(width / 2)) {
1811
- return 0; // near the beginning
1812
- } else if (middleOffset > lastColumnOffset + Math.floor(width / 2)) {
1813
- return lastColumnOffset; // near the end
1814
- } else {
1815
- return middleOffset;
1816
- }
1817
-
1818
- case 'auto':
1819
- default:
1820
- if (scrollLeft >= minOffset && scrollLeft <= maxOffset) {
1821
- return scrollLeft;
1822
- } else if (minOffset > maxOffset) {
1823
- // Because we only take into account the scrollbar size when calculating minOffset
1824
- // this value can be larger than maxOffset when at the end of the list
1825
- return minOffset;
1826
- } else if (scrollLeft < minOffset) {
1827
- return minOffset;
1828
- } else {
1829
- return maxOffset;
1830
- }
1831
-
1832
- }
1833
- },
1834
- getOffsetForRowAndAlignment: function getOffsetForRowAndAlignment(_ref8, rowIndex, align, scrollTop, instanceProps, scrollbarSize) {
1835
- var rowHeight = _ref8.rowHeight,
1836
- height = _ref8.height,
1837
- rowCount = _ref8.rowCount;
1838
- var lastRowOffset = Math.max(0, rowCount * rowHeight - height);
1839
- var maxOffset = Math.min(lastRowOffset, rowIndex * rowHeight);
1840
- var minOffset = Math.max(0, rowIndex * rowHeight - height + scrollbarSize + rowHeight);
1841
-
1842
- if (align === 'smart') {
1843
- if (scrollTop >= minOffset - height && scrollTop <= maxOffset + height) {
1844
- align = 'auto';
1845
- } else {
1846
- align = 'center';
1847
- }
1848
- }
1849
-
1850
- switch (align) {
1851
- case 'start':
1852
- return maxOffset;
1853
-
1854
- case 'end':
1855
- return minOffset;
1856
-
1857
- case 'center':
1858
- // "Centered" offset is usually the average of the min and max.
1859
- // But near the edges of the list, this doesn't hold true.
1860
- var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1861
-
1862
- if (middleOffset < Math.ceil(height / 2)) {
1863
- return 0; // near the beginning
1864
- } else if (middleOffset > lastRowOffset + Math.floor(height / 2)) {
1865
- return lastRowOffset; // near the end
1866
- } else {
1867
- return middleOffset;
1868
- }
1869
-
1870
- case 'auto':
1871
- default:
1872
- if (scrollTop >= minOffset && scrollTop <= maxOffset) {
1873
- return scrollTop;
1874
- } else if (minOffset > maxOffset) {
1875
- // Because we only take into account the scrollbar size when calculating minOffset
1876
- // this value can be larger than maxOffset when at the end of the list
1877
- return minOffset;
1878
- } else if (scrollTop < minOffset) {
1879
- return minOffset;
1880
- } else {
1881
- return maxOffset;
1882
- }
1883
-
1884
- }
1885
- },
1886
- getColumnStartIndexForOffset: function getColumnStartIndexForOffset(_ref9, scrollLeft) {
1887
- var columnWidth = _ref9.columnWidth,
1888
- columnCount = _ref9.columnCount;
1889
- return Math.max(0, Math.min(columnCount - 1, Math.floor(scrollLeft / columnWidth)));
1890
- },
1891
- getColumnStopIndexForStartIndex: function getColumnStopIndexForStartIndex(_ref10, startIndex, scrollLeft) {
1892
- var columnWidth = _ref10.columnWidth,
1893
- columnCount = _ref10.columnCount,
1894
- width = _ref10.width;
1895
- var left = startIndex * columnWidth;
1896
- var numVisibleColumns = Math.ceil((width + scrollLeft - left) / columnWidth);
1897
- return Math.max(0, Math.min(columnCount - 1, startIndex + numVisibleColumns - 1 // -1 is because stop index is inclusive
1898
- ));
1899
- },
1900
- getRowStartIndexForOffset: function getRowStartIndexForOffset(_ref11, scrollTop) {
1901
- var rowHeight = _ref11.rowHeight,
1902
- rowCount = _ref11.rowCount;
1903
- return Math.max(0, Math.min(rowCount - 1, Math.floor(scrollTop / rowHeight)));
1904
- },
1905
- getRowStopIndexForStartIndex: function getRowStopIndexForStartIndex(_ref12, startIndex, scrollTop) {
1906
- var rowHeight = _ref12.rowHeight,
1907
- rowCount = _ref12.rowCount,
1908
- height = _ref12.height;
1909
- var top = startIndex * rowHeight;
1910
- var numVisibleRows = Math.ceil((height + scrollTop - top) / rowHeight);
1911
- return Math.max(0, Math.min(rowCount - 1, startIndex + numVisibleRows - 1 // -1 is because stop index is inclusive
1912
- ));
1913
- },
1914
- initInstanceProps: function initInstanceProps(props) {// Noop
1915
- },
1916
- shouldResetStyleCacheOnItemSizeChange: true,
1917
- validateProps: function validateProps(_ref13) {
1918
- var columnWidth = _ref13.columnWidth,
1919
- rowHeight = _ref13.rowHeight;
1920
-
1921
- if (process.env.NODE_ENV !== 'production') {
1922
- if (typeof columnWidth !== 'number') {
1923
- throw Error('An invalid "columnWidth" prop has been specified. ' + 'Value should be a number. ' + ("\"" + (columnWidth === null ? 'null' : typeof columnWidth) + "\" was specified."));
1924
- }
1925
-
1926
- if (typeof rowHeight !== 'number') {
1927
- throw Error('An invalid "rowHeight" prop has been specified. ' + 'Value should be a number. ' + ("\"" + (rowHeight === null ? 'null' : typeof rowHeight) + "\" was specified."));
1928
- }
1929
- }
1930
- }
1931
-});
1932
-
1933
-var FixedSizeList =
1934
-/*#__PURE__*/
1935
-createListComponent({
1936
- getItemOffset: function getItemOffset(_ref, index) {
1937
- var itemSize = _ref.itemSize;
1938
- return index * itemSize;
1939
- },
1940
- getItemSize: function getItemSize(_ref2, index) {
1941
- var itemSize = _ref2.itemSize;
1942
- return itemSize;
1943
- },
1944
- getEstimatedTotalSize: function getEstimatedTotalSize(_ref3) {
1945
- var itemCount = _ref3.itemCount,
1946
- itemSize = _ref3.itemSize;
1947
- return itemSize * itemCount;
1948
- },
1949
- getOffsetForIndexAndAlignment: function getOffsetForIndexAndAlignment(_ref4, index, align, scrollOffset) {
1950
- var direction = _ref4.direction,
1951
- height = _ref4.height,
1952
- itemCount = _ref4.itemCount,
1953
- itemSize = _ref4.itemSize,
1954
- layout = _ref4.layout,
1955
- width = _ref4.width;
1956
- // TODO Deprecate direction "horizontal"
1957
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1958
- var size = isHorizontal ? width : height;
1959
- var lastItemOffset = Math.max(0, itemCount * itemSize - size);
1960
- var maxOffset = Math.min(lastItemOffset, index * itemSize);
1961
- var minOffset = Math.max(0, index * itemSize - size + itemSize);
1962
-
1963
- if (align === 'smart') {
1964
- if (scrollOffset >= minOffset - size && scrollOffset <= maxOffset + size) {
1965
- align = 'auto';
1966
- } else {
1967
- align = 'center';
1968
- }
1969
- }
1970
-
1971
- switch (align) {
1972
- case 'start':
1973
- return maxOffset;
1974
-
1975
- case 'end':
1976
- return minOffset;
1977
-
1978
- case 'center':
1979
- {
1980
- // "Centered" offset is usually the average of the min and max.
1981
- // But near the edges of the list, this doesn't hold true.
1982
- var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1983
-
1984
- if (middleOffset < Math.ceil(size / 2)) {
1985
- return 0; // near the beginning
1986
- } else if (middleOffset > lastItemOffset + Math.floor(size / 2)) {
1987
- return lastItemOffset; // near the end
1988
- } else {
1989
- return middleOffset;
1990
- }
1991
- }
1992
-
1993
- case 'auto':
1994
- default:
1995
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1996
- return scrollOffset;
1997
- } else if (scrollOffset < minOffset) {
1998
- return minOffset;
1999
- } else {
2000
- return maxOffset;
2001
- }
2002
-
2003
- }
2004
- },
2005
- getStartIndexForOffset: function getStartIndexForOffset(_ref5, offset) {
2006
- var itemCount = _ref5.itemCount,
2007
- itemSize = _ref5.itemSize;
2008
- return Math.max(0, Math.min(itemCount - 1, Math.floor(offset / itemSize)));
2009
- },
2010
- getStopIndexForStartIndex: function getStopIndexForStartIndex(_ref6, startIndex, scrollOffset) {
2011
- var direction = _ref6.direction,
2012
- height = _ref6.height,
2013
- itemCount = _ref6.itemCount,
2014
- itemSize = _ref6.itemSize,
2015
- layout = _ref6.layout,
2016
- width = _ref6.width;
2017
- // TODO Deprecate direction "horizontal"
2018
- var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
2019
- var offset = startIndex * itemSize;
2020
- var size = isHorizontal ? width : height;
2021
- var numVisibleItems = Math.ceil((size + scrollOffset - offset) / itemSize);
2022
- return Math.max(0, Math.min(itemCount - 1, startIndex + numVisibleItems - 1 // -1 is because stop index is inclusive
2023
- ));
2024
- },
2025
- initInstanceProps: function initInstanceProps(props) {// Noop
2026
- },
2027
- shouldResetStyleCacheOnItemSizeChange: true,
2028
- validateProps: function validateProps(_ref7) {
2029
- var itemSize = _ref7.itemSize;
2030
-
2031
- if (process.env.NODE_ENV !== 'production') {
2032
- if (typeof itemSize !== 'number') {
2033
- throw Error('An invalid "itemSize" prop has been specified. ' + 'Value should be a number. ' + ("\"" + (itemSize === null ? 'null' : typeof itemSize) + "\" was specified."));
2034
- }
2035
- }
2036
- }
2037
-});
2038
-
2039
-// Pulled from react-compat
2040
-// https://github.com/developit/preact-compat/blob/7c5de00e7c85e2ffd011bf3af02899b63f699d3a/src/index.js#L349
2041
-function shallowDiffers(prev, next) {
2042
- for (var attribute in prev) {
2043
- if (!(attribute in next)) {
2044
- return true;
2045
- }
2046
- }
2047
-
2048
- for (var _attribute in next) {
2049
- if (prev[_attribute] !== next[_attribute]) {
2050
- return true;
2051
- }
2052
- }
2053
-
2054
- return false;
2055
-}
2056
-
2057
-// It knows to compare individual style props and ignore the wrapper object.
2058
-// See https://reactjs.org/docs/react-api.html#reactmemo
2059
-
2060
-function areEqual(prevProps, nextProps) {
2061
- var prevStyle = prevProps.style,
2062
- prevRest = _objectWithoutPropertiesLoose(prevProps, ["style"]);
2063
-
2064
- var nextStyle = nextProps.style,
2065
- nextRest = _objectWithoutPropertiesLoose(nextProps, ["style"]);
2066
-
2067
- return !shallowDiffers(prevStyle, nextStyle) && !shallowDiffers(prevRest, nextRest);
2068
-}
2069
-
2070
-// It knows to compare individual style props and ignore the wrapper object.
2071
-// See https://reactjs.org/docs/react-component.html#shouldcomponentupdate
2072
-
2073
-function shouldComponentUpdate(nextProps, nextState) {
2074
- return !areEqual(this.props, nextProps) || shallowDiffers(this.state, nextState);
2075
-}
2076
-
2077
-export { VariableSizeGrid, VariableSizeList, FixedSizeGrid, FixedSizeList, areEqual, shouldComponentUpdate };
2078
-//# sourceMappingURL=index.esm.js.map
packages/react-devtools-shared/src/node_modules/react-window/dist/index.esm.js.flow
deleted
-3
@@ -1,3 +0,0 @@
1
-// @flow
2
-
3
-export * from '../src';
packages/react-devtools-shared/src/node_modules/react-window/package.json
deleted
-110
@@ -1,110 +0,0 @@
1
-{
2
- "name": "react-window",
3
- "version": "1.8.5",
4
- "description":
5
- "React components for efficiently rendering large, scrollable lists and tabular data",
6
- "author":
7
- "Brian Vaughn <brian.david.vaughn@gmail.com> (https://github.com/bvaughn/)",
8
- "contributors": [
9
- "Brian Vaughn <brian.david.vaughn@gmail.com> (https://github.com/bvaughn/)"
10
- ],
11
- "license": "MIT",
12
- "homepage": "http://react-window.now.sh/",
13
- "repository": {
14
- "type": "git",
15
- "url": "https://github.com/bvaughn/react-window.git"
16
- },
17
- "bugs": {
18
- "url": "https://github.com/bvaughn/react-window/issues"
19
- },
20
- "engines": {
21
- "node": ">8.0.0"
22
- },
23
- "keywords": [
24
- "react",
25
- "reactjs",
26
- "virtual",
27
- "window",
28
- "windowed",
29
- "list",
30
- "scrolling",
31
- "infinite",
32
- "virtualized",
33
- "table",
34
- "grid",
35
- "spreadsheet"
36
- ],
37
- "main": "dist/index.cjs.js",
38
- "module": "dist/index.esm.js",
39
- "files": ["dist", "src/*.js"],
40
- "scripts": {
41
- "flow": "flow check --max-warnings=0 src && flow check website",
42
- "precommit": "lint-staged",
43
- "prettier": "prettier --write '**/*.{js,json,css}'",
44
- "linc": "lint-staged",
45
- "lint": "eslint '**/*.js'",
46
- "test": "cross-env CI=1 react-scripts test --env=jsdom",
47
- "test:watch": "react-scripts test --env=jsdom",
48
- "build:flow":
49
- "cp flow-template dist/index.cjs.js.flow && cp flow-template dist/index.esm.js.flow",
50
- "build:source": "rollup -c",
51
- "build": "del dist && mkdir dist && yarn build:flow && yarn build:source",
52
- "start": "rollup -c -w",
53
- "prepare": "yarn run build",
54
- "website:build": "cd website && yarn build",
55
- "website:deploy": "cd website && yarn deploy",
56
- "website:run": "cd website && yarn start"
57
- },
58
- "lint-staged": {
59
- "{website,src}/**/*.{js,json,css}": ["prettier --write", "git add"],
60
- "**/*.js": "eslint --max-warnings 0"
61
- },
62
- "dependencies": {
63
- "@babel/runtime": "^7.0.0",
64
- "memoize-one": ">=3.1.1 <6"
65
- },
66
- "peerDependencies": {
67
- "react": "^15.0.0 || ^16.0.0",
68
- "react-dom": "^15.0.0 || ^16.0.0"
69
- },
70
- "devDependencies": {
71
- "@babel/core": "^7.0.0",
72
- "@babel/plugin-proposal-class-properties": "^7.0.0",
73
- "@babel/plugin-transform-runtime": "^7.0.0",
74
- "@babel/preset-env": "^7.0.0",
75
- "@babel/preset-flow": "^7.0.0",
76
- "babel-core": "^7.0.0-bridge.0",
77
- "babel-eslint": "^9.0.0",
78
- "babel-plugin-annotate-pure-calls": "^0.3.0",
79
- "cross-env": "^5.1.4",
80
- "del-cli": "^1.1.0",
81
- "eslint": "^4.19.1",
82
- "eslint-config-prettier": "^2.9.0",
83
- "eslint-config-react-app": "^2.1.0",
84
- "eslint-config-standard": "^11.0.0",
85
- "eslint-config-standard-react": "^6.0.0",
86
- "eslint-plugin-flowtype": "^2.47.1",
87
- "eslint-plugin-import": "^2.11.0",
88
- "eslint-plugin-jsx-a11y": "^5",
89
- "eslint-plugin-node": "^6.0.1",
90
- "eslint-plugin-prettier": "^2.6.0",
91
- "eslint-plugin-promise": "^3.7.0",
92
- "eslint-plugin-react": "^7.7.0",
93
- "eslint-plugin-standard": "^3.0.1",
94
- "flow-bin": "^0.103.0",
95
- "gh-pages": "^1.1.0",
96
- "lint-staged": "^7.0.5",
97
- "prettier": "^1.12.1",
98
- "react": "^16.8.4",
99
- "react-dom": "^16.8.4",
100
- "react-is": "^16.8.4",
101
- "react-scripts": "^1.1.1",
102
- "react-test-renderer": "^16.7.0",
103
- "rollup": "^1.4.1",
104
- "rollup-plugin-babel": "^4.3.2",
105
- "rollup-plugin-commonjs": "^9.2.1",
106
- "rollup-plugin-node-resolve": "^4.0.1",
107
- "rollup-plugin-replace": "^2.2.0",
108
- "rollup-plugin-terser": "^5.1.0"
109
- }
110
-}
packages/react-devtools-shared/src/node_modules/react-window/src/FixedSizeGrid.js
deleted
-244
@@ -1,244 +0,0 @@
1
-// @flow
2
-
3
-import createGridComponent from './createGridComponent';
4
-
5
-import type { Props, ScrollToAlign } from './createGridComponent';
6
-
7
-const FixedSizeGrid = createGridComponent({
8
- getColumnOffset: ({ columnWidth }: Props<any>, index: number): number =>
9
- index * ((columnWidth: any): number),
10
-
11
- getColumnWidth: ({ columnWidth }: Props<any>, index: number): number =>
12
- ((columnWidth: any): number),
13
-
14
- getRowOffset: ({ rowHeight }: Props<any>, index: number): number =>
15
- index * ((rowHeight: any): number),
16
-
17
- getRowHeight: ({ rowHeight }: Props<any>, index: number): number =>
18
- ((rowHeight: any): number),
19
-
20
- getEstimatedTotalHeight: ({ rowCount, rowHeight }: Props<any>) =>
21
- ((rowHeight: any): number) * rowCount,
22
-
23
- getEstimatedTotalWidth: ({ columnCount, columnWidth }: Props<any>) =>
24
- ((columnWidth: any): number) * columnCount,
25
-
26
- getOffsetForColumnAndAlignment: (
27
- { columnCount, columnWidth, width }: Props<any>,
28
- columnIndex: number,
29
- align: ScrollToAlign,
30
- scrollLeft: number,
31
- instanceProps: typeof undefined,
32
- scrollbarSize: number
33
- ): number => {
34
- const lastColumnOffset = Math.max(
35
- 0,
36
- columnCount * ((columnWidth: any): number) - width
37
- );
38
- const maxOffset = Math.min(
39
- lastColumnOffset,
40
- columnIndex * ((columnWidth: any): number)
41
- );
42
- const minOffset = Math.max(
43
- 0,
44
- columnIndex * ((columnWidth: any): number) -
45
- width +
46
- scrollbarSize +
47
- ((columnWidth: any): number)
48
- );
49
-
50
- if (align === 'smart') {
51
- if (scrollLeft >= minOffset - width && scrollLeft <= maxOffset + width) {
52
- align = 'auto';
53
- } else {
54
- align = 'center';
55
- }
56
- }
57
-
58
- switch (align) {
59
- case 'start':
60
- return maxOffset;
61
- case 'end':
62
- return minOffset;
63
- case 'center':
64
- // "Centered" offset is usually the average of the min and max.
65
- // But near the edges of the list, this doesn't hold true.
66
- const middleOffset = Math.round(
67
- minOffset + (maxOffset - minOffset) / 2
68
- );
69
- if (middleOffset < Math.ceil(width / 2)) {
70
- return 0; // near the beginning
71
- } else if (middleOffset > lastColumnOffset + Math.floor(width / 2)) {
72
- return lastColumnOffset; // near the end
73
- } else {
74
- return middleOffset;
75
- }
76
- case 'auto':
77
- default:
78
- if (scrollLeft >= minOffset && scrollLeft <= maxOffset) {
79
- return scrollLeft;
80
- } else if (minOffset > maxOffset) {
81
- // Because we only take into account the scrollbar size when calculating minOffset
82
- // this value can be larger than maxOffset when at the end of the list
83
- return minOffset;
84
- } else if (scrollLeft < minOffset) {
85
- return minOffset;
86
- } else {
87
- return maxOffset;
88
- }
89
- }
90
- },
91
-
92
- getOffsetForRowAndAlignment: (
93
- { rowHeight, height, rowCount }: Props<any>,
94
- rowIndex: number,
95
- align: ScrollToAlign,
96
- scrollTop: number,
97
- instanceProps: typeof undefined,
98
- scrollbarSize: number
99
- ): number => {
100
- const lastRowOffset = Math.max(
101
- 0,
102
- rowCount * ((rowHeight: any): number) - height
103
- );
104
- const maxOffset = Math.min(
105
- lastRowOffset,
106
- rowIndex * ((rowHeight: any): number)
107
- );
108
- const minOffset = Math.max(
109
- 0,
110
- rowIndex * ((rowHeight: any): number) -
111
- height +
112
- scrollbarSize +
113
- ((rowHeight: any): number)
114
- );
115
-
116
- if (align === 'smart') {
117
- if (scrollTop >= minOffset - height && scrollTop <= maxOffset + height) {
118
- align = 'auto';
119
- } else {
120
- align = 'center';
121
- }
122
- }
123
-
124
- switch (align) {
125
- case 'start':
126
- return maxOffset;
127
- case 'end':
128
- return minOffset;
129
- case 'center':
130
- // "Centered" offset is usually the average of the min and max.
131
- // But near the edges of the list, this doesn't hold true.
132
- const middleOffset = Math.round(
133
- minOffset + (maxOffset - minOffset) / 2
134
- );
135
- if (middleOffset < Math.ceil(height / 2)) {
136
- return 0; // near the beginning
137
- } else if (middleOffset > lastRowOffset + Math.floor(height / 2)) {
138
- return lastRowOffset; // near the end
139
- } else {
140
- return middleOffset;
141
- }
142
- case 'auto':
143
- default:
144
- if (scrollTop >= minOffset && scrollTop <= maxOffset) {
145
- return scrollTop;
146
- } else if (minOffset > maxOffset) {
147
- // Because we only take into account the scrollbar size when calculating minOffset
148
- // this value can be larger than maxOffset when at the end of the list
149
- return minOffset;
150
- } else if (scrollTop < minOffset) {
151
- return minOffset;
152
- } else {
153
- return maxOffset;
154
- }
155
- }
156
- },
157
-
158
- getColumnStartIndexForOffset: (
159
- { columnWidth, columnCount }: Props<any>,
160
- scrollLeft: number
161
- ): number =>
162
- Math.max(
163
- 0,
164
- Math.min(
165
- columnCount - 1,
166
- Math.floor(scrollLeft / ((columnWidth: any): number))
167
- )
168
- ),
169
-
170
- getColumnStopIndexForStartIndex: (
171
- { columnWidth, columnCount, width }: Props<any>,
172
- startIndex: number,
173
- scrollLeft: number
174
- ): number => {
175
- const left = startIndex * ((columnWidth: any): number);
176
- const numVisibleColumns = Math.ceil(
177
- (width + scrollLeft - left) / ((columnWidth: any): number)
178
- );
179
- return Math.max(
180
- 0,
181
- Math.min(
182
- columnCount - 1,
183
- startIndex + numVisibleColumns - 1 // -1 is because stop index is inclusive
184
- )
185
- );
186
- },
187
-
188
- getRowStartIndexForOffset: (
189
- { rowHeight, rowCount }: Props<any>,
190
- scrollTop: number
191
- ): number =>
192
- Math.max(
193
- 0,
194
- Math.min(rowCount - 1, Math.floor(scrollTop / ((rowHeight: any): number)))
195
- ),
196
-
197
- getRowStopIndexForStartIndex: (
198
- { rowHeight, rowCount, height }: Props<any>,
199
- startIndex: number,
200
- scrollTop: number
201
- ): number => {
202
- const top = startIndex * ((rowHeight: any): number);
203
- const numVisibleRows = Math.ceil(
204
- (height + scrollTop - top) / ((rowHeight: any): number)
205
- );
206
- return Math.max(
207
- 0,
208
- Math.min(
209
- rowCount - 1,
210
- startIndex + numVisibleRows - 1 // -1 is because stop index is inclusive
211
- )
212
- );
213
- },
214
-
215
- initInstanceProps(props: Props<any>): any {
216
- // Noop
217
- },
218
-
219
- shouldResetStyleCacheOnItemSizeChange: true,
220
-
221
- validateProps: ({ columnWidth, rowHeight }: Props<any>): void => {
222
- if (process.env.NODE_ENV !== 'production') {
223
- if (typeof columnWidth !== 'number') {
224
- throw Error(
225
- 'An invalid "columnWidth" prop has been specified. ' +
226
- 'Value should be a number. ' +
227
- `"${
228
- columnWidth === null ? 'null' : typeof columnWidth
229
- }" was specified.`
230
- );
231
- }
232
-
233
- if (typeof rowHeight !== 'number') {
234
- throw Error(
235
- 'An invalid "rowHeight" prop has been specified. ' +
236
- 'Value should be a number. ' +
237
- `"${rowHeight === null ? 'null' : typeof rowHeight}" was specified.`
238
- );
239
- }
240
- }
241
- },
242
-});
243
-
244
-export default FixedSizeGrid;
packages/react-devtools-shared/src/node_modules/react-window/src/FixedSizeList.js
deleted
-130
@@ -1,130 +0,0 @@
1
-// @flow
2
-
3
-import createListComponent from './createListComponent';
4
-
5
-import type { Props, ScrollToAlign } from './createListComponent';
6
-
7
-const FixedSizeList = createListComponent({
8
- getItemOffset: ({ itemSize }: Props<any>, index: number): number =>
9
- index * ((itemSize: any): number),
10
-
11
- getItemSize: ({ itemSize }: Props<any>, index: number): number =>
12
- ((itemSize: any): number),
13
-
14
- getEstimatedTotalSize: ({ itemCount, itemSize }: Props<any>) =>
15
- ((itemSize: any): number) * itemCount,
16
-
17
- getOffsetForIndexAndAlignment: (
18
- { direction, height, itemCount, itemSize, layout, width }: Props<any>,
19
- index: number,
20
- align: ScrollToAlign,
21
- scrollOffset: number
22
- ): number => {
23
- // TODO Deprecate direction "horizontal"
24
- const isHorizontal = direction === 'horizontal' || layout === 'horizontal';
25
- const size = (((isHorizontal ? width : height): any): number);
26
- const lastItemOffset = Math.max(
27
- 0,
28
- itemCount * ((itemSize: any): number) - size
29
- );
30
- const maxOffset = Math.min(
31
- lastItemOffset,
32
- index * ((itemSize: any): number)
33
- );
34
- const minOffset = Math.max(
35
- 0,
36
- index * ((itemSize: any): number) - size + ((itemSize: any): number)
37
- );
38
-
39
- if (align === 'smart') {
40
- if (
41
- scrollOffset >= minOffset - size &&
42
- scrollOffset <= maxOffset + size
43
- ) {
44
- align = 'auto';
45
- } else {
46
- align = 'center';
47
- }
48
- }
49
-
50
- switch (align) {
51
- case 'start':
52
- return maxOffset;
53
- case 'end':
54
- return minOffset;
55
- case 'center': {
56
- // "Centered" offset is usually the average of the min and max.
57
- // But near the edges of the list, this doesn't hold true.
58
- const middleOffset = Math.round(
59
- minOffset + (maxOffset - minOffset) / 2
60
- );
61
- if (middleOffset < Math.ceil(size / 2)) {
62
- return 0; // near the beginning
63
- } else if (middleOffset > lastItemOffset + Math.floor(size / 2)) {
64
- return lastItemOffset; // near the end
65
- } else {
66
- return middleOffset;
67
- }
68
- }
69
- case 'auto':
70
- default:
71
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
72
- return scrollOffset;
73
- } else if (scrollOffset < minOffset) {
74
- return minOffset;
75
- } else {
76
- return maxOffset;
77
- }
78
- }
79
- },
80
-
81
- getStartIndexForOffset: (
82
- { itemCount, itemSize }: Props<any>,
83
- offset: number
84
- ): number =>
85
- Math.max(
86
- 0,
87
- Math.min(itemCount - 1, Math.floor(offset / ((itemSize: any): number)))
88
- ),
89
-
90
- getStopIndexForStartIndex: (
91
- { direction, height, itemCount, itemSize, layout, width }: Props<any>,
92
- startIndex: number,
93
- scrollOffset: number
94
- ): number => {
95
- // TODO Deprecate direction "horizontal"
96
- const isHorizontal = direction === 'horizontal' || layout === 'horizontal';
97
- const offset = startIndex * ((itemSize: any): number);
98
- const size = (((isHorizontal ? width : height): any): number);
99
- const numVisibleItems = Math.ceil(
100
- (size + scrollOffset - offset) / ((itemSize: any): number)
101
- );
102
- return Math.max(
103
- 0,
104
- Math.min(
105
- itemCount - 1,
106
- startIndex + numVisibleItems - 1 // -1 is because stop index is inclusive
107
- )
108
- );
109
- },
110
-
111
- initInstanceProps(props: Props<any>): any {
112
- // Noop
113
- },
114
-
115
- shouldResetStyleCacheOnItemSizeChange: true,
116
-
117
- validateProps: ({ itemSize }: Props<any>): void => {
118
- if (process.env.NODE_ENV !== 'production') {
119
- if (typeof itemSize !== 'number') {
120
- throw Error(
121
- 'An invalid "itemSize" prop has been specified. ' +
122
- 'Value should be a number. ' +
123
- `"${itemSize === null ? 'null' : typeof itemSize}" was specified.`
124
- );
125
- }
126
- }
127
- },
128
-});
129
-
130
-export default FixedSizeList;
packages/react-devtools-shared/src/node_modules/react-window/src/VariableSizeGrid.js
deleted
-507
@@ -1,507 +0,0 @@
1
-// @flow
2
-
3
-import createGridComponent from './createGridComponent';
4
-
5
-import type { Props, ScrollToAlign } from './createGridComponent';
6
-
7
-const DEFAULT_ESTIMATED_ITEM_SIZE = 50;
8
-
9
-type VariableSizeProps = {|
10
- estimatedColumnWidth: number,
11
- estimatedRowHeight: number,
12
- ...Props<any>,
13
-|};
14
-
15
-type itemSizeGetter = (index: number) => number;
16
-type ItemType = 'column' | 'row';
17
-
18
-type ItemMetadata = {|
19
- offset: number,
20
- size: number,
21
-|};
22
-type ItemMetadataMap = { [index: number]: ItemMetadata };
23
-type InstanceProps = {|
24
- columnMetadataMap: ItemMetadataMap,
25
- estimatedColumnWidth: number,
26
- estimatedRowHeight: number,
27
- lastMeasuredColumnIndex: number,
28
- lastMeasuredRowIndex: number,
29
- rowMetadataMap: ItemMetadataMap,
30
-|};
31
-
32
-const getEstimatedTotalHeight = (
33
- { rowCount }: Props<any>,
34
- { rowMetadataMap, estimatedRowHeight, lastMeasuredRowIndex }: InstanceProps
35
-) => {
36
- let totalSizeOfMeasuredRows = 0;
37
-
38
- // Edge case check for when the number of items decreases while a scroll is in progress.
39
- // https://github.com/bvaughn/react-window/pull/138
40
- if (lastMeasuredRowIndex >= rowCount) {
41
- lastMeasuredRowIndex = rowCount - 1;
42
- }
43
-
44
- if (lastMeasuredRowIndex >= 0) {
45
- const itemMetadata = rowMetadataMap[lastMeasuredRowIndex];
46
- totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size;
47
- }
48
-
49
- const numUnmeasuredItems = rowCount - lastMeasuredRowIndex - 1;
50
- const totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedRowHeight;
51
-
52
- return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems;
53
-};
54
-
55
-const getEstimatedTotalWidth = (
56
- { columnCount }: Props<any>,
57
- {
58
- columnMetadataMap,
59
- estimatedColumnWidth,
60
- lastMeasuredColumnIndex,
61
- }: InstanceProps
62
-) => {
63
- let totalSizeOfMeasuredRows = 0;
64
-
65
- // Edge case check for when the number of items decreases while a scroll is in progress.
66
- // https://github.com/bvaughn/react-window/pull/138
67
- if (lastMeasuredColumnIndex >= columnCount) {
68
- lastMeasuredColumnIndex = columnCount - 1;
69
- }
70
-
71
- if (lastMeasuredColumnIndex >= 0) {
72
- const itemMetadata = columnMetadataMap[lastMeasuredColumnIndex];
73
- totalSizeOfMeasuredRows = itemMetadata.offset + itemMetadata.size;
74
- }
75
-
76
- const numUnmeasuredItems = columnCount - lastMeasuredColumnIndex - 1;
77
- const totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedColumnWidth;
78
-
79
- return totalSizeOfMeasuredRows + totalSizeOfUnmeasuredItems;
80
-};
81
-
82
-const getItemMetadata = (
83
- itemType: ItemType,
84
- props: Props<any>,
85
- index: number,
86
- instanceProps: InstanceProps
87
-): ItemMetadata => {
88
- let itemMetadataMap, itemSize, lastMeasuredIndex;
89
- if (itemType === 'column') {
90
- itemMetadataMap = instanceProps.columnMetadataMap;
91
- itemSize = ((props.columnWidth: any): itemSizeGetter);
92
- lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex;
93
- } else {
94
- itemMetadataMap = instanceProps.rowMetadataMap;
95
- itemSize = ((props.rowHeight: any): itemSizeGetter);
96
- lastMeasuredIndex = instanceProps.lastMeasuredRowIndex;
97
- }
98
-
99
- if (index > lastMeasuredIndex) {
100
- let offset = 0;
101
- if (lastMeasuredIndex >= 0) {
102
- const itemMetadata = itemMetadataMap[lastMeasuredIndex];
103
- offset = itemMetadata.offset + itemMetadata.size;
104
- }
105
-
106
- for (let i = lastMeasuredIndex + 1; i <= index; i++) {
107
- let size = itemSize(i);
108
-
109
- itemMetadataMap[i] = {
110
- offset,
111
- size,
112
- };
113
-
114
- offset += size;
115
- }
116
-
117
- if (itemType === 'column') {
118
- instanceProps.lastMeasuredColumnIndex = index;
119
- } else {
120
- instanceProps.lastMeasuredRowIndex = index;
121
- }
122
- }
123
-
124
- return itemMetadataMap[index];
125
-};
126
-
127
-const findNearestItem = (
128
- itemType: ItemType,
129
- props: Props<any>,
130
- instanceProps: InstanceProps,
131
- offset: number
132
-) => {
133
- let itemMetadataMap, lastMeasuredIndex;
134
- if (itemType === 'column') {
135
- itemMetadataMap = instanceProps.columnMetadataMap;
136
- lastMeasuredIndex = instanceProps.lastMeasuredColumnIndex;
137
- } else {
138
- itemMetadataMap = instanceProps.rowMetadataMap;
139
- lastMeasuredIndex = instanceProps.lastMeasuredRowIndex;
140
- }
141
-
142
- const lastMeasuredItemOffset =
143
- lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0;
144
-
145
- if (lastMeasuredItemOffset >= offset) {
146
- // If we've already measured items within this range just use a binary search as it's faster.
147
- return findNearestItemBinarySearch(
148
- itemType,
149
- props,
150
- instanceProps,
151
- lastMeasuredIndex,
152
- 0,
153
- offset
154
- );
155
- } else {
156
- // If we haven't yet measured this high, fallback to an exponential search with an inner binary search.
157
- // The exponential search avoids pre-computing sizes for the full set of items as a binary search would.
158
- // The overall complexity for this approach is O(log n).
159
- return findNearestItemExponentialSearch(
160
- itemType,
161
- props,
162
- instanceProps,
163
- Math.max(0, lastMeasuredIndex),
164
- offset
165
- );
166
- }
167
-};
168
-
169
-const findNearestItemBinarySearch = (
170
- itemType: ItemType,
171
- props: Props<any>,
172
- instanceProps: InstanceProps,
173
- high: number,
174
- low: number,
175
- offset: number
176
-): number => {
177
- while (low <= high) {
178
- const middle = low + Math.floor((high - low) / 2);
179
- const currentOffset = getItemMetadata(
180
- itemType,
181
- props,
182
- middle,
183
- instanceProps
184
- ).offset;
185
-
186
- if (currentOffset === offset) {
187
- return middle;
188
- } else if (currentOffset < offset) {
189
- low = middle + 1;
190
- } else if (currentOffset > offset) {
191
- high = middle - 1;
192
- }
193
- }
194
-
195
- if (low > 0) {
196
- return low - 1;
197
- } else {
198
- return 0;
199
- }
200
-};
201
-
202
-const findNearestItemExponentialSearch = (
203
- itemType: ItemType,
204
- props: Props<any>,
205
- instanceProps: InstanceProps,
206
- index: number,
207
- offset: number
208
-): number => {
209
- const itemCount = itemType === 'column' ? props.columnCount : props.rowCount;
210
- let interval = 1;
211
-
212
- while (
213
- index < itemCount &&
214
- getItemMetadata(itemType, props, index, instanceProps).offset < offset
215
- ) {
216
- index += interval;
217
- interval *= 2;
218
- }
219
-
220
- return findNearestItemBinarySearch(
221
- itemType,
222
- props,
223
- instanceProps,
224
- Math.min(index, itemCount - 1),
225
- Math.floor(index / 2),
226
- offset
227
- );
228
-};
229
-
230
-const getOffsetForIndexAndAlignment = (
231
- itemType: ItemType,
232
- props: Props<any>,
233
- index: number,
234
- align: ScrollToAlign,
235
- scrollOffset: number,
236
- instanceProps: InstanceProps,
237
- scrollbarSize: number
238
-): number => {
239
- const size = itemType === 'column' ? props.width : props.height;
240
- const itemMetadata = getItemMetadata(itemType, props, index, instanceProps);
241
-
242
- // Get estimated total size after ItemMetadata is computed,
243
- // To ensure it reflects actual measurements instead of just estimates.
244
- const estimatedTotalSize =
245
- itemType === 'column'
246
- ? getEstimatedTotalWidth(props, instanceProps)
247
- : getEstimatedTotalHeight(props, instanceProps);
248
-
249
- const maxOffset = Math.max(
250
- 0,
251
- Math.min(estimatedTotalSize - size, itemMetadata.offset)
252
- );
253
- const minOffset = Math.max(
254
- 0,
255
- itemMetadata.offset - size + scrollbarSize + itemMetadata.size
256
- );
257
-
258
- if (align === 'smart') {
259
- if (scrollOffset >= minOffset - size && scrollOffset <= maxOffset + size) {
260
- align = 'auto';
261
- } else {
262
- align = 'center';
263
- }
264
- }
265
-
266
- switch (align) {
267
- case 'start':
268
- return maxOffset;
269
- case 'end':
270
- return minOffset;
271
- case 'center':
272
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
273
- case 'auto':
274
- default:
275
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
276
- return scrollOffset;
277
- } else if (minOffset > maxOffset) {
278
- // Because we only take into account the scrollbar size when calculating minOffset
279
- // this value can be larger than maxOffset when at the end of the list
280
- return minOffset;
281
- } else if (scrollOffset < minOffset) {
282
- return minOffset;
283
- } else {
284
- return maxOffset;
285
- }
286
- }
287
-};
288
-
289
-const VariableSizeGrid = createGridComponent({
290
- getColumnOffset: (
291
- props: Props<any>,
292
- index: number,
293
- instanceProps: InstanceProps
294
- ): number => getItemMetadata('column', props, index, instanceProps).offset,
295
-
296
- getColumnStartIndexForOffset: (
297
- props: Props<any>,
298
- scrollLeft: number,
299
- instanceProps: InstanceProps
300
- ): number => findNearestItem('column', props, instanceProps, scrollLeft),
301
-
302
- getColumnStopIndexForStartIndex: (
303
- props: Props<any>,
304
- startIndex: number,
305
- scrollLeft: number,
306
- instanceProps: InstanceProps
307
- ): number => {
308
- const { columnCount, width } = props;
309
-
310
- const itemMetadata = getItemMetadata(
311
- 'column',
312
- props,
313
- startIndex,
314
- instanceProps
315
- );
316
- const maxOffset = scrollLeft + width;
317
-
318
- let offset = itemMetadata.offset + itemMetadata.size;
319
- let stopIndex = startIndex;
320
-
321
- while (stopIndex < columnCount - 1 && offset < maxOffset) {
322
- stopIndex++;
323
- offset += getItemMetadata('column', props, stopIndex, instanceProps).size;
324
- }
325
-
326
- return stopIndex;
327
- },
328
-
329
- getColumnWidth: (
330
- props: Props<any>,
331
- index: number,
332
- instanceProps: InstanceProps
333
- ): number => instanceProps.columnMetadataMap[index].size,
334
-
335
- getEstimatedTotalHeight,
336
- getEstimatedTotalWidth,
337
-
338
- getOffsetForColumnAndAlignment: (
339
- props: Props<any>,
340
- index: number,
341
- align: ScrollToAlign,
342
- scrollOffset: number,
343
- instanceProps: InstanceProps,
344
- scrollbarSize: number
345
- ): number =>
346
- getOffsetForIndexAndAlignment(
347
- 'column',
348
- props,
349
- index,
350
- align,
351
- scrollOffset,
352
- instanceProps,
353
- scrollbarSize
354
- ),
355
-
356
- getOffsetForRowAndAlignment: (
357
- props: Props<any>,
358
- index: number,
359
- align: ScrollToAlign,
360
- scrollOffset: number,
361
- instanceProps: InstanceProps,
362
- scrollbarSize: number
363
- ): number =>
364
- getOffsetForIndexAndAlignment(
365
- 'row',
366
- props,
367
- index,
368
- align,
369
- scrollOffset,
370
- instanceProps,
371
- scrollbarSize
372
- ),
373
-
374
- getRowOffset: (
375
- props: Props<any>,
376
- index: number,
377
- instanceProps: InstanceProps
378
- ): number => getItemMetadata('row', props, index, instanceProps).offset,
379
-
380
- getRowHeight: (
381
- props: Props<any>,
382
- index: number,
383
- instanceProps: InstanceProps
384
- ): number => instanceProps.rowMetadataMap[index].size,
385
-
386
- getRowStartIndexForOffset: (
387
- props: Props<any>,
388
- scrollTop: number,
389
- instanceProps: InstanceProps
390
- ): number => findNearestItem('row', props, instanceProps, scrollTop),
391
-
392
- getRowStopIndexForStartIndex: (
393
- props: Props<any>,
394
- startIndex: number,
395
- scrollTop: number,
396
- instanceProps: InstanceProps
397
- ): number => {
398
- const { rowCount, height } = props;
399
-
400
- const itemMetadata = getItemMetadata(
401
- 'row',
402
- props,
403
- startIndex,
404
- instanceProps
405
- );
406
- const maxOffset = scrollTop + height;
407
-
408
- let offset = itemMetadata.offset + itemMetadata.size;
409
- let stopIndex = startIndex;
410
-
411
- while (stopIndex < rowCount - 1 && offset < maxOffset) {
412
- stopIndex++;
413
- offset += getItemMetadata('row', props, stopIndex, instanceProps).size;
414
- }
415
-
416
- return stopIndex;
417
- },
418
-
419
- initInstanceProps(props: Props<any>, instance: any): InstanceProps {
420
- const {
421
- estimatedColumnWidth,
422
- estimatedRowHeight,
423
- } = ((props: any): VariableSizeProps);
424
-
425
- const instanceProps = {
426
- columnMetadataMap: {},
427
- estimatedColumnWidth: estimatedColumnWidth || DEFAULT_ESTIMATED_ITEM_SIZE,
428
- estimatedRowHeight: estimatedRowHeight || DEFAULT_ESTIMATED_ITEM_SIZE,
429
- lastMeasuredColumnIndex: -1,
430
- lastMeasuredRowIndex: -1,
431
- rowMetadataMap: {},
432
- };
433
-
434
- instance.resetAfterColumnIndex = (
435
- columnIndex: number,
436
- shouldForceUpdate?: boolean = true
437
- ) => {
438
- instance.resetAfterIndices({ columnIndex, shouldForceUpdate });
439
- };
440
-
441
- instance.resetAfterRowIndex = (
442
- rowIndex: number,
443
- shouldForceUpdate?: boolean = true
444
- ) => {
445
- instance.resetAfterIndices({ rowIndex, shouldForceUpdate });
446
- };
447
-
448
- instance.resetAfterIndices = ({
449
- columnIndex,
450
- rowIndex,
451
- shouldForceUpdate = true,
452
- }: {
453
- columnIndex?: number,
454
- rowIndex?: number,
455
- shouldForceUpdate: boolean,
456
- }) => {
457
- if (typeof columnIndex === 'number') {
458
- instanceProps.lastMeasuredColumnIndex = Math.min(
459
- instanceProps.lastMeasuredColumnIndex,
460
- columnIndex - 1
461
- );
462
- }
463
- if (typeof rowIndex === 'number') {
464
- instanceProps.lastMeasuredRowIndex = Math.min(
465
- instanceProps.lastMeasuredRowIndex,
466
- rowIndex - 1
467
- );
468
- }
469
-
470
- // We could potentially optimize further by only evicting styles after this index,
471
- // But since styles are only cached while scrolling is in progress-
472
- // It seems an unnecessary optimization.
473
- // It's unlikely that resetAfterIndex() will be called while a user is scrolling.
474
- instance._getItemStyleCache(-1);
475
-
476
- if (shouldForceUpdate) {
477
- instance.forceUpdate();
478
- }
479
- };
480
-
481
- return instanceProps;
482
- },
483
-
484
- shouldResetStyleCacheOnItemSizeChange: false,
485
-
486
- validateProps: ({ columnWidth, rowHeight }: Props<any>): void => {
487
- if (process.env.NODE_ENV !== 'production') {
488
- if (typeof columnWidth !== 'function') {
489
- throw Error(
490
- 'An invalid "columnWidth" prop has been specified. ' +
491
- 'Value should be a function. ' +
492
- `"${
493
- columnWidth === null ? 'null' : typeof columnWidth
494
- }" was specified.`
495
- );
496
- } else if (typeof rowHeight !== 'function') {
497
- throw Error(
498
- 'An invalid "rowHeight" prop has been specified. ' +
499
- 'Value should be a function. ' +
500
- `"${rowHeight === null ? 'null' : typeof rowHeight}" was specified.`
501
- );
502
- }
503
- }
504
- },
505
-});
506
-
507
-export default VariableSizeGrid;
packages/react-devtools-shared/src/node_modules/react-window/src/VariableSizeList.js
deleted
-316
@@ -1,316 +0,0 @@
1
-// @flow
2
-
3
-import createListComponent from './createListComponent';
4
-
5
-import type { Props, ScrollToAlign } from './createListComponent';
6
-
7
-const DEFAULT_ESTIMATED_ITEM_SIZE = 50;
8
-
9
-type VariableSizeProps = {|
10
- estimatedItemSize: number,
11
- ...Props<any>,
12
-|};
13
-
14
-type itemSizeGetter = (index: number) => number;
15
-
16
-type ItemMetadata = {|
17
- offset: number,
18
- size: number,
19
-|};
20
-type InstanceProps = {|
21
- itemMetadataMap: { [index: number]: ItemMetadata },
22
- estimatedItemSize: number,
23
- lastMeasuredIndex: number,
24
-|};
25
-
26
-const getItemMetadata = (
27
- props: Props<any>,
28
- index: number,
29
- instanceProps: InstanceProps
30
-): ItemMetadata => {
31
- const { itemSize } = ((props: any): VariableSizeProps);
32
- const { itemMetadataMap, lastMeasuredIndex } = instanceProps;
33
-
34
- if (index > lastMeasuredIndex) {
35
- let offset = 0;
36
- if (lastMeasuredIndex >= 0) {
37
- const itemMetadata = itemMetadataMap[lastMeasuredIndex];
38
- offset = itemMetadata.offset + itemMetadata.size;
39
- }
40
-
41
- for (let i = lastMeasuredIndex + 1; i <= index; i++) {
42
- let size = ((itemSize: any): itemSizeGetter)(i);
43
-
44
- itemMetadataMap[i] = {
45
- offset,
46
- size,
47
- };
48
-
49
- offset += size;
50
- }
51
-
52
- instanceProps.lastMeasuredIndex = index;
53
- }
54
-
55
- return itemMetadataMap[index];
56
-};
57
-
58
-const findNearestItem = (
59
- props: Props<any>,
60
- instanceProps: InstanceProps,
61
- offset: number
62
-) => {
63
- const { itemMetadataMap, lastMeasuredIndex } = instanceProps;
64
-
65
- const lastMeasuredItemOffset =
66
- lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0;
67
-
68
- if (lastMeasuredItemOffset >= offset) {
69
- // If we've already measured items within this range just use a binary search as it's faster.
70
- return findNearestItemBinarySearch(
71
- props,
72
- instanceProps,
73
- lastMeasuredIndex,
74
- 0,
75
- offset
76
- );
77
- } else {
78
- // If we haven't yet measured this high, fallback to an exponential search with an inner binary search.
79
- // The exponential search avoids pre-computing sizes for the full set of items as a binary search would.
80
- // The overall complexity for this approach is O(log n).
81
- return findNearestItemExponentialSearch(
82
- props,
83
- instanceProps,
84
- Math.max(0, lastMeasuredIndex),
85
- offset
86
- );
87
- }
88
-};
89
-
90
-const findNearestItemBinarySearch = (
91
- props: Props<any>,
92
- instanceProps: InstanceProps,
93
- high: number,
94
- low: number,
95
- offset: number
96
-): number => {
97
- while (low <= high) {
98
- const middle = low + Math.floor((high - low) / 2);
99
- const currentOffset = getItemMetadata(props, middle, instanceProps).offset;
100
-
101
- if (currentOffset === offset) {
102
- return middle;
103
- } else if (currentOffset < offset) {
104
- low = middle + 1;
105
- } else if (currentOffset > offset) {
106
- high = middle - 1;
107
- }
108
- }
109
-
110
- if (low > 0) {
111
- return low - 1;
112
- } else {
113
- return 0;
114
- }
115
-};
116
-
117
-const findNearestItemExponentialSearch = (
118
- props: Props<any>,
119
- instanceProps: InstanceProps,
120
- index: number,
121
- offset: number
122
-): number => {
123
- const { itemCount } = props;
124
- let interval = 1;
125
-
126
- while (
127
- index < itemCount &&
128
- getItemMetadata(props, index, instanceProps).offset < offset
129
- ) {
130
- index += interval;
131
- interval *= 2;
132
- }
133
-
134
- return findNearestItemBinarySearch(
135
- props,
136
- instanceProps,
137
- Math.min(index, itemCount - 1),
138
- Math.floor(index / 2),
139
- offset
140
- );
141
-};
142
-
143
-const getEstimatedTotalSize = (
144
- { itemCount }: Props<any>,
145
- { itemMetadataMap, estimatedItemSize, lastMeasuredIndex }: InstanceProps
146
-) => {
147
- let totalSizeOfMeasuredItems = 0;
148
-
149
- // Edge case check for when the number of items decreases while a scroll is in progress.
150
- // https://github.com/bvaughn/react-window/pull/138
151
- if (lastMeasuredIndex >= itemCount) {
152
- lastMeasuredIndex = itemCount - 1;
153
- }
154
-
155
- if (lastMeasuredIndex >= 0) {
156
- const itemMetadata = itemMetadataMap[lastMeasuredIndex];
157
- totalSizeOfMeasuredItems = itemMetadata.offset + itemMetadata.size;
158
- }
159
-
160
- const numUnmeasuredItems = itemCount - lastMeasuredIndex - 1;
161
- const totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedItemSize;
162
-
163
- return totalSizeOfMeasuredItems + totalSizeOfUnmeasuredItems;
164
-};
165
-
166
-const VariableSizeList = createListComponent({
167
- getItemOffset: (
168
- props: Props<any>,
169
- index: number,
170
- instanceProps: InstanceProps
171
- ): number => getItemMetadata(props, index, instanceProps).offset,
172
-
173
- getItemSize: (
174
- props: Props<any>,
175
- index: number,
176
- instanceProps: InstanceProps
177
- ): number => instanceProps.itemMetadataMap[index].size,
178
-
179
- getEstimatedTotalSize,
180
-
181
- getOffsetForIndexAndAlignment: (
182
- props: Props<any>,
183
- index: number,
184
- align: ScrollToAlign,
185
- scrollOffset: number,
186
- instanceProps: InstanceProps
187
- ): number => {
188
- const { direction, height, layout, width } = props;
189
-
190
- // TODO Deprecate direction "horizontal"
191
- const isHorizontal = direction === 'horizontal' || layout === 'horizontal';
192
- const size = (((isHorizontal ? width : height): any): number);
193
- const itemMetadata = getItemMetadata(props, index, instanceProps);
194
-
195
- // Get estimated total size after ItemMetadata is computed,
196
- // To ensure it reflects actual measurements instead of just estimates.
197
- const estimatedTotalSize = getEstimatedTotalSize(props, instanceProps);
198
-
199
- const maxOffset = Math.max(
200
- 0,
201
- Math.min(estimatedTotalSize - size, itemMetadata.offset)
202
- );
203
- const minOffset = Math.max(
204
- 0,
205
- itemMetadata.offset - size + itemMetadata.size
206
- );
207
-
208
- if (align === 'smart') {
209
- if (
210
- scrollOffset >= minOffset - size &&
211
- scrollOffset <= maxOffset + size
212
- ) {
213
- align = 'auto';
214
- } else {
215
- align = 'center';
216
- }
217
- }
218
-
219
- switch (align) {
220
- case 'start':
221
- return maxOffset;
222
- case 'end':
223
- return minOffset;
224
- case 'center':
225
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
226
- case 'auto':
227
- default:
228
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
229
- return scrollOffset;
230
- } else if (scrollOffset < minOffset) {
231
- return minOffset;
232
- } else {
233
- return maxOffset;
234
- }
235
- }
236
- },
237
-
238
- getStartIndexForOffset: (
239
- props: Props<any>,
240
- offset: number,
241
- instanceProps: InstanceProps
242
- ): number => findNearestItem(props, instanceProps, offset),
243
-
244
- getStopIndexForStartIndex: (
245
- props: Props<any>,
246
- startIndex: number,
247
- scrollOffset: number,
248
- instanceProps: InstanceProps
249
- ): number => {
250
- const { direction, height, itemCount, layout, width } = props;
251
-
252
- // TODO Deprecate direction "horizontal"
253
- const isHorizontal = direction === 'horizontal' || layout === 'horizontal';
254
- const size = (((isHorizontal ? width : height): any): number);
255
- const itemMetadata = getItemMetadata(props, startIndex, instanceProps);
256
- const maxOffset = scrollOffset + size;
257
-
258
- let offset = itemMetadata.offset + itemMetadata.size;
259
- let stopIndex = startIndex;
260
-
261
- while (stopIndex < itemCount - 1 && offset < maxOffset) {
262
- stopIndex++;
263
- offset += getItemMetadata(props, stopIndex, instanceProps).size;
264
- }
265
-
266
- return stopIndex;
267
- },
268
-
269
- initInstanceProps(props: Props<any>, instance: any): InstanceProps {
270
- const { estimatedItemSize } = ((props: any): VariableSizeProps);
271
-
272
- const instanceProps = {
273
- itemMetadataMap: {},
274
- estimatedItemSize: estimatedItemSize || DEFAULT_ESTIMATED_ITEM_SIZE,
275
- lastMeasuredIndex: -1,
276
- };
277
-
278
- instance.resetAfterIndex = (
279
- index: number,
280
- shouldForceUpdate?: boolean = true
281
- ) => {
282
- instanceProps.lastMeasuredIndex = Math.min(
283
- instanceProps.lastMeasuredIndex,
284
- index - 1
285
- );
286
-
287
- // We could potentially optimize further by only evicting styles after this index,
288
- // But since styles are only cached while scrolling is in progress-
289
- // It seems an unnecessary optimization.
290
- // It's unlikely that resetAfterIndex() will be called while a user is scrolling.
291
- instance._getItemStyleCache(-1);
292
-
293
- if (shouldForceUpdate) {
294
- instance.forceUpdate();
295
- }
296
- };
297
-
298
- return instanceProps;
299
- },
300
-
301
- shouldResetStyleCacheOnItemSizeChange: false,
302
-
303
- validateProps: ({ itemSize }: Props<any>): void => {
304
- if (process.env.NODE_ENV !== 'production') {
305
- if (typeof itemSize !== 'function') {
306
- throw Error(
307
- 'An invalid "itemSize" prop has been specified. ' +
308
- 'Value should be a function. ' +
309
- `"${itemSize === null ? 'null' : typeof itemSize}" was specified.`
310
- );
311
- }
312
- }
313
- },
314
-});
315
-
316
-export default VariableSizeList;
packages/react-devtools-shared/src/node_modules/react-window/src/areEqual.js
deleted
-18
@@ -1,18 +0,0 @@
1
-// @flow
2
-
3
-import shallowDiffers from './shallowDiffers';
4
-
5
-// Custom comparison function for React.memo().
6
-// It knows to compare individual style props and ignore the wrapper object.
7
-// See https://reactjs.org/docs/react-api.html#reactmemo
8
-export default function areEqual(
9
- prevProps: Object,
10
- nextProps: Object
11
-): boolean {
12
- const { style: prevStyle, ...prevRest } = prevProps;
13
- const { style: nextStyle, ...nextRest } = nextProps;
14
-
15
- return (
16
- !shallowDiffers(prevStyle, nextStyle) && !shallowDiffers(prevRest, nextRest)
17
- );
18
-}
packages/react-devtools-shared/src/node_modules/react-window/src/createGridComponent.js
deleted
-916
@@ -1,916 +0,0 @@
1
-// @flow
2
-
3
-import memoizeOne from 'memoize-one';
4
-import React, { createElement, PureComponent } from 'react';
5
-import { cancelTimeout, requestTimeout } from './timer';
6
-import { getScrollbarSize, getRTLOffsetType } from './domHelpers';
7
-
8
-import type { TimeoutID } from './timer';
9
-
10
-type Direction = 'ltr' | 'rtl';
11
-export type ScrollToAlign = 'auto' | 'smart' | 'center' | 'start' | 'end';
12
-
13
-type itemSize = number | ((index: number) => number);
14
-
15
-type RenderComponentProps<T> = {|
16
- columnIndex: number,
17
- data: T,
18
- isScrolling?: boolean,
19
- rowIndex: number,
20
- style: Object,
21
-|};
22
-export type RenderComponent<T> = React$ComponentType<
23
- $Shape<RenderComponentProps<T>>
24
->;
25
-
26
-type ScrollDirection = 'forward' | 'backward';
27
-
28
-type OnItemsRenderedCallback = ({
29
- overscanColumnStartIndex: number,
30
- overscanColumnStopIndex: number,
31
- overscanRowStartIndex: number,
32
- overscanRowStopIndex: number,
33
- visibleColumnStartIndex: number,
34
- visibleColumnStopIndex: number,
35
- visibleRowStartIndex: number,
36
- visibleRowStopIndex: number,
37
-}) => void;
38
-type OnScrollCallback = ({
39
- horizontalScrollDirection: ScrollDirection,
40
- scrollLeft: number,
41
- scrollTop: number,
42
- scrollUpdateWasRequested: boolean,
43
- verticalScrollDirection: ScrollDirection,
44
-}) => void;
45
-
46
-type ScrollEvent = SyntheticEvent<HTMLDivElement>;
47
-type ItemStyleCache = { [key: string]: Object };
48
-
49
-type OuterProps = {|
50
- children: React$Node,
51
- className: string | void,
52
- onScroll: ScrollEvent => void,
53
- style: {
54
- [string]: mixed,
55
- },
56
-|};
57
-
58
-type InnerProps = {|
59
- children: React$Node,
60
- style: {
61
- [string]: mixed,
62
- },
63
-|};
64
-
65
-export type Props<T> = {|
66
- children: RenderComponent<T>,
67
- className?: string,
68
- columnCount: number,
69
- columnWidth: itemSize,
70
- direction: Direction,
71
- height: number,
72
- initialScrollLeft?: number,
73
- initialScrollTop?: number,
74
- innerRef?: any,
75
- innerElementType?: string | React.AbstractComponent<InnerProps, any>,
76
- innerTagName?: string, // deprecated
77
- itemData: T,
78
- itemKey?: (params: {|
79
- columnIndex: number,
80
- data: T,
81
- rowIndex: number,
82
- |}) => any,
83
- onItemsRendered?: OnItemsRenderedCallback,
84
- onScroll?: OnScrollCallback,
85
- outerRef?: any,
86
- outerElementType?: string | React.AbstractComponent<OuterProps, any>,
87
- outerTagName?: string, // deprecated
88
- overscanColumnCount?: number,
89
- overscanColumnsCount?: number, // deprecated
90
- overscanCount?: number, // deprecated
91
- overscanRowCount?: number,
92
- overscanRowsCount?: number, // deprecated
93
- rowCount: number,
94
- rowHeight: itemSize,
95
- style?: Object,
96
- useIsScrolling: boolean,
97
- width: number,
98
-|};
99
-
100
-type State = {|
101
- instance: any,
102
- isScrolling: boolean,
103
- horizontalScrollDirection: ScrollDirection,
104
- scrollLeft: number,
105
- scrollTop: number,
106
- scrollUpdateWasRequested: boolean,
107
- verticalScrollDirection: ScrollDirection,
108
-|};
109
-
110
-type getItemOffset = (
111
- props: Props<any>,
112
- index: number,
113
- instanceProps: any
114
-) => number;
115
-type getItemSize = (
116
- props: Props<any>,
117
- index: number,
118
- instanceProps: any
119
-) => number;
120
-type getEstimatedTotalSize = (props: Props<any>, instanceProps: any) => number;
121
-type GetOffsetForItemAndAlignment = (
122
- props: Props<any>,
123
- index: number,
124
- align: ScrollToAlign,
125
- scrollOffset: number,
126
- instanceProps: any,
127
- scrollbarSize: number
128
-) => number;
129
-type GetStartIndexForOffset = (
130
- props: Props<any>,
131
- offset: number,
132
- instanceProps: any
133
-) => number;
134
-type GetStopIndexForStartIndex = (
135
- props: Props<any>,
136
- startIndex: number,
137
- scrollOffset: number,
138
- instanceProps: any
139
-) => number;
140
-type InitInstanceProps = (props: Props<any>, instance: any) => any;
141
-type ValidateProps = (props: Props<any>) => void;
142
-
143
-const IS_SCROLLING_DEBOUNCE_INTERVAL = 150;
144
-
145
-const defaultItemKey = ({ columnIndex, data, rowIndex }) =>
146
- `${rowIndex}:${columnIndex}`;
147
-
148
-// In DEV mode, this Set helps us only log a warning once per component instance.
149
-// This avoids spamming the console every time a render happens.
150
-let devWarningsOverscanCount = null;
151
-let devWarningsOverscanRowsColumnsCount = null;
152
-let devWarningsTagName = null;
153
-if (process.env.NODE_ENV !== 'production') {
154
- if (typeof window !== 'undefined' && typeof window.WeakSet !== 'undefined') {
155
- devWarningsOverscanCount = new WeakSet();
156
- devWarningsOverscanRowsColumnsCount = new WeakSet();
157
- devWarningsTagName = new WeakSet();
158
- }
159
-}
160
-
161
-export default function createGridComponent({
162
- getColumnOffset,
163
- getColumnStartIndexForOffset,
164
- getColumnStopIndexForStartIndex,
165
- getColumnWidth,
166
- getEstimatedTotalHeight,
167
- getEstimatedTotalWidth,
168
- getOffsetForColumnAndAlignment,
169
- getOffsetForRowAndAlignment,
170
- getRowHeight,
171
- getRowOffset,
172
- getRowStartIndexForOffset,
173
- getRowStopIndexForStartIndex,
174
- initInstanceProps,
175
- shouldResetStyleCacheOnItemSizeChange,
176
- validateProps,
177
-}: {|
178
- getColumnOffset: getItemOffset,
179
- getColumnStartIndexForOffset: GetStartIndexForOffset,
180
- getColumnStopIndexForStartIndex: GetStopIndexForStartIndex,
181
- getColumnWidth: getItemSize,
182
- getEstimatedTotalHeight: getEstimatedTotalSize,
183
- getEstimatedTotalWidth: getEstimatedTotalSize,
184
- getOffsetForColumnAndAlignment: GetOffsetForItemAndAlignment,
185
- getOffsetForRowAndAlignment: GetOffsetForItemAndAlignment,
186
- getRowOffset: getItemOffset,
187
- getRowHeight: getItemSize,
188
- getRowStartIndexForOffset: GetStartIndexForOffset,
189
- getRowStopIndexForStartIndex: GetStopIndexForStartIndex,
190
- initInstanceProps: InitInstanceProps,
191
- shouldResetStyleCacheOnItemSizeChange: boolean,
192
- validateProps: ValidateProps,
193
-|}) {
194
- return class Grid<T> extends PureComponent<Props<T>, State> {
195
- _instanceProps: any = initInstanceProps(this.props, this);
196
- _resetIsScrollingTimeoutId: TimeoutID | null = null;
197
- _outerRef: ?HTMLDivElement;
198
-
199
- static defaultProps = {
200
- direction: 'ltr',
201
- itemData: undefined,
202
- useIsScrolling: false,
203
- };
204
-
205
- state: State = {
206
- instance: this,
207
- isScrolling: false,
208
- horizontalScrollDirection: 'forward',
209
- scrollLeft:
210
- typeof this.props.initialScrollLeft === 'number'
211
- ? this.props.initialScrollLeft
212
- : 0,
213
- scrollTop:
214
- typeof this.props.initialScrollTop === 'number'
215
- ? this.props.initialScrollTop
216
- : 0,
217
- scrollUpdateWasRequested: false,
218
- verticalScrollDirection: 'forward',
219
- };
220
-
221
- // Always use explicit constructor for React components.
222
- // It produces less code after transpilation. (#26)
223
- // eslint-disable-next-line no-useless-constructor
224
- constructor(props: Props<T>) {
225
- super(props);
226
- }
227
-
228
- static getDerivedStateFromProps(
229
- nextProps: Props<T>,
230
- prevState: State
231
- ): $Shape<State> | null {
232
- validateSharedProps(nextProps, prevState);
233
- validateProps(nextProps);
234
- return null;
235
- }
236
-
237
- scrollTo({
238
- scrollLeft,
239
- scrollTop,
240
- }: {
241
- scrollLeft: number,
242
- scrollTop: number,
243
- }): void {
244
- if (scrollLeft !== undefined) {
245
- scrollLeft = Math.max(0, scrollLeft);
246
- }
247
- if (scrollTop !== undefined) {
248
- scrollTop = Math.max(0, scrollTop);
249
- }
250
-
251
- this.setState(prevState => {
252
- if (scrollLeft === undefined) {
253
- scrollLeft = prevState.scrollLeft;
254
- }
255
- if (scrollTop === undefined) {
256
- scrollTop = prevState.scrollTop;
257
- }
258
-
259
- if (
260
- prevState.scrollLeft === scrollLeft &&
261
- prevState.scrollTop === scrollTop
262
- ) {
263
- return null;
264
- }
265
-
266
- return {
267
- horizontalScrollDirection:
268
- prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
269
- scrollLeft: scrollLeft,
270
- scrollTop: scrollTop,
271
- scrollUpdateWasRequested: true,
272
- verticalScrollDirection:
273
- prevState.scrollTop < scrollTop ? 'forward' : 'backward',
274
- };
275
- }, this._resetIsScrollingDebounced);
276
- }
277
-
278
- scrollToItem({
279
- align = 'auto',
280
- columnIndex,
281
- rowIndex,
282
- }: {
283
- align: ScrollToAlign,
284
- columnIndex?: number,
285
- rowIndex?: number,
286
- }): void {
287
- const { columnCount, height, rowCount, width } = this.props;
288
- const { scrollLeft, scrollTop } = this.state;
289
- const scrollbarSize = getScrollbarSize();
290
-
291
- if (columnIndex !== undefined) {
292
- columnIndex = Math.max(0, Math.min(columnIndex, columnCount - 1));
293
- }
294
- if (rowIndex !== undefined) {
295
- rowIndex = Math.max(0, Math.min(rowIndex, rowCount - 1));
296
- }
297
-
298
- const estimatedTotalHeight = getEstimatedTotalHeight(
299
- this.props,
300
- this._instanceProps
301
- );
302
- const estimatedTotalWidth = getEstimatedTotalWidth(
303
- this.props,
304
- this._instanceProps
305
- );
306
-
307
- // The scrollbar size should be considered when scrolling an item into view,
308
- // to ensure it's fully visible.
309
- // But we only need to account for its size when it's actually visible.
310
- const horizontalScrollbarSize =
311
- estimatedTotalWidth > width ? scrollbarSize : 0;
312
- const verticalScrollbarSize =
313
- estimatedTotalHeight > height ? scrollbarSize : 0;
314
-
315
- this.scrollTo({
316
- scrollLeft:
317
- columnIndex !== undefined
318
- ? getOffsetForColumnAndAlignment(
319
- this.props,
320
- columnIndex,
321
- align,
322
- scrollLeft,
323
- this._instanceProps,
324
- verticalScrollbarSize
325
- )
326
- : scrollLeft,
327
- scrollTop:
328
- rowIndex !== undefined
329
- ? getOffsetForRowAndAlignment(
330
- this.props,
331
- rowIndex,
332
- align,
333
- scrollTop,
334
- this._instanceProps,
335
- horizontalScrollbarSize
336
- )
337
- : scrollTop,
338
- });
339
- }
340
-
341
- componentDidMount() {
342
- const { initialScrollLeft, initialScrollTop } = this.props;
343
-
344
- if (this._outerRef != null) {
345
- const outerRef = ((this._outerRef: any): HTMLElement);
346
- if (typeof initialScrollLeft === 'number') {
347
- outerRef.scrollLeft = initialScrollLeft;
348
- }
349
- if (typeof initialScrollTop === 'number') {
350
- outerRef.scrollTop = initialScrollTop;
351
- }
352
- }
353
-
354
- this._callPropsCallbacks();
355
- }
356
-
357
- componentDidUpdate() {
358
- const { direction } = this.props;
359
- const { scrollLeft, scrollTop, scrollUpdateWasRequested } = this.state;
360
-
361
- if (scrollUpdateWasRequested && this._outerRef != null) {
362
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
363
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
364
- // So we need to determine which browser behavior we're dealing with, and mimic it.
365
- const outerRef = ((this._outerRef: any): HTMLElement);
366
- if (direction === 'rtl') {
367
- switch (getRTLOffsetType()) {
368
- case 'negative':
369
- outerRef.scrollLeft = -scrollLeft;
370
- break;
371
- case 'positive-ascending':
372
- outerRef.scrollLeft = scrollLeft;
373
- break;
374
- default:
375
- const { clientWidth, scrollWidth } = outerRef;
376
- outerRef.scrollLeft = scrollWidth - clientWidth - scrollLeft;
377
- break;
378
- }
379
- } else {
380
- outerRef.scrollLeft = Math.max(0, scrollLeft);
381
- }
382
-
383
- outerRef.scrollTop = Math.max(0, scrollTop);
384
- }
385
-
386
- this._callPropsCallbacks();
387
- }
388
-
389
- componentWillUnmount() {
390
- if (this._resetIsScrollingTimeoutId !== null) {
391
- cancelTimeout(this._resetIsScrollingTimeoutId);
392
- }
393
- }
394
-
395
- render() {
396
- const {
397
- children,
398
- className,
399
- columnCount,
400
- direction,
401
- height,
402
- innerRef,
403
- innerElementType,
404
- innerTagName,
405
- itemData,
406
- itemKey = defaultItemKey,
407
- outerElementType,
408
- outerTagName,
409
- rowCount,
410
- style,
411
- useIsScrolling,
412
- width,
413
- } = this.props;
414
- const { isScrolling } = this.state;
415
-
416
- const [
417
- columnStartIndex,
418
- columnStopIndex,
419
- ] = this._getHorizontalRangeToRender();
420
- const [rowStartIndex, rowStopIndex] = this._getVerticalRangeToRender();
421
-
422
- const items = [];
423
- if (columnCount > 0 && rowCount) {
424
- for (
425
- let rowIndex = rowStartIndex;
426
- rowIndex <= rowStopIndex;
427
- rowIndex++
428
- ) {
429
- for (
430
- let columnIndex = columnStartIndex;
431
- columnIndex <= columnStopIndex;
432
- columnIndex++
433
- ) {
434
- items.push(
435
- createElement(children, {
436
- columnIndex,
437
- data: itemData,
438
- isScrolling: useIsScrolling ? isScrolling : undefined,
439
- key: itemKey({ columnIndex, data: itemData, rowIndex }),
440
- rowIndex,
441
- style: this._getItemStyle(rowIndex, columnIndex),
442
- })
443
- );
444
- }
445
- }
446
- }
447
-
448
- // Read this value AFTER items have been created,
449
- // So their actual sizes (if variable) are taken into consideration.
450
- const estimatedTotalHeight = getEstimatedTotalHeight(
451
- this.props,
452
- this._instanceProps
453
- );
454
- const estimatedTotalWidth = getEstimatedTotalWidth(
455
- this.props,
456
- this._instanceProps
457
- );
458
-
459
- return createElement(
460
- outerElementType || outerTagName || 'div',
461
- {
462
- className,
463
- onScroll: this._onScroll,
464
- ref: this._outerRefSetter,
465
- style: {
466
- position: 'relative',
467
- height,
468
- width,
469
- overflow: 'auto',
470
- WebkitOverflowScrolling: 'touch',
471
- willChange: 'transform',
472
- direction,
473
- ...style,
474
- },
475
- },
476
- createElement(innerElementType || innerTagName || 'div', {
477
- children: items,
478
- ref: innerRef,
479
- style: {
480
- height: estimatedTotalHeight,
481
- pointerEvents: isScrolling ? 'none' : undefined,
482
- width: estimatedTotalWidth,
483
- },
484
- })
485
- );
486
- }
487
-
488
- _callOnItemsRendered: (
489
- overscanColumnStartIndex: number,
490
- overscanColumnStopIndex: number,
491
- overscanRowStartIndex: number,
492
- overscanRowStopIndex: number,
493
- visibleColumnStartIndex: number,
494
- visibleColumnStopIndex: number,
495
- visibleRowStartIndex: number,
496
- visibleRowStopIndex: number
497
- ) => void;
498
- _callOnItemsRendered = memoizeOne(
499
- (
500
- overscanColumnStartIndex: number,
501
- overscanColumnStopIndex: number,
502
- overscanRowStartIndex: number,
503
- overscanRowStopIndex: number,
504
- visibleColumnStartIndex: number,
505
- visibleColumnStopIndex: number,
506
- visibleRowStartIndex: number,
507
- visibleRowStopIndex: number
508
- ) =>
509
- ((this.props.onItemsRendered: any): OnItemsRenderedCallback)({
510
- overscanColumnStartIndex,
511
- overscanColumnStopIndex,
512
- overscanRowStartIndex,
513
- overscanRowStopIndex,
514
- visibleColumnStartIndex,
515
- visibleColumnStopIndex,
516
- visibleRowStartIndex,
517
- visibleRowStopIndex,
518
- })
519
- );
520
-
521
- _callOnScroll: (
522
- scrollLeft: number,
523
- scrollTop: number,
524
- horizontalScrollDirection: ScrollDirection,
525
- verticalScrollDirection: ScrollDirection,
526
- scrollUpdateWasRequested: boolean
527
- ) => void;
528
- _callOnScroll = memoizeOne(
529
- (
530
- scrollLeft: number,
531
- scrollTop: number,
532
- horizontalScrollDirection: ScrollDirection,
533
- verticalScrollDirection: ScrollDirection,
534
- scrollUpdateWasRequested: boolean
535
- ) =>
536
- ((this.props.onScroll: any): OnScrollCallback)({
537
- horizontalScrollDirection,
538
- scrollLeft,
539
- scrollTop,
540
- verticalScrollDirection,
541
- scrollUpdateWasRequested,
542
- })
543
- );
544
-
545
- _callPropsCallbacks() {
546
- const { columnCount, onItemsRendered, onScroll, rowCount } = this.props;
547
-
548
- if (typeof onItemsRendered === 'function') {
549
- if (columnCount > 0 && rowCount > 0) {
550
- const [
551
- overscanColumnStartIndex,
552
- overscanColumnStopIndex,
553
- visibleColumnStartIndex,
554
- visibleColumnStopIndex,
555
- ] = this._getHorizontalRangeToRender();
556
- const [
557
- overscanRowStartIndex,
558
- overscanRowStopIndex,
559
- visibleRowStartIndex,
560
- visibleRowStopIndex,
561
- ] = this._getVerticalRangeToRender();
562
- this._callOnItemsRendered(
563
- overscanColumnStartIndex,
564
- overscanColumnStopIndex,
565
- overscanRowStartIndex,
566
- overscanRowStopIndex,
567
- visibleColumnStartIndex,
568
- visibleColumnStopIndex,
569
- visibleRowStartIndex,
570
- visibleRowStopIndex
571
- );
572
- }
573
- }
574
-
575
- if (typeof onScroll === 'function') {
576
- const {
577
- horizontalScrollDirection,
578
- scrollLeft,
579
- scrollTop,
580
- scrollUpdateWasRequested,
581
- verticalScrollDirection,
582
- } = this.state;
583
- this._callOnScroll(
584
- scrollLeft,
585
- scrollTop,
586
- horizontalScrollDirection,
587
- verticalScrollDirection,
588
- scrollUpdateWasRequested
589
- );
590
- }
591
- }
592
-
593
- // Lazily create and cache item styles while scrolling,
594
- // So that pure component sCU will prevent re-renders.
595
- // We maintain this cache, and pass a style prop rather than index,
596
- // So that List can clear cached styles and force item re-render if necessary.
597
- _getItemStyle: (rowIndex: number, columnIndex: number) => Object;
598
- _getItemStyle = (rowIndex: number, columnIndex: number): Object => {
599
- const { columnWidth, direction, rowHeight } = this.props;
600
-
601
- const itemStyleCache = this._getItemStyleCache(
602
- shouldResetStyleCacheOnItemSizeChange && columnWidth,
603
- shouldResetStyleCacheOnItemSizeChange && direction,
604
- shouldResetStyleCacheOnItemSizeChange && rowHeight
605
- );
606
-
607
- const key = `${rowIndex}:${columnIndex}`;
608
-
609
- let style;
610
- if (itemStyleCache.hasOwnProperty(key)) {
611
- style = itemStyleCache[key];
612
- } else {
613
- itemStyleCache[key] = style = {
614
- position: 'absolute',
615
- [direction === 'rtl' ? 'right' : 'left']: getColumnOffset(
616
- this.props,
617
- columnIndex,
618
- this._instanceProps
619
- ),
620
- top: getRowOffset(this.props, rowIndex, this._instanceProps),
621
- height: getRowHeight(this.props, rowIndex, this._instanceProps),
622
- width: getColumnWidth(this.props, columnIndex, this._instanceProps),
623
- };
624
- }
625
-
626
- return style;
627
- };
628
-
629
- _getItemStyleCache: (_: any, __: any, ___: any) => ItemStyleCache;
630
- _getItemStyleCache = memoizeOne((_: any, __: any, ___: any) => ({}));
631
-
632
- _getHorizontalRangeToRender(): [number, number, number, number] {
633
- const {
634
- columnCount,
635
- overscanColumnCount,
636
- overscanColumnsCount,
637
- overscanCount,
638
- rowCount,
639
- } = this.props;
640
- const { horizontalScrollDirection, isScrolling, scrollLeft } = this.state;
641
-
642
- const overscanCountResolved: number =
643
- overscanColumnCount || overscanColumnsCount || overscanCount || 1;
644
-
645
- if (columnCount === 0 || rowCount === 0) {
646
- return [0, 0, 0, 0];
647
- }
648
-
649
- const startIndex = getColumnStartIndexForOffset(
650
- this.props,
651
- scrollLeft,
652
- this._instanceProps
653
- );
654
- const stopIndex = getColumnStopIndexForStartIndex(
655
- this.props,
656
- startIndex,
657
- scrollLeft,
658
- this._instanceProps
659
- );
660
-
661
- // Overscan by one item in each direction so that tab/focus works.
662
- // If there isn't at least one extra item, tab loops back around.
663
- const overscanBackward =
664
- !isScrolling || horizontalScrollDirection === 'backward'
665
- ? Math.max(1, overscanCountResolved)
666
- : 1;
667
- const overscanForward =
668
- !isScrolling || horizontalScrollDirection === 'forward'
669
- ? Math.max(1, overscanCountResolved)
670
- : 1;
671
-
672
- return [
673
- Math.max(0, startIndex - overscanBackward),
674
- Math.max(0, Math.min(columnCount - 1, stopIndex + overscanForward)),
675
- startIndex,
676
- stopIndex,
677
- ];
678
- }
679
-
680
- _getVerticalRangeToRender(): [number, number, number, number] {
681
- const {
682
- columnCount,
683
- overscanCount,
684
- overscanRowCount,
685
- overscanRowsCount,
686
- rowCount,
687
- } = this.props;
688
- const { isScrolling, verticalScrollDirection, scrollTop } = this.state;
689
-
690
- const overscanCountResolved: number =
691
- overscanRowCount || overscanRowsCount || overscanCount || 1;
692
-
693
- if (columnCount === 0 || rowCount === 0) {
694
- return [0, 0, 0, 0];
695
- }
696
-
697
- const startIndex = getRowStartIndexForOffset(
698
- this.props,
699
- scrollTop,
700
- this._instanceProps
701
- );
702
- const stopIndex = getRowStopIndexForStartIndex(
703
- this.props,
704
- startIndex,
705
- scrollTop,
706
- this._instanceProps
707
- );
708
-
709
- // Overscan by one item in each direction so that tab/focus works.
710
- // If there isn't at least one extra item, tab loops back around.
711
- const overscanBackward =
712
- !isScrolling || verticalScrollDirection === 'backward'
713
- ? Math.max(1, overscanCountResolved)
714
- : 1;
715
- const overscanForward =
716
- !isScrolling || verticalScrollDirection === 'forward'
717
- ? Math.max(1, overscanCountResolved)
718
- : 1;
719
-
720
- return [
721
- Math.max(0, startIndex - overscanBackward),
722
- Math.max(0, Math.min(rowCount - 1, stopIndex + overscanForward)),
723
- startIndex,
724
- stopIndex,
725
- ];
726
- }
727
-
728
- _onScroll = (event: ScrollEvent): void => {
729
- const {
730
- clientHeight,
731
- clientWidth,
732
- scrollLeft,
733
- scrollTop,
734
- scrollHeight,
735
- scrollWidth,
736
- } = event.currentTarget;
737
- this.setState(prevState => {
738
- if (
739
- prevState.scrollLeft === scrollLeft &&
740
- prevState.scrollTop === scrollTop
741
- ) {
742
- // Scroll position may have been updated by cDM/cDU,
743
- // In which case we don't need to trigger another render,
744
- // And we don't want to update state.isScrolling.
745
- return null;
746
- }
747
-
748
- const { direction } = this.props;
749
-
750
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
751
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
752
- // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
753
- // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
754
- let calculatedScrollLeft = scrollLeft;
755
- if (direction === 'rtl') {
756
- switch (getRTLOffsetType()) {
757
- case 'negative':
758
- calculatedScrollLeft = -scrollLeft;
759
- break;
760
- case 'positive-descending':
761
- calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
762
- break;
763
- }
764
- }
765
-
766
- // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
767
- calculatedScrollLeft = Math.max(
768
- 0,
769
- Math.min(calculatedScrollLeft, scrollWidth - clientWidth)
770
- );
771
- const calculatedScrollTop = Math.max(
772
- 0,
773
- Math.min(scrollTop, scrollHeight - clientHeight)
774
- );
775
-
776
- return {
777
- isScrolling: true,
778
- horizontalScrollDirection:
779
- prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
780
- scrollLeft: calculatedScrollLeft,
781
- scrollTop: calculatedScrollTop,
782
- verticalScrollDirection:
783
- prevState.scrollTop < scrollTop ? 'forward' : 'backward',
784
- scrollUpdateWasRequested: false,
785
- };
786
- }, this._resetIsScrollingDebounced);
787
- };
788
-
789
- _outerRefSetter = (ref: any): void => {
790
- const { outerRef } = this.props;
791
-
792
- this._outerRef = ((ref: any): HTMLDivElement);
793
-
794
- if (typeof outerRef === 'function') {
795
- outerRef(ref);
796
- } else if (
797
- outerRef != null &&
798
- typeof outerRef === 'object' &&
799
- outerRef.hasOwnProperty('current')
800
- ) {
801
- outerRef.current = ref;
802
- }
803
- };
804
-
805
- _resetIsScrollingDebounced = () => {
806
- if (this._resetIsScrollingTimeoutId !== null) {
807
- cancelTimeout(this._resetIsScrollingTimeoutId);
808
- }
809
-
810
- this._resetIsScrollingTimeoutId = requestTimeout(
811
- this._resetIsScrolling,
812
- IS_SCROLLING_DEBOUNCE_INTERVAL
813
- );
814
- };
815
-
816
- _resetIsScrolling = () => {
817
- this._resetIsScrollingTimeoutId = null;
818
-
819
- this.setState({ isScrolling: false }, () => {
820
- // Clear style cache after state update has been committed.
821
- // This way we don't break pure sCU for items that don't use isScrolling param.
822
- this._getItemStyleCache(-1);
823
- });
824
- };
825
- };
826
-}
827
-
828
-const validateSharedProps = (
829
- {
830
- children,
831
- direction,
832
- height,
833
- innerTagName,
834
- outerTagName,
835
- overscanColumnsCount,
836
- overscanCount,
837
- overscanRowsCount,
838
- width,
839
- }: Props<any>,
840
- { instance }: State
841
-): void => {
842
- if (process.env.NODE_ENV !== 'production') {
843
- if (typeof overscanCount === 'number') {
844
- if (devWarningsOverscanCount && !devWarningsOverscanCount.has(instance)) {
845
- devWarningsOverscanCount.add(instance);
846
- console.warn(
847
- 'The overscanCount prop has been deprecated. ' +
848
- 'Please use the overscanColumnCount and overscanRowCount props instead.'
849
- );
850
- }
851
- }
852
-
853
- if (
854
- typeof overscanColumnsCount === 'number' ||
855
- typeof overscanRowsCount === 'number'
856
- ) {
857
- if (
858
- devWarningsOverscanRowsColumnsCount &&
859
- !devWarningsOverscanRowsColumnsCount.has(instance)
860
- ) {
861
- devWarningsOverscanRowsColumnsCount.add(instance);
862
- console.warn(
863
- 'The overscanColumnsCount and overscanRowsCount props have been deprecated. ' +
864
- 'Please use the overscanColumnCount and overscanRowCount props instead.'
865
- );
866
- }
867
- }
868
-
869
- if (innerTagName != null || outerTagName != null) {
870
- if (devWarningsTagName && !devWarningsTagName.has(instance)) {
871
- devWarningsTagName.add(instance);
872
- console.warn(
873
- 'The innerTagName and outerTagName props have been deprecated. ' +
874
- 'Please use the innerElementType and outerElementType props instead.'
875
- );
876
- }
877
- }
878
-
879
- if (children == null) {
880
- throw Error(
881
- 'An invalid "children" prop has been specified. ' +
882
- 'Value should be a React component. ' +
883
- `"${children === null ? 'null' : typeof children}" was specified.`
884
- );
885
- }
886
-
887
- switch (direction) {
888
- case 'ltr':
889
- case 'rtl':
890
- // Valid values
891
- break;
892
- default:
893
- throw Error(
894
- 'An invalid "direction" prop has been specified. ' +
895
- 'Value should be either "ltr" or "rtl". ' +
896
- `"${direction}" was specified.`
897
- );
898
- }
899
-
900
- if (typeof width !== 'number') {
901
- throw Error(
902
- 'An invalid "width" prop has been specified. ' +
903
- 'Grids must specify a number for width. ' +
904
- `"${width === null ? 'null' : typeof width}" was specified.`
905
- );
906
- }
907
-
908
- if (typeof height !== 'number') {
909
- throw Error(
910
- 'An invalid "height" prop has been specified. ' +
911
- 'Grids must specify a number for height. ' +
912
- `"${height === null ? 'null' : typeof height}" was specified.`
913
- );
914
- }
915
- }
916
-};
packages/react-devtools-shared/src/node_modules/react-window/src/createListComponent.js
deleted
-722
@@ -1,722 +0,0 @@
1
-// @flow
2
-
3
-import memoizeOne from 'memoize-one';
4
-import React, { createElement, PureComponent } from 'react';
5
-import { cancelTimeout, requestTimeout } from './timer';
6
-import { getRTLOffsetType } from './domHelpers';
7
-
8
-import type { TimeoutID } from './timer';
9
-
10
-export type ScrollToAlign = 'auto' | 'smart' | 'center' | 'start' | 'end';
11
-
12
-type itemSize = number | ((index: number) => number);
13
-// TODO Deprecate directions "horizontal" and "vertical"
14
-type Direction = 'ltr' | 'rtl' | 'horizontal' | 'vertical';
15
-type Layout = 'horizontal' | 'vertical';
16
-
17
-type RenderComponentProps<T> = {|
18
- data: T,
19
- index: number,
20
- isScrolling?: boolean,
21
- style: Object,
22
-|};
23
-type RenderComponent<T> = React$ComponentType<$Shape<RenderComponentProps<T>>>;
24
-
25
-type ScrollDirection = 'forward' | 'backward';
26
-
27
-type onItemsRenderedCallback = ({
28
- overscanStartIndex: number,
29
- overscanStopIndex: number,
30
- visibleStartIndex: number,
31
- visibleStopIndex: number,
32
-}) => void;
33
-type onScrollCallback = ({
34
- scrollDirection: ScrollDirection,
35
- scrollOffset: number,
36
- scrollUpdateWasRequested: boolean,
37
-}) => void;
38
-
39
-type ScrollEvent = SyntheticEvent<HTMLDivElement>;
40
-type ItemStyleCache = { [index: number]: Object };
41
-
42
-type OuterProps = {|
43
- children: React$Node,
44
- className: string | void,
45
- onScroll: ScrollEvent => void,
46
- style: {
47
- [string]: mixed,
48
- },
49
-|};
50
-
51
-type InnerProps = {|
52
- children: React$Node,
53
- style: {
54
- [string]: mixed,
55
- },
56
-|};
57
-
58
-export type Props<T> = {|
59
- children: RenderComponent<T>,
60
- className?: string,
61
- direction: Direction,
62
- height: number | string,
63
- initialScrollOffset?: number,
64
- innerRef?: any,
65
- innerElementType?: string | React.AbstractComponent<InnerProps, any>,
66
- innerTagName?: string, // deprecated
67
- itemCount: number,
68
- itemData: T,
69
- itemKey?: (index: number, data: T) => any,
70
- itemSize: itemSize,
71
- layout: Layout,
72
- onItemsRendered?: onItemsRenderedCallback,
73
- onScroll?: onScrollCallback,
74
- outerRef?: any,
75
- outerElementType?: string | React.AbstractComponent<OuterProps, any>,
76
- outerTagName?: string, // deprecated
77
- overscanCount: number,
78
- style?: Object,
79
- useIsScrolling: boolean,
80
- width: number | string,
81
-|};
82
-
83
-type State = {|
84
- instance: any,
85
- isScrolling: boolean,
86
- scrollDirection: ScrollDirection,
87
- scrollOffset: number,
88
- scrollUpdateWasRequested: boolean,
89
-|};
90
-
91
-type GetItemOffset = (
92
- props: Props<any>,
93
- index: number,
94
- instanceProps: any
95
-) => number;
96
-type GetItemSize = (
97
- props: Props<any>,
98
- index: number,
99
- instanceProps: any
100
-) => number;
101
-type GetEstimatedTotalSize = (props: Props<any>, instanceProps: any) => number;
102
-type GetOffsetForIndexAndAlignment = (
103
- props: Props<any>,
104
- index: number,
105
- align: ScrollToAlign,
106
- scrollOffset: number,
107
- instanceProps: any
108
-) => number;
109
-type GetStartIndexForOffset = (
110
- props: Props<any>,
111
- offset: number,
112
- instanceProps: any
113
-) => number;
114
-type GetStopIndexForStartIndex = (
115
- props: Props<any>,
116
- startIndex: number,
117
- scrollOffset: number,
118
- instanceProps: any
119
-) => number;
120
-type InitInstanceProps = (props: Props<any>, instance: any) => any;
121
-type ValidateProps = (props: Props<any>) => void;
122
-
123
-const IS_SCROLLING_DEBOUNCE_INTERVAL = 150;
124
-
125
-const defaultItemKey = (index: number, data: any) => index;
126
-
127
-// In DEV mode, this Set helps us only log a warning once per component instance.
128
-// This avoids spamming the console every time a render happens.
129
-let devWarningsDirection = null;
130
-let devWarningsTagName = null;
131
-if (process.env.NODE_ENV !== 'production') {
132
- if (typeof window !== 'undefined' && typeof window.WeakSet !== 'undefined') {
133
- devWarningsDirection = new WeakSet();
134
- devWarningsTagName = new WeakSet();
135
- }
136
-}
137
-
138
-export default function createListComponent({
139
- getItemOffset,
140
- getEstimatedTotalSize,
141
- getItemSize,
142
- getOffsetForIndexAndAlignment,
143
- getStartIndexForOffset,
144
- getStopIndexForStartIndex,
145
- initInstanceProps,
146
- shouldResetStyleCacheOnItemSizeChange,
147
- validateProps,
148
-}: {|
149
- getItemOffset: GetItemOffset,
150
- getEstimatedTotalSize: GetEstimatedTotalSize,
151
- getItemSize: GetItemSize,
152
- getOffsetForIndexAndAlignment: GetOffsetForIndexAndAlignment,
153
- getStartIndexForOffset: GetStartIndexForOffset,
154
- getStopIndexForStartIndex: GetStopIndexForStartIndex,
155
- initInstanceProps: InitInstanceProps,
156
- shouldResetStyleCacheOnItemSizeChange: boolean,
157
- validateProps: ValidateProps,
158
-|}) {
159
- return class List<T> extends PureComponent<Props<T>, State> {
160
- _instanceProps: any = initInstanceProps(this.props, this);
161
- _outerRef: ?HTMLDivElement;
162
- _resetIsScrollingTimeoutId: TimeoutID | null = null;
163
-
164
- static defaultProps = {
165
- direction: 'ltr',
166
- itemData: undefined,
167
- layout: 'vertical',
168
- overscanCount: 2,
169
- useIsScrolling: false,
170
- };
171
-
172
- state: State = {
173
- instance: this,
174
- isScrolling: false,
175
- scrollDirection: 'forward',
176
- scrollOffset:
177
- typeof this.props.initialScrollOffset === 'number'
178
- ? this.props.initialScrollOffset
179
- : 0,
180
- scrollUpdateWasRequested: false,
181
- };
182
-
183
- // Always use explicit constructor for React components.
184
- // It produces less code after transpilation. (#26)
185
- // eslint-disable-next-line no-useless-constructor
186
- constructor(props: Props<T>) {
187
- super(props);
188
- }
189
-
190
- static getDerivedStateFromProps(
191
- nextProps: Props<T>,
192
- prevState: State
193
- ): $Shape<State> | null {
194
- validateSharedProps(nextProps, prevState);
195
- validateProps(nextProps);
196
- return null;
197
- }
198
-
199
- scrollTo(scrollOffset: number): void {
200
- scrollOffset = Math.max(0, scrollOffset);
201
-
202
- this.setState(prevState => {
203
- if (prevState.scrollOffset === scrollOffset) {
204
- return null;
205
- }
206
- return {
207
- scrollDirection:
208
- prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
209
- scrollOffset: scrollOffset,
210
- scrollUpdateWasRequested: true,
211
- };
212
- }, this._resetIsScrollingDebounced);
213
- }
214
-
215
- scrollToItem(index: number, align: ScrollToAlign = 'auto'): void {
216
- const { itemCount } = this.props;
217
- const { scrollOffset } = this.state;
218
-
219
- index = Math.max(0, Math.min(index, itemCount - 1));
220
-
221
- this.scrollTo(
222
- getOffsetForIndexAndAlignment(
223
- this.props,
224
- index,
225
- align,
226
- scrollOffset,
227
- this._instanceProps
228
- )
229
- );
230
- }
231
-
232
- componentDidMount() {
233
- const { direction, initialScrollOffset, layout } = this.props;
234
-
235
- if (typeof initialScrollOffset === 'number' && this._outerRef != null) {
236
- const outerRef = ((this._outerRef: any): HTMLElement);
237
- // TODO Deprecate direction "horizontal"
238
- if (direction === 'horizontal' || layout === 'horizontal') {
239
- outerRef.scrollLeft = initialScrollOffset;
240
- } else {
241
- outerRef.scrollTop = initialScrollOffset;
242
- }
243
- }
244
-
245
- this._callPropsCallbacks();
246
- }
247
-
248
- componentDidUpdate() {
249
- const { direction, layout } = this.props;
250
- const { scrollOffset, scrollUpdateWasRequested } = this.state;
251
-
252
- if (scrollUpdateWasRequested && this._outerRef != null) {
253
- const outerRef = ((this._outerRef: any): HTMLElement);
254
-
255
- // TODO Deprecate direction "horizontal"
256
- if (direction === 'horizontal' || layout === 'horizontal') {
257
- if (direction === 'rtl') {
258
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
259
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
260
- // So we need to determine which browser behavior we're dealing with, and mimic it.
261
- switch (getRTLOffsetType()) {
262
- case 'negative':
263
- outerRef.scrollLeft = -scrollOffset;
264
- break;
265
- case 'positive-ascending':
266
- outerRef.scrollLeft = scrollOffset;
267
- break;
268
- default:
269
- const { clientWidth, scrollWidth } = outerRef;
270
- outerRef.scrollLeft = scrollWidth - clientWidth - scrollOffset;
271
- break;
272
- }
273
- } else {
274
- outerRef.scrollLeft = scrollOffset;
275
- }
276
- } else {
277
- outerRef.scrollTop = scrollOffset;
278
- }
279
- }
280
-
281
- this._callPropsCallbacks();
282
- }
283
-
284
- componentWillUnmount() {
285
- if (this._resetIsScrollingTimeoutId !== null) {
286
- cancelTimeout(this._resetIsScrollingTimeoutId);
287
- }
288
- }
289
-
290
- render() {
291
- const {
292
- children,
293
- className,
294
- direction,
295
- height,
296
- innerRef,
297
- innerElementType,
298
- innerTagName,
299
- itemCount,
300
- itemData,
301
- itemKey = defaultItemKey,
302
- layout,
303
- outerElementType,
304
- outerTagName,
305
- style,
306
- useIsScrolling,
307
- width,
308
- } = this.props;
309
- const { isScrolling } = this.state;
310
-
311
- // TODO Deprecate direction "horizontal"
312
- const isHorizontal =
313
- direction === 'horizontal' || layout === 'horizontal';
314
-
315
- const onScroll = isHorizontal
316
- ? this._onScrollHorizontal
317
- : this._onScrollVertical;
318
-
319
- const [startIndex, stopIndex] = this._getRangeToRender();
320
-
321
- const items = [];
322
- if (itemCount > 0) {
323
- for (let index = startIndex; index <= stopIndex; index++) {
324
- items.push(
325
- createElement(children, {
326
- data: itemData,
327
- key: itemKey(index, itemData),
328
- index,
329
- isScrolling: useIsScrolling ? isScrolling : undefined,
330
- style: this._getItemStyle(index),
331
- })
332
- );
333
- }
334
- }
335
-
336
- // Read this value AFTER items have been created,
337
- // So their actual sizes (if variable) are taken into consideration.
338
- const estimatedTotalSize = getEstimatedTotalSize(
339
- this.props,
340
- this._instanceProps
341
- );
342
-
343
- return createElement(
344
- outerElementType || outerTagName || 'div',
345
- {
346
- className,
347
- onScroll,
348
- ref: this._outerRefSetter,
349
- style: {
350
- position: 'relative',
351
- height,
352
- width,
353
- overflow: 'auto',
354
- WebkitOverflowScrolling: 'touch',
355
- willChange: 'transform',
356
- direction,
357
- ...style,
358
- },
359
- },
360
- createElement(innerElementType || innerTagName || 'div', {
361
- children: items,
362
- ref: innerRef,
363
- style: {
364
- height: isHorizontal ? '100%' : estimatedTotalSize,
365
- pointerEvents: isScrolling ? 'none' : undefined,
366
- width: isHorizontal ? estimatedTotalSize : '100%',
367
- },
368
- })
369
- );
370
- }
371
-
372
- _callOnItemsRendered: (
373
- overscanStartIndex: number,
374
- overscanStopIndex: number,
375
- visibleStartIndex: number,
376
- visibleStopIndex: number
377
- ) => void;
378
- _callOnItemsRendered = memoizeOne(
379
- (
380
- overscanStartIndex: number,
381
- overscanStopIndex: number,
382
- visibleStartIndex: number,
383
- visibleStopIndex: number
384
- ) =>
385
- ((this.props.onItemsRendered: any): onItemsRenderedCallback)({
386
- overscanStartIndex,
387
- overscanStopIndex,
388
- visibleStartIndex,
389
- visibleStopIndex,
390
- })
391
- );
392
-
393
- _callOnScroll: (
394
- scrollDirection: ScrollDirection,
395
- scrollOffset: number,
396
- scrollUpdateWasRequested: boolean
397
- ) => void;
398
- _callOnScroll = memoizeOne(
399
- (
400
- scrollDirection: ScrollDirection,
401
- scrollOffset: number,
402
- scrollUpdateWasRequested: boolean
403
- ) =>
404
- ((this.props.onScroll: any): onScrollCallback)({
405
- scrollDirection,
406
- scrollOffset,
407
- scrollUpdateWasRequested,
408
- })
409
- );
410
-
411
- _callPropsCallbacks() {
412
- if (typeof this.props.onItemsRendered === 'function') {
413
- const { itemCount } = this.props;
414
- if (itemCount > 0) {
415
- const [
416
- overscanStartIndex,
417
- overscanStopIndex,
418
- visibleStartIndex,
419
- visibleStopIndex,
420
- ] = this._getRangeToRender();
421
- this._callOnItemsRendered(
422
- overscanStartIndex,
423
- overscanStopIndex,
424
- visibleStartIndex,
425
- visibleStopIndex
426
- );
427
- }
428
- }
429
-
430
- if (typeof this.props.onScroll === 'function') {
431
- const {
432
- scrollDirection,
433
- scrollOffset,
434
- scrollUpdateWasRequested,
435
- } = this.state;
436
- this._callOnScroll(
437
- scrollDirection,
438
- scrollOffset,
439
- scrollUpdateWasRequested
440
- );
441
- }
442
- }
443
-
444
- // Lazily create and cache item styles while scrolling,
445
- // So that pure component sCU will prevent re-renders.
446
- // We maintain this cache, and pass a style prop rather than index,
447
- // So that List can clear cached styles and force item re-render if necessary.
448
- _getItemStyle: (index: number) => Object;
449
- _getItemStyle = (index: number): Object => {
450
- const { direction, itemSize, layout } = this.props;
451
-
452
- const itemStyleCache = this._getItemStyleCache(
453
- shouldResetStyleCacheOnItemSizeChange && itemSize,
454
- shouldResetStyleCacheOnItemSizeChange && layout,
455
- shouldResetStyleCacheOnItemSizeChange && direction
456
- );
457
-
458
- let style;
459
- if (itemStyleCache.hasOwnProperty(index)) {
460
- style = itemStyleCache[index];
461
- } else {
462
- const offset = getItemOffset(this.props, index, this._instanceProps);
463
- const size = getItemSize(this.props, index, this._instanceProps);
464
-
465
- // TODO Deprecate direction "horizontal"
466
- const isHorizontal =
467
- direction === 'horizontal' || layout === 'horizontal';
468
-
469
- itemStyleCache[index] = style = {
470
- position: 'absolute',
471
- [direction === 'rtl' ? 'right' : 'left']: isHorizontal ? offset : 0,
472
- top: !isHorizontal ? offset : 0,
473
- height: !isHorizontal ? size : '100%',
474
- width: isHorizontal ? size : '100%',
475
- };
476
- }
477
-
478
- return style;
479
- };
480
-
481
- _getItemStyleCache: (_: any, __: any, ___: any) => ItemStyleCache;
482
- _getItemStyleCache = memoizeOne((_: any, __: any, ___: any) => ({}));
483
-
484
- _getRangeToRender(): [number, number, number, number] {
485
- const { itemCount, overscanCount } = this.props;
486
- const { isScrolling, scrollDirection, scrollOffset } = this.state;
487
-
488
- if (itemCount === 0) {
489
- return [0, 0, 0, 0];
490
- }
491
-
492
- const startIndex = getStartIndexForOffset(
493
- this.props,
494
- scrollOffset,
495
- this._instanceProps
496
- );
497
- const stopIndex = getStopIndexForStartIndex(
498
- this.props,
499
- startIndex,
500
- scrollOffset,
501
- this._instanceProps
502
- );
503
-
504
- // Overscan by one item in each direction so that tab/focus works.
505
- // If there isn't at least one extra item, tab loops back around.
506
- const overscanBackward =
507
- !isScrolling || scrollDirection === 'backward'
508
- ? Math.max(1, overscanCount)
509
- : 1;
510
- const overscanForward =
511
- !isScrolling || scrollDirection === 'forward'
512
- ? Math.max(1, overscanCount)
513
- : 1;
514
-
515
- return [
516
- Math.max(0, startIndex - overscanBackward),
517
- Math.max(0, Math.min(itemCount - 1, stopIndex + overscanForward)),
518
- startIndex,
519
- stopIndex,
520
- ];
521
- }
522
-
523
- _onScrollHorizontal = (event: ScrollEvent): void => {
524
- const { clientWidth, scrollLeft, scrollWidth } = event.currentTarget;
525
- this.setState(prevState => {
526
- if (prevState.scrollOffset === scrollLeft) {
527
- // Scroll position may have been updated by cDM/cDU,
528
- // In which case we don't need to trigger another render,
529
- // And we don't want to update state.isScrolling.
530
- return null;
531
- }
532
-
533
- const { direction } = this.props;
534
-
535
- let scrollOffset = scrollLeft;
536
- if (direction === 'rtl') {
537
- // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
538
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
539
- // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
540
- // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
541
- switch (getRTLOffsetType()) {
542
- case 'negative':
543
- scrollOffset = -scrollLeft;
544
- break;
545
- case 'positive-descending':
546
- scrollOffset = scrollWidth - clientWidth - scrollLeft;
547
- break;
548
- }
549
- }
550
-
551
- // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
552
- scrollOffset = Math.max(
553
- 0,
554
- Math.min(scrollOffset, scrollWidth - clientWidth)
555
- );
556
-
557
- return {
558
- isScrolling: true,
559
- scrollDirection:
560
- prevState.scrollOffset < scrollLeft ? 'forward' : 'backward',
561
- scrollOffset,
562
- scrollUpdateWasRequested: false,
563
- };
564
- }, this._resetIsScrollingDebounced);
565
- };
566
-
567
- _onScrollVertical = (event: ScrollEvent): void => {
568
- const { clientHeight, scrollHeight, scrollTop } = event.currentTarget;
569
- this.setState(prevState => {
570
- if (prevState.scrollOffset === scrollTop) {
571
- // Scroll position may have been updated by cDM/cDU,
572
- // In which case we don't need to trigger another render,
573
- // And we don't want to update state.isScrolling.
574
- return null;
575
- }
576
-
577
- // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
578
- const scrollOffset = Math.max(
579
- 0,
580
- Math.min(scrollTop, scrollHeight - clientHeight)
581
- );
582
-
583
- return {
584
- isScrolling: true,
585
- scrollDirection:
586
- prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
587
- scrollOffset,
588
- scrollUpdateWasRequested: false,
589
- };
590
- }, this._resetIsScrollingDebounced);
591
- };
592
-
593
- _outerRefSetter = (ref: any): void => {
594
- const { outerRef } = this.props;
595
-
596
- this._outerRef = ((ref: any): HTMLDivElement);
597
-
598
- if (typeof outerRef === 'function') {
599
- outerRef(ref);
600
- } else if (
601
- outerRef != null &&
602
- typeof outerRef === 'object' &&
603
- outerRef.hasOwnProperty('current')
604
- ) {
605
- outerRef.current = ref;
606
- }
607
- };
608
-
609
- _resetIsScrollingDebounced = () => {
610
- if (this._resetIsScrollingTimeoutId !== null) {
611
- cancelTimeout(this._resetIsScrollingTimeoutId);
612
- }
613
-
614
- this._resetIsScrollingTimeoutId = requestTimeout(
615
- this._resetIsScrolling,
616
- IS_SCROLLING_DEBOUNCE_INTERVAL
617
- );
618
- };
619
-
620
- _resetIsScrolling = () => {
621
- this._resetIsScrollingTimeoutId = null;
622
-
623
- this.setState({ isScrolling: false }, () => {
624
- // Clear style cache after state update has been committed.
625
- // This way we don't break pure sCU for items that don't use isScrolling param.
626
- this._getItemStyleCache(-1, null);
627
- });
628
- };
629
- };
630
-}
631
-
632
-// NOTE: I considered further wrapping individual items with a pure ListItem component.
633
-// This would avoid ever calling the render function for the same index more than once,
634
-// But it would also add the overhead of a lot of components/fibers.
635
-// I assume people already do this (render function returning a class component),
636
-// So my doing it would just unnecessarily double the wrappers.
637
-
638
-const validateSharedProps = (
639
- {
640
- children,
641
- direction,
642
- height,
643
- layout,
644
- innerTagName,
645
- outerTagName,
646
- width,
647
- }: Props<any>,
648
- { instance }: State
649
-): void => {
650
- if (process.env.NODE_ENV !== 'production') {
651
- if (innerTagName != null || outerTagName != null) {
652
- if (devWarningsTagName && !devWarningsTagName.has(instance)) {
653
- devWarningsTagName.add(instance);
654
- console.warn(
655
- 'The innerTagName and outerTagName props have been deprecated. ' +
656
- 'Please use the innerElementType and outerElementType props instead.'
657
- );
658
- }
659
- }
660
-
661
- // TODO Deprecate direction "horizontal"
662
- const isHorizontal = direction === 'horizontal' || layout === 'horizontal';
663
-
664
- switch (direction) {
665
- case 'horizontal':
666
- case 'vertical':
667
- if (devWarningsDirection && !devWarningsDirection.has(instance)) {
668
- devWarningsDirection.add(instance);
669
- console.warn(
670
- 'The direction prop should be either "ltr" (default) or "rtl". ' +
671
- 'Please use the layout prop to specify "vertical" (default) or "horizontal" orientation.'
672
- );
673
- }
674
- break;
675
- case 'ltr':
676
- case 'rtl':
677
- // Valid values
678
- break;
679
- default:
680
- throw Error(
681
- 'An invalid "direction" prop has been specified. ' +
682
- 'Value should be either "ltr" or "rtl". ' +
683
- `"${direction}" was specified.`
684
- );
685
- }
686
-
687
- switch (layout) {
688
- case 'horizontal':
689
- case 'vertical':
690
- // Valid values
691
- break;
692
- default:
693
- throw Error(
694
- 'An invalid "layout" prop has been specified. ' +
695
- 'Value should be either "horizontal" or "vertical". ' +
696
- `"${layout}" was specified.`
697
- );
698
- }
699
-
700
- if (children == null) {
701
- throw Error(
702
- 'An invalid "children" prop has been specified. ' +
703
- 'Value should be a React component. ' +
704
- `"${children === null ? 'null' : typeof children}" was specified.`
705
- );
706
- }
707
-
708
- if (isHorizontal && typeof width !== 'number') {
709
- throw Error(
710
- 'An invalid "width" prop has been specified. ' +
711
- 'Horizontal lists must specify a number for width. ' +
712
- `"${width === null ? 'null' : typeof width}" was specified.`
713
- );
714
- } else if (!isHorizontal && typeof height !== 'number') {
715
- throw Error(
716
- 'An invalid "height" prop has been specified. ' +
717
- 'Vertical lists must specify a number for height. ' +
718
- `"${height === null ? 'null' : typeof height}" was specified.`
719
- );
720
- }
721
- }
722
-};
packages/react-devtools-shared/src/node_modules/react-window/src/domHelpers.js
deleted
-72
@@ -1,72 +0,0 @@
1
-// @flow
2
-
3
-let size: number = -1;
4
-
5
-// This utility copied from "dom-helpers" package.
6
-export function getScrollbarSize(recalculate?: boolean = false): number {
7
- if (size === -1 || recalculate) {
8
- const div = document.createElement('div');
9
- const style = div.style;
10
- style.width = '50px';
11
- style.height = '50px';
12
- style.overflow = 'scroll';
13
-
14
- ((document.body: any): HTMLBodyElement).appendChild(div);
15
-
16
- size = div.offsetWidth - div.clientWidth;
17
-
18
- ((document.body: any): HTMLBodyElement).removeChild(div);
19
- }
20
-
21
- return size;
22
-}
23
-
24
-export type RTLOffsetType =
25
- | 'negative'
26
- | 'positive-descending'
27
- | 'positive-ascending';
28
-
29
-let cachedRTLResult: RTLOffsetType | null = null;
30
-
31
-// TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
32
-// Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
33
-// Safari's elastic bounce makes detecting this even more complicated wrt potential false positives.
34
-// The safest way to check this is to intentionally set a negative offset,
35
-// and then verify that the subsequent "scroll" event matches the negative offset.
36
-// If it does not match, then we can assume a non-standard RTL scroll implementation.
37
-export function getRTLOffsetType(recalculate?: boolean = false): RTLOffsetType {
38
- if (cachedRTLResult === null || recalculate) {
39
- const outerDiv = document.createElement('div');
40
- const outerStyle = outerDiv.style;
41
- outerStyle.width = '50px';
42
- outerStyle.height = '50px';
43
- outerStyle.overflow = 'scroll';
44
- outerStyle.direction = 'rtl';
45
-
46
- const innerDiv = document.createElement('div');
47
- const innerStyle = innerDiv.style;
48
- innerStyle.width = '100px';
49
- innerStyle.height = '100px';
50
-
51
- outerDiv.appendChild(innerDiv);
52
-
53
- ((document.body: any): HTMLBodyElement).appendChild(outerDiv);
54
-
55
- if (outerDiv.scrollLeft > 0) {
56
- cachedRTLResult = 'positive-descending';
57
- } else {
58
- outerDiv.scrollLeft = 1;
59
- if (outerDiv.scrollLeft === 0) {
60
- cachedRTLResult = 'negative';
61
- } else {
62
- cachedRTLResult = 'positive-ascending';
63
- }
64
- }
65
-
66
- ((document.body: any): HTMLBodyElement).removeChild(outerDiv);
67
-
68
- return cachedRTLResult;
69
- }
70
-
71
- return cachedRTLResult;
72
-}
packages/react-devtools-shared/src/node_modules/react-window/src/index.js
deleted
-9
@@ -1,9 +0,0 @@
1
-// @flow
2
-
3
-export { default as VariableSizeGrid } from './VariableSizeGrid';
4
-export { default as VariableSizeList } from './VariableSizeList';
5
-export { default as FixedSizeGrid } from './FixedSizeGrid';
6
-export { default as FixedSizeList } from './FixedSizeList';
7
-
8
-export { default as areEqual } from './areEqual';
9
-export { default as shouldComponentUpdate } from './shouldComponentUpdate';
packages/react-devtools-shared/src/node_modules/react-window/src/shallowDiffers.js
deleted
-17
@@ -1,17 +0,0 @@
1
-// @flow
2
-
3
-// Pulled from react-compat
4
-// https://github.com/developit/preact-compat/blob/7c5de00e7c85e2ffd011bf3af02899b63f699d3a/src/index.js#L349
5
-export default function shallowDiffers(prev: Object, next: Object): boolean {
6
- for (let attribute in prev) {
7
- if (!(attribute in next)) {
8
- return true;
9
- }
10
- }
11
- for (let attribute in next) {
12
- if (prev[attribute] !== next[attribute]) {
13
- return true;
14
- }
15
- }
16
- return false;
17
-}
packages/react-devtools-shared/src/node_modules/react-window/src/shouldComponentUpdate.js
deleted
-16
@@ -1,16 +0,0 @@
1
-// @flow
2
-
3
-import areEqual from './areEqual';
4
-import shallowDiffers from './shallowDiffers';
5
-
6
-// Custom shouldComponentUpdate for class components.
7
-// It knows to compare individual style props and ignore the wrapper object.
8
-// See https://reactjs.org/docs/react-component.html#shouldcomponentupdate
9
-export default function shouldComponentUpdate(
10
- nextProps: Object,
11
- nextState: Object
12
-): boolean {
13
- return (
14
- !areEqual(this.props, nextProps) || shallowDiffers(this.state, nextState)
15
- );
16
-}
packages/react-devtools-shared/src/node_modules/react-window/src/timer.js
deleted
-37
@@ -1,37 +0,0 @@
1
-// @flow
2
-
3
-// Animation frame based implementation of setTimeout.
4
-// Inspired by Joe Lambert, https://gist.github.com/joelambert/1002116#file-requesttimeout-js
5
-
6
-const hasNativePerformanceNow =
7
- typeof performance === 'object' && typeof performance.now === 'function';
8
-
9
-const now = hasNativePerformanceNow
10
- ? () => performance.now()
11
- : () => Date.now();
12
-
13
-export type TimeoutID = {|
14
- id: AnimationFrameID,
15
-|};
16
-
17
-export function cancelTimeout(timeoutID: TimeoutID) {
18
- cancelAnimationFrame(timeoutID.id);
19
-}
20
-
21
-export function requestTimeout(callback: Function, delay: number): TimeoutID {
22
- const start = now();
23
-
24
- function tick() {
25
- if (now() - start >= delay) {
26
- callback.call(null);
27
- } else {
28
- timeoutID.id = requestAnimationFrame(tick);
29
- }
30
- }
31
-
32
- const timeoutID: TimeoutID = {
33
- id: requestAnimationFrame(tick),
34
- };
35
-
36
- return timeoutID;
37
-}
packages/react-devtools-shared/src/storage.js
deleted
-48
@@ -1,48 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-export function localStorageGetItem(key: string): any {
11
- try {
12
- return localStorage.getItem(key);
13
- } catch (error) {
14
- return null;
15
- }
16
-}
17
-
18
-export function localStorageRemoveItem(key: string): void {
19
- try {
20
- localStorage.removeItem(key);
21
- } catch (error) {}
22
-}
23
-
24
-export function localStorageSetItem(key: string, value: any): void {
25
- try {
26
- return localStorage.setItem(key, value);
27
- } catch (error) {}
28
-}
29
-
30
-export function sessionStorageGetItem(key: string): any {
31
- try {
32
- return sessionStorage.getItem(key);
33
- } catch (error) {
34
- return null;
35
- }
36
-}
37
-
38
-export function sessionStorageRemoveItem(key: string): void {
39
- try {
40
- sessionStorage.removeItem(key);
41
- } catch (error) {}
42
-}
43
-
44
-export function sessionStorageSetItem(key: string, value: any): void {
45
- try {
46
- return sessionStorage.setItem(key, value);
47
- } catch (error) {}
48
-}
packages/react-devtools-shared/src/types.js
deleted
-77
@@ -1,77 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-export type Wall = {|
11
- // `listen` returns the "unlisten" function.
12
- listen: (fn: Function) => Function,
13
- send: (event: string, payload: any, transferable?: Array<any>) => void,
14
-|};
15
-
16
-// WARNING
17
-// The values below are referenced by ComponentFilters (which are saved via localStorage).
18
-// Do not change them or it will break previously saved user customizations.
19
-// If new element types are added, use new numbers rather than re-ordering existing ones.
20
-//
21
-// Changing these types is also a backwards breaking change for the standalone shell,
22
-// since the frontend and backend must share the same values-
23
-// and the backend is embedded in certain environments (like React Native).
24
-export const ElementTypeClass = 1;
25
-export const ElementTypeContext = 2;
26
-export const ElementTypeFunction = 5;
27
-export const ElementTypeForwardRef = 6;
28
-export const ElementTypeHostComponent = 7;
29
-export const ElementTypeMemo = 8;
30
-export const ElementTypeOtherOrUnknown = 9;
31
-export const ElementTypeProfiler = 10;
32
-export const ElementTypeRoot = 11;
33
-export const ElementTypeSuspense = 12;
34
-
35
-// Different types of elements displayed in the Elements tree.
36
-// These types may be used to visually distinguish types,
37
-// or to enable/disable certain functionality.
38
-export type ElementType = 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
39
-
40
-// WARNING
41
-// The values below are referenced by ComponentFilters (which are saved via localStorage).
42
-// Do not change them or it will break previously saved user customizations.
43
-// If new filter types are added, use new numbers rather than re-ordering existing ones.
44
-export const ComponentFilterElementType = 1;
45
-export const ComponentFilterDisplayName = 2;
46
-export const ComponentFilterLocation = 3;
47
-export const ComponentFilterHOC = 4;
48
-
49
-export type ComponentFilterType = 1 | 2 | 3 | 4;
50
-
51
-// Hide all elements of types in this Set.
52
-// We hide host components only by default.
53
-export type ElementTypeComponentFilter = {|
54
- isEnabled: boolean,
55
- type: 1,
56
- value: ElementType,
57
-|};
58
-
59
-// Hide all elements with displayNames or paths matching one or more of the RegExps in this Set.
60
-// Path filters are only used when elements include debug source location.
61
-export type RegExpComponentFilter = {|
62
- isEnabled: boolean,
63
- isValid: boolean,
64
- type: 2 | 3,
65
- value: string,
66
-|};
67
-
68
-export type BooleanComponentFilter = {|
69
- isEnabled: boolean,
70
- isValid: boolean,
71
- type: 4,
72
-|};
73
-
74
-export type ComponentFilter =
75
- | BooleanComponentFilter
76
- | ElementTypeComponentFilter
77
- | RegExpComponentFilter;
packages/react-devtools-shared/src/utils.js
deleted
-309
@@ -1,309 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import Symbol from 'es6-symbol';
11
-import LRU from 'lru-cache';
12
-import {
13
- TREE_OPERATION_ADD,
14
- TREE_OPERATION_REMOVE,
15
- TREE_OPERATION_REORDER_CHILDREN,
16
- TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
17
-} from './constants';
18
-import {ElementTypeRoot} from 'react-devtools-shared/src/types';
19
-import {
20
- LOCAL_STORAGE_FILTER_PREFERENCES_KEY,
21
- LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY,
22
-} from './constants';
23
-import {ComponentFilterElementType, ElementTypeHostComponent} from './types';
24
-import {
25
- ElementTypeClass,
26
- ElementTypeForwardRef,
27
- ElementTypeFunction,
28
- ElementTypeMemo,
29
-} from 'react-devtools-shared/src/types';
30
-import {localStorageGetItem, localStorageSetItem} from './storage';
31
-
32
-import type {ComponentFilter, ElementType} from './types';
33
-
34
-const cachedDisplayNames: WeakMap<Function, string> = new WeakMap();
35
-
36
-// On large trees, encoding takes significant time.
37
-// Try to reuse the already encoded strings.
38
-let encodedStringCache = new LRU({max: 1000});
39
-
40
-export function getDisplayName(
41
- type: Function,
42
- fallbackName: string = 'Anonymous',
43
-): string {
44
- const nameFromCache = cachedDisplayNames.get(type);
45
- if (nameFromCache != null) {
46
- return nameFromCache;
47
- }
48
-
49
- let displayName;
50
-
51
- // The displayName property is not guaranteed to be a string.
52
- // It's only safe to use for our purposes if it's a string.
53
- // github.com/facebook/react-devtools/issues/803
54
- if (typeof type.displayName === 'string') {
55
- displayName = type.displayName;
56
- }
57
-
58
- if (!displayName) {
59
- displayName = type.name || fallbackName;
60
- }
61
-
62
- cachedDisplayNames.set(type, displayName);
63
- return displayName;
64
-}
65
-
66
-let uidCounter: number = 0;
67
-
68
-export function getUID(): number {
69
- return ++uidCounter;
70
-}
71
-
72
-export function utfDecodeString(array: Array<number>): string {
73
- return String.fromCodePoint(...array);
74
-}
75
-
76
-export function utfEncodeString(string: string): Array<number> {
77
- let cached = encodedStringCache.get(string);
78
- if (cached !== undefined) {
79
- return cached;
80
- }
81
-
82
- const encoded = new Array(string.length);
83
- for (let i = 0; i < string.length; i++) {
84
- encoded[i] = string.codePointAt(i);
85
- }
86
- encodedStringCache.set(string, encoded);
87
- return encoded;
88
-}
89
-
90
-export function printOperationsArray(operations: Array<number>) {
91
- // The first two values are always rendererID and rootID
92
- const rendererID = operations[0];
93
- const rootID = operations[1];
94
-
95
- const logs = [`opertions for renderer:${rendererID} and root:${rootID}`];
96
-
97
- let i = 2;
98
-
99
- // Reassemble the string table.
100
- const stringTable = [
101
- null, // ID = 0 corresponds to the null string.
102
- ];
103
- const stringTableSize = operations[i++];
104
- const stringTableEnd = i + stringTableSize;
105
- while (i < stringTableEnd) {
106
- const nextLength = operations[i++];
107
- const nextString = utfDecodeString(
108
- (operations.slice(i, i + nextLength): any),
109
- );
110
- stringTable.push(nextString);
111
- i += nextLength;
112
- }
113
-
114
- while (i < operations.length) {
115
- const operation = operations[i];
116
-
117
- switch (operation) {
118
- case TREE_OPERATION_ADD: {
119
- const id = ((operations[i + 1]: any): number);
120
- const type = ((operations[i + 2]: any): ElementType);
121
-
122
- i += 3;
123
-
124
- if (type === ElementTypeRoot) {
125
- logs.push(`Add new root node ${id}`);
126
-
127
- i++; // supportsProfiling
128
- i++; // hasOwnerMetadata
129
- } else {
130
- const parentID = ((operations[i]: any): number);
131
- i++;
132
-
133
- i++; // ownerID
134
-
135
- const displayNameStringID = operations[i];
136
- const displayName = stringTable[displayNameStringID];
137
- i++;
138
-
139
- i++; // key
140
-
141
- logs.push(
142
- `Add node ${id} (${displayName || 'null'}) as child of ${parentID}`,
143
- );
144
- }
145
- break;
146
- }
147
- case TREE_OPERATION_REMOVE: {
148
- const removeLength = ((operations[i + 1]: any): number);
149
- i += 2;
150
-
151
- for (let removeIndex = 0; removeIndex < removeLength; removeIndex++) {
152
- const id = ((operations[i]: any): number);
153
- i += 1;
154
-
155
- logs.push(`Remove node ${id}`);
156
- }
157
- break;
158
- }
159
- case TREE_OPERATION_REORDER_CHILDREN: {
160
- const id = ((operations[i + 1]: any): number);
161
- const numChildren = ((operations[i + 2]: any): number);
162
- i += 3;
163
- const children = operations.slice(i, i + numChildren);
164
- i += numChildren;
165
-
166
- logs.push(`Re-order node ${id} children ${children.join(',')}`);
167
- break;
168
- }
169
- case TREE_OPERATION_UPDATE_TREE_BASE_DURATION:
170
- // Base duration updates are only sent while profiling is in progress.
171
- // We can ignore them at this point.
172
- // The profiler UI uses them lazily in order to generate the tree.
173
- i += 3;
174
- break;
175
- default:
176
- throw Error(`Unsupported Bridge operation ${operation}`);
177
- }
178
- }
179
-
180
- console.log(logs.join('\n '));
181
-}
182
-
183
-export function getDefaultComponentFilters(): Array<ComponentFilter> {
184
- return [
185
- {
186
- type: ComponentFilterElementType,
187
- value: ElementTypeHostComponent,
188
- isEnabled: true,
189
- },
190
- ];
191
-}
192
-
193
-export function getSavedComponentFilters(): Array<ComponentFilter> {
194
- try {
195
- const raw = localStorageGetItem(LOCAL_STORAGE_FILTER_PREFERENCES_KEY);
196
- if (raw != null) {
197
- return JSON.parse(raw);
198
- }
199
- } catch (error) {}
200
- return getDefaultComponentFilters();
201
-}
202
-
203
-export function saveComponentFilters(
204
- componentFilters: Array<ComponentFilter>,
205
-): void {
206
- localStorageSetItem(
207
- LOCAL_STORAGE_FILTER_PREFERENCES_KEY,
208
- JSON.stringify(componentFilters),
209
- );
210
-}
211
-
212
-export function getAppendComponentStack(): boolean {
213
- try {
214
- const raw = localStorageGetItem(LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY);
215
- if (raw != null) {
216
- return JSON.parse(raw);
217
- }
218
- } catch (error) {}
219
- return true;
220
-}
221
-
222
-export function setAppendComponentStack(value: boolean): void {
223
- localStorageSetItem(
224
- LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY,
225
- JSON.stringify(value),
226
- );
227
-}
228
-
229
-export function separateDisplayNameAndHOCs(
230
- displayName: string | null,
231
- type: ElementType,
232
-): [string | null, Array<string> | null] {
233
- if (displayName === null) {
234
- return [null, null];
235
- }
236
-
237
- let hocDisplayNames = null;
238
-
239
- switch (type) {
240
- case ElementTypeClass:
241
- case ElementTypeForwardRef:
242
- case ElementTypeFunction:
243
- case ElementTypeMemo:
244
- if (displayName.indexOf('(') >= 0) {
245
- const matches = displayName.match(/[^()]+/g);
246
- if (matches != null) {
247
- displayName = matches.pop();
248
- hocDisplayNames = matches;
249
- }
250
- }
251
- break;
252
- default:
253
- break;
254
- }
255
-
256
- return [displayName, hocDisplayNames];
257
-}
258
-
259
-// Pulled from react-compat
260
-// https://github.com/developit/preact-compat/blob/7c5de00e7c85e2ffd011bf3af02899b63f699d3a/src/index.js#L349
261
-export function shallowDiffers(prev: Object, next: Object): boolean {
262
- for (let attribute in prev) {
263
- if (!(attribute in next)) {
264
- return true;
265
- }
266
- }
267
- for (let attribute in next) {
268
- if (prev[attribute] !== next[attribute]) {
269
- return true;
270
- }
271
- }
272
- return false;
273
-}
274
-
275
-export function getInObject(object: Object, path: Array<string | number>): any {
276
- return path.reduce((reduced: Object, attr: any): any => {
277
- if (reduced) {
278
- if (hasOwnProperty.call(reduced, attr)) {
279
- return reduced[attr];
280
- }
281
- if (typeof reduced[Symbol.iterator] === 'function') {
282
- // Convert iterable to array and return array[index]
283
- //
284
- // TRICKY
285
- // Don't use [...spread] syntax for this purpose.
286
- // This project uses @babel/plugin-transform-spread in "loose" mode which only works with Array values.
287
- // Other types (e.g. typed arrays, Sets) will not spread correctly.
288
- return Array.from(reduced)[attr];
289
- }
290
- }
291
-
292
- return null;
293
- }, object);
294
-}
295
-
296
-export function setInObject(
297
- object: Object,
298
- path: Array<string | number>,
299
- value: any,
300
-) {
301
- const length = path.length;
302
- const last = path[length - 1];
303
- if (object != null) {
304
- const parent = getInObject(object, path.slice(0, length - 1));
305
- if (parent) {
306
- parent[last] = value;
307
- }
308
- }
309
-}
packages/react-devtools-shell/README.md
deleted
-17
@@ -1,17 +0,0 @@
1
-Harness for testing local changes to the `react-devtools-inline` and `react-devtools-shared` packages.
2
-
3
-## Development
4
-
5
-This target should be run in parallel with the `react-devtools-inline` package. The first step then is to watch for changes to that target:
6
-```sh
7
-cd packages/react-devtools-inline
8
-
9
-yarn start
10
-```
11
-
12
-Next, watch for changes to the test harness:
13
-```sh
14
-cd packages/react-devtools-shell
15
-
16
-yarn start
17
-```
packages/react-devtools-shell/index.html
deleted
-68
@@ -1,68 +0,0 @@
1
-<!doctype html>
2
-<html>
3
- <head>
4
- <meta charset="utf8">
5
- <title>React DevTools</title>
6
- <meta name="viewport" content="width=device-width, initial-scale=1">
7
- <style>
8
- #target {
9
- flex: 1;
10
- border: none;
11
- }
12
- #devtools {
13
- height: 400px;
14
- max-height: 50%;
15
- overflow: hidden;
16
- z-index: 10000001;
17
- }
18
- body {
19
- display: flex;
20
- flex-direction: column;
21
- position: absolute;
22
- top: 0;
23
- left: 0;
24
- right: 0;
25
- bottom: 0;
26
- margin: 0;
27
- padding: 0;
28
- font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
29
- sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
30
- font-size: 12px;
31
- line-height: 1.5;
32
- }
33
- .optionsRow {
34
- width: 100%;
35
- display: flex;
36
- padding: 0.25rem;
37
- background: aliceblue;
38
- border-bottom: 1px solid lightblue;
39
- }
40
- .optionsRowSpacer {
41
- flex: 1;
42
- }
43
- </style>
44
- </head>
45
- <body>
46
- <div class="optionsRow">
47
- <button id="mountButton">Unmount test app</button>
48
- <div class="optionsRowSpacer"> </div>
49
- <span>
50
- <a href="https://react-devtools-experimental-chrome.now.sh/">Chrome extension</a>
51
- <a href="https://react-devtools-experimental-firefox.now.sh/">Firefox extension</a>
52
- </span>
53
- </div>
54
-
55
- <!-- React test app (shells/dev/app) is injected here -->
56
- <!-- DevTools backend (shells/dev/src) is injected here -->
57
- <!-- global "hook" is defined on the iframe's contentWindow -->
58
- <iframe id="target"></iframe>
59
-
60
- <!-- DevTools frontend UI (shells/dev/src) renders here -->
61
- <div id="devtools"></div>
62
-
63
- <!-- This script installs the hook, injects the backend, and renders the DevTools UI -->
64
- <!-- In DEV mode, this file is served by the Webpack dev server -->
65
- <!-- For production builds, it's built by Webpack and uploaded from the local file system -->
66
- <script src="dist/devtools.js"></script>
67
- </body>
68
-</html>
\ No newline at end of file
packages/react-devtools-shell/now.json
deleted
-5
@@ -1,5 +0,0 @@
1
-{
2
- "name": "react-devtools-experimental",
3
- "alias": ["react-devtools-experimental"],
4
- "files": ["index.html", "dist"]
5
-}
packages/react-devtools-shell/package.json
deleted
-34
@@ -1,34 +0,0 @@
1
-{
2
- "private": true,
3
- "name": "react-devtools-shell",
4
- "version": "0.0.0",
5
- "scripts": {
6
- "build": "cross-env NODE_ENV=development cross-env TARGET=remote webpack --config webpack.config.js",
7
- "deploy": "yarn run build && now deploy && now alias react-devtools-experimental",
8
- "start": "cross-env NODE_ENV=development cross-env TARGET=local webpack-dev-server --open"
9
- },
10
- "dependencies": {
11
- "immutable": "^4.0.0-rc.12",
12
- "react-native-web": "^0.11.5"
13
- },
14
- "devDependencies": {
15
- "@babel/core": "^7.1.6",
16
- "@babel/plugin-proposal-class-properties": "^7.1.0",
17
- "@babel/plugin-transform-flow-strip-types": "^7.1.6",
18
- "@babel/plugin-transform-react-jsx-source": "^7.2.0",
19
- "@babel/preset-env": "^7.1.6",
20
- "@babel/preset-flow": "^7.0.0",
21
- "@babel/preset-react": "^7.0.0",
22
- "babel-core": "^7.0.0-bridge",
23
- "babel-eslint": "^9.0.0",
24
- "babel-jest": "^24.7.1",
25
- "babel-loader": "^8.0.4",
26
- "cross-env": "^3.1.4",
27
- "css-loader": "^1.0.1",
28
- "raw-loader": "^3.1.0",
29
- "style-loader": "^0.23.1",
30
- "webpack": "^4.26.0",
31
- "webpack-cli": "^3.1.2",
32
- "webpack-dev-server": "^3.3.1"
33
- }
34
-}
packages/react-devtools-shell/src/app/DeeplyNestedComponents/index.js
deleted
-45
@@ -1,45 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment} from 'react';
11
-
12
-function wrapWithHoc(Component, index) {
13
- function HOC() {
14
- return <Component />;
15
- }
16
-
17
- // $FlowFixMe
18
- const displayName = Component.displayName || Component.name;
19
-
20
- HOC.displayName = `withHoc${index}(${displayName})`;
21
- return HOC;
22
-}
23
-
24
-function wrapWithNested(Component, times) {
25
- for (let i = 0; i < times; i++) {
26
- Component = wrapWithHoc(Component, i);
27
- }
28
-
29
- return Component;
30
-}
31
-
32
-function Nested() {
33
- return <div>Deeply nested div</div>;
34
-}
35
-
36
-const DeeplyNested = wrapWithNested(Nested, 100);
37
-
38
-export default function DeeplyNestedComponents() {
39
- return (
40
- <Fragment>
41
- <h1>Deeply nested component</h1>
42
- <DeeplyNested />
43
- </Fragment>
44
- );
45
-}
packages/react-devtools-shell/src/app/EditableProps/index.js
deleted
-169
@@ -1,169 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- createContext,
12
- Component,
13
- forwardRef,
14
- Fragment,
15
- memo,
16
- useCallback,
17
- useDebugValue,
18
- useEffect,
19
- useReducer,
20
- useState,
21
-} from 'react';
22
-
23
-const initialData = {foo: 'FOO', bar: 'BAR'};
24
-
25
-function reducer(state, action) {
26
- switch (action.type) {
27
- case 'swap':
28
- return {foo: state.bar, bar: state.foo};
29
- default:
30
- throw new Error();
31
- }
32
-}
33
-
34
-type StatefulFunctionProps = {|name: string|};
35
-
36
-function StatefulFunction({name}: StatefulFunctionProps) {
37
- const [count, updateCount] = useState(0);
38
- const debouncedCount = useDebounce(count, 1000);
39
- const handleUpdateCountClick = useCallback(() => updateCount(count + 1), [
40
- count,
41
- ]);
42
-
43
- const [data, dispatch] = useReducer(reducer, initialData);
44
- const handleUpdateReducerClick = useCallback(
45
- () => dispatch({type: 'swap'}),
46
- [],
47
- );
48
-
49
- return (
50
- <ul>
51
- <li>Name: {name}</li>
52
- <li>
53
- <button onClick={handleUpdateCountClick}>
54
- Debounced count: {debouncedCount}
55
- </button>
56
- </li>
57
- <li>
58
- Reducer state: foo "{data.foo}", bar "{data.bar}"
59
- </li>
60
- <li>
61
- <button onClick={handleUpdateReducerClick}>Swap reducer values</button>
62
- </li>
63
- </ul>
64
- );
65
-}
66
-
67
-const BoolContext = createContext(true);
68
-BoolContext.displayName = 'BoolContext';
69
-
70
-type Props = {|name: string, toggle: boolean|};
71
-type State = {|cities: Array<string>, state: string|};
72
-
73
-class StatefulClass extends Component<Props, State> {
74
- static contextType = BoolContext;
75
-
76
- state: State = {
77
- cities: ['San Francisco', 'San Jose'],
78
- state: 'California',
79
- };
80
-
81
- handleChange = ({target}) =>
82
- this.setState({
83
- state: target.value,
84
- });
85
-
86
- render() {
87
- return (
88
- <ul>
89
- <li>Name: {this.props.name}</li>
90
- <li>Toggle: {this.props.toggle ? 'true' : 'false'}</li>
91
- <li>
92
- State: <input value={this.state.state} onChange={this.handleChange} />
93
- </li>
94
- <li>Cities: {this.state.cities.join(', ')}</li>
95
- <li>Context: {this.context ? 'true' : 'false'}</li>
96
- </ul>
97
- );
98
- }
99
-}
100
-
101
-const MemoizedStatefulClass = memo(StatefulClass);
102
-const MemoizedStatefulFunction = memo(StatefulFunction);
103
-
104
-const ForwardRef = forwardRef<{|name: string|}, HTMLUListElement>(
105
- ({name}, ref) => {
106
- const [count, updateCount] = useState(0);
107
- const debouncedCount = useDebounce(count, 1000);
108
- const handleUpdateCountClick = useCallback(() => updateCount(count + 1), [
109
- count,
110
- ]);
111
- return (
112
- <ul ref={ref}>
113
- <li>Name: {name}</li>
114
- <li>
115
- <button onClick={handleUpdateCountClick}>
116
- Debounced count: {debouncedCount}
117
- </button>
118
- </li>
119
- </ul>
120
- );
121
- },
122
-);
123
-
124
-export default function EditableProps() {
125
- return (
126
- <Fragment>
127
- <h1>Editable props</h1>
128
- <strong>Class</strong>
129
- <StatefulClass name="Brian" toggle={true} />
130
- <strong>Function</strong>
131
- <StatefulFunction name="Brian" />
132
- <strong>Memoized Class</strong>
133
- <MemoizedStatefulClass name="Brian" toggle={true} />
134
- <strong>Memoized Function</strong>
135
- <MemoizedStatefulFunction name="Brian" />
136
- <strong>Forward Ref</strong>
137
- <ForwardRef name="Brian" />
138
- </Fragment>
139
- );
140
-}
141
-
142
-// Below copied from https://usehooks.com/
143
-function useDebounce(value, delay) {
144
- // State and setters for debounced value
145
- const [debouncedValue, setDebouncedValue] = useState(value);
146
-
147
- // Show the value in DevTools
148
- useDebugValue(debouncedValue);
149
-
150
- useEffect(
151
- () => {
152
- // Update debounced value after delay
153
- const handler = setTimeout(() => {
154
- setDebouncedValue(value);
155
- }, delay);
156
-
157
- // Cancel the timeout if value changes (also on delay change or unmount)
158
- // This is how we prevent debounced value from updating if value is changed ...
159
- // .. within the delay period. Timeout gets cleared and restarted.
160
- return () => {
161
- clearTimeout(handler);
162
- };
163
- },
164
- [value, delay], // Only re-call effect if value or delay changes
165
- );
166
-
167
- return debouncedValue;
168
-}
169
-// Above copied from https://usehooks.com/
packages/react-devtools-shell/src/app/ElementTypes/index.js
deleted
-67
@@ -1,67 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- createContext,
12
- forwardRef,
13
- lazy,
14
- memo,
15
- Component,
16
- Fragment,
17
- // $FlowFixMe Flow doesn't know about the Profiler import yet
18
- Profiler,
19
- StrictMode,
20
- Suspense,
21
-} from 'react';
22
-
23
-const Context = createContext('abc');
24
-Context.displayName = 'ExampleContext';
25
-
26
-class ClassComponent extends Component<any> {
27
- render() {
28
- return null;
29
- }
30
-}
31
-
32
-function FunctionComponent() {
33
- return null;
34
-}
35
-
36
-const MemoFunctionComponent = memo(FunctionComponent);
37
-
38
-const ForwardRefComponent = forwardRef((props, ref) => (
39
- <ClassComponent ref={ref} {...props} />
40
-));
41
-
42
-const LazyComponent = lazy(() =>
43
- Promise.resolve({
44
- default: FunctionComponent,
45
- }),
46
-);
47
-
48
-export default function ElementTypes() {
49
- return (
50
- <Profiler id="test" onRender={() => {}}>
51
- <Fragment>
52
- <Context.Provider value={'def'}>
53
- <Context.Consumer>{value => null}</Context.Consumer>
54
- </Context.Provider>
55
- <StrictMode>
56
- <Suspense fallback={<div>Loading...</div>}>
57
- <ClassComponent />
58
- <FunctionComponent />
59
- <MemoFunctionComponent />
60
- <ForwardRefComponent />
61
- <LazyComponent />
62
- </Suspense>
63
- </StrictMode>
64
- </Fragment>
65
- </Profiler>
66
- );
67
-}
packages/react-devtools-shell/src/app/Hydration/index.js
deleted
-140
@@ -1,140 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useDebugValue, useState} from 'react';
11
-
12
-const div = document.createElement('div');
13
-const exmapleFunction = () => {};
14
-const typedArray = new Uint8Array(3);
15
-typedArray[0] = 1;
16
-typedArray[1] = 2;
17
-typedArray[2] = 3;
18
-
19
-const arrayOfArrays = [
20
- [['a', 'b', 'c'], ['d', 'e', 'f'], ['h', 'i', 'j']],
21
- [['k', 'l', 'm'], ['n', 'o', 'p'], ['q', 'r', 's']],
22
- [['t', 'u', 'v'], ['w', 'x', 'y'], ['z']],
23
- [],
24
-];
25
-
26
-const objectOfObjects = {
27
- foo: {
28
- a: 1,
29
- b: 2,
30
- c: 3,
31
- },
32
- bar: {
33
- e: 4,
34
- f: 5,
35
- g: 6,
36
- },
37
- baz: {
38
- h: 7,
39
- i: 8,
40
- j: 9,
41
- },
42
- qux: {},
43
-};
44
-
45
-function useOuterFoo() {
46
- useDebugValue({
47
- debugA: {
48
- debugB: {
49
- debugC: 'abc',
50
- },
51
- },
52
- });
53
- useState({
54
- valueA: {
55
- valueB: {
56
- valueC: 'abc',
57
- },
58
- },
59
- });
60
- return useInnerFoo();
61
-}
62
-
63
-function useInnerFoo() {
64
- const [value] = useState([[['a', 'b', 'c']]]);
65
- return value;
66
-}
67
-
68
-function useOuterBar() {
69
- useDebugValue({
70
- debugA: {
71
- debugB: {
72
- debugC: 'abc',
73
- },
74
- },
75
- });
76
- return useInnerBar();
77
-}
78
-
79
-function useInnerBar() {
80
- useDebugValue({
81
- debugA: {
82
- debugB: {
83
- debugC: 'abc',
84
- },
85
- },
86
- });
87
- const [count] = useState(123);
88
- return count;
89
-}
90
-
91
-function useOuterBaz() {
92
- return useInnerBaz();
93
-}
94
-
95
-function useInnerBaz() {
96
- const [count] = useState(123);
97
- return count;
98
-}
99
-
100
-export default function Hydration() {
101
- return (
102
- <Fragment>
103
- <h1>Hydration</h1>
104
- <DehydratableProps
105
- html_element={div}
106
- fn={exmapleFunction}
107
- symbol={Symbol('symbol')}
108
- react_element={<span />}
109
- array_buffer={typedArray.buffer}
110
- typed_array={typedArray}
111
- date={new Date()}
112
- array={arrayOfArrays}
113
- object={objectOfObjects}
114
- />
115
- <DeepHooks />
116
- </Fragment>
117
- );
118
-}
119
-
120
-function DehydratableProps({array, object}: any) {
121
- return (
122
- <ul>
123
- <li>array: {JSON.stringify(array, null, 2)}</li>
124
- <li>object: {JSON.stringify(object, null, 2)}</li>
125
- </ul>
126
- );
127
-}
128
-
129
-function DeepHooks(props: any) {
130
- const foo = useOuterFoo();
131
- const bar = useOuterBar();
132
- const baz = useOuterBaz();
133
- return (
134
- <ul>
135
- <li>foo: {foo}</li>
136
- <li>bar: {bar}</li>
137
- <li>baz: {baz}</li>
138
- </ul>
139
- );
140
-}
packages/react-devtools-shell/src/app/Iframe/index.js
deleted
-69
@@ -1,69 +0,0 @@
1
-/** @flow */
2
-
3
-import React, {Fragment} from 'react';
4
-import ReactDOM from 'react-dom';
5
-
6
-export default function Iframe() {
7
- return (
8
- <Fragment>
9
- <h2>Iframe</h2>
10
- <div>
11
- <Frame>
12
- <Greeting />
13
- </Frame>
14
- </div>
15
- </Fragment>
16
- );
17
-}
18
-
19
-const iframeStyle = {border: '2px solid #eee', height: 80};
20
-
21
-function Frame(props) {
22
- const [element, setElement] = React.useState(null);
23
-
24
- const ref = React.useRef();
25
-
26
- React.useLayoutEffect(function() {
27
- const iframe = ref.current;
28
-
29
- if (iframe) {
30
- const html = `
31
- <!DOCTYPE html>
32
- <html>
33
- <body>
34
- <div id="root"></div>
35
- </body>
36
- </html>
37
- `;
38
-
39
- const document = iframe.contentDocument;
40
-
41
- document.open();
42
- document.write(html);
43
- document.close();
44
-
45
- setElement(document.getElementById('root'));
46
- }
47
- }, []);
48
-
49
- return (
50
- <Fragment>
51
- <iframe title="Test Iframe" ref={ref} style={iframeStyle} />
52
- <iframe
53
- title="Secured Iframe"
54
- src="https://example.com"
55
- style={iframeStyle}
56
- />
57
-
58
- {element ? ReactDOM.createPortal(props.children, element) : null}
59
- </Fragment>
60
- );
61
-}
62
-
63
-function Greeting() {
64
- return (
65
- <p>
66
- Hello from within an <code><iframe></code>!
67
- </p>
68
- );
69
-}
packages/react-devtools-shell/src/app/InspectableElements/Contexts.js
deleted
-120
@@ -1,120 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {createContext, Component, Fragment, useContext} from 'react';
11
-import PropTypes from 'prop-types';
12
-
13
-function someNamedFunction() {}
14
-
15
-const contextData = {
16
- array: ['first', 'second', 'third'],
17
- bool: true,
18
- func: someNamedFunction,
19
- number: 123,
20
- object: {outer: {inner: {}}},
21
- string: 'abc',
22
- symbol: Symbol.for('symbol'),
23
- null: null,
24
- undefined: undefined,
25
-};
26
-
27
-class LegacyContextProvider extends Component<any> {
28
- static childContextTypes = {
29
- array: PropTypes.array,
30
- bool: PropTypes.bool,
31
- func: PropTypes.func,
32
- number: PropTypes.number,
33
- object: PropTypes.object,
34
- string: PropTypes.string,
35
- symbol: PropTypes.symbol,
36
- null: PropTypes.any,
37
- undefined: PropTypes.any,
38
- };
39
-
40
- getChildContext() {
41
- return contextData;
42
- }
43
-
44
- render() {
45
- return this.props.children;
46
- }
47
-}
48
-
49
-class LegacyContextConsumer extends Component<any> {
50
- static contextTypes = {
51
- array: PropTypes.array,
52
- bool: PropTypes.bool,
53
- func: PropTypes.func,
54
- number: PropTypes.number,
55
- object: PropTypes.object,
56
- string: PropTypes.string,
57
- symbol: PropTypes.symbol,
58
- null: PropTypes.any,
59
- undefined: PropTypes.any,
60
- };
61
-
62
- render() {
63
- return null;
64
- }
65
-}
66
-
67
-const ModernContext = createContext();
68
-ModernContext.displayName = 'ModernContext';
69
-const ArrayContext = createContext(contextData.array);
70
-ArrayContext.displayName = 'ArrayContext';
71
-const BoolContext = createContext(contextData.bool);
72
-BoolContext.displayName = 'BoolContext';
73
-const FuncContext = createContext(contextData.func);
74
-FuncContext.displayName = 'FuncContext';
75
-const NumberContext = createContext(contextData.number);
76
-NumberContext.displayName = 'NumberContext';
77
-const StringContext = createContext(contextData.string);
78
-StringContext.displayName = 'StringContext';
79
-const SymbolContext = createContext(contextData.symbol);
80
-SymbolContext.displayName = 'SymbolContext';
81
-const NullContext = createContext(null);
82
-NullContext.displayName = 'NullContext';
83
-const UndefinedContext = createContext(undefined);
84
-UndefinedContext.displayName = 'UndefinedContext';
85
-
86
-class ModernContextType extends Component<any> {
87
- static contextType = ModernContext;
88
-
89
- render() {
90
- return null;
91
- }
92
-}
93
-
94
-function FunctionalContextConsumer() {
95
- useContext(StringContext);
96
- return null;
97
-}
98
-
99
-export default function Contexts() {
100
- return (
101
- <Fragment>
102
- <LegacyContextProvider>
103
- <LegacyContextConsumer />
104
- </LegacyContextProvider>
105
- <ModernContext.Provider value={contextData}>
106
- <ModernContext.Consumer>{value => null}</ModernContext.Consumer>
107
- <ModernContextType />
108
- </ModernContext.Provider>
109
- <FunctionalContextConsumer />
110
- <ArrayContext.Consumer>{value => null}</ArrayContext.Consumer>
111
- <BoolContext.Consumer>{value => null}</BoolContext.Consumer>
112
- <FuncContext.Consumer>{value => null}</FuncContext.Consumer>
113
- <NumberContext.Consumer>{value => null}</NumberContext.Consumer>
114
- <StringContext.Consumer>{value => null}</StringContext.Consumer>
115
- <SymbolContext.Consumer>{value => null}</SymbolContext.Consumer>
116
- <NullContext.Consumer>{value => null}</NullContext.Consumer>
117
- <UndefinedContext.Consumer>{value => null}</UndefinedContext.Consumer>
118
- </Fragment>
119
- );
120
-}
packages/react-devtools-shell/src/app/InspectableElements/CustomHooks.js
deleted
-132
@@ -1,132 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {
11
- forwardRef,
12
- Fragment,
13
- memo,
14
- useCallback,
15
- useDebugValue,
16
- useEffect,
17
- useState,
18
-} from 'react';
19
-
20
-const object = {
21
- string: 'abc',
22
- number: 123,
23
- boolean: true,
24
- null: null,
25
- undefined: undefined,
26
- array: ['a', 'b', 'c'],
27
- object: {foo: 1, bar: 2, baz: 3},
28
-};
29
-
30
-function useNestedInnerHook() {
31
- return useState(123);
32
-}
33
-function useNestedOuterHook() {
34
- return useNestedInnerHook();
35
-}
36
-
37
-function useCustomObject() {
38
- useDebugValue(object);
39
- return useState(123);
40
-}
41
-
42
-function useDeepHookA() {
43
- useDebugValue('useDeepHookA');
44
- useDeepHookB();
45
-}
46
-function useDeepHookB() {
47
- useDebugValue('useDeepHookB');
48
- useDeepHookC();
49
-}
50
-function useDeepHookC() {
51
- useDebugValue('useDeepHookC');
52
- useDeepHookD();
53
-}
54
-function useDeepHookD() {
55
- useDebugValue('useDeepHookD');
56
- useDeepHookE();
57
-}
58
-function useDeepHookE() {
59
- useDebugValue('useDeepHookE');
60
- useDeepHookF();
61
-}
62
-function useDeepHookF() {
63
- useDebugValue('useDeepHookF');
64
-}
65
-
66
-function FunctionWithHooks(props: any, ref: React$Ref<any>) {
67
- const [count, updateCount] = useState(0);
68
-
69
- // eslint-disable-next-line no-unused-vars
70
- const [_, __] = useState(object);
71
-
72
- // Custom hook with a custom debug label
73
- const debouncedCount = useDebounce(count, 1000);
74
-
75
- useCustomObject();
76
-
77
- const onClick = useCallback(
78
- function onClick() {
79
- updateCount(count + 1);
80
- },
81
- [count],
82
- );
83
-
84
- // Tests nested custom hooks
85
- useNestedOuterHook();
86
-
87
- // Verify deep nesting doesn't break
88
- useDeepHookA();
89
-
90
- return <button onClick={onClick}>Count: {debouncedCount}</button>;
91
-}
92
-const MemoWithHooks = memo(FunctionWithHooks);
93
-const ForwardRefWithHooks = forwardRef(FunctionWithHooks);
94
-
95
-export default function CustomHooks() {
96
- return (
97
- <Fragment>
98
- <FunctionWithHooks />
99
- <MemoWithHooks />
100
- <ForwardRefWithHooks />
101
- </Fragment>
102
- );
103
-}
104
-
105
-// Below copied from https://usehooks.com/
106
-function useDebounce(value, delay) {
107
- // State and setters for debounced value
108
- const [debouncedValue, setDebouncedValue] = useState(value);
109
-
110
- // Show the value in DevTools
111
- useDebugValue(debouncedValue);
112
-
113
- useEffect(
114
- () => {
115
- // Update debounced value after delay
116
- const handler = setTimeout(() => {
117
- setDebouncedValue(value);
118
- }, delay);
119
-
120
- // Cancel the timeout if value changes (also on delay change or unmount)
121
- // This is how we prevent debounced value from updating if value is changed ...
122
- // .. within the delay period. Timeout gets cleared and restarted.
123
- return () => {
124
- clearTimeout(handler);
125
- };
126
- },
127
- [value, delay], // Only re-call effect if value or delay changes
128
- );
129
-
130
- return debouncedValue;
131
-}
132
-// Above copied from https://usehooks.com/
packages/react-devtools-shell/src/app/InspectableElements/CustomObject.js
deleted
-25
@@ -1,25 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-
12
-class Custom {
13
- _number = 42;
14
- get number() {
15
- return this._number;
16
- }
17
-}
18
-
19
-export default function CustomObject() {
20
- return <ChildComponent customObject={new Custom()} />;
21
-}
22
-
23
-function ChildComponent(props: any) {
24
- return null;
25
-}
packages/react-devtools-shell/src/app/InspectableElements/InspectableElements.js
deleted
-32
@@ -1,32 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment} from 'react';
11
-import UnserializableProps from './UnserializableProps';
12
-import Contexts from './Contexts';
13
-import CustomHooks from './CustomHooks';
14
-import CustomObject from './CustomObject';
15
-import NestedProps from './NestedProps';
16
-import SimpleValues from './SimpleValues';
17
-
18
-// TODO Add Immutable JS example
19
-
20
-export default function InspectableElements() {
21
- return (
22
- <Fragment>
23
- <h1>Inspectable elements</h1>
24
- <SimpleValues />
25
- <UnserializableProps />
26
- <NestedProps />
27
- <Contexts />
28
- <CustomHooks />
29
- <CustomObject />
30
- </Fragment>
31
- );
32
-}
packages/react-devtools-shell/src/app/InspectableElements/NestedProps.js
deleted
-64
@@ -1,64 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-
12
-const object = {
13
- string: 'abc',
14
- longString: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKJLMNOPQRSTUVWXYZ1234567890',
15
- emptyString: '',
16
- number: 123,
17
- boolean: true,
18
- undefined: undefined,
19
- null: null,
20
-};
21
-
22
-export default function ObjectProps() {
23
- return (
24
- <ChildComponent
25
- object={{
26
- outer: {
27
- inner: object,
28
- },
29
- }}
30
- array={['first', 'second', 'third']}
31
- objectInArray={[object]}
32
- arrayInObject={{array: ['first', 'second', 'third']}}
33
- deepObject={{
34
- // Known limitation: we won't go deeper than several levels.
35
- // In the future, we might offer a way to request deeper access on demand.
36
- a: {
37
- b: {
38
- c: {
39
- d: {
40
- e: {
41
- f: {
42
- g: {
43
- h: {
44
- i: {
45
- j: 10,
46
- },
47
- },
48
- },
49
- },
50
- },
51
- },
52
- },
53
- },
54
- },
55
- }}
56
- emptyArray={[]}
57
- emptyObject={{}}
58
- />
59
- );
60
-}
61
-
62
-function ChildComponent(props: any) {
63
- return null;
64
-}
packages/react-devtools-shell/src/app/InspectableElements/SimpleValues.js
deleted
-30
@@ -1,30 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-
12
-export default function SimpleValues() {
13
- return (
14
- <ChildComponent
15
- string="abc"
16
- emptyString=""
17
- number={123}
18
- undefined={undefined}
19
- null={null}
20
- nan={NaN}
21
- infinity={Infinity}
22
- true={true}
23
- false={false}
24
- />
25
- );
26
-}
27
-
28
-function ChildComponent(props: any) {
29
- return null;
30
-}
packages/react-devtools-shell/src/app/InspectableElements/UnserializableProps.js
deleted
-42
@@ -1,42 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React from 'react';
11
-import Immutable from 'immutable';
12
-
13
-const set = new Set(['abc', 123]);
14
-const map = new Map([['name', 'Brian'], ['food', 'sushi']]);
15
-const setOfSets = new Set([new Set(['a', 'b', 'c']), new Set([1, 2, 3])]);
16
-const mapOfMaps = new Map([['first', map], ['second', map]]);
17
-const typedArray = Int8Array.from([100, -100, 0]);
18
-const immutable = Immutable.fromJS({
19
- a: [{hello: 'there'}, 'fixed', true],
20
- b: 123,
21
- c: {
22
- '1': 'xyz',
23
- xyz: 1,
24
- },
25
-});
26
-
27
-export default function UnserializableProps() {
28
- return (
29
- <ChildComponent
30
- map={map}
31
- set={set}
32
- mapOfMaps={mapOfMaps}
33
- setOfSets={setOfSets}
34
- typedArray={typedArray}
35
- immutable={immutable}
36
- />
37
- );
38
-}
39
-
40
-function ChildComponent(props: any) {
41
- return null;
42
-}
packages/react-devtools-shell/src/app/InspectableElements/index.js
deleted
-12
@@ -1,12 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import InspectableElements from './InspectableElements';
11
-
12
-export default InspectableElements;
packages/react-devtools-shell/src/app/InteractionTracing/index.js
deleted
-92
@@ -1,92 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useCallback, useEffect, useState} from 'react';
11
-import {unstable_batchedUpdates as batchedUpdates} from 'react-dom';
12
-import {
13
- unstable_trace as trace,
14
- unstable_wrap as wrap,
15
-} from 'scheduler/tracing';
16
-
17
-export default function InteractionTracing() {
18
- const [count, setCount] = useState(0);
19
- const [shouldCascade, setShouldCascade] = useState(false);
20
-
21
- const handleUpdate = useCallback(
22
- () => {
23
- trace('count', performance.now(), () => {
24
- setTimeout(
25
- wrap(() => {
26
- setCount(count + 1);
27
- }),
28
- count * 100,
29
- );
30
- });
31
- },
32
- [count],
33
- );
34
-
35
- const handleCascadingUpdate = useCallback(
36
- () => {
37
- trace('cascade', performance.now(), () => {
38
- setTimeout(
39
- wrap(() => {
40
- batchedUpdates(() => {
41
- setCount(count + 1);
42
- setShouldCascade(true);
43
- });
44
- }),
45
- count * 100,
46
- );
47
- });
48
- },
49
- [count],
50
- );
51
-
52
- const handleMultiple = useCallback(
53
- () => {
54
- trace('first', performance.now(), () => {
55
- trace('second', performance.now(), () => {
56
- setTimeout(
57
- wrap(() => {
58
- setCount(count + 1);
59
- }),
60
- count * 100,
61
- );
62
- });
63
- });
64
- },
65
- [count],
66
- );
67
-
68
- useEffect(
69
- () => {
70
- if (shouldCascade) {
71
- setTimeout(
72
- wrap(() => {
73
- setShouldCascade(false);
74
- }),
75
- count * 100,
76
- );
77
- }
78
- },
79
- [count, shouldCascade],
80
- );
81
-
82
- return (
83
- <Fragment>
84
- <h1>Interaction Tracing</h1>
85
- <button onClick={handleUpdate}>Update ({count})</button>
86
- <button onClick={handleCascadingUpdate}>
87
- Cascading Update ({count}, {shouldCascade ? 'true' : 'false'})
88
- </button>
89
- <button onClick={handleMultiple}>Multiple</button>
90
- </Fragment>
91
- );
92
-}
packages/react-devtools-shell/src/app/PriorityLevels/index.js
deleted
-53
@@ -1,53 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useCallback, useState} from 'react';
11
-import {
12
- unstable_IdlePriority as IdlePriority,
13
- unstable_LowPriority as LowPriority,
14
- unstable_runWithPriority as runWithPriority,
15
-} from 'scheduler';
16
-
17
-export default function PriorityLevels() {
18
- const [defaultPriority, setDefaultPriority] = useState<boolean>(false);
19
- const [idlePriority, setIdlePriority] = useState<boolean>(false);
20
- const [normalPriority, setLowPriority] = useState<boolean>(false);
21
-
22
- const resetSequence = useCallback(() => {
23
- setDefaultPriority(false);
24
- setLowPriority(false);
25
- setIdlePriority(false);
26
- }, []);
27
-
28
- const startSequence = useCallback(() => {
29
- setDefaultPriority(true);
30
- runWithPriority(LowPriority, () => setLowPriority(true));
31
- runWithPriority(IdlePriority, () => setIdlePriority(true));
32
- }, []);
33
-
34
- const labels = [];
35
- if (defaultPriority) {
36
- labels.push('(default priority)');
37
- }
38
- if (normalPriority) {
39
- labels.push('Low Priority');
40
- }
41
- if (idlePriority) {
42
- labels.push('Idle Priority');
43
- }
44
-
45
- return (
46
- <Fragment>
47
- <h1>Priority Levels</h1>
48
- <button onClick={resetSequence}>Reset</button>
49
- <button onClick={startSequence}>Start sequence</button>
50
- <span>{labels.join(', ')}</span>
51
- </Fragment>
52
- );
53
-}
packages/react-devtools-shell/src/app/ReactNativeWeb/index.js
deleted
-41
@@ -1,41 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useState} from 'react';
11
-import {Button, Text, View} from 'react-native-web';
12
-
13
-export default function ReactNativeWeb() {
14
- const [backgroundColor, setBackgroundColor] = useState('blue');
15
- const toggleColor = () =>
16
- setBackgroundColor(backgroundColor === 'purple' ? 'green' : 'purple');
17
- return (
18
- <Fragment>
19
- <h1>ReactNativeWeb</h1>
20
- <View>
21
- <Text>auto (default) - english LTR</Text>
22
- <Text>
23
- {
24
- '\u0623\u062D\u0628 \u0627\u0644\u0644\u063A\u0629 \u0627\u0644\u0639\u0631\u0628\u064A\u0629 auto (default) - arabic RTL'
25
- }
26
- </Text>
27
- <Text style={{textAlign: 'left'}}>
28
- left left left left left left left left left left left left left left
29
- left
30
- </Text>
31
- <Button
32
- onPress={toggleColor}
33
- style={{backgroundColor}}
34
- title={`Switch background color to "${
35
- backgroundColor === 'purple' ? 'green' : 'purple'
36
- }"`}
37
- />
38
- </View>
39
- </Fragment>
40
- );
41
-}
packages/react-devtools-shell/src/app/SuspenseTree/index.js
deleted
-143
@@ -1,143 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, Suspense, useState} from 'react';
11
-
12
-function SuspenseTree() {
13
- return (
14
- <Fragment>
15
- <h1>Suspense</h1>
16
- <h4>Primary to Fallback Cycle</h4>
17
- <PrimaryFallbackTest initialSuspend={false} />
18
- <h4>Fallback to Primary Cycle</h4>
19
- <PrimaryFallbackTest initialSuspend={true} />
20
- <NestedSuspenseTest />
21
- </Fragment>
22
- );
23
-}
24
-
25
-function PrimaryFallbackTest({initialSuspend}) {
26
- const [suspend, setSuspend] = useState(initialSuspend);
27
- const fallbackStep = useTestSequence('fallback', Fallback1, Fallback2);
28
- const primaryStep = useTestSequence('primary', Primary1, Primary2);
29
- return (
30
- <Fragment>
31
- <label>
32
- <input
33
- checked={suspend}
34
- onChange={e => setSuspend(e.target.checked)}
35
- type="checkbox"
36
- />
37
- Suspend
38
- </label>
39
- <br />
40
- <Suspense fallback={fallbackStep}>
41
- {suspend ? <Never /> : primaryStep}
42
- </Suspense>
43
- </Fragment>
44
- );
45
-}
46
-
47
-function useTestSequence(label, T1, T2) {
48
- let [step, setStep] = useState(0);
49
- let next = (
50
- <button onClick={() => setStep(s => (s + 1) % allSteps.length)}>
51
- next {label} content
52
- </button>
53
- );
54
- let allSteps = [
55
- <Fragment>{next}</Fragment>,
56
- <Fragment>
57
- {next} <T1 prop={step}>mount</T1>
58
- </Fragment>,
59
- <Fragment>
60
- {next} <T1 prop={step}>update</T1>
61
- </Fragment>,
62
- <Fragment>
63
- {next} <T2 prop={step}>several</T2> <T1 prop={step}>different</T1>{' '}
64
- <T2 prop={step}>children</T2>
65
- </Fragment>,
66
- <Fragment>
67
- {next} <T2 prop={step}>goodbye</T2>
68
- </Fragment>,
69
- ];
70
- return allSteps[step];
71
-}
72
-
73
-function NestedSuspenseTest() {
74
- return (
75
- <Fragment>
76
- <h3>Nested Suspense</h3>
77
- <Suspense fallback={<Fallback1>Loading outer</Fallback1>}>
78
- <Parent />
79
- </Suspense>
80
- </Fragment>
81
- );
82
-}
83
-
84
-function Parent() {
85
- return (
86
- <div>
87
- <Suspense fallback={<Fallback1>Loading inner 1</Fallback1>}>
88
- <Primary1>Hello</Primary1>
89
- </Suspense>{' '}
90
- <Suspense fallback={<Fallback2>Loading inner 2</Fallback2>}>
91
- <Primary2>World</Primary2>
92
- </Suspense>
93
- <br />
94
- <Suspense fallback={<Fallback1>This will never load</Fallback1>}>
95
- <Never />
96
- </Suspense>
97
- <br />
98
- <b>
99
- <LoadLater />
100
- </b>
101
- </div>
102
- );
103
-}
104
-
105
-function LoadLater() {
106
- const [loadChild, setLoadChild] = useState(0);
107
- return (
108
- <Suspense
109
- fallback={
110
- <Fallback1 onClick={() => setLoadChild(true)}>Click to load</Fallback1>
111
- }>
112
- {loadChild ? (
113
- <Primary1 onClick={() => setLoadChild(false)}>
114
- Loaded! Click to suspend again.
115
- </Primary1>
116
- ) : (
117
- <Never />
118
- )}
119
- </Suspense>
120
- );
121
-}
122
-
123
-function Never() {
124
- throw new Promise(resolve => {});
125
-}
126
-
127
-function Fallback1({prop, ...rest}: any) {
128
- return <span {...rest} />;
129
-}
130
-
131
-function Fallback2({prop, ...rest}: any) {
132
- return <span {...rest} />;
133
-}
134
-
135
-function Primary1({prop, ...rest}: any) {
136
- return <span {...rest} />;
137
-}
138
-
139
-function Primary2({prop, ...rest}: any) {
140
- return <span {...rest} />;
141
-}
142
-
143
-export default SuspenseTree;
packages/react-devtools-shell/src/app/ToDoList/List.css
deleted
-16
@@ -1,16 +0,0 @@
1
-.Input {
2
- font-size: 1rem;
3
- padding: 0.25rem;
4
-}
5
-
6
-.IconButton {
7
- padding: 0.25rem;
8
- border: none;
9
- background: none;
10
- cursor: pointer;
11
-}
12
-
13
-.List {
14
- margin: 0.5rem 0 0;
15
- padding: 0;
16
-}
packages/react-devtools-shell/src/app/ToDoList/List.js
deleted
-120
@@ -1,120 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {Fragment, useCallback, useState} from 'react';
11
-import ListItem from './ListItem';
12
-import styles from './List.css';
13
-
14
-export type Item = {|
15
- id: number,
16
- isComplete: boolean,
17
- text: string,
18
-|};
19
-
20
-type Props = {||};
21
-
22
-export default function List(props: Props) {
23
- const [newItemText, setNewItemText] = useState<string>('');
24
- const [items, setItems] = useState<Array<Item>>([
25
- {id: 1, isComplete: true, text: 'First'},
26
- {id: 2, isComplete: true, text: 'Second'},
27
- {id: 3, isComplete: false, text: 'Third'},
28
- ]);
29
- const [uid, setUID] = useState<number>(4);
30
-
31
- const handleClick = useCallback(
32
- () => {
33
- if (newItemText !== '') {
34
- setItems([
35
- ...items,
36
- {
37
- id: uid,
38
- isComplete: false,
39
- text: newItemText,
40
- },
41
- ]);
42
- setUID(uid + 1);
43
- setNewItemText('');
44
- }
45
- },
46
- [newItemText, items, uid],
47
- );
48
-
49
- const handleKeyPress = useCallback(
50
- event => {
51
- if (event.key === 'Enter') {
52
- handleClick();
53
- }
54
- },
55
- [handleClick],
56
- );
57
-
58
- const handleChange = useCallback(
59
- event => {
60
- setNewItemText(event.currentTarget.value);
61
- },
62
- [setNewItemText],
63
- );
64
-
65
- const removeItem = useCallback(
66
- itemToRemove => setItems(items.filter(item => item !== itemToRemove)),
67
- [items],
68
- );
69
-
70
- const toggleItem = useCallback(
71
- itemToToggle => {
72
- // Dont use indexOf()
73
- // because editing props in DevTools creates a new Object.
74
- const index = items.findIndex(item => item.id === itemToToggle.id);
75
-
76
- setItems(
77
- items
78
- .slice(0, index)
79
- .concat({
80
- ...itemToToggle,
81
- isComplete: !itemToToggle.isComplete,
82
- })
83
- .concat(items.slice(index + 1)),
84
- );
85
- },
86
- [items],
87
- );
88
-
89
- return (
90
- <Fragment>
91
- <h1>List</h1>
92
- <input
93
- type="text"
94
- placeholder="New list item..."
95
- className={styles.Input}
96
- value={newItemText}
97
- onChange={handleChange}
98
- onKeyPress={handleKeyPress}
99
- />
100
- <button
101
- className={styles.IconButton}
102
- disabled={newItemText === ''}
103
- onClick={handleClick}>
104
- <span role="img" aria-label="Add item">
105
- ➕
106
- </span>
107
- </button>
108
- <ul className={styles.List}>
109
- {items.map(item => (
110
- <ListItem
111
- key={item.id}
112
- item={item}
113
- removeItem={removeItem}
114
- toggleItem={toggleItem}
115
- />
116
- ))}
117
- </ul>
118
- </Fragment>
119
- );
120
-}
packages/react-devtools-shell/src/app/ToDoList/ListItem.css
deleted
-23
@@ -1,23 +0,0 @@
1
-.ListItem {
2
- list-style-type: none;
3
-}
4
-
5
-.Input {
6
- cursor: pointer;
7
-}
8
-
9
-.Label {
10
- cursor: pointer;
11
- padding: 0.25rem;
12
- color: #555;
13
-}
14
-.Label:hover {
15
- color: #000;
16
-}
17
-
18
-.IconButton {
19
- padding: 0.25rem;
20
- border: none;
21
- background: none;
22
- cursor: pointer;
23
-}
packages/react-devtools-shell/src/app/ToDoList/ListItem.js
deleted
-54
@@ -1,54 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import React, {memo, useCallback} from 'react';
11
-import styles from './ListItem.css';
12
-
13
-import type {Item} from './List';
14
-
15
-type Props = {|
16
- item: Item,
17
- removeItem: (item: Item) => void,
18
- toggleItem: (item: Item) => void,
19
-|};
20
-
21
-function ListItem({item, removeItem, toggleItem}: Props) {
22
- const handleDelete = useCallback(
23
- () => {
24
- removeItem(item);
25
- },
26
- [item, removeItem],
27
- );
28
-
29
- const handleToggle = useCallback(
30
- () => {
31
- toggleItem(item);
32
- },
33
- [item, toggleItem],
34
- );
35
-
36
- return (
37
- <li className={styles.ListItem}>
38
- <button className={styles.IconButton} onClick={handleDelete}>
39
- 🗑
40
- </button>
41
- <label className={styles.Label}>
42
- <input
43
- className={styles.Input}
44
- checked={item.isComplete}
45
- onChange={handleToggle}
46
- type="checkbox"
47
- />{' '}
48
- {item.text}
49
- </label>
50
- </li>
51
- );
52
-}
53
-
54
-export default memo<Props>(ListItem);
packages/react-devtools-shell/src/app/ToDoList/index.js
deleted
-12
@@ -1,12 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import List from './List';
11
-
12
-export default List;
packages/react-devtools-shell/src/app/Toggle/index.js
deleted
-21
@@ -1,21 +0,0 @@
1
-import React, {useState} from 'react';
2
-
3
-export default function Toggle() {
4
- const [show, setShow] = useState(false);
5
- return (
6
- <>
7
- <h2>Toggle</h2>
8
- <div>
9
- <>
10
- <button onClick={() => setShow(s => !s)}>Show child</button>
11
- {show && ' '}
12
- {show && <Greeting>Hello</Greeting>}
13
- </>
14
- </div>
15
- </>
16
- );
17
-}
18
-
19
-function Greeting({children}) {
20
- return <p>{children}</p>;
21
-}
packages/react-devtools-shell/src/app/console.js
deleted
-34
@@ -1,34 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-function ignoreStrings(
11
- methodName: string,
12
- stringsToIgnore: Array<string>,
13
-): void {
14
- const originalMethod = console[methodName];
15
- console[methodName] = (...args) => {
16
- const maybeString = args[0];
17
- if (typeof maybeString === 'string') {
18
- for (let i = 0; i < stringsToIgnore.length; i++) {
19
- if (maybeString.startsWith(stringsToIgnore[i])) {
20
- return;
21
- }
22
- }
23
- }
24
- originalMethod(...args);
25
- };
26
-}
27
-
28
-export function ignoreErrors(errorsToIgnore: Array<string>): void {
29
- ignoreStrings('error', errorsToIgnore);
30
-}
31
-
32
-export function ignoreWarnings(warningsToIgnore: Array<string>): void {
33
- ignoreStrings('warn', warningsToIgnore);
34
-}
packages/react-devtools-shell/src/app/index.js
deleted
-71
@@ -1,71 +0,0 @@
1
-/** @flow */
2
-
3
-// This test harness mounts each test app as a separate root to test multi-root applications.
4
-
5
-import {createElement} from 'react';
6
-import {
7
- // $FlowFixMe Flow does not yet know about createRoot()
8
- unstable_createRoot as createRoot,
9
-} from 'react-dom';
10
-import DeeplyNestedComponents from './DeeplyNestedComponents';
11
-import Iframe from './Iframe';
12
-import EditableProps from './EditableProps';
13
-import ElementTypes from './ElementTypes';
14
-import Hydration from './Hydration';
15
-import InspectableElements from './InspectableElements';
16
-import InteractionTracing from './InteractionTracing';
17
-import PriorityLevels from './PriorityLevels';
18
-import ReactNativeWeb from './ReactNativeWeb';
19
-import ToDoList from './ToDoList';
20
-import Toggle from './Toggle';
21
-import SuspenseTree from './SuspenseTree';
22
-import {ignoreErrors, ignoreWarnings} from './console';
23
-
24
-import './styles.css';
25
-
26
-// DevTools intentionally tests compatibility with certain legacy APIs.
27
-// Suppress their error messages in the local dev shell,
28
-// because they might mask other more serious error messages.
29
-ignoreErrors([
30
- 'Warning: Legacy context API',
31
- 'Warning: Unsafe lifecycle methods',
32
- 'Warning: %s is deprecated in StrictMode.', // findDOMNode
33
-]);
34
-ignoreWarnings(['Warning: componentWillReceiveProps is deprecated']);
35
-
36
-const roots = [];
37
-
38
-function mountHelper(App) {
39
- const container = document.createElement('div');
40
-
41
- ((document.body: any): HTMLBodyElement).appendChild(container);
42
-
43
- const root = createRoot(container);
44
- root.render(createElement(App));
45
-
46
- roots.push(root);
47
-}
48
-
49
-function mountTestApp() {
50
- mountHelper(ToDoList);
51
- mountHelper(InteractionTracing);
52
- mountHelper(InspectableElements);
53
- mountHelper(Hydration);
54
- mountHelper(ElementTypes);
55
- mountHelper(EditableProps);
56
- mountHelper(PriorityLevels);
57
- mountHelper(ReactNativeWeb);
58
- mountHelper(Toggle);
59
- mountHelper(SuspenseTree);
60
- mountHelper(DeeplyNestedComponents);
61
- mountHelper(Iframe);
62
-}
63
-
64
-function unmountTestApp() {
65
- roots.forEach(root => root.unmount());
66
-}
67
-
68
-mountTestApp();
69
-
70
-window.parent.mountTestApp = mountTestApp;
71
-window.parent.unmountTestApp = unmountTestApp;
packages/react-devtools-shell/src/app/styles.css
deleted
-13
@@ -1,13 +0,0 @@
1
-body {
2
- /* GitHub.com frontend fonts */
3
- font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
4
- sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
5
- font-size: 14px;
6
- line-height: 1.5;
7
-}
8
-
9
-h1 {
10
- font-size: 1.5rem;
11
- font-weight: bold;
12
- margin-bottom: 0.5rem;
13
-}
packages/react-devtools-shell/src/devtools.js
deleted
-77
@@ -1,77 +0,0 @@
1
-/** @flow */
2
-
3
-import {createElement} from 'react';
4
-// $FlowFixMe Flow does not yet know about createRoot()
5
-import {unstable_createRoot as createRoot} from 'react-dom';
6
-import {
7
- activate as activateBackend,
8
- initialize as initializeBackend,
9
-} from 'react-devtools-inline/backend';
10
-import {initialize as initializeFrontend} from 'react-devtools-inline/frontend';
11
-import {initDevTools} from 'react-devtools-shared/src/devtools';
12
-
13
-const iframe = ((document.getElementById('target'): any): HTMLIFrameElement);
14
-
15
-const {contentDocument, contentWindow} = iframe;
16
-
17
-// Helps with positioning Overlay UI.
18
-contentWindow.__REACT_DEVTOOLS_TARGET_WINDOW__ = window;
19
-
20
-initializeBackend(contentWindow);
21
-
22
-const container = ((document.getElementById('devtools'): any): HTMLElement);
23
-
24
-let isTestAppMounted = true;
25
-
26
-const mountButton = ((document.getElementById(
27
- 'mountButton',
28
-): any): HTMLButtonElement);
29
-mountButton.addEventListener('click', function() {
30
- if (isTestAppMounted) {
31
- if (typeof window.unmountTestApp === 'function') {
32
- window.unmountTestApp();
33
- mountButton.innerText = 'Mount test app';
34
- isTestAppMounted = false;
35
- }
36
- } else {
37
- if (typeof window.mountTestApp === 'function') {
38
- window.mountTestApp();
39
- mountButton.innerText = 'Unmount test app';
40
- isTestAppMounted = true;
41
- }
42
- }
43
-});
44
-
45
-inject('dist/app.js', () => {
46
- initDevTools({
47
- connect(cb) {
48
- const DevTools = initializeFrontend(contentWindow);
49
-
50
- // Activate the backend only once the DevTools frontend Store has been initialized.
51
- // Otherwise the Store may miss important initial tree op codes.
52
- activateBackend(contentWindow);
53
-
54
- const root = createRoot(container);
55
- root.render(
56
- createElement(DevTools, {
57
- browserTheme: 'light',
58
- showTabBar: true,
59
- showWelcomeToTheNewDevToolsDialog: true,
60
- warnIfLegacyBackendDetected: true,
61
- }),
62
- );
63
- },
64
-
65
- onReload(reloadFn) {
66
- iframe.onload = reloadFn;
67
- },
68
- });
69
-});
70
-
71
-function inject(sourcePath, callback) {
72
- const script = contentDocument.createElement('script');
73
- script.onload = callback;
74
- script.src = sourcePath;
75
-
76
- ((contentDocument.body: any): HTMLBodyElement).appendChild(script);
77
-}
packages/react-devtools-shell/webpack.config.js
deleted
-99
@@ -1,99 +0,0 @@
1
-const {resolve} = require('path');
2
-const {DefinePlugin} = require('webpack');
3
-const {
4
- getGitHubURL,
5
- getVersionString,
6
-} = require('react-devtools-extensions/utils');
7
-
8
-const NODE_ENV = process.env.NODE_ENV;
9
-if (!NODE_ENV) {
10
- console.error('NODE_ENV not set');
11
- process.exit(1);
12
-}
13
-
14
-const TARGET = process.env.TARGET;
15
-if (!TARGET) {
16
- console.error('TARGET not set');
17
- process.exit(1);
18
-}
19
-
20
-const builtModulesDir = resolve(__dirname, '..', '..', 'build', 'node_modules');
21
-
22
-const __DEV__ = NODE_ENV === 'development';
23
-
24
-const GITHUB_URL = getGitHubURL();
25
-const DEVTOOLS_VERSION = getVersionString();
26
-
27
-const config = {
28
- mode: __DEV__ ? 'development' : 'production',
29
- devtool: false,
30
- entry: {
31
- app: './src/app/index.js',
32
- devtools: './src/devtools.js',
33
- },
34
- resolve: {
35
- alias: {
36
- react: resolve(builtModulesDir, 'react'),
37
- 'react-dom': resolve(builtModulesDir, 'react-dom'),
38
- 'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
39
- 'react-is': resolve(builtModulesDir, 'react-is'),
40
- scheduler: resolve(builtModulesDir, 'scheduler'),
41
- },
42
- },
43
- plugins: [
44
- new DefinePlugin({
45
- __DEV__,
46
- 'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
47
- 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
48
- }),
49
- ],
50
- module: {
51
- rules: [
52
- {
53
- test: /\.js$/,
54
- loader: 'babel-loader',
55
- options: {
56
- configFile: resolve(
57
- __dirname,
58
- '..',
59
- 'react-devtools-shared',
60
- 'babel.config.js',
61
- ),
62
- },
63
- },
64
- {
65
- test: /\.css$/,
66
- use: [
67
- {
68
- loader: 'style-loader',
69
- },
70
- {
71
- loader: 'css-loader',
72
- options: {
73
- sourceMap: true,
74
- modules: true,
75
- localIdentName: '[local]___[hash:base64:5]',
76
- },
77
- },
78
- ],
79
- },
80
- ],
81
- },
82
-};
83
-
84
-if (TARGET === 'local') {
85
- config.devServer = {
86
- hot: true,
87
- port: 8080,
88
- clientLogLevel: 'warning',
89
- publicPath: '/dist/',
90
- stats: 'errors-only',
91
- };
92
-} else {
93
- config.output = {
94
- path: resolve(__dirname, 'dist'),
95
- filename: '[name].js',
96
- };
97
-}
98
-
99
-module.exports = config;
packages/react-devtools/README.md
+4
-5
@@ -4,7 +4,7 @@ React DevTools is available as a built-in extension for Chrome and Firefox brows
4
5
It works both with React DOM and React Native.
6
7
-
7
+<img src="http://i.imgur.com/IXeHiZD.png" width="600" alt="Screenshot of React DevTools running with React Native">
8
9
## Installation
10
Install the `react-devtools` package. Because this is a development tool, a global install is often the most convenient:
@@ -47,8 +47,7 @@ You can open the [in-app developer menu](https://facebook.github.io/react-native
47
48
However, when `react-devtools` is running, Inspector will enter a special collapsed mode, and instead use the DevTools as primary UI. In this mode, clicking on something in the simulator will bring up the relevant components in the DevTools:
49
50
-
51
-
50
+
51
52
You can choose "Hide Inspector" in the same menu to exit this mode.
53
@@ -62,7 +61,7 @@ Make sure that the dropdown in the top left corner of the Chrome console says `d
61
62
Then select a React component in React DevTools. There is a search box at the top that helps you find one by name. As soon as you select it, it will be available as `$r` in the Chrome console, letting you inspect its props, state, and instance properties.
63
65
-
64
+
65
66
67
## Usage with React DOM
@@ -91,7 +90,7 @@ This will ensure the developer tools are connected. **Don’t forget to remove i
90
91
By default DevTools listen to port `8097` on `localhost`. If you need to customize host, port, or other settings, see the `react-devtools-core` package instead.
92
94
-## Development
93
+## Developing
94
95
* Run `yarn start:backend` and `yarn start:standalone` in `../react-devtools-core`
96
* Run `yarn start` in this folder
packages/react-devtools/app.html
deleted
-129
@@ -1,129 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
- <head>
4
- <title>React Developer Tools</title>
5
- <meta charset="utf8" />
6
- <style>
7
- html {
8
- display: flex;
9
- font-family: sans-serif;
10
- }
11
- body {
12
- margin: 0;
13
- padding: 0;
14
- flex: 1;
15
- display: flex;
16
- }
17
- #container {
18
- display: flex;
19
- position: fixed;
20
- top: 0;
21
- left: 0;
22
- right: 0;
23
- bottom: 0;
24
- background-color: white;
25
- }
26
- #logs {
27
- position: fixed;
28
- top: 0;
29
- left: 0;
30
- white-space: pre;
31
- }
32
- #waiting {
33
- flex-direction: column;
34
- text-align: center;
35
- font-family: sans-serif;
36
- color: #aaa;
37
- flex: 1;
38
- overflow: auto;
39
- }
40
- #waiting h2 {
41
- padding: 30px;
42
- }
43
- #waiting p {
44
- padding: 0;
45
- margin: 0;
46
- }
47
- .input {
48
- display: inline-block;
49
- max-width: 100%;
50
- font-weight: 100;
51
- border: 1px solid #aaa;
52
- padding: 0.125rem 0.25rem;
53
- margin: 0.125rem;
54
- color: #666;
55
- }
56
- #loading-status {
57
- margin-top: 10px;
58
- }
59
- </style>
60
- </head>
61
- <body>
62
- <div id="container">
63
- <div id="waiting" style="-webkit-user-select: none; -webkit-app-region: drag;">
64
- <h2>Waiting for React to connect…</h2>
65
- <div>
66
- <h4>React Native</h4>
67
- <div>The active app will automatically connect in a few seconds.</div>
68
- <br />
69
- <h4>React DOM</h4>
70
- <div>
71
- Add <span class="input" contenteditable="true" id="localhost"></span><br />
72
- or <span class="input" contenteditable="true" id="byip"></span>
73
- </div>
74
- <div>
75
- to the top of the page you want to debug,
76
- <br />
77
- <b>before</b> importing React DOM.
78
- </div>
79
- </div>
80
- <br />
81
- <br />
82
- <div id="loading-status">Starting the server…</div>
83
- </div>
84
- </div>
85
- <script>
86
- const port = process.env.PORT || 8097;
87
- const localIp = require("ip").address();
88
- const $ = document.querySelector.bind(document);
89
-
90
- function selectAll(event) {
91
- const element = event.target;
92
- if (window.getSelection) {
93
- const selection = window.getSelection();
94
- const range = document.createRange();
95
- range.selectNodeContents(element);
96
- selection.removeAllRanges();
97
- selection.addRange(range);
98
- }
99
- }
100
-
101
- const $localhost = $("#localhost");
102
- $localhost.innerText = `<script src="http://localhost:${port}"></` + 'script>';
103
- $localhost.addEventListener('click', selectAll);
104
- $localhost.addEventListener('focus', selectAll);
105
-
106
- const $byIp = $("#byip");
107
- $byIp.innerText = `<script src="http://${localIp}:${port}"></` + 'script>';
108
- $byIp.addEventListener('click', selectAll);
109
- $byIp.addEventListener('focus', selectAll);
110
-
111
- let devtools;
112
- try {
113
- devtools = require("react-devtools-core/standalone").default;
114
- } catch (err) {
115
- alert(
116
- err.toString() +
117
- "\n\nDid you run `yarn` and `yarn run build` in packages/react-devtools-core?"
118
- );
119
- }
120
- window.devtools = devtools;
121
- window.server = devtools
122
- .setContentDOMNode(document.getElementById("container"))
123
- .setStatusListener(function(status) {
124
- document.getElementById("loading-status").innerText = status;
125
- })
126
- .startServer(port);
127
- </script>
128
- </body>
129
-</html>
packages/react-devtools/app.js
deleted
-48
@@ -1,48 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-const {app, BrowserWindow} = require('electron'); // Module to create native browser window.
11
-const {join} = require('path');
12
-
13
-const argv = require('minimist')(process.argv.slice(2));
14
-const projectRoots = argv._;
15
-
16
-let mainWindow = null;
17
-
18
-app.on('window-all-closed', function() {
19
- app.quit();
20
-});
21
-
22
-app.on('ready', function() {
23
- // Create the browser window.
24
- mainWindow = new BrowserWindow({
25
- width: 800,
26
- height: 600,
27
- icon: join(__dirname, 'icons/icon128.png'),
28
- frame: false,
29
- //titleBarStyle: 'customButtonsOnHover',
30
- webPreferences: {
31
- nodeIntegration: true,
32
- },
33
- });
34
-
35
- // and load the index.html of the app.
36
- mainWindow.loadURL('file://' + __dirname + '/app.html'); // eslint-disable-line no-path-concat
37
- mainWindow.webContents.executeJavaScript(
38
- // We use this so that RN can keep relative JSX __source filenames
39
- // but "click to open in editor" still works. js1 passes project roots
40
- // as the argument to DevTools.
41
- 'window.devtools.setProjectRoots(' + JSON.stringify(projectRoots) + ')',
42
- );
43
-
44
- // Emitted when the window is closed.
45
- mainWindow.on('closed', function() {
46
- mainWindow = null;
47
- });
48
-});
packages/react-devtools/bin.js
deleted
-25
@@ -1,25 +0,0 @@
1
-#!/usr/bin/env node
2
-
3
-/**
4
- * Copyright (c) Facebook, Inc. and its affiliates.
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE file in the root directory of this source tree.
8
- *
9
- * @flow
10
- */
11
-
12
-const electron = require('electron');
13
-const spawn = require('cross-spawn');
14
-const argv = process.argv.slice(2);
15
-const pkg = require('./package.json');
16
-const updateNotifier = require('update-notifier');
17
-
18
-// notify if there's an update
19
-updateNotifier({pkg}).notify({defer: false});
20
-
21
-const result = spawn.sync(electron, [require.resolve('./app')].concat(argv), {
22
- stdio: 'ignore',
23
-});
24
-
25
-process.exit(result.status);
packages/react-devtools/icons/icon128.png
Binary files a/packages/react-devtools/icons/icon128.png and /dev/null differ
packages/react-devtools/index.js
deleted
-14
@@ -1,14 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-const {connectToDevTools} = require('react-devtools-core/backend');
11
-
12
-// Connect immediately with default options.
13
-// If you need more control, use `react-devtools-core` directly instead of `react-devtools`.
14
-connectToDevTools();
packages/react-devtools/package.json
+2
-30
@@ -1,33 +1,5 @@
1
{
2
+ "private": true,
3
"name": "react-devtools",
3
- "version": "4.0.6",
4
- "description": "Use react-devtools outside of the browser",
5
- "license": "MIT",
6
- "repository": {
7
- "type": "git",
8
- "url": "https://github.com/facebook/react.git",
9
- "directory": "packages/react-devtools"
10
- },
11
- "bin": {
12
- "react-devtools": "./bin.js"
13
- },
14
- "files": [
15
- "bin.js",
16
- "build-info.json",
17
- "app.html",
18
- "app.js",
19
- "index.js",
20
- "icons"
21
- ],
22
- "scripts": {
23
- "start": "node bin.js"
24
- },
25
- "dependencies": {
26
- "cross-spawn": "^5.0.1",
27
- "electron": "^5.0.0",
28
- "ip": "^1.1.4",
29
- "minimist": "^1.2.0",
30
- "react-devtools-core": "4.0.6",
31
- "update-notifier": "^2.1.0"
32
- }
4
+ "version": "0.0.0"
5
}
scripts/flow/config/flowconfig
-2
@@ -5,7 +5,6 @@
5
.*/rollup/shims/facebook-www/.*
6
.*/rollup/shims/react-native/.*
7
8
-.*/node_modules/@snyk/.*
8
.*/node_modules/y18n/.*
9
.*/node_modules/chrome-devtools-frontend/.*
10
.*/node_modules/devtools-timeline-model/.*
@@ -21,7 +20,6 @@
20
[libs]
21
../../../node_modules/fbjs/flow/lib/dev.js
22
../environment.js
24
-../react-devtools.js
23
../react-native-host-hooks.js
24
25
[lints]
scripts/flow/react-devtools.js
deleted
-25
@@ -1,25 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-declare module 'events' {
11
- declare class EventEmitter<Events: Object> {
12
- addListener<Event: $Keys<Events>>(
13
- event: Event,
14
- listener: (...$ElementType<Events, Event>) => any,
15
- ): void;
16
- emit: <Event: $Keys<Events>>(
17
- event: Event,
18
- ...$ElementType<Events, Event>
19
- ) => void;
20
- removeListener(event: $Keys<Events>, listener: Function): void;
21
- removeAllListeners(event?: $Keys<Events>): void;
22
- }
23
-
24
- declare export default typeof EventEmitter;
25
-}
scripts/jest/config.build-devtools.js
deleted
-67
@@ -1,67 +0,0 @@
1
-'use strict';
2
-
3
-const {readdirSync, statSync} = require('fs');
4
-const {join} = require('path');
5
-const baseConfig = require('./config.base');
6
-
7
-// Find all folders in packages/* with package.json
8
-const packagesRoot = join(__dirname, '..', '..', 'packages');
9
-const packages = readdirSync(packagesRoot).filter(dir => {
10
- if (dir.charAt(0) === '.') {
11
- return false;
12
- }
13
- if (dir.includes('react-devtools')) {
14
- return false;
15
- }
16
- const packagePath = join(packagesRoot, dir, 'package.json');
17
- return statSync(packagePath).isFile();
18
-});
19
-
20
-// Create a module map to point React packages to the build output
21
-const moduleNameMapper = {};
22
-
23
-// Allow bundle tests to read (but not write!) default feature flags.
24
-// This lets us determine whether we're running in different modes
25
-// without making relevant tests internal-only.
26
-moduleNameMapper[
27
- '^shared/ReactFeatureFlags'
28
-] = `<rootDir>/packages/shared/forks/ReactFeatureFlags.readonly`;
29
-
30
-// Map packages to bundles
31
-packages.forEach(name => {
32
- // Root entry point
33
- moduleNameMapper[`^${name}$`] = `<rootDir>/build/node_modules/${name}`;
34
- // Named entry points
35
- moduleNameMapper[
36
- `^${name}\/([^\/]+)$`
37
- ] = `<rootDir>/build/node_modules/${name}/$1`;
38
-});
39
-
40
-module.exports = Object.assign({}, baseConfig, {
41
- // Redirect imports to the compiled bundles
42
- moduleNameMapper,
43
- // Don't run bundle tests on -test.internal.* files
44
- testPathIgnorePatterns: ['/node_modules/', '-test.internal.js$'],
45
- // Exclude the build output from transforms
46
- transformIgnorePatterns: ['/node_modules/', '<rootDir>/build/'],
47
- testRegex: 'packages/react-devtools-shared/src/__tests__/[^]+.test.js$',
48
- snapshotSerializers: [
49
- require.resolve(
50
- '../../packages/react-devtools-shared/src/__tests__/inspectedElementSerializer.js'
51
- ),
52
- require.resolve(
53
- '../../packages/react-devtools-shared/src/__tests__/storeSerializer.js'
54
- ),
55
- ],
56
- setupFiles: [
57
- ...baseConfig.setupFiles,
58
- require.resolve('./setupTests.build.js'),
59
- require.resolve(
60
- '../../packages/react-devtools-shared/src/__tests__/setupEnv.js'
61
- ),
62
- ],
63
- // TODO (Jest v24) Rename "setupFilesAfterEnv" after Jest upgrade
64
- setupTestFrameworkScriptFile: require.resolve(
65
- '../../packages/react-devtools-shared/src/__tests__/setupTests.js'
66
- ),
67
-});
scripts/jest/config.build.js
-4
@@ -37,10 +37,6 @@ packages.forEach(name => {
37
module.exports = Object.assign({}, baseConfig, {
38
// Redirect imports to the compiled bundles
39
moduleNameMapper,
40
- modulePathIgnorePatterns: [
41
- ...baseConfig.modulePathIgnorePatterns,
42
- 'packages/react-devtools-shared',
43
- ],
40
// Don't run bundle tests on -test.internal.* files
41
testPathIgnorePatterns: ['/node_modules/', '-test.internal.js$'],
42
// Exclude the build output from transforms
scripts/jest/config.source-persistent.js
-2
@@ -4,8 +4,6 @@ const baseConfig = require('./config.base');
4
5
module.exports = Object.assign({}, baseConfig, {
6
modulePathIgnorePatterns: [
7
- ...baseConfig.modulePathIgnorePatterns,
8
- 'packages/react-devtools-shared',
7
'ReactIncrementalPerf',
8
'ReactIncrementalUpdatesMinimalism',
9
'ReactIncrementalTriangle',
scripts/jest/config.source.js
-4
@@ -3,10 +3,6 @@
3
const baseConfig = require('./config.base');
4
5
module.exports = Object.assign({}, baseConfig, {
6
- modulePathIgnorePatterns: [
7
- ...baseConfig.modulePathIgnorePatterns,
8
- 'packages/react-devtools-shared',
9
- ],
6
setupFiles: [
7
...baseConfig.setupFiles,
8
require.resolve('./setupHostConfigs.js'),
scripts/jest/preprocessor.js
-7
@@ -40,13 +40,6 @@ const babelOptions = {
40
require.resolve('@babel/plugin-transform-react-jsx-source'),
41
42
require.resolve('../babel/transform-prevent-infinite-loops'),
43
-
44
- // This optimization is important for extremely performance-sensitive (e.g. React source).
45
- // It's okay to disable it for tests.
46
- [
47
- require.resolve('@babel/plugin-transform-block-scoping'),
48
- {throwIfClosureRequired: false},
49
- ],
43
],
44
retainLines: true,
45
};
scripts/print-warnings/print-warnings.js
-1
@@ -82,7 +82,6 @@ function transform(file, enc, cb) {
82
gs([
83
'packages/**/*.js',
84
'!packages/shared/warning.js',
85
- '!packages/react-devtools*/**/*.js',
85
'!**/__tests__/**/*.js',
86
'!**/__mocks__/**/*.js',
87
]).pipe(
yarn.lock
+196
-7469
@@ -26,7 +26,7 @@
26
dependencies:
27
"@babel/highlight" "^7.0.0"
28
29
-"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.1.6":
29
+"@babel/core@^7.0.0":
30
version "7.5.5"
31
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30"
32
integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==
@@ -46,7 +46,7 @@
46
semver "^5.4.1"
47
source-map "^0.5.0"
48
49
-"@babel/generator@^7.4.0", "@babel/generator@^7.5.5":
49
+"@babel/generator@^7.5.5":
50
version "7.5.5"
51
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf"
52
integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==
@@ -64,14 +64,6 @@
64
dependencies:
65
"@babel/types" "^7.0.0"
66
67
-"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0":
68
- version "7.1.0"
69
- resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f"
70
- integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==
71
- dependencies:
72
- "@babel/helper-explode-assignable-expression" "^7.1.0"
73
- "@babel/types" "^7.0.0"
74
-
67
"@babel/helper-builder-react-jsx@^7.3.0":
68
version "7.3.0"
69
resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4"
@@ -110,14 +102,6 @@
102
"@babel/types" "^7.5.5"
103
lodash "^4.17.13"
104
113
-"@babel/helper-explode-assignable-expression@^7.1.0":
114
- version "7.1.0"
115
- resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6"
116
- integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==
117
- dependencies:
118
- "@babel/traverse" "^7.1.0"
119
- "@babel/types" "^7.0.0"
120
-
105
"@babel/helper-function-name@^7.1.0":
106
version "7.1.0"
107
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53"
@@ -155,7 +139,7 @@
139
dependencies:
140
"@babel/types" "^7.0.0"
141
158
-"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4":
142
+"@babel/helper-module-transforms@^7.4.4":
143
version "7.5.5"
144
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a"
145
integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==
@@ -179,13 +163,6 @@
163
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250"
164
integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==
165
182
-"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4":
183
- version "7.5.5"
184
- resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351"
185
- integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==
186
- dependencies:
187
- lodash "^4.17.13"
188
-
166
"@babel/helper-remap-async-to-generator@^7.1.0":
167
version "7.1.0"
168
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f"
@@ -250,7 +227,7 @@
227
esutils "^2.0.2"
228
js-tokens "^4.0.0"
229
253
-"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5":
230
+"@babel/parser@^7.0.0", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5":
231
version "7.5.5"
232
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b"
233
integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==
@@ -262,16 +239,7 @@
239
dependencies:
240
"@babel/helper-plugin-utils" "^7.0.0"
241
265
-"@babel/plugin-proposal-async-generator-functions@^7.2.0":
266
- version "7.2.0"
267
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e"
268
- integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==
269
- dependencies:
270
- "@babel/helper-plugin-utils" "^7.0.0"
271
- "@babel/helper-remap-async-to-generator" "^7.1.0"
272
- "@babel/plugin-syntax-async-generators" "^7.2.0"
273
-
274
-"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.1.0":
242
+"@babel/plugin-proposal-class-properties@^7.0.0":
243
version "7.5.5"
244
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4"
245
integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==
@@ -279,23 +247,7 @@
247
"@babel/helper-create-class-features-plugin" "^7.5.5"
248
"@babel/helper-plugin-utils" "^7.0.0"
249
282
-"@babel/plugin-proposal-dynamic-import@^7.5.0":
283
- version "7.5.0"
284
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506"
285
- integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==
286
- dependencies:
287
- "@babel/helper-plugin-utils" "^7.0.0"
288
- "@babel/plugin-syntax-dynamic-import" "^7.2.0"
289
-
290
-"@babel/plugin-proposal-json-strings@^7.2.0":
291
- version "7.2.0"
292
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317"
293
- integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==
294
- dependencies:
295
- "@babel/helper-plugin-utils" "^7.0.0"
296
- "@babel/plugin-syntax-json-strings" "^7.2.0"
297
-
298
-"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.5.5":
250
+"@babel/plugin-proposal-object-rest-spread@^7.0.0":
251
version "7.5.5"
252
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58"
253
integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==
@@ -303,31 +255,7 @@
255
"@babel/helper-plugin-utils" "^7.0.0"
256
"@babel/plugin-syntax-object-rest-spread" "^7.2.0"
257
306
-"@babel/plugin-proposal-optional-catch-binding@^7.2.0":
307
- version "7.2.0"
308
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5"
309
- integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==
310
- dependencies:
311
- "@babel/helper-plugin-utils" "^7.0.0"
312
- "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
313
-
314
-"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
315
- version "7.4.4"
316
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78"
317
- integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==
318
- dependencies:
319
- "@babel/helper-plugin-utils" "^7.0.0"
320
- "@babel/helper-regex" "^7.4.4"
321
- regexpu-core "^4.5.4"
322
-
323
-"@babel/plugin-syntax-async-generators@^7.2.0":
324
- version "7.2.0"
325
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f"
326
- integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==
327
- dependencies:
328
- "@babel/helper-plugin-utils" "^7.0.0"
329
-
330
-"@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.2.0":
258
+"@babel/plugin-syntax-dynamic-import@^7.0.0":
259
version "7.2.0"
260
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612"
261
integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==
@@ -341,13 +269,6 @@
269
dependencies:
270
"@babel/helper-plugin-utils" "^7.0.0"
271
344
-"@babel/plugin-syntax-json-strings@^7.2.0":
345
- version "7.2.0"
346
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470"
347
- integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==
348
- dependencies:
349
- "@babel/helper-plugin-utils" "^7.0.0"
350
-
272
"@babel/plugin-syntax-jsx@^7.2.0":
273
version "7.2.0"
274
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7"
@@ -355,28 +276,21 @@
276
dependencies:
277
"@babel/helper-plugin-utils" "^7.0.0"
278
358
-"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0":
279
+"@babel/plugin-syntax-object-rest-spread@^7.2.0":
280
version "7.2.0"
281
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e"
282
integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==
283
dependencies:
284
"@babel/helper-plugin-utils" "^7.0.0"
285
365
-"@babel/plugin-syntax-optional-catch-binding@^7.2.0":
366
- version "7.2.0"
367
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c"
368
- integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==
369
- dependencies:
370
- "@babel/helper-plugin-utils" "^7.0.0"
371
-
372
-"@babel/plugin-transform-arrow-functions@^7.0.0", "@babel/plugin-transform-arrow-functions@^7.2.0":
286
+"@babel/plugin-transform-arrow-functions@^7.0.0":
287
version "7.2.0"
288
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550"
289
integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==
290
dependencies:
291
"@babel/helper-plugin-utils" "^7.0.0"
292
379
-"@babel/plugin-transform-async-to-generator@^7.0.0", "@babel/plugin-transform-async-to-generator@^7.5.0":
293
+"@babel/plugin-transform-async-to-generator@^7.0.0":
294
version "7.5.0"
295
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e"
296
integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==
@@ -385,14 +299,14 @@
299
"@babel/helper-plugin-utils" "^7.0.0"
300
"@babel/helper-remap-async-to-generator" "^7.1.0"
301
388
-"@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.2.0":
302
+"@babel/plugin-transform-block-scoped-functions@^7.0.0":
303
version "7.2.0"
304
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190"
305
integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==
306
dependencies:
307
"@babel/helper-plugin-utils" "^7.0.0"
308
395
-"@babel/plugin-transform-block-scoping@^7.0.0", "@babel/plugin-transform-block-scoping@^7.5.5":
309
+"@babel/plugin-transform-block-scoping@^7.0.0":
310
version "7.5.5"
311
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce"
312
integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==
@@ -400,7 +314,7 @@
314
"@babel/helper-plugin-utils" "^7.0.0"
315
lodash "^4.17.13"
316
403
-"@babel/plugin-transform-classes@^7.0.0", "@babel/plugin-transform-classes@^7.5.5":
317
+"@babel/plugin-transform-classes@^7.0.0":
318
version "7.5.5"
319
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9"
320
integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==
@@ -414,45 +328,21 @@
328
"@babel/helper-split-export-declaration" "^7.4.4"
329
globals "^11.1.0"
330
417
-"@babel/plugin-transform-computed-properties@^7.0.0", "@babel/plugin-transform-computed-properties@^7.2.0":
331
+"@babel/plugin-transform-computed-properties@^7.0.0":
332
version "7.2.0"
333
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da"
334
integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==
335
dependencies:
336
"@babel/helper-plugin-utils" "^7.0.0"
337
424
-"@babel/plugin-transform-destructuring@^7.0.0", "@babel/plugin-transform-destructuring@^7.5.0":
338
+"@babel/plugin-transform-destructuring@^7.0.0":
339
version "7.5.0"
340
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a"
341
integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==
342
dependencies:
343
"@babel/helper-plugin-utils" "^7.0.0"
344
431
-"@babel/plugin-transform-dotall-regex@^7.4.4":
432
- version "7.4.4"
433
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3"
434
- integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==
435
- dependencies:
436
- "@babel/helper-plugin-utils" "^7.0.0"
437
- "@babel/helper-regex" "^7.4.4"
438
- regexpu-core "^4.5.4"
439
-
440
-"@babel/plugin-transform-duplicate-keys@^7.5.0":
441
- version "7.5.0"
442
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853"
443
- integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==
444
- dependencies:
445
- "@babel/helper-plugin-utils" "^7.0.0"
446
-
447
-"@babel/plugin-transform-exponentiation-operator@^7.2.0":
448
- version "7.2.0"
449
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008"
450
- integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==
451
- dependencies:
452
- "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0"
453
- "@babel/helper-plugin-utils" "^7.0.0"
454
-
455
-"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.1.6":
345
+"@babel/plugin-transform-flow-strip-types@^7.0.0":
346
version "7.4.4"
347
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.4.tgz#d267a081f49a8705fc9146de0768c6b58dccd8f7"
348
integrity sha512-WyVedfeEIILYEaWGAUWzVNyqG4sfsNooMhXWsu/YzOvVGcsnPb5PguysjJqI3t3qiaYj0BR8T2f5njdjTGe44Q==
@@ -460,45 +350,21 @@
350
"@babel/helper-plugin-utils" "^7.0.0"
351
"@babel/plugin-syntax-flow" "^7.2.0"
352
463
-"@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.4.4":
353
+"@babel/plugin-transform-for-of@^7.0.0":
354
version "7.4.4"
355
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556"
356
integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==
357
dependencies:
358
"@babel/helper-plugin-utils" "^7.0.0"
359
470
-"@babel/plugin-transform-function-name@^7.4.4":
471
- version "7.4.4"
472
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad"
473
- integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==
474
- dependencies:
475
- "@babel/helper-function-name" "^7.1.0"
476
- "@babel/helper-plugin-utils" "^7.0.0"
477
-
478
-"@babel/plugin-transform-literals@^7.0.0", "@babel/plugin-transform-literals@^7.2.0":
360
+"@babel/plugin-transform-literals@^7.0.0":
361
version "7.2.0"
362
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1"
363
integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==
364
dependencies:
365
"@babel/helper-plugin-utils" "^7.0.0"
366
485
-"@babel/plugin-transform-member-expression-literals@^7.2.0":
486
- version "7.2.0"
487
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d"
488
- integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==
489
- dependencies:
490
- "@babel/helper-plugin-utils" "^7.0.0"
491
-
492
-"@babel/plugin-transform-modules-amd@^7.5.0":
493
- version "7.5.0"
494
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91"
495
- integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==
496
- dependencies:
497
- "@babel/helper-module-transforms" "^7.1.0"
498
- "@babel/helper-plugin-utils" "^7.0.0"
499
- babel-plugin-dynamic-import-node "^2.3.0"
500
-
501
-"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.5.0":
367
+"@babel/plugin-transform-modules-commonjs@^7.0.0":
368
version "7.5.0"
369
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74"
370
integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==
@@ -508,38 +374,7 @@
374
"@babel/helper-simple-access" "^7.1.0"
375
babel-plugin-dynamic-import-node "^2.3.0"
376
511
-"@babel/plugin-transform-modules-systemjs@^7.5.0":
512
- version "7.5.0"
513
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249"
514
- integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==
515
- dependencies:
516
- "@babel/helper-hoist-variables" "^7.4.4"
517
- "@babel/helper-plugin-utils" "^7.0.0"
518
- babel-plugin-dynamic-import-node "^2.3.0"
519
-
520
-"@babel/plugin-transform-modules-umd@^7.2.0":
521
- version "7.2.0"
522
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae"
523
- integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==
524
- dependencies:
525
- "@babel/helper-module-transforms" "^7.1.0"
526
- "@babel/helper-plugin-utils" "^7.0.0"
527
-
528
-"@babel/plugin-transform-named-capturing-groups-regex@^7.4.5":
529
- version "7.4.5"
530
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106"
531
- integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==
532
- dependencies:
533
- regexp-tree "^0.1.6"
534
-
535
-"@babel/plugin-transform-new-target@^7.4.4":
536
- version "7.4.4"
537
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5"
538
- integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==
539
- dependencies:
540
- "@babel/helper-plugin-utils" "^7.0.0"
541
-
542
-"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.5.5":
377
+"@babel/plugin-transform-object-super@^7.0.0":
378
version "7.5.5"
379
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9"
380
integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==
@@ -547,7 +382,7 @@
382
"@babel/helper-plugin-utils" "^7.0.0"
383
"@babel/helper-replace-supers" "^7.5.5"
384
550
-"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.4.4":
385
+"@babel/plugin-transform-parameters@^7.0.0":
386
version "7.4.4"
387
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16"
388
integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==
@@ -556,13 +391,6 @@
391
"@babel/helper-get-function-arity" "^7.0.0"
392
"@babel/helper-plugin-utils" "^7.0.0"
393
559
-"@babel/plugin-transform-property-literals@^7.2.0":
560
- version "7.2.0"
561
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905"
562
- integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==
563
- dependencies:
564
- "@babel/helper-plugin-utils" "^7.0.0"
565
-
394
"@babel/plugin-transform-react-display-name@^7.0.0":
395
version "7.2.0"
396
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0"
@@ -578,7 +406,7 @@
406
"@babel/helper-plugin-utils" "^7.0.0"
407
"@babel/plugin-syntax-jsx" "^7.2.0"
408
581
-"@babel/plugin-transform-react-jsx-source@^7.0.0", "@babel/plugin-transform-react-jsx-source@^7.2.0":
409
+"@babel/plugin-transform-react-jsx-source@^7.0.0":
410
version "7.5.0"
411
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz#583b10c49cf057e237085bcbd8cc960bd83bd96b"
412
integrity sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg==
@@ -595,43 +423,21 @@
423
"@babel/helper-plugin-utils" "^7.0.0"
424
"@babel/plugin-syntax-jsx" "^7.2.0"
425
598
-"@babel/plugin-transform-regenerator@^7.4.5":
599
- version "7.4.5"
600
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f"
601
- integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==
602
- dependencies:
603
- regenerator-transform "^0.14.0"
604
-
605
-"@babel/plugin-transform-reserved-words@^7.2.0":
606
- version "7.2.0"
607
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634"
608
- integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==
609
- dependencies:
610
- "@babel/helper-plugin-utils" "^7.0.0"
611
-
612
-"@babel/plugin-transform-shorthand-properties@^7.0.0", "@babel/plugin-transform-shorthand-properties@^7.2.0":
426
+"@babel/plugin-transform-shorthand-properties@^7.0.0":
427
version "7.2.0"
428
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0"
429
integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==
430
dependencies:
431
"@babel/helper-plugin-utils" "^7.0.0"
432
619
-"@babel/plugin-transform-spread@^7.0.0", "@babel/plugin-transform-spread@^7.2.0":
433
+"@babel/plugin-transform-spread@^7.0.0":
434
version "7.2.2"
435
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406"
436
integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==
437
dependencies:
438
"@babel/helper-plugin-utils" "^7.0.0"
439
626
-"@babel/plugin-transform-sticky-regex@^7.2.0":
627
- version "7.2.0"
628
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1"
629
- integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==
630
- dependencies:
631
- "@babel/helper-plugin-utils" "^7.0.0"
632
- "@babel/helper-regex" "^7.0.0"
633
-
634
-"@babel/plugin-transform-template-literals@^7.0.0", "@babel/plugin-transform-template-literals@^7.4.4":
440
+"@babel/plugin-transform-template-literals@^7.0.0":
441
version "7.4.4"
442
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0"
443
integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==
@@ -639,86 +445,6 @@
445
"@babel/helper-annotate-as-pure" "^7.0.0"
446
"@babel/helper-plugin-utils" "^7.0.0"
447
642
-"@babel/plugin-transform-typeof-symbol@^7.2.0":
643
- version "7.2.0"
644
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2"
645
- integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==
646
- dependencies:
647
- "@babel/helper-plugin-utils" "^7.0.0"
648
-
649
-"@babel/plugin-transform-unicode-regex@^7.4.4":
650
- version "7.4.4"
651
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f"
652
- integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==
653
- dependencies:
654
- "@babel/helper-plugin-utils" "^7.0.0"
655
- "@babel/helper-regex" "^7.4.4"
656
- regexpu-core "^4.5.4"
657
-
658
-"@babel/polyfill@7.4.4":
659
- version "7.4.4"
660
- resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.4.4.tgz#78801cf3dbe657844eeabf31c1cae3828051e893"
661
- integrity sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==
662
- dependencies:
663
- core-js "^2.6.5"
664
- regenerator-runtime "^0.13.2"
665
-
666
-"@babel/preset-env@^7.1.6":
667
- version "7.5.5"
668
- resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a"
669
- integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==
670
- dependencies:
671
- "@babel/helper-module-imports" "^7.0.0"
672
- "@babel/helper-plugin-utils" "^7.0.0"
673
- "@babel/plugin-proposal-async-generator-functions" "^7.2.0"
674
- "@babel/plugin-proposal-dynamic-import" "^7.5.0"
675
- "@babel/plugin-proposal-json-strings" "^7.2.0"
676
- "@babel/plugin-proposal-object-rest-spread" "^7.5.5"
677
- "@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
678
- "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
679
- "@babel/plugin-syntax-async-generators" "^7.2.0"
680
- "@babel/plugin-syntax-dynamic-import" "^7.2.0"
681
- "@babel/plugin-syntax-json-strings" "^7.2.0"
682
- "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
683
- "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
684
- "@babel/plugin-transform-arrow-functions" "^7.2.0"
685
- "@babel/plugin-transform-async-to-generator" "^7.5.0"
686
- "@babel/plugin-transform-block-scoped-functions" "^7.2.0"
687
- "@babel/plugin-transform-block-scoping" "^7.5.5"
688
- "@babel/plugin-transform-classes" "^7.5.5"
689
- "@babel/plugin-transform-computed-properties" "^7.2.0"
690
- "@babel/plugin-transform-destructuring" "^7.5.0"
691
- "@babel/plugin-transform-dotall-regex" "^7.4.4"
692
- "@babel/plugin-transform-duplicate-keys" "^7.5.0"
693
- "@babel/plugin-transform-exponentiation-operator" "^7.2.0"
694
- "@babel/plugin-transform-for-of" "^7.4.4"
695
- "@babel/plugin-transform-function-name" "^7.4.4"
696
- "@babel/plugin-transform-literals" "^7.2.0"
697
- "@babel/plugin-transform-member-expression-literals" "^7.2.0"
698
- "@babel/plugin-transform-modules-amd" "^7.5.0"
699
- "@babel/plugin-transform-modules-commonjs" "^7.5.0"
700
- "@babel/plugin-transform-modules-systemjs" "^7.5.0"
701
- "@babel/plugin-transform-modules-umd" "^7.2.0"
702
- "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5"
703
- "@babel/plugin-transform-new-target" "^7.4.4"
704
- "@babel/plugin-transform-object-super" "^7.5.5"
705
- "@babel/plugin-transform-parameters" "^7.4.4"
706
- "@babel/plugin-transform-property-literals" "^7.2.0"
707
- "@babel/plugin-transform-regenerator" "^7.4.5"
708
- "@babel/plugin-transform-reserved-words" "^7.2.0"
709
- "@babel/plugin-transform-shorthand-properties" "^7.2.0"
710
- "@babel/plugin-transform-spread" "^7.2.0"
711
- "@babel/plugin-transform-sticky-regex" "^7.2.0"
712
- "@babel/plugin-transform-template-literals" "^7.4.4"
713
- "@babel/plugin-transform-typeof-symbol" "^7.2.0"
714
- "@babel/plugin-transform-unicode-regex" "^7.4.4"
715
- "@babel/types" "^7.5.5"
716
- browserslist "^4.6.0"
717
- core-js-compat "^3.1.1"
718
- invariant "^2.2.2"
719
- js-levenshtein "^1.1.3"
720
- semver "^5.5.0"
721
-
448
"@babel/preset-flow@^7.0.0":
449
version "7.0.0"
450
resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0.tgz#afd764835d9535ec63d8c7d4caf1c06457263da2"
@@ -738,29 +464,7 @@
464
"@babel/plugin-transform-react-jsx-self" "^7.0.0"
465
"@babel/plugin-transform-react-jsx-source" "^7.0.0"
466
741
-"@babel/runtime-corejs2@^7.2.0":
742
- version "7.5.5"
743
- resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.5.5.tgz#c3214c08ef20341af4187f1c9fbdc357fbec96b2"
744
- integrity sha512-FYATQVR00NSNi7mUfpPDp7E8RYMXDuO8gaix7u/w3GekfUinKgX1AcTxs7SoiEmoEW9mbpjrwqWSW6zCmw5h8A==
745
- dependencies:
746
- core-js "^2.6.5"
747
- regenerator-runtime "^0.13.2"
748
-
749
-"@babel/runtime@7.4.5":
750
- version "7.4.5"
751
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
752
- integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==
753
- dependencies:
754
- regenerator-runtime "^0.13.2"
755
-
756
-"@babel/runtime@^7.0.0":
757
- version "7.5.5"
758
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
759
- integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
760
- dependencies:
761
- regenerator-runtime "^0.13.2"
762
-
763
-"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4":
467
+"@babel/template@^7.1.0", "@babel/template@^7.4.4":
468
version "7.4.4"
469
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237"
470
integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==
@@ -769,7 +473,7 @@
473
"@babel/parser" "^7.4.4"
474
"@babel/types" "^7.4.4"
475
772
-"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5":
476
+"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5":
477
version "7.5.5"
478
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb"
479
integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==
@@ -784,7 +488,7 @@
488
globals "^11.1.0"
489
lodash "^4.17.13"
490
787
-"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5":
491
+"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5":
492
version "7.5.5"
493
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a"
494
integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==
@@ -793,96 +497,6 @@
497
lodash "^4.17.13"
498
to-fast-properties "^2.0.0"
499
796
-"@cliqz-oss/firefox-client@0.3.1":
797
- version "0.3.1"
798
- resolved "https://registry.yarnpkg.com/@cliqz-oss/firefox-client/-/firefox-client-0.3.1.tgz#86479239f060835608b06584afe5e0a1dd91613c"
799
- integrity sha512-RO+Tops/wGnBzWoZYkCraqyh2JqOejqJq5/a4b54HhmjTNSKdUPwAOK17EGg/zPb0nWqkuB7QyZsI9bo+ev8Kw==
800
- dependencies:
801
- colors "0.5.x"
802
- js-select "~0.6.0"
803
-
804
-"@cliqz-oss/node-firefox-connect@1.2.1":
805
- version "1.2.1"
806
- resolved "https://registry.yarnpkg.com/@cliqz-oss/node-firefox-connect/-/node-firefox-connect-1.2.1.tgz#1d42cf9a7ddcdde3ff232715d7712662966e2df4"
807
- integrity sha512-O/IyiB5pfztCdmxQZg0/xeq5w+YiP3gtJz8d4We2EpLPKzbDVjOrtfLKYgVfm6Ya6mbvDge1uLkSRwaoVCWKnA==
808
- dependencies:
809
- "@cliqz-oss/firefox-client" "0.3.1"
810
- es6-promise "^2.0.1"
811
-
812
-"@cnakazawa/watch@^1.0.3":
813
- version "1.0.3"
814
- resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
815
- integrity sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==
816
- dependencies:
817
- exec-sh "^0.3.2"
818
- minimist "^1.2.0"
819
-
820
-"@jest/console@^24.7.1":
821
- version "24.7.1"
822
- resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545"
823
- integrity sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==
824
- dependencies:
825
- "@jest/source-map" "^24.3.0"
826
- chalk "^2.0.1"
827
- slash "^2.0.0"
828
-
829
-"@jest/fake-timers@^24.8.0":
830
- version "24.8.0"
831
- resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.8.0.tgz#2e5b80a4f78f284bcb4bd5714b8e10dd36a8d3d1"
832
- integrity sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==
833
- dependencies:
834
- "@jest/types" "^24.8.0"
835
- jest-message-util "^24.8.0"
836
- jest-mock "^24.8.0"
837
-
838
-"@jest/source-map@^24.3.0":
839
- version "24.3.0"
840
- resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28"
841
- integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag==
842
- dependencies:
843
- callsites "^3.0.0"
844
- graceful-fs "^4.1.15"
845
- source-map "^0.6.0"
846
-
847
-"@jest/test-result@^24.8.0":
848
- version "24.8.0"
849
- resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.8.0.tgz#7675d0aaf9d2484caa65e048d9b467d160f8e9d3"
850
- integrity sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==
851
- dependencies:
852
- "@jest/console" "^24.7.1"
853
- "@jest/types" "^24.8.0"
854
- "@types/istanbul-lib-coverage" "^2.0.0"
855
-
856
-"@jest/transform@^24.8.0":
857
- version "24.8.0"
858
- resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.8.0.tgz#628fb99dce4f9d254c6fd9341e3eea262e06fef5"
859
- integrity sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==
860
- dependencies:
861
- "@babel/core" "^7.1.0"
862
- "@jest/types" "^24.8.0"
863
- babel-plugin-istanbul "^5.1.0"
864
- chalk "^2.0.1"
865
- convert-source-map "^1.4.0"
866
- fast-json-stable-stringify "^2.0.0"
867
- graceful-fs "^4.1.15"
868
- jest-haste-map "^24.8.0"
869
- jest-regex-util "^24.3.0"
870
- jest-util "^24.8.0"
871
- micromatch "^3.1.10"
872
- realpath-native "^1.1.0"
873
- slash "^2.0.0"
874
- source-map "^0.6.1"
875
- write-file-atomic "2.4.1"
876
-
877
-"@jest/types@^24.8.0":
878
- version "24.8.0"
879
- resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.8.0.tgz#f31e25948c58f0abd8c845ae26fcea1491dea7ad"
880
- integrity sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==
881
- dependencies:
882
- "@types/istanbul-lib-coverage" "^2.0.0"
883
- "@types/istanbul-reports" "^1.1.1"
884
- "@types/yargs" "^12.0.9"
885
-
500
"@mattiasbuelens/web-streams-polyfill@0.1.0":
501
version "0.1.0"
502
resolved "https://registry.yarnpkg.com/@mattiasbuelens/web-streams-polyfill/-/web-streams-polyfill-0.1.0.tgz#c06ebfa7e00cc512a878c3aaae4cf113ac89ac24"
@@ -890,265 +504,16 @@
504
dependencies:
505
"@types/whatwg-streams" "^0.0.6"
506
893
-"@reach/auto-id@0.2.0":
894
- version "0.2.0"
895
- resolved "https://registry.yarnpkg.com/@reach/auto-id/-/auto-id-0.2.0.tgz#97f9e48fe736aa5c6f4f32cf73c1f19d005f8550"
896
- integrity sha512-lVK/svL2HuQdp7jgvlrLkFsUx50Az9chAhxpiPwBqcS83I2pVWvXp98FOcSCCJCV++l115QmzHhFd+ycw1zLBg==
897
-
898
-"@reach/component-component@0.1.3", "@reach/component-component@^0.1.3":
899
- version "0.1.3"
900
- resolved "https://registry.yarnpkg.com/@reach/component-component/-/component-component-0.1.3.tgz#5d156319572dc38995b246f81878bc2577c517e5"
901
- integrity sha512-a1USH7L3bEfDdPN4iNZGvMEFuBfkdG+QNybeyDv8RloVFgZYRoM+KGXyy2KOfEnTUM8QWDRSROwaL3+ts5Angg==
902
-
903
-"@reach/menu-button@^0.1.17":
904
- version "0.1.18"
905
- resolved "https://registry.yarnpkg.com/@reach/menu-button/-/menu-button-0.1.18.tgz#cb9e3bf1c2a2bdb5d618697b87ad353dfbca123e"
906
- integrity sha512-MGdN8SWaQ0u0xj6KWUnK9fFc1VBg8NhNnFhEd2sp3D56XJcr08HU5GeVq/MFf5C97mxRnIPIKGnMPPeGAn9OFA==
907
- dependencies:
908
- "@reach/component-component" "0.1.3"
909
- "@reach/portal" "^0.2.1"
910
- "@reach/rect" "0.2.1"
911
- "@reach/utils" "^0.2.3"
912
- "@reach/window-size" "^0.1.4"
913
- warning "^4.0.2"
914
-
915
-"@reach/observe-rect@^1.0.3":
916
- version "1.0.3"
917
- resolved "https://registry.yarnpkg.com/@reach/observe-rect/-/observe-rect-1.0.3.tgz#2ea3dcc369ab22bd9f050a92ea319321356a61e8"
918
- integrity sha1-LqPcw2mrIr2fBQqS6jGTITVqYeg=
919
-
920
-"@reach/portal@^0.2.1":
921
- version "0.2.1"
922
- resolved "https://registry.yarnpkg.com/@reach/portal/-/portal-0.2.1.tgz#07720b999e0063a9e179c14dbdc60fd991cfc9fa"
923
- integrity sha512-pUQ0EtCcYm4ormEjJmdk4uzZCxOpaRHB8FDKJXy6q6GqRqQwZ4lAT1f2Tvw0DAmULmyZTpe1/heXY27Tdnct+Q==
924
- dependencies:
925
- "@reach/component-component" "^0.1.3"
926
-
927
-"@reach/rect@0.2.1", "@reach/rect@^0.2.1":
928
- version "0.2.1"
929
- resolved "https://registry.yarnpkg.com/@reach/rect/-/rect-0.2.1.tgz#7343020174c90e2290b844d17c03fd9c78e6b601"
930
- integrity sha512-aZ9RsNHDMQ3zETonikqu9/85iXxj+LPqZ9Gr9UAncj3AufYmGeWG3XG6b37B+7ORH+mkhVpLU2ZlIWxmOe9Cqg==
931
- dependencies:
932
- "@reach/component-component" "^0.1.3"
933
- "@reach/observe-rect" "^1.0.3"
934
-
935
-"@reach/tooltip@^0.2.2":
936
- version "0.2.2"
937
- resolved "https://registry.yarnpkg.com/@reach/tooltip/-/tooltip-0.2.2.tgz#a861ce38269b586597ab40417323b33d3d6dc927"
938
- integrity sha512-afcfqH6EzDHmwTB6g1k0dSbkyT0s9KPIi5bX56nNuldsCIasImFFYDjRZLhFcuxjskwIsHAi06yC3GV6mtcRxw==
939
- dependencies:
940
- "@reach/auto-id" "0.2.0"
941
- "@reach/portal" "^0.2.1"
942
- "@reach/rect" "^0.2.1"
943
- "@reach/utils" "^0.2.3"
944
- "@reach/visually-hidden" "^0.1.4"
945
- prop-types "^15.7.2"
946
-
947
-"@reach/utils@^0.2.3":
948
- version "0.2.3"
949
- resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.2.3.tgz#820f6a6af4301b4c5065cfc04bb89e6a3d1d723f"
950
- integrity sha512-zM9rA8jDchr05giMhL95dPeYkK67cBQnIhCVrOKKqgWGsv+2GE/HZqeptvU4zqs0BvIqsThwov+YxVNVh5csTQ==
951
-
952
-"@reach/visually-hidden@^0.1.4":
953
- version "0.1.4"
954
- resolved "https://registry.yarnpkg.com/@reach/visually-hidden/-/visually-hidden-0.1.4.tgz#0dc4ecedf523004337214187db70a46183bd945b"
955
- integrity sha512-QHbzXjflSlCvDd6vJwdwx16mSB+vUCCQMiU/wK/CgVNPibtpEiIbisyxkpZc55DyDFNUIqP91rSUsNae+ogGDQ==
956
-
957
-"@reach/window-size@^0.1.4":
958
- version "0.1.4"
959
- resolved "https://registry.yarnpkg.com/@reach/window-size/-/window-size-0.1.4.tgz#3257b646548f61c2708a661a683620fbe0a706cb"
960
- integrity sha512-JZshEuGsLvi6fUIJ7Unx12yNeM5SmqWjber2MLr9tfwf1hpNv73EiPBOIJyV0DjW7GXzjcOEvwnqysm59s2s/A==
961
- dependencies:
962
- "@reach/component-component" "^0.1.3"
963
-
964
-"@sindresorhus/is@^0.14.0":
965
- version "0.14.0"
966
- resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
967
- integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
968
-
969
-"@snyk/cli-interface@^2.0.2":
970
- version "2.0.2"
971
- resolved "https://registry.yarnpkg.com/@snyk/cli-interface/-/cli-interface-2.0.2.tgz#96dd229b3afda216a051b39a6ab520332d72db56"
972
- integrity sha512-2/wTI7ML7tMy7TKk49dcVPAdiVtybILpW+dlaoUFDZKcYuthgJeWkiifQvx7fhDcmNNCjY/+6WlVYjLvVVvXKA==
973
- dependencies:
974
- tslib "^1.9.3"
975
-
976
-"@snyk/composer-lockfile-parser@1.0.3":
977
- version "1.0.3"
978
- resolved "https://registry.yarnpkg.com/@snyk/composer-lockfile-parser/-/composer-lockfile-parser-1.0.3.tgz#4b703883ec36f3cec63c64355031e06698c771f5"
979
- integrity sha512-hb+6E7kMzWlcwfe//ILDoktBPKL2a3+RnJT/CXnzRXaiLQpsdkf5li4q2v0fmvd+4v7L3tTN8KM+//lJyviEkg==
980
- dependencies:
981
- lodash "^4.17.13"
982
-
983
-"@snyk/dep-graph@1.12.0":
984
- version "1.12.0"
985
- resolved "https://registry.yarnpkg.com/@snyk/dep-graph/-/dep-graph-1.12.0.tgz#aa0df8549849a4857bc5510e839da268293e4750"
986
- integrity sha512-n7+PlHn3SqznHgsCpeBRfEvU1oiQydoGkXQlnSB2+tfImiKXvY7YZbrg4wlbvYgylYiTbpCi5CpPNkJG14S+UQ==
987
- dependencies:
988
- graphlib "^2.1.5"
989
- lodash "^4.7.14"
990
- object-hash "^1.3.1"
991
- semver "^6.0.0"
992
- source-map-support "^0.5.11"
993
- tslib "^1.9.3"
994
-
995
-"@snyk/gemfile@1.2.0":
996
- version "1.2.0"
997
- resolved "https://registry.yarnpkg.com/@snyk/gemfile/-/gemfile-1.2.0.tgz#919857944973cce74c650e5428aaf11bcd5c0457"
998
- integrity sha512-nI7ELxukf7pT4/VraL4iabtNNMz8mUo7EXlqCFld8O5z6mIMLX9llps24iPpaIZOwArkY3FWA+4t+ixyvtTSIA==
999
-
1000
-"@szmarczak/http-timer@^1.1.2":
1001
- version "1.1.2"
1002
- resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
1003
- integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
1004
- dependencies:
1005
- defer-to-connect "^1.0.1"
1006
-
1007
-"@types/agent-base@^4.2.0":
1008
- version "4.2.0"
1009
- resolved "https://registry.yarnpkg.com/@types/agent-base/-/agent-base-4.2.0.tgz#00644e8b395b40e1bf50aaf1d22cabc1200d5051"
1010
- integrity sha512-8mrhPstU+ZX0Ugya8tl5DsDZ1I5ZwQzbL/8PA0z8Gj0k9nql7nkaMzmPVLj+l/nixWaliXi+EBiLA8bptw3z7Q==
1011
- dependencies:
1012
- "@types/events" "*"
1013
- "@types/node" "*"
1014
-
1015
-"@types/babel__core@^7.1.0":
1016
- version "7.1.2"
1017
- resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f"
1018
- integrity sha512-cfCCrFmiGY/yq0NuKNxIQvZFy9kY/1immpSpTngOnyIbD4+eJOG5mxphhHDv3CHL9GltO4GcKr54kGBg3RNdbg==
1019
- dependencies:
1020
- "@babel/parser" "^7.1.0"
1021
- "@babel/types" "^7.0.0"
1022
- "@types/babel__generator" "*"
1023
- "@types/babel__template" "*"
1024
- "@types/babel__traverse" "*"
1025
-
1026
-"@types/babel__generator@*":
1027
- version "7.0.2"
1028
- resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc"
1029
- integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ==
1030
- dependencies:
1031
- "@babel/types" "^7.0.0"
1032
-
1033
-"@types/babel__template@*":
1034
- version "7.0.2"
1035
- resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307"
1036
- integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==
1037
- dependencies:
1038
- "@babel/parser" "^7.1.0"
1039
- "@babel/types" "^7.0.0"
1040
-
1041
-"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6":
1042
- version "7.0.7"
1043
- resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.7.tgz#2496e9ff56196cc1429c72034e07eab6121b6f3f"
1044
- integrity sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==
1045
- dependencies:
1046
- "@babel/types" "^7.3.0"
1047
-
1048
-"@types/debug@^4.1.4":
1049
- version "4.1.5"
1050
- resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
1051
- integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==
1052
-
1053
-"@types/events@*":
1054
- version "3.0.0"
1055
- resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
1056
- integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
1057
-
1058
-"@types/glob@^7.1.1":
1059
- version "7.1.1"
1060
- resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
1061
- integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
1062
- dependencies:
1063
- "@types/events" "*"
1064
- "@types/minimatch" "*"
1065
- "@types/node" "*"
1066
-
1067
-"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
1068
- version "2.0.1"
1069
- resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
1070
- integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==
1071
-
1072
-"@types/istanbul-lib-report@*":
1073
- version "1.1.1"
1074
- resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c"
1075
- integrity sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==
1076
- dependencies:
1077
- "@types/istanbul-lib-coverage" "*"
1078
-
1079
-"@types/istanbul-reports@^1.1.1":
1080
- version "1.1.1"
1081
- resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a"
1082
- integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==
1083
- dependencies:
1084
- "@types/istanbul-lib-coverage" "*"
1085
- "@types/istanbul-lib-report" "*"
1086
-
507
"@types/json-schema@^7.0.3":
508
version "7.0.3"
509
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"
510
integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==
511
1092
-"@types/minimatch@*", "@types/minimatch@^3.0.3":
1093
- version "3.0.3"
1094
- resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
1095
- integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
1096
-
1097
-"@types/node@*":
1098
- version "12.7.1"
1099
- resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d"
1100
- integrity sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw==
1101
-
1102
-"@types/node@^10.12.18":
1103
- version "10.14.15"
1104
- resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.15.tgz#e8f7729b631be1b02ae130ff0b61f3e018000640"
1105
- integrity sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g==
1106
-
1107
-"@types/node@^6.14.4":
1108
- version "6.14.7"
1109
- resolved "https://registry.yarnpkg.com/@types/node/-/node-6.14.7.tgz#2173f79d7a61d97d3aad2feeaac7ac69a3df39af"
1110
- integrity sha512-YbPXbaynBTe0pVExPhL76TsWnxSPeFAvImIsmylpBWn/yfw+lHy+Q68aawvZHsgskT44ZAoeE67GM5f+Brekew==
1111
-
1112
-"@types/node@^8.0.7":
1113
- version "8.10.51"
1114
- resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.51.tgz#80600857c0a47a8e8bafc2dae6daed6db58e3627"
1115
- integrity sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==
1116
-
1117
-"@types/package-json@^5.0.0":
1118
- version "5.0.1"
1119
- resolved "https://registry.yarnpkg.com/@types/package-json/-/package-json-5.0.1.tgz#0157acd348cf3ec8834290367e7f24b85cf6e1d0"
1120
- integrity sha512-0M6UdBDyGmgWly5Dtenf1U9HPMNCXtAnvvxIKoK9u6b5CCrxiVxc32eoqBzLccH/1Z8ApY927UiYoQ5cwPKcJw==
1121
- dependencies:
1122
- package-json "*"
1123
-
1124
-"@types/semver@^5.5.0":
1125
- version "5.5.0"
1126
- resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45"
1127
- integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==
1128
-
1129
-"@types/stack-utils@^1.0.1":
1130
- version "1.0.1"
1131
- resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
1132
- integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
1133
-
512
"@types/whatwg-streams@^0.0.6":
513
version "0.0.6"
514
resolved "https://registry.yarnpkg.com/@types/whatwg-streams/-/whatwg-streams-0.0.6.tgz#5062c67efb695c886fe3dbb9618df35aac418503"
515
integrity sha512-O4Hat94N1RUCObqAbVUtd6EcucseqBcpfbFXzy12CYF6BQVHWR+ztDA3YPjewCmdKHYZ5VA7TZ5hq2bMyqxiBw==
516
1139
-"@types/xml2js@0.4.3":
1140
- version "0.4.3"
1141
- resolved "https://registry.yarnpkg.com/@types/xml2js/-/xml2js-0.4.3.tgz#2f41bfc74d5a4022511721f872ed395a210ad3b7"
1142
- integrity sha512-Pv2HGRE4gWLs31In7nsyXEH4uVVsd0HNV9i2dyASvtDIlOtSTr1eczPLDpdEuyv5LWH5LT20GIXwPjkshKWI1g==
1143
- dependencies:
1144
- "@types/events" "*"
1145
- "@types/node" "*"
1146
-
1147
-"@types/yargs@^12.0.9":
1148
- version "12.0.12"
1149
- resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916"
1150
- integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==
1151
-
517
"@typescript-eslint/experimental-utils@^1.13.0":
518
version "1.13.0"
519
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz#b08c60d780c0067de2fb44b04b432f540138301e"
@@ -1166,199 +531,20 @@
531
lodash.unescape "4.0.1"
532
semver "5.5.0"
533
1169
-"@webassemblyjs/ast@1.8.5":
1170
- version "1.8.5"
1171
- resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
1172
- integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==
1173
- dependencies:
1174
- "@webassemblyjs/helper-module-context" "1.8.5"
1175
- "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
1176
- "@webassemblyjs/wast-parser" "1.8.5"
1177
-
1178
-"@webassemblyjs/floating-point-hex-parser@1.8.5":
1179
- version "1.8.5"
1180
- resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721"
1181
- integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==
534
+abab@^1.0.4:
535
+ version "1.0.4"
536
+ resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
537
+ integrity sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=
538
1183
-"@webassemblyjs/helper-api-error@1.8.5":
1184
- version "1.8.5"
1185
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7"
1186
- integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==
539
+abab@^2.0.0:
540
+ version "2.0.0"
541
+ resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f"
542
+ integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==
543
1188
-"@webassemblyjs/helper-buffer@1.8.5":
1189
- version "1.8.5"
1190
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204"
1191
- integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==
1192
-
1193
-"@webassemblyjs/helper-code-frame@1.8.5":
1194
- version "1.8.5"
1195
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e"
1196
- integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==
1197
- dependencies:
1198
- "@webassemblyjs/wast-printer" "1.8.5"
1199
-
1200
-"@webassemblyjs/helper-fsm@1.8.5":
1201
- version "1.8.5"
1202
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452"
1203
- integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==
1204
-
1205
-"@webassemblyjs/helper-module-context@1.8.5":
1206
- version "1.8.5"
1207
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245"
1208
- integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==
1209
- dependencies:
1210
- "@webassemblyjs/ast" "1.8.5"
1211
- mamacro "^0.0.3"
1212
-
1213
-"@webassemblyjs/helper-wasm-bytecode@1.8.5":
1214
- version "1.8.5"
1215
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61"
1216
- integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==
1217
-
1218
-"@webassemblyjs/helper-wasm-section@1.8.5":
1219
- version "1.8.5"
1220
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf"
1221
- integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==
1222
- dependencies:
1223
- "@webassemblyjs/ast" "1.8.5"
1224
- "@webassemblyjs/helper-buffer" "1.8.5"
1225
- "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
1226
- "@webassemblyjs/wasm-gen" "1.8.5"
1227
-
1228
-"@webassemblyjs/ieee754@1.8.5":
1229
- version "1.8.5"
1230
- resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e"
1231
- integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==
1232
- dependencies:
1233
- "@xtuc/ieee754" "^1.2.0"
1234
-
1235
-"@webassemblyjs/leb128@1.8.5":
1236
- version "1.8.5"
1237
- resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10"
1238
- integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==
1239
- dependencies:
1240
- "@xtuc/long" "4.2.2"
1241
-
1242
-"@webassemblyjs/utf8@1.8.5":
1243
- version "1.8.5"
1244
- resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc"
1245
- integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==
1246
-
1247
-"@webassemblyjs/wasm-edit@1.8.5":
1248
- version "1.8.5"
1249
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a"
1250
- integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==
1251
- dependencies:
1252
- "@webassemblyjs/ast" "1.8.5"
1253
- "@webassemblyjs/helper-buffer" "1.8.5"
1254
- "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
1255
- "@webassemblyjs/helper-wasm-section" "1.8.5"
1256
- "@webassemblyjs/wasm-gen" "1.8.5"
1257
- "@webassemblyjs/wasm-opt" "1.8.5"
1258
- "@webassemblyjs/wasm-parser" "1.8.5"
1259
- "@webassemblyjs/wast-printer" "1.8.5"
1260
-
1261
-"@webassemblyjs/wasm-gen@1.8.5":
1262
- version "1.8.5"
1263
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc"
1264
- integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==
1265
- dependencies:
1266
- "@webassemblyjs/ast" "1.8.5"
1267
- "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
1268
- "@webassemblyjs/ieee754" "1.8.5"
1269
- "@webassemblyjs/leb128" "1.8.5"
1270
- "@webassemblyjs/utf8" "1.8.5"
1271
-
1272
-"@webassemblyjs/wasm-opt@1.8.5":
1273
- version "1.8.5"
1274
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264"
1275
- integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==
1276
- dependencies:
1277
- "@webassemblyjs/ast" "1.8.5"
1278
- "@webassemblyjs/helper-buffer" "1.8.5"
1279
- "@webassemblyjs/wasm-gen" "1.8.5"
1280
- "@webassemblyjs/wasm-parser" "1.8.5"
1281
-
1282
-"@webassemblyjs/wasm-parser@1.8.5":
1283
- version "1.8.5"
1284
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d"
1285
- integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==
1286
- dependencies:
1287
- "@webassemblyjs/ast" "1.8.5"
1288
- "@webassemblyjs/helper-api-error" "1.8.5"
1289
- "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
1290
- "@webassemblyjs/ieee754" "1.8.5"
1291
- "@webassemblyjs/leb128" "1.8.5"
1292
- "@webassemblyjs/utf8" "1.8.5"
1293
-
1294
-"@webassemblyjs/wast-parser@1.8.5":
1295
- version "1.8.5"
1296
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c"
1297
- integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==
1298
- dependencies:
1299
- "@webassemblyjs/ast" "1.8.5"
1300
- "@webassemblyjs/floating-point-hex-parser" "1.8.5"
1301
- "@webassemblyjs/helper-api-error" "1.8.5"
1302
- "@webassemblyjs/helper-code-frame" "1.8.5"
1303
- "@webassemblyjs/helper-fsm" "1.8.5"
1304
- "@xtuc/long" "4.2.2"
1305
-
1306
-"@webassemblyjs/wast-printer@1.8.5":
1307
- version "1.8.5"
1308
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc"
1309
- integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==
1310
- dependencies:
1311
- "@webassemblyjs/ast" "1.8.5"
1312
- "@webassemblyjs/wast-parser" "1.8.5"
1313
- "@xtuc/long" "4.2.2"
1314
-
1315
-"@xtuc/ieee754@^1.2.0":
1316
- version "1.2.0"
1317
- resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
1318
- integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
1319
-
1320
-"@xtuc/long@4.2.2":
1321
- version "4.2.2"
1322
- resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
1323
- integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
1324
-
1325
-"@yarnpkg/lockfile@^1.0.2":
1326
- version "1.1.0"
1327
- resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
1328
- integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
1329
-
1330
-Base64@~0.2.0:
1331
- version "0.2.1"
1332
- resolved "https://registry.yarnpkg.com/Base64/-/Base64-0.2.1.tgz#ba3a4230708e186705065e66babdd4c35cf60028"
1333
- integrity sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg=
1334
-
1335
-JSONSelect@0.2.1:
1336
- version "0.2.1"
1337
- resolved "https://registry.yarnpkg.com/JSONSelect/-/JSONSelect-0.2.1.tgz#415418a526d33fe31d74b4defa3c836d485ec203"
1338
- integrity sha1-QVQYpSbTP+MddLTe+jyDbUhewgM=
1339
-
1340
-abab@^1.0.4:
1341
- version "1.0.4"
1342
- resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
1343
- integrity sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=
1344
-
1345
-abab@^2.0.0:
1346
- version "2.0.0"
1347
- resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f"
1348
- integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==
1349
-
1350
-abbrev@1, abbrev@^1.1.1:
1351
- version "1.1.1"
1352
- resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
1353
- integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
1354
-
1355
-accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
1356
- version "1.3.7"
1357
- resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
1358
- integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
1359
- dependencies:
1360
- mime-types "~2.1.24"
1361
- negotiator "0.6.2"
544
+abbrev@1:
545
+ version "1.1.1"
546
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
547
+ integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
548
549
acorn-globals@^4.1.0:
550
version "4.3.3"
@@ -1368,13 +554,6 @@ acorn-globals@^4.1.0:
554
acorn "^6.0.1"
555
acorn-walk "^6.0.1"
556
1371
-acorn-jsx@^3.0.0:
1372
- version "3.0.1"
1373
- resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
1374
- integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=
1375
- dependencies:
1376
- acorn "^3.0.4"
1377
-
557
acorn-jsx@^5.0.0:
558
version "5.0.1"
559
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e"
@@ -1385,12 +564,7 @@ acorn-walk@^6.0.1:
564
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c"
565
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
566
1388
-acorn@^3.0.4:
1389
- version "3.3.0"
1390
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
1391
- integrity sha1-ReN/s56No/JbruP/U2niu18iAXo=
1392
-
1393
-acorn@^5.2.1, acorn@^5.3.0, acorn@^5.5.0:
567
+acorn@^5.2.1, acorn@^5.3.0:
568
version "5.7.3"
569
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
570
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
@@ -1400,157 +574,13 @@ acorn@^6.0.1, acorn@^6.0.7:
574
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51"
575
integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==
576
1403
-acorn@^6.2.1:
1404
- version "6.3.0"
1405
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
1406
- integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
1407
-
1408
-adbkit-logcat@^1.1.0:
1409
- version "1.1.0"
1410
- resolved "https://registry.yarnpkg.com/adbkit-logcat/-/adbkit-logcat-1.1.0.tgz#01d7f9b0cef9093a30bcb3b007efff301508962f"
1411
- integrity sha1-Adf5sM75CTowvLOwB+//MBUIli8=
1412
-
1413
-adbkit-monkey@~1.0.1:
1414
- version "1.0.1"
1415
- resolved "https://registry.yarnpkg.com/adbkit-monkey/-/adbkit-monkey-1.0.1.tgz#f291be701a2efc567a63fc7aa6afcded31430be1"
1416
- integrity sha1-8pG+cBou/FZ6Y/x6pq/N7TFDC+E=
1417
- dependencies:
1418
- async "~0.2.9"
1419
-
1420
-adbkit@2.11.1:
1421
- version "2.11.1"
1422
- resolved "https://registry.yarnpkg.com/adbkit/-/adbkit-2.11.1.tgz#7da847fe561254f3121088947bc1907ef053e894"
1423
- integrity sha512-hDTiRg9NX3HQt7WoDAPCplUpvzr4ZzQa2lq7BdTTJ/iOZ6O7YNAs6UYD8sFAiBEcYHDRIyq3cm9sZP6uZnhvXw==
1424
- dependencies:
1425
- adbkit-logcat "^1.1.0"
1426
- adbkit-monkey "~1.0.1"
1427
- bluebird "~2.9.24"
1428
- commander "^2.3.0"
1429
- debug "~2.6.3"
1430
- node-forge "^0.7.1"
1431
- split "~0.3.3"
1432
-
1433
-addons-linter@1.10.0:
1434
- version "1.10.0"
1435
- resolved "https://registry.yarnpkg.com/addons-linter/-/addons-linter-1.10.0.tgz#4b079647c860161602ff5772c1510bb63ec644ec"
1436
- integrity sha512-2i2qSayVPx4h1Aa2ZTdQlpgmjcCNIHZ4AJQS8V/QsBXIdmXl+Djmeyr096bjaC3Usq0rZfYhGgFdwR1dgHVItw==
1437
- dependencies:
1438
- ajv "6.10.0"
1439
- ajv-merge-patch "4.1.0"
1440
- chalk "2.4.2"
1441
- cheerio "1.0.0-rc.3"
1442
- columnify "1.5.4"
1443
- common-tags "1.8.0"
1444
- crx-parser "0.1.2"
1445
- deepmerge "3.2.0"
1446
- dispensary "0.37.0"
1447
- es6-promisify "6.0.1"
1448
- eslint "5.16.0"
1449
- eslint-plugin-no-unsafe-innerhtml "1.0.16"
1450
- eslint-visitor-keys "1.0.0"
1451
- espree "5.0.1"
1452
- esprima "4.0.1"
1453
- first-chunk-stream "3.0.0"
1454
- fluent-syntax "0.13.0"
1455
- glob "7.1.4"
1456
- is-mergeable-object "1.1.0"
1457
- jed "1.1.1"
1458
- mdn-browser-compat-data "0.0.82"
1459
- os-locale "3.1.0"
1460
- pino "5.12.6"
1461
- po2json "0.4.5"
1462
- postcss "7.0.16"
1463
- probe-image-size "4.0.0"
1464
- regenerator-runtime "0.13.2"
1465
- relaxed-json "1.0.3"
1466
- semver "6.1.1"
1467
- source-map-support "0.5.12"
1468
- strip-bom-stream "4.0.0"
1469
- tosource "1.0.0"
1470
- upath "1.1.2"
1471
- whatwg-url "7.0.0"
1472
- yargs "13.2.4"
1473
- yauzl "2.10.0"
1474
- optionalDependencies:
1475
- fsevents "2.0.7"
1476
-
1477
-adm-zip@~0.4.x:
1478
- version "0.4.13"
1479
- resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.13.tgz#597e2f8cc3672151e1307d3e95cddbc75672314a"
1480
- integrity sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==
1481
-
1482
-agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0:
1483
- version "4.3.0"
1484
- resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
1485
- integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
1486
- dependencies:
1487
- es6-promisify "^5.0.0"
1488
-
577
agent-base@^4.1.0:
578
version "4.1.2"
579
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.1.2.tgz#80fa6cde440f4dcf9af2617cf246099b5d99f0c8"
580
dependencies:
581
es6-promisify "^5.0.0"
582
1495
-agent-base@~4.2.1:
1496
- version "4.2.1"
1497
- resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
1498
- integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
1499
- dependencies:
1500
- es6-promisify "^5.0.0"
1501
-
1502
-ajv-errors@^1.0.0:
1503
- version "1.0.1"
1504
- resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
1505
- integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
1506
-
1507
-ajv-keywords@^1.0.0:
1508
- version "1.5.1"
1509
- resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
1510
- integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw=
1511
-
1512
-ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
1513
- version "3.4.1"
1514
- resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da"
1515
- integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
1516
-
1517
-ajv-merge-patch@4.1.0:
1518
- version "4.1.0"
1519
- resolved "https://registry.yarnpkg.com/ajv-merge-patch/-/ajv-merge-patch-4.1.0.tgz#cd580e5860ac53431d6aa901fa3d5e2eb2b74a6c"
1520
- integrity sha512-0mAYXMSauA8RZ7r+B4+EAOYcZEcO9OK5EiQCR7W7Cv4E44pJj56ZnkKLJ9/PAcOc0dT+LlV9fdDcq2TxVJfOYw==
1521
- dependencies:
1522
- fast-json-patch "^2.0.6"
1523
- json-merge-patch "^0.2.3"
1524
-
1525
-ajv@6.10.0:
1526
- version "6.10.0"
1527
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
1528
- integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==
1529
- dependencies:
1530
- fast-deep-equal "^2.0.1"
1531
- fast-json-stable-stringify "^2.0.0"
1532
- json-schema-traverse "^0.4.1"
1533
- uri-js "^4.2.2"
1534
-
1535
-ajv@^4.7.0:
1536
- version "4.11.8"
1537
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
1538
- integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=
1539
- dependencies:
1540
- co "^4.6.0"
1541
- json-stable-stringify "^1.0.1"
1542
-
1543
-ajv@^5.1.0:
1544
- version "5.5.2"
1545
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
1546
- integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=
1547
- dependencies:
1548
- co "^4.6.0"
1549
- fast-deep-equal "^1.0.0"
1550
- fast-json-stable-stringify "^2.0.0"
1551
- json-schema-traverse "^0.3.0"
1552
-
1553
-ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1:
583
+ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
584
version "6.10.2"
585
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52"
586
integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==
@@ -1560,65 +590,29 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1:
590
json-schema-traverse "^0.4.1"
591
uri-js "^4.2.2"
592
1563
-ansi-align@^2.0.0:
1564
- version "2.0.0"
1565
- resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
1566
- integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=
1567
- dependencies:
1568
- string-width "^2.0.0"
1569
-
1570
-ansi-align@^3.0.0:
1571
- version "3.0.0"
1572
- resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb"
1573
- integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==
1574
- dependencies:
1575
- string-width "^3.0.0"
1576
-
593
ansi-colors@^1.0.1:
594
version "1.1.0"
595
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9"
596
dependencies:
597
ansi-wrap "^0.1.0"
598
1583
-ansi-colors@^3.0.0:
1584
- version "3.2.4"
1585
- resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf"
1586
- integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==
1587
-
599
ansi-cyan@^0.1.1:
600
version "0.1.1"
601
resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873"
602
dependencies:
603
ansi-wrap "0.1.0"
604
1594
-ansi-escapes@^1.1.0:
1595
- version "1.4.0"
1596
- resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
1597
- integrity sha1-06ioOzGapneTZisT52HHkRQiMG4=
1598
-
605
ansi-escapes@^3.0.0, ansi-escapes@^3.2.0:
606
version "3.2.0"
607
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
608
integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
609
1604
-ansi-escapes@^4.1.0, ansi-escapes@^4.2.1:
1605
- version "4.2.1"
1606
- resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.1.tgz#4dccdb846c3eee10f6d64dea66273eab90c37228"
1607
- integrity sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==
1608
- dependencies:
1609
- type-fest "^0.5.2"
1610
-
610
ansi-gray@^0.1.1:
611
version "0.1.1"
612
resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251"
613
dependencies:
614
ansi-wrap "0.1.0"
615
1617
-ansi-html@0.0.7:
1618
- version "0.0.7"
1619
- resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e"
1620
- integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4=
1621
-
616
ansi-red@^0.1.1:
617
version "0.1.1"
618
resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c"
@@ -1648,25 +642,10 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
642
dependencies:
643
color-convert "^1.9.0"
644
1651
-ansi-styles@~1.0.0:
1652
- version "1.0.0"
1653
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
1654
- integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=
1655
-
645
ansi-wrap@0.1.0, ansi-wrap@^0.1.0:
646
version "0.1.0"
647
resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
648
1660
-ansicolors@^0.3.2:
1661
- version "0.3.2"
1662
- resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
1663
- integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=
1664
-
1665
-any-promise@^1.0.0, any-promise@^1.1.0, any-promise@^1.3.0, any-promise@~1.3.0:
1666
- version "1.3.0"
1667
- resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
1668
- integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
1669
-
649
anymatch@^2.0.0:
650
version "2.0.0"
651
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@@ -1682,71 +661,11 @@ append-transform@^0.4.0:
661
dependencies:
662
default-require-extensions "^1.0.0"
663
1685
-aproba@^1.0.3, aproba@^1.1.1:
664
+aproba@^1.0.3:
665
version "1.2.0"
666
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
667
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
668
1690
-archiver-utils@^1.3.0:
1691
- version "1.3.0"
1692
- resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-1.3.0.tgz#e50b4c09c70bf3d680e32ff1b7994e9f9d895174"
1693
- integrity sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=
1694
- dependencies:
1695
- glob "^7.0.0"
1696
- graceful-fs "^4.1.0"
1697
- lazystream "^1.0.0"
1698
- lodash "^4.8.0"
1699
- normalize-path "^2.0.0"
1700
- readable-stream "^2.0.0"
1701
-
1702
-archiver-utils@^2.1.0:
1703
- version "2.1.0"
1704
- resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2"
1705
- integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==
1706
- dependencies:
1707
- glob "^7.1.4"
1708
- graceful-fs "^4.2.0"
1709
- lazystream "^1.0.0"
1710
- lodash.defaults "^4.2.0"
1711
- lodash.difference "^4.5.0"
1712
- lodash.flatten "^4.4.0"
1713
- lodash.isplainobject "^4.0.6"
1714
- lodash.union "^4.6.0"
1715
- normalize-path "^3.0.0"
1716
- readable-stream "^2.0.0"
1717
-
1718
-archiver@^3.0.0:
1719
- version "3.1.1"
1720
- resolved "https://registry.yarnpkg.com/archiver/-/archiver-3.1.1.tgz#9db7819d4daf60aec10fe86b16cb9258ced66ea0"
1721
- integrity sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==
1722
- dependencies:
1723
- archiver-utils "^2.1.0"
1724
- async "^2.6.3"
1725
- buffer-crc32 "^0.2.1"
1726
- glob "^7.1.4"
1727
- readable-stream "^3.4.0"
1728
- tar-stream "^2.1.0"
1729
- zip-stream "^2.1.2"
1730
-
1731
-archiver@~2.1.0:
1732
- version "2.1.1"
1733
- resolved "https://registry.yarnpkg.com/archiver/-/archiver-2.1.1.tgz#ff662b4a78201494a3ee544d3a33fe7496509ebc"
1734
- integrity sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=
1735
- dependencies:
1736
- archiver-utils "^1.3.0"
1737
- async "^2.0.0"
1738
- buffer-crc32 "^0.2.1"
1739
- glob "^7.0.0"
1740
- lodash "^4.8.0"
1741
- readable-stream "^2.0.0"
1742
- tar-stream "^1.5.0"
1743
- zip-stream "^1.2.0"
1744
-
1745
-archy@^1.0.0:
1746
- version "1.0.0"
1747
- resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
1748
- integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=
1749
-
669
are-we-there-yet@~1.1.2:
670
version "1.1.5"
671
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
@@ -1793,72 +712,15 @@ arr-union@^3.1.0:
712
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
713
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
714
1796
-array-differ@^3.0.0:
1797
- version "3.0.0"
1798
- resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b"
1799
- integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==
1800
-
715
array-equal@^1.0.0:
716
version "1.0.0"
717
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
718
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
719
1806
-array-filter@~0.0.0:
1807
- version "0.0.1"
1808
- resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
1809
- integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw=
1810
-
1811
-array-find-index@^1.0.1, array-find-index@^1.0.2:
1812
- version "1.0.2"
1813
- resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
1814
- integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=
1815
-
1816
-array-flatten@1.1.1:
1817
- version "1.1.1"
1818
- resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
1819
- integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
1820
-
1821
-array-flatten@^2.1.0:
1822
- version "2.1.2"
1823
- resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
1824
- integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
1825
-
1826
-array-from@~2.1.1:
1827
- version "2.1.1"
1828
- resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195"
1829
- integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=
1830
-
1831
-array-map@~0.0.0:
1832
- version "0.0.0"
1833
- resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
1834
- integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=
1835
-
1836
-array-reduce@~0.0.0:
1837
- version "0.0.0"
1838
- resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
1839
- integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=
1840
-
720
array-slice@^0.2.3:
721
version "0.2.3"
722
resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5"
723
1845
-array-union@^1.0.1:
1846
- version "1.0.2"
1847
- resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
1848
- integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=
1849
- dependencies:
1850
- array-uniq "^1.0.1"
1851
-
1852
-array-union@^2.1.0:
1853
- version "2.1.0"
1854
- resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
1855
- integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
1856
-
1857
-array-uniq@^1.0.1:
1858
- version "1.0.3"
1859
- resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
1860
- integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
1861
-
724
array-unique@^0.2.1:
725
version "0.2.1"
726
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
@@ -1879,12 +741,6 @@ array.prototype.find@^2.0.1:
741
arrify@^1.0.1:
742
version "1.0.1"
743
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
1882
- integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
1883
-
1884
-arrify@^2.0.1:
1885
- version "2.0.1"
1886
- resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
1887
- integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
744
745
art@^0.10.1:
746
version "0.10.1"
@@ -1894,15 +750,6 @@ asap@~2.0.3:
750
version "2.0.6"
751
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
752
1897
-asn1.js@^4.0.0:
1898
- version "4.10.1"
1899
- resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
1900
- integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==
1901
- dependencies:
1902
- bn.js "^4.0.0"
1903
- inherits "^2.0.1"
1904
- minimalistic-assert "^1.0.0"
1905
-
753
asn1@~0.2.3:
754
version "0.2.3"
755
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
@@ -1915,24 +762,11 @@ assert-plus@^0.2.0:
762
version "0.2.0"
763
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
764
1918
-assert@^1.1.1:
1919
- version "1.5.0"
1920
- resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
1921
- integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==
1922
- dependencies:
1923
- object-assign "^4.1.1"
1924
- util "0.10.3"
1925
-
765
assign-symbols@^1.0.0:
766
version "1.0.0"
767
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
768
integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
769
1931
-ast-types@0.x.x:
1932
- version "0.13.2"
1933
- resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48"
1934
- integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==
1935
-
770
astral-regex@^1.0.0:
771
version "1.0.0"
772
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
@@ -1943,40 +777,18 @@ async-each@^1.0.1:
777
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
778
integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
779
1946
-async-limiter@^1.0.0, async-limiter@~1.0.0:
780
+async-limiter@~1.0.0:
781
version "1.0.1"
782
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
783
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
784
1951
-async@^1.4.0, async@^1.5.2:
1952
- version "1.5.2"
1953
- resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
1954
- integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
1955
-
1956
-async@^2.0.0, async@^2.1.4, async@^2.6.3:
785
+async@^2.1.4:
786
version "2.6.3"
787
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
788
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
789
dependencies:
790
lodash "^4.17.14"
791
1963
-async@~0.2.9:
1964
- version "0.2.10"
1965
- resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
1966
- integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E=
1967
-
1968
-async@~2.5.0:
1969
- version "2.5.0"
1970
- resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d"
1971
- integrity sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==
1972
- dependencies:
1973
- lodash "^4.14.0"
1974
-
1975
-async@~3.0.0:
1976
- version "3.0.1"
1977
- resolved "https://registry.yarnpkg.com/async/-/async-3.0.1.tgz#dfeb34657d1e63c94c0eee424297bf8a2c9a8182"
1978
- integrity sha512-ZswD8vwPtmBZzbn9xyi8XBQWXH3AvOQ43Za1KWYq7JeycrZuUYzx01KvHcVbXltjqH4y0MWrQ33008uLTqXuDw==
1979
-
792
asynckit@^0.4.0:
793
version "0.4.0"
794
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -1995,12 +807,12 @@ aws-sign2@~0.7.0:
807
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
808
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
809
1998
-aws4@^1.2.1, aws4@^1.6.0, aws4@^1.8.0:
810
+aws4@^1.2.1, aws4@^1.8.0:
811
version "1.8.0"
812
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
813
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
814
2003
-babel-code-frame@^6.16.0, babel-code-frame@^6.26.0:
815
+babel-code-frame@^6.26.0:
816
version "6.26.0"
817
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
818
dependencies:
@@ -2032,11 +844,6 @@ babel-core@^6.0.0, babel-core@^6.26.0, babel-core@^6.7.2:
844
slash "^1.0.0"
845
source-map "^0.5.7"
846
2035
-babel-core@^7.0.0-bridge:
2036
- version "7.0.0-bridge.0"
2037
- resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece"
2038
- integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==
2039
-
847
babel-eslint@^10.0.0:
848
version "10.0.0"
849
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.0.tgz#0bb43e6b11a119bf3defbb1ee2521f42e2d413c9"
@@ -2049,18 +856,6 @@ babel-eslint@^10.0.0:
856
eslint-scope "3.7.1"
857
eslint-visitor-keys "^1.0.0"
858
2052
-babel-eslint@^9.0.0:
2053
- version "9.0.0"
2054
- resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-9.0.0.tgz#7d9445f81ed9f60aff38115f838970df9f2b6220"
2055
- integrity sha512-itv1MwE3TMbY0QtNfeL7wzak1mV47Uy+n6HtSOO4Xd7rvmO+tsGQSgyOEEgo6Y2vHZKZphaoelNeSVj4vkLA1g==
2056
- dependencies:
2057
- "@babel/code-frame" "^7.0.0"
2058
- "@babel/parser" "^7.0.0"
2059
- "@babel/traverse" "^7.0.0"
2060
- "@babel/types" "^7.0.0"
2061
- eslint-scope "3.7.1"
2062
- eslint-visitor-keys "^1.0.0"
2063
-
859
babel-generator@^6.18.0, babel-generator@^6.26.0:
860
version "6.26.1"
861
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90"
@@ -2157,29 +952,6 @@ babel-jest@^23.6.0:
952
babel-plugin-istanbul "^4.1.6"
953
babel-preset-jest "^23.2.0"
954
2160
-babel-jest@^24.7.1:
2161
- version "24.8.0"
2162
- resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.8.0.tgz#5c15ff2b28e20b0f45df43fe6b7f2aae93dba589"
2163
- integrity sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw==
2164
- dependencies:
2165
- "@jest/transform" "^24.8.0"
2166
- "@jest/types" "^24.8.0"
2167
- "@types/babel__core" "^7.1.0"
2168
- babel-plugin-istanbul "^5.1.0"
2169
- babel-preset-jest "^24.6.0"
2170
- chalk "^2.4.2"
2171
- slash "^2.0.0"
2172
-
2173
-babel-loader@^8.0.4:
2174
- version "8.0.6"
2175
- resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb"
2176
- integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==
2177
- dependencies:
2178
- find-cache-dir "^2.0.0"
2179
- loader-utils "^1.0.2"
2180
- mkdirp "^0.5.1"
2181
- pify "^4.0.1"
2182
-
955
babel-messages@^6.23.0:
956
version "6.23.0"
957
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
@@ -2209,28 +981,11 @@ babel-plugin-istanbul@^4.1.6:
981
istanbul-lib-instrument "^1.10.1"
982
test-exclude "^4.2.1"
983
2212
-babel-plugin-istanbul@^5.1.0:
2213
- version "5.2.0"
2214
- resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854"
2215
- integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==
2216
- dependencies:
2217
- "@babel/helper-plugin-utils" "^7.0.0"
2218
- find-up "^3.0.0"
2219
- istanbul-lib-instrument "^3.3.0"
2220
- test-exclude "^5.2.3"
2221
-
984
babel-plugin-jest-hoist@^23.2.0:
985
version "23.2.0"
986
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167"
987
integrity sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc=
988
2227
-babel-plugin-jest-hoist@^24.6.0:
2228
- version "24.6.0"
2229
- resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz#f7f7f7ad150ee96d7a5e8e2c5da8319579e78019"
2230
- integrity sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w==
2231
- dependencies:
2232
- "@types/babel__traverse" "^7.0.6"
2233
-
989
babel-plugin-syntax-class-properties@^6.8.0:
990
version "6.13.0"
991
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
@@ -2423,15 +1178,6 @@ babel-plugin-transform-strict-mode@^6.24.1:
1178
babel-runtime "^6.22.0"
1179
babel-types "^6.24.1"
1180
2426
-babel-polyfill@6.16.0:
2427
- version "6.16.0"
2428
- resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.16.0.tgz#2d45021df87e26a374b6d4d1a9c65964d17f2422"
2429
- integrity sha1-LUUCHfh+JqN0ttTRqcZZZNF/JCI=
2430
- dependencies:
2431
- babel-runtime "^6.9.1"
2432
- core-js "^2.4.0"
2433
- regenerator-runtime "^0.9.5"
2434
-
1181
babel-polyfill@^6.23.0:
1182
version "6.26.0"
1183
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
@@ -2481,14 +1227,6 @@ babel-preset-jest@^23.2.0:
1227
babel-plugin-jest-hoist "^23.2.0"
1228
babel-plugin-syntax-object-rest-spread "^6.13.0"
1229
2484
-babel-preset-jest@^24.6.0:
2485
- version "24.6.0"
2486
- resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz#66f06136eefce87797539c0d63f1769cc3915984"
2487
- integrity sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw==
2488
- dependencies:
2489
- "@babel/plugin-syntax-object-rest-spread" "^7.0.0"
2490
- babel-plugin-jest-hoist "^24.6.0"
2491
-
1230
babel-register@^6.26.0:
1231
version "6.26.0"
1232
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
@@ -2501,7 +1239,7 @@ babel-register@^6.26.0:
1239
mkdirp "^0.5.1"
1240
source-map-support "^0.4.15"
1241
2504
-babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.9.1:
1242
+babel-runtime@^6.22.0, babel-runtime@^6.26.0:
1243
version "6.26.0"
1244
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
1245
dependencies:
@@ -2549,16 +1287,6 @@ balanced-match@^1.0.0:
1287
version "1.0.0"
1288
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
1289
2552
-base64-js@0.0.8:
2553
- version "0.0.8"
2554
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978"
2555
- integrity sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=
2556
-
2557
-base64-js@^1.0.2:
2558
- version "1.3.1"
2559
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
2560
- integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
2561
-
1290
base@^0.11.1:
1291
version "0.11.2"
1292
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
@@ -2572,22 +1300,12 @@ base@^0.11.1:
1300
mixin-deep "^1.2.0"
1301
pascalcase "^0.1.1"
1302
2575
-batch@0.6.1:
2576
- version "0.6.1"
2577
- resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
2578
- integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=
2579
-
1303
bcrypt-pbkdf@^1.0.0:
1304
version "1.0.1"
1305
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
1306
dependencies:
1307
tweetnacl "^0.14.3"
1308
2586
-big.js@^5.2.2:
2587
- version "5.2.2"
2588
- resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
2589
- integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
2590
-
1309
binary-extensions@^1.0.0:
1310
version "1.13.1"
1311
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
@@ -2599,94 +1317,12 @@ bl@^1.0.0:
1317
dependencies:
1318
readable-stream "^2.0.5"
1319
2602
-bl@^3.0.0:
2603
- version "3.0.0"
2604
- resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88"
2605
- integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==
2606
- dependencies:
2607
- readable-stream "^3.0.1"
2608
-
2609
-bluebird@^3.5.5:
2610
- version "3.5.5"
2611
- resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f"
2612
- integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==
2613
-
2614
-bluebird@~2.9.24:
2615
- version "2.9.34"
2616
- resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.9.34.tgz#2f7b4ec80216328a9fddebdf69c8d4942feff7d8"
2617
- integrity sha1-L3tOyAIWMoqf3evfacjUlC/v99g=
2618
-
2619
-bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
2620
- version "4.11.8"
2621
- resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
2622
- integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
2623
-
2624
-body-parser@1.19.0:
2625
- version "1.19.0"
2626
- resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
2627
- integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
2628
- dependencies:
2629
- bytes "3.1.0"
2630
- content-type "~1.0.4"
2631
- debug "2.6.9"
2632
- depd "~1.1.2"
2633
- http-errors "1.7.2"
2634
- iconv-lite "0.4.24"
2635
- on-finished "~2.3.0"
2636
- qs "6.7.0"
2637
- raw-body "2.4.0"
2638
- type-is "~1.6.17"
2639
-
2640
-bonjour@^3.5.0:
2641
- version "3.5.0"
2642
- resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5"
2643
- integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU=
2644
- dependencies:
2645
- array-flatten "^2.1.0"
2646
- deep-equal "^1.0.1"
2647
- dns-equal "^1.0.0"
2648
- dns-txt "^2.0.2"
2649
- multicast-dns "^6.0.1"
2650
- multicast-dns-service-types "^1.1.0"
2651
-
2652
-boolbase@~1.0.0:
2653
- version "1.0.0"
2654
- resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
2655
- integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
2656
-
1320
boom@2.x.x:
1321
version "2.10.1"
1322
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
1323
dependencies:
1324
hoek "2.x.x"
1325
2663
-boxen@^1.2.1:
2664
- version "1.3.0"
2665
- resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
2666
- integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==
2667
- dependencies:
2668
- ansi-align "^2.0.0"
2669
- camelcase "^4.0.0"
2670
- chalk "^2.0.1"
2671
- cli-boxes "^1.0.0"
2672
- string-width "^2.0.0"
2673
- term-size "^1.2.0"
2674
- widest-line "^2.0.0"
2675
-
2676
-boxen@^3.0.0:
2677
- version "3.2.0"
2678
- resolved "https://registry.yarnpkg.com/boxen/-/boxen-3.2.0.tgz#fbdff0de93636ab4450886b6ff45b92d098f45eb"
2679
- integrity sha512-cU4J/+NodM3IHdSL2yN8bqYqnmlBTidDR4RC7nJs61ZmtGz8VZzM3HLQX0zY5mrSmPtR3xWwsq2jOUQqFZN8+A==
2680
- dependencies:
2681
- ansi-align "^3.0.0"
2682
- camelcase "^5.3.1"
2683
- chalk "^2.4.2"
2684
- cli-boxes "^2.2.0"
2685
- string-width "^3.0.0"
2686
- term-size "^1.2.0"
2687
- type-fest "^0.3.0"
2688
- widest-line "^2.0.0"
2689
-
1326
brace-expansion@^1.1.7:
1327
version "1.1.11"
1328
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -2718,11 +1354,6 @@ braces@^2.3.1, braces@^2.3.2:
1354
split-string "^3.0.2"
1355
to-regex "^3.0.1"
1356
2721
-brorand@^1.0.1:
2722
- version "1.1.0"
2723
- resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
2724
- integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
2725
-
1357
browser-process-hrtime@^0.1.2:
1358
version "0.1.3"
1359
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4"
@@ -2735,207 +1366,22 @@ browser-resolve@^1.11.0, browser-resolve@^1.11.3:
1366
dependencies:
1367
resolve "1.1.7"
1368
2738
-browserify-aes@^1.0.0, browserify-aes@^1.0.4:
2739
- version "1.2.0"
2740
- resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
2741
- integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
2742
- dependencies:
2743
- buffer-xor "^1.0.3"
2744
- cipher-base "^1.0.0"
2745
- create-hash "^1.1.0"
2746
- evp_bytestokey "^1.0.3"
2747
- inherits "^2.0.1"
2748
- safe-buffer "^5.0.1"
2749
-
2750
-browserify-cipher@^1.0.0:
2751
- version "1.0.1"
2752
- resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
2753
- integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
1369
+bser@^2.0.0:
1370
+ version "2.1.0"
1371
+ resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.0.tgz#65fc784bf7f87c009b973c12db6546902fa9c7b5"
1372
+ integrity sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==
1373
dependencies:
2755
- browserify-aes "^1.0.4"
2756
- browserify-des "^1.0.0"
2757
- evp_bytestokey "^1.0.0"
2758
-
2759
-browserify-des@^1.0.0:
2760
- version "1.0.2"
2761
- resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
2762
- integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
2763
- dependencies:
2764
- cipher-base "^1.0.1"
2765
- des.js "^1.0.0"
2766
- inherits "^2.0.1"
2767
- safe-buffer "^5.1.2"
2768
-
2769
-browserify-rsa@^4.0.0:
2770
- version "4.0.1"
2771
- resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524"
2772
- integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=
2773
- dependencies:
2774
- bn.js "^4.1.0"
2775
- randombytes "^2.0.1"
2776
-
2777
-browserify-sign@^4.0.0:
2778
- version "4.0.4"
2779
- resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298"
2780
- integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=
2781
- dependencies:
2782
- bn.js "^4.1.1"
2783
- browserify-rsa "^4.0.0"
2784
- create-hash "^1.1.0"
2785
- create-hmac "^1.1.2"
2786
- elliptic "^6.0.0"
2787
- inherits "^2.0.1"
2788
- parse-asn1 "^5.0.0"
2789
-
2790
-browserify-zlib@^0.2.0:
2791
- version "0.2.0"
2792
- resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
2793
- integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==
2794
- dependencies:
2795
- pako "~1.0.5"
2796
-
2797
-browserify-zlib@~0.1.4:
2798
- version "0.1.4"
2799
- resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d"
2800
- integrity sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=
2801
- dependencies:
2802
- pako "~0.2.0"
2803
-
2804
-browserslist@^4.6.0, browserslist@^4.6.6:
2805
- version "4.6.6"
2806
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453"
2807
- integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==
2808
- dependencies:
2809
- caniuse-lite "^1.0.30000984"
2810
- electron-to-chromium "^1.3.191"
2811
- node-releases "^1.1.25"
2812
-
2813
-bser@^2.0.0:
2814
- version "2.1.0"
2815
- resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.0.tgz#65fc784bf7f87c009b973c12db6546902fa9c7b5"
2816
- integrity sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==
2817
- dependencies:
2818
- node-int64 "^0.4.0"
2819
-
2820
-buffer-alloc-unsafe@^1.1.0:
2821
- version "1.1.0"
2822
- resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
2823
- integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
2824
-
2825
-buffer-alloc@^1.2.0:
2826
- version "1.2.0"
2827
- resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
2828
- integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
2829
- dependencies:
2830
- buffer-alloc-unsafe "^1.1.0"
2831
- buffer-fill "^1.0.0"
2832
-
2833
-buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3:
2834
- version "0.2.13"
2835
- resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
2836
- integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
2837
-
2838
-buffer-equal-constant-time@1.0.1:
2839
- version "1.0.1"
2840
- resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
2841
- integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
2842
-
2843
-buffer-fill@^1.0.0:
2844
- version "1.0.0"
2845
- resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
2846
- integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
1374
+ node-int64 "^0.4.0"
1375
1376
buffer-from@^1.0.0:
1377
version "1.1.1"
1378
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
1379
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
1380
2853
-buffer-indexof@^1.0.0:
2854
- version "1.1.1"
2855
- resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
2856
- integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==
2857
-
2858
-buffer-xor@^1.0.3:
2859
- version "1.0.3"
2860
- resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
2861
- integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
2862
-
2863
-buffer@^3.0.3:
2864
- version "3.6.0"
2865
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-3.6.0.tgz#a72c936f77b96bf52f5f7e7b467180628551defb"
2866
- integrity sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=
2867
- dependencies:
2868
- base64-js "0.0.8"
2869
- ieee754 "^1.1.4"
2870
- isarray "^1.0.0"
2871
-
2872
-buffer@^4.3.0:
2873
- version "4.9.1"
2874
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
2875
- integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=
2876
- dependencies:
2877
- base64-js "^1.0.2"
2878
- ieee754 "^1.1.4"
2879
- isarray "^1.0.0"
2880
-
2881
-buffer@^5.1.0:
2882
- version "5.4.0"
2883
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.0.tgz#33294f5c1f26e08461e528b69fa06de3c45cbd8c"
2884
- integrity sha512-Xpgy0IwHK2N01ncykXTy6FpCWuM+CJSHoPVBLyNqyrWxsedpLvwsYUhf0ME3WRFNUhos0dMamz9cOS/xRDtU5g==
2885
- dependencies:
2886
- base64-js "^1.0.2"
2887
- ieee754 "^1.1.4"
2888
-
1381
builtin-modules@^1.0.0, builtin-modules@^1.1.0:
1382
version "1.1.1"
1383
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
1384
2893
-builtin-status-codes@^3.0.0:
2894
- version "3.0.0"
2895
- resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
2896
- integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
2897
-
2898
-bunyan@1.8.12:
2899
- version "1.8.12"
2900
- resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797"
2901
- integrity sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=
2902
- optionalDependencies:
2903
- dtrace-provider "~0.8"
2904
- moment "^2.10.6"
2905
- mv "~2"
2906
- safe-json-stringify "~1"
2907
-
2908
-bytes@3.0.0:
2909
- version "3.0.0"
2910
- resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
2911
- integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
2912
-
2913
-bytes@3.1.0:
2914
- version "3.1.0"
2915
- resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
2916
- integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
2917
-
2918
-cacache@^12.0.2:
2919
- version "12.0.2"
2920
- resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.2.tgz#8db03205e36089a3df6954c66ce92541441ac46c"
2921
- integrity sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==
2922
- dependencies:
2923
- bluebird "^3.5.5"
2924
- chownr "^1.1.1"
2925
- figgy-pudding "^3.5.1"
2926
- glob "^7.1.4"
2927
- graceful-fs "^4.1.15"
2928
- infer-owner "^1.0.3"
2929
- lru-cache "^5.1.1"
2930
- mississippi "^3.0.0"
2931
- mkdirp "^0.5.1"
2932
- move-concurrently "^1.0.1"
2933
- promise-inflight "^1.0.1"
2934
- rimraf "^2.6.3"
2935
- ssri "^6.0.1"
2936
- unique-filename "^1.1.1"
2937
- y18n "^4.0.0"
2938
-
1385
cache-base@^1.0.1:
1386
version "1.0.1"
1387
resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
@@ -2951,31 +1397,6 @@ cache-base@^1.0.1:
1397
union-value "^1.0.0"
1398
unset-value "^1.0.0"
1399
2954
-cacheable-request@^6.0.0:
2955
- version "6.1.0"
2956
- resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
2957
- integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
2958
- dependencies:
2959
- clone-response "^1.0.2"
2960
- get-stream "^5.1.0"
2961
- http-cache-semantics "^4.0.0"
2962
- keyv "^3.0.0"
2963
- lowercase-keys "^2.0.0"
2964
- normalize-url "^4.1.0"
2965
- responselike "^1.0.2"
2966
-
2967
-caller-path@^0.1.0:
2968
- version "0.1.0"
2969
- resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
2970
- integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=
2971
- dependencies:
2972
- callsites "^0.2.0"
2973
-
2974
-callsites@^0.2.0:
2975
- version "0.2.0"
2976
- resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
2977
- integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=
2978
-
1400
callsites@^2.0.0:
1401
version "2.0.0"
1402
resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
@@ -2986,38 +1407,15 @@ callsites@^3.0.0:
1407
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
1408
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
1409
2989
-camelcase-keys@^2.0.0:
2990
- version "2.1.0"
2991
- resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
2992
- integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc=
2993
- dependencies:
2994
- camelcase "^2.0.0"
2995
- map-obj "^1.0.0"
2996
-
2997
-camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1:
2998
- version "5.3.1"
2999
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
3000
- integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
3001
-
3002
-camelcase@^2.0.0, camelcase@^2.0.1:
3003
- version "2.1.1"
3004
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
3005
- integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=
3006
-
1410
camelcase@^3.0.0:
1411
version "3.0.0"
1412
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
1413
3011
-camelcase@^4.0.0, camelcase@^4.1.0:
1414
+camelcase@^4.1.0:
1415
version "4.1.0"
1416
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
1417
integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
1418
3016
-caniuse-lite@^1.0.30000984:
3017
- version "1.0.30000989"
3018
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9"
3019
- integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==
3020
-
1419
capture-exit@^1.2.0:
1420
version "1.2.0"
1421
resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f"
@@ -3025,18 +1423,6 @@ capture-exit@^1.2.0:
1423
dependencies:
1424
rsvp "^3.3.3"
1425
3028
-capture-exit@^2.0.0:
3029
- version "2.0.0"
3030
- resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4"
3031
- integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==
3032
- dependencies:
3033
- rsvp "^4.8.4"
3034
-
3035
-capture-stack-trace@^1.0.0:
3036
- version "1.0.1"
3037
- resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d"
3038
- integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==
3039
-
1426
caseless@~0.11.0:
1427
version "0.11.0"
1428
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
@@ -3046,15 +1432,6 @@ caseless@~0.12.0:
1432
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
1433
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
1434
3049
-chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2:
3050
- version "2.4.2"
3051
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
3052
- integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
3053
- dependencies:
3054
- ansi-styles "^3.2.1"
3055
- escape-string-regexp "^1.0.5"
3056
- supports-color "^5.3.0"
3057
-
1435
chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
1436
version "1.1.3"
1437
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -3065,42 +1442,21 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
1442
strip-ansi "^3.0.0"
1443
supports-color "^2.0.0"
1444
3068
-chalk@~0.4.0:
3069
- version "0.4.0"
3070
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
3071
- integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=
1445
+chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.2:
1446
+ version "2.4.2"
1447
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
1448
+ integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
1449
dependencies:
3073
- ansi-styles "~1.0.0"
3074
- has-color "~0.1.0"
3075
- strip-ansi "~0.1.0"
1450
+ ansi-styles "^3.2.1"
1451
+ escape-string-regexp "^1.0.5"
1452
+ supports-color "^5.3.0"
1453
1454
chardet@^0.7.0:
1455
version "0.7.0"
1456
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
1457
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
1458
3082
-cheerio@1.0.0-rc.3:
3083
- version "1.0.0-rc.3"
3084
- resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6"
3085
- integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==
3086
- dependencies:
3087
- css-select "~1.2.0"
3088
- dom-serializer "~0.1.1"
3089
- entities "~1.1.1"
3090
- htmlparser2 "^3.9.1"
3091
- lodash "^4.15.0"
3092
- parse5 "^3.0.1"
3093
-
3094
-child-process-promise@^2.2.1:
3095
- version "2.2.1"
3096
- resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074"
3097
- integrity sha1-RzChHvYQ+tRQuPIjx50x172tgHQ=
3098
- dependencies:
3099
- cross-spawn "^4.0.2"
3100
- node-version "^1.0.0"
3101
- promise-polyfill "^6.0.1"
3102
-
3103
-chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.6:
1459
+chokidar@^2.0.4:
1460
version "2.1.6"
1461
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5"
1462
integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==
@@ -3124,54 +1480,11 @@ chownr@^1.0.1, chownr@^1.1.1:
1480
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6"
1481
integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==
1482
3127
-chrome-launch@^1.1.4:
3128
- version "1.1.4"
3129
- resolved "https://registry.yarnpkg.com/chrome-launch/-/chrome-launch-1.1.4.tgz#c8985bd022635a5cc897099bafd19831838a7252"
3130
- integrity sha1-yJhb0CJjWlzIlwmbr9GYMYOKclI=
3131
- dependencies:
3132
- chrome-location "^1.2.0"
3133
- quick-tmp "0.0.0"
3134
- rimraf "^2.2.8"
3135
- shallow-copy "0.0.1"
3136
-
3137
-chrome-location@^1.2.0:
3138
- version "1.2.1"
3139
- resolved "https://registry.yarnpkg.com/chrome-location/-/chrome-location-1.2.1.tgz#6911511a4eac55027625c73b937ca5ca7ab94995"
3140
- integrity sha1-aRFRGk6sVQJ2Jcc7k3ylynq5SZU=
3141
- dependencies:
3142
- userhome "^1.0.0"
3143
- which "^1.0.5"
3144
-
3145
-chrome-trace-event@^1.0.2:
3146
- version "1.0.2"
3147
- resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4"
3148
- integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==
3149
- dependencies:
3150
- tslib "^1.9.0"
3151
-
1483
ci-info@^1.5.0:
1484
version "1.6.0"
1485
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
1486
integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
1487
3157
-ci-info@^2.0.0:
3158
- version "2.0.0"
3159
- resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
3160
- integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
3161
-
3162
-cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
3163
- version "1.0.4"
3164
- resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
3165
- integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
3166
- dependencies:
3167
- inherits "^2.0.1"
3168
- safe-buffer "^5.0.1"
3169
-
3170
-circular-json@^0.3.1:
3171
- version "0.3.3"
3172
- resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
3173
- integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==
3174
-
1488
class-utils@^0.3.5:
1489
version "0.3.6"
1490
resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
@@ -3182,36 +1495,12 @@ class-utils@^0.3.5:
1495
isobject "^3.0.0"
1496
static-extend "^0.1.1"
1497
3185
-cli-boxes@^1.0.0:
3186
- version "1.0.0"
3187
- resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
3188
- integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM=
3189
-
3190
-cli-boxes@^2.2.0:
3191
- version "2.2.0"
3192
- resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d"
3193
- integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==
3194
-
3195
-cli-cursor@^1.0.1:
3196
- version "1.0.2"
3197
- resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
3198
- integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=
3199
- dependencies:
3200
- restore-cursor "^1.0.1"
3201
-
1498
cli-cursor@^2.1.0:
1499
version "2.1.0"
1500
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
1501
dependencies:
1502
restore-cursor "^2.0.0"
1503
3208
-cli-cursor@^3.1.0:
3209
- version "3.1.0"
3210
- resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
3211
- integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==
3212
- dependencies:
3213
- restore-cursor "^3.1.0"
3214
-
1504
cli-table@^0.3.1:
1505
version "0.3.1"
1506
resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
@@ -3222,12 +1511,7 @@ cli-width@^2.0.0:
1511
version "2.1.0"
1512
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
1513
3225
-clipboard-js@^0.3.6:
3226
- version "0.3.6"
3227
- resolved "https://registry.yarnpkg.com/clipboard-js/-/clipboard-js-0.3.6.tgz#6260add69b5318fde40b80f9d3c8c863efdaf339"
3228
- integrity sha512-hyrmvbrYCeRBHdiR3KrEz0tmrUTXXEU8HLeGW0Y0icUSwYmAsmc+d6wfE4EDb/TxZmAVJG0eTfMlulCIT+ecfw==
3229
-
3230
-cliui@^3.0.3, cliui@^3.2.0:
1514
+cliui@^3.2.0:
1515
version "3.2.0"
1516
resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
1517
dependencies:
@@ -3244,45 +1528,14 @@ cliui@^4.0.0:
1528
strip-ansi "^4.0.0"
1529
wrap-ansi "^2.0.0"
1530
3247
-cliui@^5.0.0:
3248
- version "5.0.0"
3249
- resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5"
3250
- integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==
3251
- dependencies:
3252
- string-width "^3.1.0"
3253
- strip-ansi "^5.2.0"
3254
- wrap-ansi "^5.1.0"
3255
-
1531
clone-buffer@^1.0.0:
1532
version "1.0.0"
1533
resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
1534
3260
-clone-deep@^0.3.0:
3261
- version "0.3.0"
3262
- resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.3.0.tgz#348c61ae9cdbe0edfe053d91ff4cc521d790ede8"
3263
- integrity sha1-NIxhrpzb4O3+BT2R/0zFIdeQ7eg=
3264
- dependencies:
3265
- for-own "^1.0.0"
3266
- is-plain-object "^2.0.1"
3267
- kind-of "^3.2.2"
3268
- shallow-clone "^0.1.2"
3269
-
3270
-clone-response@^1.0.2:
3271
- version "1.0.2"
3272
- resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
3273
- integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
3274
- dependencies:
3275
- mimic-response "^1.0.0"
3276
-
1535
clone-stats@^1.0.0:
1536
version "1.0.0"
1537
resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680"
1538
3281
-clone@^1.0.2:
3282
- version "1.0.4"
3283
- resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
3284
- integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
3285
-
1539
clone@^2.1.1:
1540
version "2.1.1"
1541
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb"
@@ -3329,23 +1582,10 @@ color-support@^1.1.3:
1582
version "1.1.3"
1583
resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
1584
3332
-colors@0.5.x:
3333
- version "0.5.1"
3334
- resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
3335
- integrity sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q=
3336
-
1585
colors@1.0.3:
1586
version "1.0.3"
1587
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
1588
3341
-columnify@1.5.4:
3342
- version "1.5.4"
3343
- resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
3344
- integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=
3345
- dependencies:
3346
- strip-ansi "^3.0.0"
3347
- wcwidth "^1.0.0"
3348
-
1589
combined-stream@^1.0.5, combined-stream@^1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6:
1590
version "1.0.8"
1591
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@@ -3353,150 +1593,25 @@ combined-stream@^1.0.5, combined-stream@^1.0.6, combined-stream@~1.0.5, combined
1593
dependencies:
1594
delayed-stream "~1.0.0"
1595
3356
-commander@2.9.0:
3357
- version "2.9.0"
3358
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
3359
- integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=
3360
- dependencies:
3361
- graceful-readlink ">= 1.0.0"
3362
-
3363
-commander@^2.12.2, commander@^2.20.0, commander@^2.3.0, commander@^2.6.0, commander@^2.8.1, commander@^2.9.0, commander@~2.20.0:
1596
+commander@^2.12.2, commander@^2.8.1, commander@^2.9.0, commander@~2.20.0:
1597
version "2.20.0"
1598
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
1599
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
1600
3368
-common-tags@1.8.0:
3369
- version "1.8.0"
3370
- resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
3371
- integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==
3372
-
3373
-commondir@^1.0.1:
3374
- version "1.0.1"
3375
- resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
3376
- integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
3377
-
1601
component-emitter@^1.2.1:
1602
version "1.3.0"
1603
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
1604
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
1605
3383
-compress-commons@^1.2.0:
3384
- version "1.2.2"
3385
- resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.2.2.tgz#524a9f10903f3a813389b0225d27c48bb751890f"
3386
- integrity sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=
3387
- dependencies:
3388
- buffer-crc32 "^0.2.1"
3389
- crc32-stream "^2.0.0"
3390
- normalize-path "^2.0.0"
3391
- readable-stream "^2.0.0"
3392
-
3393
-compress-commons@^2.1.1:
3394
- version "2.1.1"
3395
- resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-2.1.1.tgz#9410d9a534cf8435e3fbbb7c6ce48de2dc2f0610"
3396
- integrity sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==
3397
- dependencies:
3398
- buffer-crc32 "^0.2.13"
3399
- crc32-stream "^3.0.1"
3400
- normalize-path "^3.0.0"
3401
- readable-stream "^2.3.6"
3402
-
3403
-compressible@~2.0.16:
3404
- version "2.0.17"
3405
- resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1"
3406
- integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==
3407
- dependencies:
3408
- mime-db ">= 1.40.0 < 2"
3409
-
3410
-compression@^1.7.4:
3411
- version "1.7.4"
3412
- resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
3413
- integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
3414
- dependencies:
3415
- accepts "~1.3.5"
3416
- bytes "3.0.0"
3417
- compressible "~2.0.16"
3418
- debug "2.6.9"
3419
- on-headers "~1.0.2"
3420
- safe-buffer "5.1.2"
3421
- vary "~1.1.2"
3422
-
1606
concat-map@0.0.1:
1607
version "0.0.1"
1608
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
1609
3427
-concat-stream@1.6.2, concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.5.2:
3428
- version "1.6.2"
3429
- resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
3430
- integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
3431
- dependencies:
3432
- buffer-from "^1.0.0"
3433
- inherits "^2.0.3"
3434
- readable-stream "^2.2.2"
3435
- typedarray "^0.0.6"
3436
-
3437
-configstore@^3.0.0, configstore@^3.1.2:
3438
- version "3.1.2"
3439
- resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f"
3440
- integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==
3441
- dependencies:
3442
- dot-prop "^4.1.0"
3443
- graceful-fs "^4.1.2"
3444
- make-dir "^1.0.0"
3445
- unique-string "^1.0.0"
3446
- write-file-atomic "^2.0.0"
3447
- xdg-basedir "^3.0.0"
3448
-
3449
-configstore@^4.0.0:
3450
- version "4.0.0"
3451
- resolved "https://registry.yarnpkg.com/configstore/-/configstore-4.0.0.tgz#5933311e95d3687efb592c528b922d9262d227e7"
3452
- integrity sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==
3453
- dependencies:
3454
- dot-prop "^4.1.0"
3455
- graceful-fs "^4.1.2"
3456
- make-dir "^1.0.0"
3457
- unique-string "^1.0.0"
3458
- write-file-atomic "^2.0.0"
3459
- xdg-basedir "^3.0.0"
3460
-
3461
-connect-history-api-fallback@^1.6.0:
3462
- version "1.6.0"
3463
- resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
3464
- integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
3465
-
3466
-console-browserify@^1.1.0:
3467
- version "1.1.0"
3468
- resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
3469
- integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=
3470
- dependencies:
3471
- date-now "^0.1.4"
3472
-
1610
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
1611
version "1.1.0"
1612
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
1613
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
1614
3478
-constants-browserify@0.0.1:
3479
- version "0.0.1"
3480
- resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-0.0.1.tgz#92577db527ba6c4cf0a4568d84bc031f441e21f2"
3481
- integrity sha1-kld9tSe6bEzwpFaNhLwDH0QeIfI=
3482
-
3483
-constants-browserify@^1.0.0:
3484
- version "1.0.0"
3485
- resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
3486
- integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
3487
-
3488
-content-disposition@0.5.3:
3489
- version "0.5.3"
3490
- resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
3491
- integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
3492
- dependencies:
3493
- safe-buffer "5.1.2"
3494
-
3495
-content-type@~1.0.4:
3496
- version "1.0.4"
3497
- resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
3498
- integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
3499
-
1615
convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1:
1616
version "1.6.0"
1617
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
@@ -3504,46 +1619,11 @@ convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1:
1619
dependencies:
1620
safe-buffer "~5.1.1"
1621
3507
-cookie-signature@1.0.6:
3508
- version "1.0.6"
3509
- resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
3510
- integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
3511
-
3512
-cookie@0.4.0:
3513
- version "0.4.0"
3514
- resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
3515
- integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
3516
-
3517
-cookie@^0.3.1:
3518
- version "0.3.1"
3519
- resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
3520
- integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
3521
-
3522
-copy-concurrently@^1.0.0:
3523
- version "1.0.5"
3524
- resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
3525
- integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==
3526
- dependencies:
3527
- aproba "^1.1.1"
3528
- fs-write-stream-atomic "^1.0.8"
3529
- iferr "^0.1.5"
3530
- mkdirp "^0.5.1"
3531
- rimraf "^2.5.4"
3532
- run-queue "^1.0.0"
3533
-
1622
copy-descriptor@^0.1.0:
1623
version "0.1.1"
1624
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
1625
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
1626
3539
-core-js-compat@^3.1.1:
3540
- version "3.2.1"
3541
- resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.2.1.tgz#0cbdbc2e386e8e00d3b85dc81c848effec5b8150"
3542
- integrity sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A==
3543
- dependencies:
3544
- browserslist "^4.6.6"
3545
- semver "^6.3.0"
3546
-
1627
core-js@^1.0.0:
1628
version "1.2.7"
1629
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
@@ -3552,11 +1632,6 @@ core-js@^2.2.1, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0:
1632
version "2.5.7"
1633
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
1634
3555
-core-js@^2.6.5:
3556
- version "2.6.9"
3557
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
3558
- integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
3559
-
1635
core-util-is@1.0.2, core-util-is@~1.0.0:
1636
version "1.0.2"
1637
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -3571,68 +1646,7 @@ coveralls@^2.11.6:
1646
minimist "1.2.0"
1647
request "2.79.0"
1648
3574
-crc32-stream@^2.0.0:
3575
- version "2.0.0"
3576
- resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4"
3577
- integrity sha1-483TtN8xaN10494/u8t7KX/pCPQ=
3578
- dependencies:
3579
- crc "^3.4.4"
3580
- readable-stream "^2.0.0"
3581
-
3582
-crc32-stream@^3.0.1:
3583
- version "3.0.1"
3584
- resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-3.0.1.tgz#cae6eeed003b0e44d739d279de5ae63b171b4e85"
3585
- integrity sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==
3586
- dependencies:
3587
- crc "^3.4.4"
3588
- readable-stream "^3.4.0"
3589
-
3590
-crc@^3.4.4:
3591
- version "3.8.0"
3592
- resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6"
3593
- integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==
3594
- dependencies:
3595
- buffer "^5.1.0"
3596
-
3597
-create-ecdh@^4.0.0:
3598
- version "4.0.3"
3599
- resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
3600
- integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==
3601
- dependencies:
3602
- bn.js "^4.1.0"
3603
- elliptic "^6.0.0"
3604
-
3605
-create-error-class@^3.0.0:
3606
- version "3.0.2"
3607
- resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
3608
- integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=
3609
- dependencies:
3610
- capture-stack-trace "^1.0.0"
3611
-
3612
-create-hash@^1.1.0, create-hash@^1.1.2:
3613
- version "1.2.0"
3614
- resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
3615
- integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==
3616
- dependencies:
3617
- cipher-base "^1.0.1"
3618
- inherits "^2.0.1"
3619
- md5.js "^1.3.4"
3620
- ripemd160 "^2.0.1"
3621
- sha.js "^2.4.0"
3622
-
3623
-create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
3624
- version "1.1.7"
3625
- resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
3626
- integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
3627
- dependencies:
3628
- cipher-base "^1.0.3"
3629
- create-hash "^1.1.0"
3630
- inherits "^2.0.1"
3631
- ripemd160 "^2.0.0"
3632
- safe-buffer "^5.0.1"
3633
- sha.js "^2.4.8"
3634
-
3635
-create-react-class@^15.6.0, create-react-class@^15.6.2, create-react-class@^15.6.3:
1649
+create-react-class@^15.6.2, create-react-class@^15.6.3:
1650
version "15.6.3"
1651
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036"
1652
dependencies:
@@ -3640,14 +1654,6 @@ create-react-class@^15.6.0, create-react-class@^15.6.2, create-react-class@^15.6
1654
loose-envify "^1.3.1"
1655
object-assign "^4.1.1"
1656
3643
-cross-env@^3.1.4:
3644
- version "3.2.4"
3645
- resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-3.2.4.tgz#9e0585f277864ed421ce756f81a980ff0d698aba"
3646
- integrity sha1-ngWF8neGTtQhznVvgamA/w1piro=
3647
- dependencies:
3648
- cross-spawn "^5.1.0"
3649
- is-windows "^1.0.0"
3650
-
1657
cross-env@^5.1.1:
1658
version "5.1.1"
1659
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.1.1.tgz#b6d8ab97f304c0f71dae7277b75fe424c08dfa74"
@@ -3655,7 +1661,15 @@ cross-env@^5.1.1:
1661
cross-spawn "^5.1.0"
1662
is-windows "^1.0.0"
1663
3658
-cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
1664
+cross-spawn@^5.0.1, cross-spawn@^5.1.0:
1665
+ version "5.1.0"
1666
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
1667
+ dependencies:
1668
+ lru-cache "^4.0.1"
1669
+ shebang-command "^1.2.0"
1670
+ which "^1.2.9"
1671
+
1672
+cross-spawn@^6.0.5:
1673
version "6.0.5"
1674
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
1675
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
@@ -3666,119 +1680,12 @@ cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
1680
shebang-command "^1.2.0"
1681
which "^1.2.9"
1682
3669
-cross-spawn@^4.0.2:
3670
- version "4.0.2"
3671
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
3672
- integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=
3673
- dependencies:
3674
- lru-cache "^4.0.1"
3675
- which "^1.2.9"
3676
-
3677
-cross-spawn@^5.0.1, cross-spawn@^5.1.0:
3678
- version "5.1.0"
3679
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
3680
- dependencies:
3681
- lru-cache "^4.0.1"
3682
- shebang-command "^1.2.0"
3683
- which "^1.2.9"
3684
-
3685
-crx-parser@0.1.2:
3686
- version "0.1.2"
3687
- resolved "https://registry.yarnpkg.com/crx-parser/-/crx-parser-0.1.2.tgz#7eeeed9eddc95e22c189382e34624044a89a5a6d"
3688
- integrity sha1-fu7tnt3JXiLBiTguNGJARKiaWm0=
3689
-
1683
cryptiles@2.x.x:
1684
version "2.0.5"
1685
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
1686
dependencies:
1687
boom "2.x.x"
1688
3696
-crypto-browserify@^3.11.0:
3697
- version "3.12.0"
3698
- resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
3699
- integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
3700
- dependencies:
3701
- browserify-cipher "^1.0.0"
3702
- browserify-sign "^4.0.0"
3703
- create-ecdh "^4.0.0"
3704
- create-hash "^1.1.0"
3705
- create-hmac "^1.1.0"
3706
- diffie-hellman "^5.0.0"
3707
- inherits "^2.0.1"
3708
- pbkdf2 "^3.0.3"
3709
- public-encrypt "^4.0.0"
3710
- randombytes "^2.0.0"
3711
- randomfill "^1.0.3"
3712
-
3713
-crypto-browserify@~3.2.6:
3714
- version "3.2.8"
3715
- resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.2.8.tgz#b9b11dbe6d9651dd882a01e6cc467df718ecf189"
3716
- integrity sha1-ubEdvm2WUd2IKgHmzEZ99xjs8Yk=
3717
- dependencies:
3718
- pbkdf2-compat "2.0.1"
3719
- ripemd160 "0.2.0"
3720
- sha.js "2.2.6"
3721
-
3722
-crypto-random-string@^1.0.0:
3723
- version "1.0.0"
3724
- resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
3725
- integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=
3726
-
3727
-css-in-js-utils@^2.0.0:
3728
- version "2.0.1"
3729
- resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz#3b472b398787291b47cfe3e44fecfdd9e914ba99"
3730
- integrity sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==
3731
- dependencies:
3732
- hyphenate-style-name "^1.0.2"
3733
- isobject "^3.0.1"
3734
-
3735
-css-loader@^1.0.1:
3736
- version "1.0.1"
3737
- resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-1.0.1.tgz#6885bb5233b35ec47b006057da01cc640b6b79fe"
3738
- integrity sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw==
3739
- dependencies:
3740
- babel-code-frame "^6.26.0"
3741
- css-selector-tokenizer "^0.7.0"
3742
- icss-utils "^2.1.0"
3743
- loader-utils "^1.0.2"
3744
- lodash "^4.17.11"
3745
- postcss "^6.0.23"
3746
- postcss-modules-extract-imports "^1.2.0"
3747
- postcss-modules-local-by-default "^1.2.0"
3748
- postcss-modules-scope "^1.1.0"
3749
- postcss-modules-values "^1.3.0"
3750
- postcss-value-parser "^3.3.0"
3751
- source-list-map "^2.0.0"
3752
-
3753
-css-select@~1.2.0:
3754
- version "1.2.0"
3755
- resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
3756
- integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=
3757
- dependencies:
3758
- boolbase "~1.0.0"
3759
- css-what "2.1"
3760
- domutils "1.5.1"
3761
- nth-check "~1.0.1"
3762
-
3763
-css-selector-tokenizer@^0.7.0:
3764
- version "0.7.1"
3765
- resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz#a177271a8bca5019172f4f891fc6eed9cbf68d5d"
3766
- integrity sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==
3767
- dependencies:
3768
- cssesc "^0.1.0"
3769
- fastparse "^1.1.1"
3770
- regexpu-core "^1.0.0"
3771
-
3772
-css-what@2.1:
3773
- version "2.1.3"
3774
- resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
3775
- integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
3776
-
3777
-cssesc@^0.1.0:
3778
- version "0.1.0"
3779
- resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
3780
- integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=
3781
-
1689
cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
1690
version "0.3.8"
1691
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
@@ -3791,26 +1698,6 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
1698
dependencies:
1699
cssom "0.3.x"
1700
3794
-currently-unhandled@^0.4.1:
3795
- version "0.4.1"
3796
- resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
3797
- integrity sha1-mI3zP+qxke95mmE2nddsF635V+o=
3798
- dependencies:
3799
- array-find-index "^1.0.1"
3800
-
3801
-cyclist@~0.2.2:
3802
- version "0.2.2"
3803
- resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
3804
- integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
3805
-
3806
-d@1:
3807
- version "1.0.1"
3808
- resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
3809
- integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
3810
- dependencies:
3811
- es5-ext "^0.10.50"
3812
- type "^1.0.1"
3813
-
1701
danger@^3.0.4:
1702
version "3.0.4"
1703
resolved "https://registry.yarnpkg.com/danger/-/danger-3.0.4.tgz#df8bb80ec9e220f68718e0c7ce83efb7fe5b5367"
@@ -3849,13 +1736,6 @@ dashdash@^1.12.0:
1736
dependencies:
1737
assert-plus "^1.0.0"
1738
3852
-data-uri-to-buffer@2:
3853
- version "2.0.1"
3854
- resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-2.0.1.tgz#ca8f56fe38b1fd329473e9d1b4a9afcd8ce1c045"
3855
- integrity sha512-OkVVLrerfAKZlW2ZZ3Ve2y65jgiWqBKsTfUIAFbn8nVbPcCZg6l6gikKlEYv0kXcmzqGm6mFq/Jf2vriuEkv8A==
3856
- dependencies:
3857
- "@types/node" "^8.0.7"
3858
-
1739
data-urls@^1.0.0:
1740
version "1.1.0"
1741
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe"
@@ -3865,52 +1745,28 @@ data-urls@^1.0.0:
1745
whatwg-mimetype "^2.2.0"
1746
whatwg-url "^7.0.0"
1747
3868
-date-now@^0.1.4:
3869
- version "0.1.4"
3870
- resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
3871
- integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=
3872
-
3873
-debounce@1.2.0, debounce@^1.2.0:
3874
- version "1.2.0"
3875
- resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131"
3876
- integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg==
3877
-
3878
-debug@2, debug@2.6.9, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9, debug@~2.6.3:
1748
+debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
1749
version "2.6.9"
1750
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
1751
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
1752
dependencies:
1753
ms "2.0.0"
1754
3885
-debug@3.1.0:
3886
- version "3.1.0"
3887
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
3888
- integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
3889
- dependencies:
3890
- ms "2.0.0"
3891
-
3892
-debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
3893
- version "4.1.1"
3894
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
3895
- integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
3896
- dependencies:
3897
- ms "^2.1.1"
3898
-
3899
-debug@^3.0.0, debug@^3.1.0, debug@^3.2.5, debug@^3.2.6:
1755
+debug@^3.1.0, debug@^3.2.6:
1756
version "3.2.6"
1757
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
1758
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
1759
dependencies:
1760
ms "^2.1.1"
1761
3906
-decamelize@3.2.0:
3907
- version "3.2.0"
3908
- resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-3.2.0.tgz#84b8e8f4f8c579f938e35e2cc7024907e0090851"
3909
- integrity sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==
1762
+debug@^4.0.1, debug@^4.1.0:
1763
+ version "4.1.1"
1764
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
1765
+ integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
1766
dependencies:
3911
- xregexp "^4.2.4"
1767
+ ms "^2.1.1"
1768
3913
-decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0:
1769
+decamelize@^1.1.1:
1770
version "1.2.0"
1771
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
1772
@@ -3919,25 +1775,6 @@ decode-uri-component@^0.2.0:
1775
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
1776
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
1777
3922
-decompress-response@^3.3.0:
3923
- version "3.3.0"
3924
- resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
3925
- integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
3926
- dependencies:
3927
- mimic-response "^1.0.0"
3928
-
3929
-deep-assign@^3.0.0:
3930
- version "3.0.0"
3931
- resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-3.0.0.tgz#c8e4c4d401cba25550a2f0f486a2e75bc5f219a2"
3932
- integrity sha512-YX2i9XjJ7h5q/aQ/IM9PEwEnDqETAIYbggmdDB3HLTlSgo1CxPsj6pvhPG68rq6SVE0+p+6Ywsm5fTYNrYtBWw==
3933
- dependencies:
3934
- is-obj "^1.0.0"
3935
-
3936
-deep-equal@^1.0.0, deep-equal@^1.0.1:
3937
- version "1.0.1"
3938
- resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
3939
- integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
3940
-
1778
deep-extend@^0.6.0:
1779
version "0.6.0"
1780
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
@@ -3947,29 +1784,6 @@ deep-is@~0.1.3:
1784
version "0.1.3"
1785
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
1786
3950
-deepcopy@0.6.3:
3951
- version "0.6.3"
3952
- resolved "https://registry.yarnpkg.com/deepcopy/-/deepcopy-0.6.3.tgz#634780f2f8656ab771af8fa8431ed1ccee55c7b0"
3953
- integrity sha1-Y0eA8vhlardxr4+oQx7RzO5Vx7A=
3954
-
3955
-deepmerge@3.2.0:
3956
- version "3.2.0"
3957
- resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e"
3958
- integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow==
3959
-
3960
-deepmerge@^2.0.1:
3961
- version "2.2.1"
3962
- resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
3963
- integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
3964
-
3965
-default-gateway@^4.2.0:
3966
- version "4.2.0"
3967
- resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
3968
- integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==
3969
- dependencies:
3970
- execa "^1.0.0"
3971
- ip-regex "^2.1.0"
3972
-
1787
default-require-extensions@^1.0.0:
1788
version "1.0.0"
1789
resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8"
@@ -3977,18 +1791,6 @@ default-require-extensions@^1.0.0:
1791
dependencies:
1792
strip-bom "^2.0.0"
1793
3980
-defaults@^1.0.3:
3981
- version "1.0.3"
3982
- resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
3983
- integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
3984
- dependencies:
3985
- clone "^1.0.2"
3986
-
3987
-defer-to-connect@^1.0.1:
3988
- version "1.0.2"
3989
- resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.0.2.tgz#4bae758a314b034ae33902b5aac25a8dd6a8633e"
3990
- integrity sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw==
3991
-
1794
define-properties@^1.1.2, define-properties@^1.1.3:
1795
version "1.1.3"
1796
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -4018,28 +1820,6 @@ define-property@^2.0.2:
1820
is-descriptor "^1.0.2"
1821
isobject "^3.0.1"
1822
4021
-degenerator@^1.0.4:
4022
- version "1.0.4"
4023
- resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095"
4024
- integrity sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=
4025
- dependencies:
4026
- ast-types "0.x.x"
4027
- escodegen "1.x.x"
4028
- esprima "3.x.x"
4029
-
4030
-del@^4.1.1:
4031
- version "4.1.1"
4032
- resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4"
4033
- integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==
4034
- dependencies:
4035
- "@types/glob" "^7.1.1"
4036
- globby "^6.1.0"
4037
- is-path-cwd "^2.0.0"
4038
- is-path-in-cwd "^2.0.0"
4039
- p-map "^2.0.0"
4040
- pify "^4.0.1"
4041
- rimraf "^2.6.3"
4042
-
1823
delayed-stream@~1.0.0:
1824
version "1.0.0"
1825
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@@ -4049,29 +1829,6 @@ delegates@^1.0.0:
1829
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
1830
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
1831
4052
-depd@~1.1.2:
4053
- version "1.1.2"
4054
- resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
4055
- integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
4056
-
4057
-des.js@^1.0.0:
4058
- version "1.0.0"
4059
- resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc"
4060
- integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=
4061
- dependencies:
4062
- inherits "^2.0.1"
4063
- minimalistic-assert "^1.0.0"
4064
-
4065
-destroy@~1.0.4:
4066
- version "1.0.4"
4067
- resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
4068
- integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
4069
-
4070
-detect-file@^1.0.0:
4071
- version "1.0.0"
4072
- resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
4073
- integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
4074
-
1832
detect-indent@^4.0.0:
1833
version "4.0.0"
1834
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
@@ -4088,11 +1845,6 @@ detect-newline@^2.1.0:
1845
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
1846
integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=
1847
4091
-detect-node@^2.0.4:
4092
- version "2.0.4"
4093
- resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
4094
- integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
4095
-
1848
diff@3.3.0:
1849
version "3.3.0"
1850
resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9"
@@ -4102,62 +1854,6 @@ diff@^3.2.0:
1854
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
1855
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
1856
4105
-diff@^4.0.1:
4106
- version "4.0.1"
4107
- resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff"
4108
- integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==
4109
-
4110
-diffie-hellman@^5.0.0:
4111
- version "5.0.3"
4112
- resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
4113
- integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
4114
- dependencies:
4115
- bn.js "^4.1.0"
4116
- miller-rabin "^4.0.0"
4117
- randombytes "^2.0.0"
4118
-
4119
-dispensary@0.37.0:
4120
- version "0.37.0"
4121
- resolved "https://registry.yarnpkg.com/dispensary/-/dispensary-0.37.0.tgz#7c384d78984aabd1ed4915f633b4a5c8d5e6e8aa"
4122
- integrity sha512-Baqbt8MDkRYQZHB7XEd8iBUP8wRkRLjNWbm16nSDTOIoGvgF4Z8Q9wV1yD72TYjFC0kj1/o3nfPXPiAvWqjC8g==
4123
- dependencies:
4124
- array-from "~2.1.1"
4125
- async "~3.0.0"
4126
- natural-compare-lite "~1.4.0"
4127
- pino "~5.12.0"
4128
- request "~2.88.0"
4129
- sha.js "~2.4.4"
4130
- snyk "^1.165.1"
4131
- source-map-support "~0.5.4"
4132
- yargs "~13.2.0"
4133
-
4134
-dns-equal@^1.0.0:
4135
- version "1.0.0"
4136
- resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
4137
- integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0=
4138
-
4139
-dns-packet@^1.3.1:
4140
- version "1.3.1"
4141
- resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a"
4142
- integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==
4143
- dependencies:
4144
- ip "^1.1.0"
4145
- safe-buffer "^5.0.1"
4146
-
4147
-dns-txt@^2.0.2:
4148
- version "2.0.2"
4149
- resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6"
4150
- integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=
4151
- dependencies:
4152
- buffer-indexof "^1.0.0"
4153
-
4154
-dockerfile-ast@0.0.16:
4155
- version "0.0.16"
4156
- resolved "https://registry.yarnpkg.com/dockerfile-ast/-/dockerfile-ast-0.0.16.tgz#10b329d343329dab1de70375833495f85ad65913"
4157
- integrity sha512-+HZToHjjiLPl46TqBrok5dMrg5oCkZFPSROMQjRmvin0zG4FxK0DJXTpV/CUPYY2zpmEvVza55XLwSHFx/xZMw==
4158
- dependencies:
4159
- vscode-languageserver-types "^3.5.0"
4160
-
1857
doctrine@^1.2.2:
1858
version "1.5.0"
1859
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
@@ -4166,13 +1862,6 @@ doctrine@^1.2.2:
1862
esutils "^2.0.2"
1863
isarray "^1.0.0"
1864
4169
-doctrine@^2.0.0:
4170
- version "2.1.0"
4171
- resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
4172
- integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
4173
- dependencies:
4174
- esutils "^2.0.2"
4175
-
1865
doctrine@^3.0.0:
1866
version "3.0.0"
1867
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
@@ -4180,37 +1869,6 @@ doctrine@^3.0.0:
1869
dependencies:
1870
esutils "^2.0.2"
1871
4183
-dom-serializer@0:
4184
- version "0.2.1"
4185
- resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.1.tgz#13650c850daffea35d8b626a4cfc4d3a17643fdb"
4186
- integrity sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==
4187
- dependencies:
4188
- domelementtype "^2.0.1"
4189
- entities "^2.0.0"
4190
-
4191
-dom-serializer@~0.1.1:
4192
- version "0.1.1"
4193
- resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
4194
- integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
4195
- dependencies:
4196
- domelementtype "^1.3.0"
4197
- entities "^1.1.1"
4198
-
4199
-domain-browser@^1.1.1:
4200
- version "1.2.0"
4201
- resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
4202
- integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
4203
-
4204
-domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
4205
- version "1.3.1"
4206
- resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
4207
- integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
4208
-
4209
-domelementtype@^2.0.1:
4210
- version "2.0.1"
4211
- resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d"
4212
- integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==
4213
-
1872
domexception@^1.0.0:
1873
version "1.0.1"
1874
resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
@@ -4218,63 +1876,10 @@ domexception@^1.0.0:
1876
dependencies:
1877
webidl-conversions "^4.0.2"
1878
4221
-domhandler@^2.3.0:
4222
- version "2.4.2"
4223
- resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
4224
- integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
4225
- dependencies:
4226
- domelementtype "1"
4227
-
4228
-domutils@1.5.1:
4229
- version "1.5.1"
4230
- resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
4231
- integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=
4232
- dependencies:
4233
- dom-serializer "0"
4234
- domelementtype "1"
4235
-
4236
-domutils@^1.5.1:
4237
- version "1.7.0"
4238
- resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
4239
- integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
4240
- dependencies:
4241
- dom-serializer "0"
4242
- domelementtype "1"
4243
-
4244
-dot-prop@^4.1.0:
4245
- version "4.2.0"
4246
- resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
4247
- integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==
4248
- dependencies:
4249
- is-obj "^1.0.0"
4250
-
1879
dotenv@^4.0.0:
1880
version "4.0.0"
1881
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d"
1882
4255
-dotnet-deps-parser@4.5.0:
4256
- version "4.5.0"
4257
- resolved "https://registry.yarnpkg.com/dotnet-deps-parser/-/dotnet-deps-parser-4.5.0.tgz#53ef53a058dec156fcdf9008b880ecc9675ddde0"
4258
- integrity sha512-t6rBxcWVZSDNhhWdsbq9ozaCzfPXV79FiyES1JLNEoA7nYF+zDC2VZvFZSnH8ilU3bghJXxZPH+EcKYvfw8g/g==
4259
- dependencies:
4260
- "@types/xml2js" "0.4.3"
4261
- lodash "^4.17.11"
4262
- source-map-support "^0.5.7"
4263
- tslib "^1.9.3"
4264
- xml2js "0.4.19"
4265
-
4266
-dtrace-provider@~0.8:
4267
- version "0.8.7"
4268
- resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.7.tgz#dc939b4d3e0620cfe0c1cd803d0d2d7ed04ffd04"
4269
- integrity sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ=
4270
- dependencies:
4271
- nan "^2.10.0"
4272
-
4273
-duplexer3@^0.1.4:
4274
- version "0.1.4"
4275
- resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
4276
- integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
4277
-
1883
duplexer@^0.1.1:
1884
version "0.1.1"
1885
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
@@ -4283,17 +1888,7 @@ duplexify@^3.1.2:
1888
version "3.5.0"
1889
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.0.tgz#1aa773002e1578457e9d9d4a50b0ccaaebcbd604"
1890
dependencies:
4286
- end-of-stream "1.0.0"
4287
- inherits "^2.0.1"
4288
- readable-stream "^2.0.0"
4289
- stream-shift "^1.0.0"
4290
-
4291
-duplexify@^3.4.2, duplexify@^3.6.0:
4292
- version "3.7.1"
4293
- resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309"
4294
- integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==
4295
- dependencies:
4296
- end-of-stream "^1.0.0"
1891
+ end-of-stream "1.0.0"
1892
inherits "^2.0.1"
1893
readable-stream "^2.0.0"
1894
stream-shift "^1.0.0"
@@ -4304,85 +1899,11 @@ ecc-jsbn@~0.1.1:
1899
dependencies:
1900
jsbn "~0.1.0"
1901
4307
-ecdsa-sig-formatter@1.0.11:
4308
- version "1.0.11"
4309
- resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
4310
- integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
4311
- dependencies:
4312
- safe-buffer "^5.0.1"
4313
-
4314
-ee-first@1.1.1:
4315
- version "1.1.1"
4316
- resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
4317
- integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
4318
-
4319
-electron-download@^4.1.0:
4320
- version "4.1.1"
4321
- resolved "https://registry.yarnpkg.com/electron-download/-/electron-download-4.1.1.tgz#02e69556705cc456e520f9e035556ed5a015ebe8"
4322
- integrity sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg==
4323
- dependencies:
4324
- debug "^3.0.0"
4325
- env-paths "^1.0.0"
4326
- fs-extra "^4.0.1"
4327
- minimist "^1.2.0"
4328
- nugget "^2.0.1"
4329
- path-exists "^3.0.0"
4330
- rc "^1.2.1"
4331
- semver "^5.4.1"
4332
- sumchecker "^2.0.2"
4333
-
4334
-electron-to-chromium@^1.3.191:
4335
- version "1.3.225"
4336
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.225.tgz#c6786475b5eb5f491ade01a78b82ba2c5bfdf72b"
4337
- integrity sha512-7W/L3jw7HYE+tUPbcVOGBmnSrlUmyZ/Uyg24QS7Vx0a9KodtNrN0r0Q/LyGHrcYMtw2rv7E49F/vTXwlV/fuaA==
4338
-
4339
-electron@^5.0.0:
4340
- version "5.0.9"
4341
- resolved "https://registry.yarnpkg.com/electron/-/electron-5.0.9.tgz#d7000dcb69b74a85b81cb168e7ffdcac254464e5"
4342
- integrity sha512-yCt+lnQr47OWB3Oei19odMVB8VKzecTwZLm75PB56f/keeJAM3UqV7+dtjKlPdKt0hJ4sWxe4vjxGPO/oZDv7A==
4343
- dependencies:
4344
- "@types/node" "^10.12.18"
4345
- electron-download "^4.1.0"
4346
- extract-zip "^1.0.3"
4347
-
4348
-elliptic@^6.0.0:
4349
- version "6.5.0"
4350
- resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.0.tgz#2b8ed4c891b7de3200e14412a5b8248c7af505ca"
4351
- integrity sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==
4352
- dependencies:
4353
- bn.js "^4.4.0"
4354
- brorand "^1.0.1"
4355
- hash.js "^1.0.0"
4356
- hmac-drbg "^1.0.0"
4357
- inherits "^2.0.1"
4358
- minimalistic-assert "^1.0.0"
4359
- minimalistic-crypto-utils "^1.0.0"
4360
-
4361
-email-validator@^2.0.4:
4362
- version "2.0.4"
4363
- resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed"
4364
- integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==
4365
-
1902
emoji-regex@^7.0.1:
1903
version "7.0.3"
1904
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
1905
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
1906
4371
-emoji-regex@^8.0.0:
4372
- version "8.0.0"
4373
- resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
4374
- integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
4375
-
4376
-emojis-list@^2.0.0:
4377
- version "2.1.0"
4378
- resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
4379
- integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
4380
-
4381
-encodeurl@~1.0.2:
4382
- version "1.0.2"
4383
- resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
4384
- integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
4385
-
1907
encoding@^0.1.11:
1908
version "0.1.12"
1909
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
@@ -4401,52 +1922,7 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
1922
dependencies:
1923
once "^1.4.0"
1924
4404
-end-of-stream@^1.4.1:
4405
- version "1.4.1"
4406
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
4407
- integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==
4408
- dependencies:
4409
- once "^1.4.0"
4410
-
4411
-end-of-stream@~1.1.0:
4412
- version "1.1.0"
4413
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.1.0.tgz#e9353258baa9108965efc41cb0ef8ade2f3cfb07"
4414
- integrity sha1-6TUyWLqpEIll78QcsO+K3i88+wc=
4415
- dependencies:
4416
- once "~1.3.0"
4417
-
4418
-enhanced-resolve@4.1.0, enhanced-resolve@^4.1.0:
4419
- version "4.1.0"
4420
- resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f"
4421
- integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==
4422
- dependencies:
4423
- graceful-fs "^4.1.2"
4424
- memory-fs "^0.4.0"
4425
- tapable "^1.0.0"
4426
-
4427
-entities@^1.1.1, entities@~1.1.1:
4428
- version "1.1.2"
4429
- resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
4430
- integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
4431
-
4432
-entities@^2.0.0:
4433
- version "2.0.0"
4434
- resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
4435
- integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
4436
-
4437
-env-paths@^1.0.0:
4438
- version "1.0.0"
4439
- resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0"
4440
- integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=
4441
-
4442
-errno@^0.1.3, errno@~0.1.7:
4443
- version "0.1.7"
4444
- resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
4445
- integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==
4446
- dependencies:
4447
- prr "~1.0.1"
4448
-
4449
-error-ex@^1.2.0, error-ex@^1.3.1:
1925
+error-ex@^1.2.0:
1926
version "1.3.2"
1927
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
1928
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
@@ -4480,116 +1956,20 @@ es-to-primitive@^1.2.0:
1956
is-date-object "^1.0.1"
1957
is-symbol "^1.0.2"
1958
4483
-es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@~0.10.14:
4484
- version "0.10.50"
4485
- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778"
4486
- integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==
4487
- dependencies:
4488
- es6-iterator "~2.0.3"
4489
- es6-symbol "~3.1.1"
4490
- next-tick "^1.0.0"
4491
-
4492
-es6-error@4.0.0:
4493
- version "4.0.0"
4494
- resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.0.0.tgz#f094c7041f662599bb12720da059d6b9c7ff0f40"
4495
- integrity sha1-8JTHBB9mJZm7EnINoFnWucf/D0A=
4496
-
4497
-es6-error@4.1.1:
4498
- version "4.1.1"
4499
- resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
4500
- integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
4501
-
4502
-es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3:
4503
- version "2.0.3"
4504
- resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
4505
- integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
4506
- dependencies:
4507
- d "1"
4508
- es5-ext "^0.10.35"
4509
- es6-symbol "^3.1.1"
4510
-
4511
-es6-map@^0.1.3:
4512
- version "0.1.5"
4513
- resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
4514
- integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=
4515
- dependencies:
4516
- d "1"
4517
- es5-ext "~0.10.14"
4518
- es6-iterator "~2.0.1"
4519
- es6-set "~0.1.5"
4520
- es6-symbol "~3.1.1"
4521
- event-emitter "~0.3.5"
4522
-
4523
-es6-promise@^2.0.1:
4524
- version "2.3.0"
4525
- resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-2.3.0.tgz#96edb9f2fdb01995822b263dd8aadab6748181bc"
4526
- integrity sha1-lu258v2wGZWCKyY92KratnSBgbw=
4527
-
1959
es6-promise@^4.0.3:
1960
version "4.2.2"
1961
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.2.tgz#f722d7769af88bd33bc13ec6605e1f92966b82d9"
1962
4532
-es6-promisify@5.0.0, es6-promisify@^5.0.0:
1963
+es6-promisify@^5.0.0:
1964
version "5.0.0"
1965
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
1966
dependencies:
1967
es6-promise "^4.0.3"
1968
4538
-es6-promisify@6.0.1:
4539
- version "6.0.1"
4540
- resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-6.0.1.tgz#6edaa45f3bd570ffe08febce66f7116be4b1cdb6"
4541
- integrity sha512-J3ZkwbEnnO+fGAKrjVpeUAnZshAdfZvbhQpqfIH9kSAspReRC4nJnu8ewm55b4y9ElyeuhCTzJD0XiH8Tsbhlw==
4542
-
4543
-es6-set@~0.1.5:
4544
- version "0.1.5"
4545
- resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
4546
- integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=
4547
- dependencies:
4548
- d "1"
4549
- es5-ext "~0.10.14"
4550
- es6-iterator "~2.0.1"
4551
- es6-symbol "3.1.1"
4552
- event-emitter "~0.3.5"
4553
-
4554
-es6-symbol@3.1.1, es6-symbol@^3, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
4555
- version "3.1.1"
4556
- resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
4557
- integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=
4558
- dependencies:
4559
- d "1"
4560
- es5-ext "~0.10.14"
4561
-
4562
-es6-weak-map@^2.0.1:
4563
- version "2.0.3"
4564
- resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53"
4565
- integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==
4566
- dependencies:
4567
- d "1"
4568
- es5-ext "^0.10.46"
4569
- es6-iterator "^2.0.3"
4570
- es6-symbol "^3.1.1"
4571
-
4572
-escape-html@~1.0.3:
4573
- version "1.0.3"
4574
- resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
4575
- integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
4576
-
4577
-escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
1969
+escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
1970
version "1.0.5"
1971
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
1972
4581
-escodegen@1.x.x:
4582
- version "1.12.0"
4583
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541"
4584
- integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==
4585
- dependencies:
4586
- esprima "^3.1.3"
4587
- estraverse "^4.2.0"
4588
- esutils "^2.0.2"
4589
- optionator "^0.8.1"
4590
- optionalDependencies:
4591
- source-map "~0.6.1"
4592
-
1973
escodegen@^1.9.0:
1974
version "1.11.1"
1975
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510"
@@ -4602,16 +1982,6 @@ escodegen@^1.9.0:
1982
optionalDependencies:
1983
source-map "~0.6.1"
1984
4605
-escope@^3.6.0:
4606
- version "3.6.0"
4607
- resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
4608
- integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=
4609
- dependencies:
4610
- es6-map "^0.1.3"
4611
- es6-weak-map "^2.0.1"
4612
- esrecurse "^4.1.0"
4613
- estraverse "^4.1.1"
4614
-
1985
eslint-config-fbjs@^1.1.1:
1986
version "1.1.1"
1987
resolved "https://registry.yarnpkg.com/eslint-config-fbjs/-/eslint-config-fbjs-1.1.1.tgz#dd29f8d912e8a755257e9eeef00bae1cce57f73a"
@@ -4643,13 +2013,6 @@ eslint-plugin-no-for-of-loops@^1.0.0:
2013
resolved "https://registry.yarnpkg.com/eslint-plugin-no-for-of-loops/-/eslint-plugin-no-for-of-loops-1.0.1.tgz#2ee3732d50c642b8d1bfacedbfe3b28f86222369"
2014
integrity sha512-uCotzBHt2W+HbLw2srRmqDJHOPbJGzeVLstKh8YyxS3ppduq2P50qdpJfHKoD+UGbnqA/zhy8NRgPH6p0y8bnA==
2015
4646
-eslint-plugin-no-unsafe-innerhtml@1.0.16:
4647
- version "1.0.16"
4648
- resolved "https://registry.yarnpkg.com/eslint-plugin-no-unsafe-innerhtml/-/eslint-plugin-no-unsafe-innerhtml-1.0.16.tgz#7d02878c8e9bf7916b88836d5ac122b42f151932"
4649
- integrity sha1-fQKHjI6b95FriINtWsEitC8VGTI=
4650
- dependencies:
4651
- eslint "^3.7.1"
4652
-
2016
"eslint-plugin-react-internal@link:./scripts/eslint-rules":
2017
version "0.0.0"
2018
uid ""
@@ -4678,7 +2041,7 @@ eslint-scope@3.7.1:
2041
esrecurse "^4.1.0"
2042
estraverse "^4.1.1"
2043
4681
-eslint-scope@^4.0.0, eslint-scope@^4.0.3:
2044
+eslint-scope@^4.0.0:
2045
version "4.0.3"
2046
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848"
2047
integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==
@@ -4701,93 +2064,10 @@ eslint-utils@^1.3.1:
2064
dependencies:
2065
eslint-visitor-keys "^1.0.0"
2066
4704
-eslint-visitor-keys@1.0.0, eslint-visitor-keys@^1.0.0:
2067
+eslint-visitor-keys@^1.0.0:
2068
version "1.0.0"
2069
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
2070
4708
-eslint@5.16.0:
4709
- version "5.16.0"
4710
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea"
4711
- integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==
4712
- dependencies:
4713
- "@babel/code-frame" "^7.0.0"
4714
- ajv "^6.9.1"
4715
- chalk "^2.1.0"
4716
- cross-spawn "^6.0.5"
4717
- debug "^4.0.1"
4718
- doctrine "^3.0.0"
4719
- eslint-scope "^4.0.3"
4720
- eslint-utils "^1.3.1"
4721
- eslint-visitor-keys "^1.0.0"
4722
- espree "^5.0.1"
4723
- esquery "^1.0.1"
4724
- esutils "^2.0.2"
4725
- file-entry-cache "^5.0.1"
4726
- functional-red-black-tree "^1.0.1"
4727
- glob "^7.1.2"
4728
- globals "^11.7.0"
4729
- ignore "^4.0.6"
4730
- import-fresh "^3.0.0"
4731
- imurmurhash "^0.1.4"
4732
- inquirer "^6.2.2"
4733
- js-yaml "^3.13.0"
4734
- json-stable-stringify-without-jsonify "^1.0.1"
4735
- levn "^0.3.0"
4736
- lodash "^4.17.11"
4737
- minimatch "^3.0.4"
4738
- mkdirp "^0.5.1"
4739
- natural-compare "^1.4.0"
4740
- optionator "^0.8.2"
4741
- path-is-inside "^1.0.2"
4742
- progress "^2.0.0"
4743
- regexpp "^2.0.1"
4744
- semver "^5.5.1"
4745
- strip-ansi "^4.0.0"
4746
- strip-json-comments "^2.0.1"
4747
- table "^5.2.3"
4748
- text-table "^0.2.0"
4749
-
4750
-eslint@^3.7.1:
4751
- version "3.19.0"
4752
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc"
4753
- integrity sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=
4754
- dependencies:
4755
- babel-code-frame "^6.16.0"
4756
- chalk "^1.1.3"
4757
- concat-stream "^1.5.2"
4758
- debug "^2.1.1"
4759
- doctrine "^2.0.0"
4760
- escope "^3.6.0"
4761
- espree "^3.4.0"
4762
- esquery "^1.0.0"
4763
- estraverse "^4.2.0"
4764
- esutils "^2.0.2"
4765
- file-entry-cache "^2.0.0"
4766
- glob "^7.0.3"
4767
- globals "^9.14.0"
4768
- ignore "^3.2.0"
4769
- imurmurhash "^0.1.4"
4770
- inquirer "^0.12.0"
4771
- is-my-json-valid "^2.10.0"
4772
- is-resolvable "^1.0.0"
4773
- js-yaml "^3.5.1"
4774
- json-stable-stringify "^1.0.0"
4775
- levn "^0.3.0"
4776
- lodash "^4.0.0"
4777
- mkdirp "^0.5.0"
4778
- natural-compare "^1.4.0"
4779
- optionator "^0.8.2"
4780
- path-is-inside "^1.0.1"
4781
- pluralize "^1.2.1"
4782
- progress "^1.1.8"
4783
- require-uncached "^1.0.2"
4784
- shelljs "^0.7.5"
4785
- strip-bom "^3.0.0"
4786
- strip-json-comments "~2.0.1"
4787
- table "^3.7.8"
4788
- text-table "~0.2.0"
4789
- user-home "^2.0.0"
4790
-
2071
eslint@^6.1.0:
2072
version "6.1.0"
2073
resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646"
@@ -4831,23 +2111,6 @@ eslint@^6.1.0:
2111
text-table "^0.2.0"
2112
v8-compile-cache "^2.0.3"
2113
4834
-espree@5.0.1, espree@^5.0.1:
4835
- version "5.0.1"
4836
- resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a"
4837
- integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==
4838
- dependencies:
4839
- acorn "^6.0.7"
4840
- acorn-jsx "^5.0.0"
4841
- eslint-visitor-keys "^1.0.0"
4842
-
4843
-espree@^3.4.0:
4844
- version "3.5.4"
4845
- resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
4846
- integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==
4847
- dependencies:
4848
- acorn "^5.5.0"
4849
- acorn-jsx "^3.0.0"
4850
-
2114
espree@^6.0.0:
2115
version "6.0.0"
2116
resolved "https://registry.yarnpkg.com/espree/-/espree-6.0.0.tgz#716fc1f5a245ef5b9a7fdb1d7b0d3f02322e75f6"
@@ -4857,25 +2120,20 @@ espree@^6.0.0:
2120
acorn-jsx "^5.0.0"
2121
eslint-visitor-keys "^1.0.0"
2122
4860
-esprima@3.x.x, esprima@^3.1.3:
4861
- version "3.1.3"
4862
- resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
4863
- integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
4864
-
4865
-esprima@4.0.1:
4866
- version "4.0.1"
4867
- resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
4868
- integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
4869
-
2123
esprima@^2.6.0:
2124
version "2.7.3"
2125
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
2126
2127
+esprima@^3.1.3:
2128
+ version "3.1.3"
2129
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
2130
+ integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
2131
+
2132
esprima@^4.0.0:
2133
version "4.0.0"
2134
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
2135
4878
-esquery@^1.0.0, esquery@^1.0.1:
2136
+esquery@^1.0.1:
2137
version "1.0.1"
2138
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
2139
integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==
@@ -4909,55 +2167,6 @@ esutils@^2.0.0, esutils@^2.0.2:
2167
version "2.0.2"
2168
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
2169
4912
-etag@~1.8.1:
4913
- version "1.8.1"
4914
- resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
4915
- integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
4916
-
4917
-event-emitter@~0.3.5:
4918
- version "0.3.5"
4919
- resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
4920
- integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=
4921
- dependencies:
4922
- d "1"
4923
- es5-ext "~0.10.14"
4924
-
4925
-event-to-promise@0.8.0:
4926
- version "0.8.0"
4927
- resolved "https://registry.yarnpkg.com/event-to-promise/-/event-to-promise-0.8.0.tgz#4b84f11772b6f25f7752fc74d971531ac6f5b626"
4928
- integrity sha1-S4TxF3K28l93Uvx02XFTGsb1tiY=
4929
-
4930
-eventemitter3@^3.0.0:
4931
- version "3.1.2"
4932
- resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
4933
- integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==
4934
-
4935
-events@^1.0.0:
4936
- version "1.1.1"
4937
- resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
4938
- integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=
4939
-
4940
-events@^3.0.0:
4941
- name node-events
4942
- version "3.0.0"
4943
- resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88"
4944
- integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==
4945
-
4946
-eventsource@^1.0.7:
4947
- version "1.0.7"
4948
- resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0"
4949
- integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==
4950
- dependencies:
4951
- original "^1.0.0"
4952
-
4953
-evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
4954
- version "1.0.3"
4955
- resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
4956
- integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
4957
- dependencies:
4958
- md5.js "^1.3.4"
4959
- safe-buffer "^5.1.1"
4960
-
2170
exec-sh@^0.2.0:
2171
version "0.2.2"
2172
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36"
@@ -4965,11 +2174,6 @@ exec-sh@^0.2.0:
2174
dependencies:
2175
merge "^1.2.0"
2176
4968
-exec-sh@^0.3.2:
4969
- version "0.3.2"
4970
- resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b"
4971
- integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==
4972
-
2177
execa@^0.7.0:
2178
version "0.7.0"
2179
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
@@ -4983,24 +2187,6 @@ execa@^0.7.0:
2187
signal-exit "^3.0.0"
2188
strip-eof "^1.0.0"
2189
4986
-execa@^1.0.0:
4987
- version "1.0.0"
4988
- resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
4989
- integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
4990
- dependencies:
4991
- cross-spawn "^6.0.0"
4992
- get-stream "^4.0.0"
4993
- is-stream "^1.1.0"
4994
- npm-run-path "^2.0.0"
4995
- p-finally "^1.0.0"
4996
- signal-exit "^3.0.0"
4997
- strip-eof "^1.0.0"
4998
-
4999
-exit-hook@^1.0.0:
5000
- version "1.1.1"
5001
- resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
5002
- integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=
5003
-
2190
exit@^0.1.2:
2191
version "0.1.2"
2192
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -5031,13 +2217,6 @@ expand-range@^1.8.1:
2217
dependencies:
2218
fill-range "^2.1.0"
2219
5034
-expand-tilde@^2.0.0, expand-tilde@^2.0.2:
5035
- version "2.0.2"
5036
- resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
5037
- integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=
5038
- dependencies:
5039
- homedir-polyfill "^1.0.1"
5040
-
2220
expect@^23.6.0:
2221
version "23.6.0"
2222
resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98"
@@ -5050,42 +2229,6 @@ expect@^23.6.0:
2229
jest-message-util "^23.4.0"
2230
jest-regex-util "^23.3.0"
2231
5053
-express@^4.17.1:
5054
- version "4.17.1"
5055
- resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
5056
- integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
5057
- dependencies:
5058
- accepts "~1.3.7"
5059
- array-flatten "1.1.1"
5060
- body-parser "1.19.0"
5061
- content-disposition "0.5.3"
5062
- content-type "~1.0.4"
5063
- cookie "0.4.0"
5064
- cookie-signature "1.0.6"
5065
- debug "2.6.9"
5066
- depd "~1.1.2"
5067
- encodeurl "~1.0.2"
5068
- escape-html "~1.0.3"
5069
- etag "~1.8.1"
5070
- finalhandler "~1.1.2"
5071
- fresh "0.5.2"
5072
- merge-descriptors "1.0.1"
5073
- methods "~1.1.2"
5074
- on-finished "~2.3.0"
5075
- parseurl "~1.3.3"
5076
- path-to-regexp "0.1.7"
5077
- proxy-addr "~2.0.5"
5078
- qs "6.7.0"
5079
- range-parser "~1.2.1"
5080
- safe-buffer "5.1.2"
5081
- send "0.17.1"
5082
- serve-static "1.14.1"
5083
- setprototypeof "1.1.1"
5084
- statuses "~1.5.0"
5085
- type-is "~1.6.18"
5086
- utils-merge "1.0.1"
5087
- vary "~1.1.2"
5088
-
2232
extend-shallow@^1.1.2:
2233
version "1.1.4"
2234
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071"
@@ -5106,7 +2249,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
2249
assign-symbols "^1.0.0"
2250
is-extendable "^1.0.1"
2251
5109
-extend@3.0.2, extend@^3.0.0, extend@~3.0.0, extend@~3.0.1, extend@~3.0.2:
2252
+extend@^3.0.0, extend@~3.0.0, extend@~3.0.2:
2253
version "3.0.2"
2254
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
2255
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
@@ -5147,16 +2290,6 @@ extract-banner@0.1.2:
2290
strip-bom-string "^0.1.2"
2291
strip-use-strict "^0.1.0"
2292
5150
-extract-zip@^1.0.3:
5151
- version "1.6.7"
5152
- resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9"
5153
- integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=
5154
- dependencies:
5155
- concat-stream "1.6.2"
5156
- debug "2.6.9"
5157
- mkdirp "0.5.1"
5158
- yauzl "2.4.1"
5159
-
2293
extsprintf@1.3.0, extsprintf@^1.2.0:
2294
version "1.3.0"
2295
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
@@ -5169,23 +2302,11 @@ fancy-log@^1.3.2:
2302
color-support "^1.1.3"
2303
time-stamp "^1.0.0"
2304
5172
-fast-deep-equal@^1.0.0:
5173
- version "1.1.0"
5174
- resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
5175
- integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=
5176
-
2305
fast-deep-equal@^2.0.1:
2306
version "2.0.1"
2307
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
2308
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
2309
5182
-fast-json-patch@^2.0.6:
5183
- version "2.2.1"
5184
- resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.2.1.tgz#18150d36c9ab65c7209e7d4eb113f4f8eaabe6d9"
5185
- integrity sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig==
5186
- dependencies:
5187
- fast-deep-equal "^2.0.1"
5188
-
2310
fast-json-stable-stringify@^2.0.0:
2311
version "2.0.0"
2312
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
@@ -5194,35 +2315,6 @@ fast-levenshtein@~2.0.4:
2315
version "2.0.6"
2316
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
2317
5197
-fast-redact@^1.4.4:
5198
- version "1.5.0"
5199
- resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-1.5.0.tgz#302892f566750c4f5eec7b830bfc9bc473484034"
5200
- integrity sha512-Afo61CgUjkzdvOKDHn08qnZ0kwck38AOGcMlvSGzvJbIab6soAP5rdoQayecGCDsD69AiF9vJBXyq31eoEO2tQ==
5201
-
5202
-fast-safe-stringify@^2.0.6:
5203
- version "2.0.6"
5204
- resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2"
5205
- integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==
5206
-
5207
-fastparse@^1.1.1:
5208
- version "1.1.2"
5209
- resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
5210
- integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
5211
-
5212
-faye-websocket@^0.10.0:
5213
- version "0.10.0"
5214
- resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
5215
- integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=
5216
- dependencies:
5217
- websocket-driver ">=0.5.1"
5218
-
5219
-faye-websocket@~0.11.1:
5220
- version "0.11.3"
5221
- resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
5222
- integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==
5223
- dependencies:
5224
- websocket-driver ">=0.5.1"
5225
-
2318
fb-watchman@^2.0.0:
2319
version "2.0.0"
2320
resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58"
@@ -5230,11 +2322,6 @@ fb-watchman@^2.0.0:
2322
dependencies:
2323
bser "^2.0.0"
2324
5233
-fbjs-css-vars@^1.0.0:
5234
- version "1.0.2"
5235
- resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8"
5236
- integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==
5237
-
2325
fbjs-scripts@^0.8.3:
2326
version "0.8.3"
2327
resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-0.8.3.tgz#b854de7a11e62a37f72dab9aaf4d9b53c4a03174"
@@ -5262,68 +2349,12 @@ fbjs@^0.8.9:
2349
setimmediate "^1.0.5"
2350
ua-parser-js "^0.7.9"
2351
5265
-fbjs@^1.0.0:
5266
- version "1.0.0"
5267
- resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-1.0.0.tgz#52c215e0883a3c86af2a7a776ed51525ae8e0a5a"
5268
- integrity sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==
5269
- dependencies:
5270
- core-js "^2.4.1"
5271
- fbjs-css-vars "^1.0.0"
5272
- isomorphic-fetch "^2.1.1"
5273
- loose-envify "^1.0.0"
5274
- object-assign "^4.1.0"
5275
- promise "^7.1.1"
5276
- setimmediate "^1.0.5"
5277
- ua-parser-js "^0.7.18"
5278
-
5279
-fd-slicer@~1.0.1:
5280
- version "1.0.1"
5281
- resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65"
5282
- integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=
5283
- dependencies:
5284
- pend "~1.2.0"
5285
-
5286
-fd-slicer@~1.1.0:
5287
- version "1.1.0"
5288
- resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
5289
- integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
5290
- dependencies:
5291
- pend "~1.2.0"
5292
-
5293
-figgy-pudding@^3.5.1:
5294
- version "3.5.1"
5295
- resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
5296
- integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
5297
-
5298
-figures@^1.3.5:
5299
- version "1.7.0"
5300
- resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
5301
- integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=
5302
- dependencies:
5303
- escape-string-regexp "^1.0.5"
5304
- object-assign "^4.1.0"
5305
-
2352
figures@^2.0.0:
2353
version "2.0.0"
2354
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
2355
dependencies:
2356
escape-string-regexp "^1.0.5"
2357
5312
-figures@^3.0.0:
5313
- version "3.0.0"
5314
- resolved "https://registry.yarnpkg.com/figures/-/figures-3.0.0.tgz#756275c964646163cc6f9197c7a0295dbfd04de9"
5315
- integrity sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==
5316
- dependencies:
5317
- escape-string-regexp "^1.0.5"
5318
-
5319
-file-entry-cache@^2.0.0:
5320
- version "2.0.0"
5321
- resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
5322
- integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=
5323
- dependencies:
5324
- flat-cache "^1.2.1"
5325
- object-assign "^4.0.1"
5326
-
2358
file-entry-cache@^5.0.1:
2359
version "5.0.1"
2360
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c"
@@ -5331,11 +2362,6 @@ file-entry-cache@^5.0.1:
2362
dependencies:
2363
flat-cache "^2.0.1"
2364
5334
-file-uri-to-path@1:
5335
- version "1.0.0"
5336
- resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
5337
- integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
5338
-
2365
filename-regex@^2.0.0:
2366
version "2.0.1"
2367
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
@@ -5372,28 +2398,6 @@ fill-range@^4.0.0:
2398
repeat-string "^1.6.1"
2399
to-regex-range "^2.1.0"
2400
5375
-finalhandler@~1.1.2:
5376
- version "1.1.2"
5377
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
5378
- integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
5379
- dependencies:
5380
- debug "2.6.9"
5381
- encodeurl "~1.0.2"
5382
- escape-html "~1.0.3"
5383
- on-finished "~2.3.0"
5384
- parseurl "~1.3.3"
5385
- statuses "~1.5.0"
5386
- unpipe "~1.0.0"
5387
-
5388
-find-cache-dir@^2.0.0, find-cache-dir@^2.1.0:
5389
- version "2.1.0"
5390
- resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
5391
- integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==
5392
- dependencies:
5393
- commondir "^1.0.1"
5394
- make-dir "^2.0.0"
5395
- pkg-dir "^3.0.0"
5396
-
2401
find-up@^1.0.0:
2402
version "1.1.2"
2403
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
@@ -5404,63 +2408,9 @@ find-up@^1.0.0:
2408
find-up@^2.1.0:
2409
version "2.1.0"
2410
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
5407
- integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
5408
- dependencies:
5409
- locate-path "^2.0.0"
5410
-
5411
-find-up@^3.0.0:
5412
- version "3.0.0"
5413
- resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
5414
- integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
5415
- dependencies:
5416
- locate-path "^3.0.0"
5417
-
5418
-findup-sync@3.0.0:
5419
- version "3.0.0"
5420
- resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
5421
- integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
5422
- dependencies:
5423
- detect-file "^1.0.0"
5424
- is-glob "^4.0.0"
5425
- micromatch "^3.0.4"
5426
- resolve-dir "^1.0.1"
5427
-
5428
-firefox-profile@1.2.0, firefox-profile@^1.0.2:
5429
- version "1.2.0"
5430
- resolved "https://registry.yarnpkg.com/firefox-profile/-/firefox-profile-1.2.0.tgz#2068227924e714a2b10ec5fba8392e19b5788509"
5431
- integrity sha512-TTEFfPOkyaz4EWx/5ZDQC1mJAe3a+JgVcchpIfD4Tvx1UspwlTJRJxOYA35x/z2iJcxaF6aW2rdh6oj6qwgd2g==
5432
- dependencies:
5433
- adm-zip "~0.4.x"
5434
- archiver "~2.1.0"
5435
- async "~2.5.0"
5436
- fs-extra "~4.0.2"
5437
- ini "~1.3.3"
5438
- jetpack-id "1.0.0"
5439
- lazystream "~1.0.0"
5440
- lodash "~4.17.2"
5441
- minimist "^1.1.1"
5442
- uuid "^3.0.0"
5443
- xml2js "~0.4.4"
5444
-
5445
-first-chunk-stream@3.0.0, first-chunk-stream@^3.0.0:
5446
- version "3.0.0"
5447
- resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-3.0.0.tgz#06972a66263505ed82b2c4db93c1b5e078a6576a"
5448
- integrity sha512-LNRvR4hr/S8cXXkIY5pTgVP7L3tq6LlYWcg9nWBuW7o1NMxKZo6oOVa/6GIekMGI0Iw7uC+HWimMe9u/VAeKqw==
5449
-
5450
-first-match@0.0.1:
5451
- version "0.0.1"
5452
- resolved "https://registry.yarnpkg.com/first-match/-/first-match-0.0.1.tgz#a60ec642700f0f437234ebb7ec3f382476e542fd"
5453
- integrity sha1-pg7GQnAPD0NyNOu37D84JHblQv0=
5454
-
5455
-flat-cache@^1.2.1:
5456
- version "1.3.4"
5457
- resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f"
5458
- integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==
2411
+ integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
2412
dependencies:
5460
- circular-json "^0.3.1"
5461
- graceful-fs "^4.1.2"
5462
- rimraf "~2.6.2"
5463
- write "^0.2.1"
2413
+ locate-path "^2.0.0"
2414
2415
flat-cache@^2.0.1:
2416
version "2.0.1"
@@ -5471,11 +2421,6 @@ flat-cache@^2.0.1:
2421
rimraf "2.6.3"
2422
write "1.0.3"
2423
5474
-flatstr@^1.0.12, flatstr@^1.0.9:
5475
- version "1.0.12"
5476
- resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931"
5477
- integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==
5478
-
2424
flatted@^2.0.0:
2425
version "2.0.1"
2426
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08"
@@ -5485,31 +2430,6 @@ flow-bin@^0.72.0:
2430
version "0.72.0"
2431
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.72.0.tgz#12051180fb2db7ccb728fefe67c77e955e92a44d"
2432
5488
-fluent-syntax@0.13.0:
5489
- version "0.13.0"
5490
- resolved "https://registry.yarnpkg.com/fluent-syntax/-/fluent-syntax-0.13.0.tgz#417144d99cba94ff474c422b3e6623d5a842855a"
5491
- integrity sha512-0Bk1AsliuYB550zr4JV9AYhsETsD3ELXUQzdXGJfIc1Ni/ukAfBdQInDhVMYJUaT2QxoamNslwkYF7MlOrPUwg==
5492
-
5493
-flush-write-stream@^1.0.0:
5494
- version "1.1.1"
5495
- resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8"
5496
- integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==
5497
- dependencies:
5498
- inherits "^2.0.3"
5499
- readable-stream "^2.3.6"
5500
-
5501
-follow-redirects@^1.0.0:
5502
- version "1.7.0"
5503
- resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76"
5504
- integrity sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==
5505
- dependencies:
5506
- debug "^3.2.6"
5507
-
5508
-for-in@^0.1.3:
5509
- version "0.1.8"
5510
- resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
5511
- integrity sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=
5512
-
2433
for-in@^1.0.1, for-in@^1.0.2:
2434
version "1.0.2"
2435
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -5521,13 +2441,6 @@ for-own@^0.1.4:
2441
dependencies:
2442
for-in "^1.0.1"
2443
5524
-for-own@^1.0.0:
5525
- version "1.0.0"
5526
- resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b"
5527
- integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=
5528
- dependencies:
5529
- for-in "^1.0.1"
5530
-
2444
forever-agent@~0.6.1:
2445
version "0.6.1"
2446
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
@@ -5540,7 +2453,7 @@ form-data@~2.1.1:
2453
combined-stream "^1.0.5"
2454
mime-types "^2.1.12"
2455
5543
-form-data@~2.3.1, form-data@~2.3.2:
2456
+form-data@~2.3.2:
2457
version "2.3.3"
2458
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
2459
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
@@ -5549,11 +2462,6 @@ form-data@~2.3.1, form-data@~2.3.2:
2462
combined-stream "^1.0.6"
2463
mime-types "^2.1.12"
2464
5552
-forwarded@~0.1.2:
5553
- version "0.1.2"
5554
- resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
5555
- integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
5556
-
2465
fragment-cache@^0.2.1:
2466
version "0.2.1"
2467
resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
@@ -5561,37 +2469,10 @@ fragment-cache@^0.2.1:
2469
dependencies:
2470
map-cache "^0.2.2"
2471
5564
-fresh@0.5.2:
5565
- version "0.5.2"
5566
- resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
5567
- integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
5568
-
5569
-from2@^2.1.0:
5570
- version "2.3.0"
5571
- resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
5572
- integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=
5573
- dependencies:
5574
- inherits "^2.0.1"
5575
- readable-stream "^2.0.0"
5576
-
5577
-fs-constants@^1.0.0:
5578
- version "1.0.0"
5579
- resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
5580
- integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
5581
-
2472
fs-exists-sync@^0.1.0:
2473
version "0.1.0"
2474
resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
2475
5586
-fs-extra@^4.0.1, fs-extra@~4.0.2:
5587
- version "4.0.3"
5588
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94"
5589
- integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==
5590
- dependencies:
5591
- graceful-fs "^4.1.2"
5592
- jsonfile "^4.0.0"
5593
- universalify "^0.1.0"
5594
-
2476
fs-minipass@^1.2.5:
2477
version "1.2.6"
2478
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07"
@@ -5604,25 +2485,10 @@ fs-readdir-recursive@^1.1.0:
2485
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
2486
integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==
2487
5607
-fs-write-stream-atomic@^1.0.8:
5608
- version "1.0.10"
5609
- resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
5610
- integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=
5611
- dependencies:
5612
- graceful-fs "^4.1.2"
5613
- iferr "^0.1.5"
5614
- imurmurhash "^0.1.4"
5615
- readable-stream "1 || 2"
5616
-
2488
fs.realpath@^1.0.0:
2489
version "1.0.0"
2490
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
2491
5621
-fsevents@2.0.7:
5622
- version "2.0.7"
5623
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a"
5624
- integrity sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==
5625
-
2492
fsevents@^1.2.3, fsevents@^1.2.7:
2493
version "1.2.9"
2494
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f"
@@ -5631,14 +2497,6 @@ fsevents@^1.2.3, fsevents@^1.2.7:
2497
nan "^2.12.1"
2498
node-pre-gyp "^0.12.0"
2499
5634
-ftp@~0.3.10:
5635
- version "0.3.10"
5636
- resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d"
5637
- integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=
5638
- dependencies:
5639
- readable-stream "1.1.x"
5640
- xregexp "2.0.0"
5641
-
2500
function-bind@^1.1.1:
2501
version "1.1.1"
2502
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@@ -5647,18 +2505,6 @@ functional-red-black-tree@^1.0.1:
2505
version "1.0.1"
2506
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
2507
5650
-fx-runner@1.0.11:
5651
- version "1.0.11"
5652
- resolved "https://registry.yarnpkg.com/fx-runner/-/fx-runner-1.0.11.tgz#528d2d0c3dc8bb05570b506728c4f62e0b0ef095"
5653
- integrity sha512-igHogHf5wTqqaPPTOav18MMTVq/eoeTJiw/PvPUuwnzU8vbyZInFPgR66G9ZBwvwxC7e611nbtB4xSMcYVhlvg==
5654
- dependencies:
5655
- commander "2.9.0"
5656
- shell-quote "1.6.1"
5657
- spawn-sync "1.0.15"
5658
- when "3.7.7"
5659
- which "1.2.4"
5660
- winreg "0.0.12"
5661
-
2508
gauge@~2.7.3:
2509
version "2.7.4"
2510
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
@@ -5687,16 +2533,6 @@ get-caller-file@^1.0.1:
2533
version "1.0.2"
2534
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5"
2535
5690
-get-caller-file@^2.0.1:
5691
- version "2.0.5"
5692
- resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
5693
- integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
5694
-
5695
-get-stdin@^4.0.1:
5696
- version "4.0.1"
5697
- resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
5698
- integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
5699
-
2536
get-stdin@^5.0.1:
2537
version "5.0.1"
2538
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
@@ -5706,32 +2542,6 @@ get-stream@^3.0.0:
2542
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
2543
integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
2544
5709
-get-stream@^4.0.0, get-stream@^4.1.0:
5710
- version "4.1.0"
5711
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
5712
- integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
5713
- dependencies:
5714
- pump "^3.0.0"
5715
-
5716
-get-stream@^5.1.0:
5717
- version "5.1.0"
5718
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9"
5719
- integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==
5720
- dependencies:
5721
- pump "^3.0.0"
5722
-
5723
-get-uri@^2.0.0:
5724
- version "2.0.3"
5725
- resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.3.tgz#fa13352269781d75162c6fc813c9e905323fbab5"
5726
- integrity sha512-x5j6Ks7FOgLD/GlvjKwgu7wdmMR55iuRHhn8hj/+gA+eSbxQvZ+AEomq+3MgVEZj1vpi738QahGbCCSIDtXtkw==
5727
- dependencies:
5728
- data-uri-to-buffer "2"
5729
- debug "4"
5730
- extend "~3.0.2"
5731
- file-uri-to-path "1"
5732
- ftp "~0.3.10"
5733
- readable-stream "3"
5734
-
2545
get-value@^2.0.3, get-value@^2.0.6:
2546
version "2.0.6"
2547
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@@ -5743,13 +2553,6 @@ getpass@^0.1.1:
2553
dependencies:
2554
assert-plus "^1.0.0"
2555
5746
-gettext-parser@1.1.0:
5747
- version "1.1.0"
5748
- resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.1.0.tgz#2c5a6638d893934b9b55037d0ad82cb7004b2679"
5749
- integrity sha1-LFpmONiTk0ubVQN9CtgstwBLJnk=
5750
- dependencies:
5751
- encoding "^0.1.11"
5752
-
2556
git-config-path@^1.0.1:
2557
version "1.0.1"
2558
resolved "https://registry.yarnpkg.com/git-config-path/-/git-config-path-1.0.1.tgz#6d33f7ed63db0d0e118131503bab3aca47d54664"
@@ -5758,30 +2561,6 @@ git-config-path@^1.0.1:
2561
fs-exists-sync "^0.1.0"
2562
homedir-polyfill "^1.0.0"
2563
5761
-git-rev-sync@1.12.0:
5762
- version "1.12.0"
5763
- resolved "https://registry.yarnpkg.com/git-rev-sync/-/git-rev-sync-1.12.0.tgz#4468406c7e6c3ba4cf4587999e1adb28d9d1af55"
5764
- integrity sha1-RGhAbH5sO6TPRYeZnhrbKNnRr1U=
5765
- dependencies:
5766
- escape-string-regexp "1.0.5"
5767
- graceful-fs "4.1.11"
5768
- shelljs "0.7.7"
5769
-
5770
-git-up@^4.0.0:
5771
- version "4.0.1"
5772
- resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.1.tgz#cb2ef086653640e721d2042fe3104857d89007c0"
5773
- integrity sha512-LFTZZrBlrCrGCG07/dm1aCjjpL1z9L3+5aEeI9SBhAqSc+kiA9Or1bgZhQFNppJX6h/f5McrvJt1mQXTFm6Qrw==
5774
- dependencies:
5775
- is-ssh "^1.3.0"
5776
- parse-url "^5.0.0"
5777
-
5778
-git-url-parse@11.1.2:
5779
- version "11.1.2"
5780
- resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.1.2.tgz#aff1a897c36cc93699270587bea3dbcbbb95de67"
5781
- integrity sha512-gZeLVGY8QVKMIkckncX+iCq2/L8PlwncvDFKiWkBn9EtCfYDbliRTTp6qzyQ1VMdITUfq7293zDzfpjdiGASSQ==
5782
- dependencies:
5783
- git-up "^4.0.0"
5784
-
2564
github@^13.0.1:
2565
version "13.0.1"
2566
resolved "https://registry.yarnpkg.com/github/-/github-13.0.1.tgz#4ccf4a41df662f92367e77a474674eabb1b6c78d"
@@ -5835,91 +2614,37 @@ glob-stream@^6.1.0:
2614
to-absolute-glob "^2.0.0"
2615
unique-stream "^2.0.2"
2616
5838
-glob@7.1.4, glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
5839
- version "7.1.4"
5840
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
5841
- integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
2617
+glob@^6.0.4:
2618
+ version "6.0.4"
2619
+ resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
2620
dependencies:
5843
- fs.realpath "^1.0.0"
2621
inflight "^1.0.4"
2622
inherits "2"
5846
- minimatch "^3.0.4"
2623
+ minimatch "2 || 3"
2624
once "^1.3.0"
2625
path-is-absolute "^1.0.0"
2626
5850
-glob@^6.0.1, glob@^6.0.4:
5851
- version "6.0.4"
5852
- resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
2627
+glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3:
2628
+ version "7.1.4"
2629
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
2630
+ integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
2631
dependencies:
2632
+ fs.realpath "^1.0.0"
2633
inflight "^1.0.4"
2634
inherits "2"
5856
- minimatch "2 || 3"
2635
+ minimatch "^3.0.4"
2636
once "^1.3.0"
2637
path-is-absolute "^1.0.0"
2638
5860
-global-dirs@^0.1.0:
5861
- version "0.1.1"
5862
- resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445"
5863
- integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=
5864
- dependencies:
5865
- ini "^1.3.4"
5866
-
5867
-global-modules@2.0.0:
5868
- version "2.0.0"
5869
- resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
5870
- integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
5871
- dependencies:
5872
- global-prefix "^3.0.0"
5873
-
5874
-global-modules@^1.0.0:
5875
- version "1.0.0"
5876
- resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
5877
- integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==
5878
- dependencies:
5879
- global-prefix "^1.0.1"
5880
- is-windows "^1.0.1"
5881
- resolve-dir "^1.0.0"
5882
-
5883
-global-prefix@^1.0.1:
5884
- version "1.0.2"
5885
- resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
5886
- integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=
5887
- dependencies:
5888
- expand-tilde "^2.0.2"
5889
- homedir-polyfill "^1.0.1"
5890
- ini "^1.3.4"
5891
- is-windows "^1.0.1"
5892
- which "^1.2.14"
5893
-
5894
-global-prefix@^3.0.0:
5895
- version "3.0.0"
5896
- resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97"
5897
- integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==
5898
- dependencies:
5899
- ini "^1.3.5"
5900
- kind-of "^6.0.2"
5901
- which "^1.3.1"
5902
-
2639
globals@^11.1.0, globals@^11.7.0:
2640
version "11.12.0"
2641
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
2642
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
2643
5908
-globals@^9.14.0, globals@^9.18.0:
2644
+globals@^9.18.0:
2645
version "9.18.0"
2646
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
2647
5912
-globby@^6.1.0:
5913
- version "6.1.0"
5914
- resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
5915
- integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=
5916
- dependencies:
5917
- array-union "^1.0.1"
5918
- glob "^7.0.3"
5919
- object-assign "^4.0.1"
5920
- pify "^2.0.0"
5921
- pinkie-promise "^2.0.0"
5922
-
2648
google-closure-compiler-java@^20190301.0.0:
2649
version "20190301.0.0"
2650
resolved "https://registry.yarnpkg.com/google-closure-compiler-java/-/google-closure-compiler-java-20190301.0.0.tgz#89d1d6ab04b7625daf38d63b28b557f92103e3e1"
@@ -5955,67 +2680,11 @@ google-closure-compiler@20190301.0.0:
2680
google-closure-compiler-linux "^20190301.0.0"
2681
google-closure-compiler-osx "^20190301.0.0"
2682
5958
-got@^6.7.1:
5959
- version "6.7.1"
5960
- resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
5961
- integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=
5962
- dependencies:
5963
- create-error-class "^3.0.0"
5964
- duplexer3 "^0.1.4"
5965
- get-stream "^3.0.0"
5966
- is-redirect "^1.0.0"
5967
- is-retry-allowed "^1.0.0"
5968
- is-stream "^1.0.0"
5969
- lowercase-keys "^1.0.0"
5970
- safe-buffer "^5.0.1"
5971
- timed-out "^4.0.0"
5972
- unzip-response "^2.0.1"
5973
- url-parse-lax "^1.0.0"
5974
-
5975
-got@^9.6.0:
5976
- version "9.6.0"
5977
- resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
5978
- integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
5979
- dependencies:
5980
- "@sindresorhus/is" "^0.14.0"
5981
- "@szmarczak/http-timer" "^1.1.2"
5982
- cacheable-request "^6.0.0"
5983
- decompress-response "^3.3.0"
5984
- duplexer3 "^0.1.4"
5985
- get-stream "^4.1.0"
5986
- lowercase-keys "^1.0.1"
5987
- mimic-response "^1.0.1"
5988
- p-cancelable "^1.0.0"
5989
- to-readable-stream "^1.0.0"
5990
- url-parse-lax "^3.0.0"
5991
-
5992
-graceful-fs@4.1.11:
5993
- version "4.1.11"
5994
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
5995
- integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=
5996
-
5997
-graceful-fs@^4.1.0, graceful-fs@^4.1.15, graceful-fs@^4.1.6, graceful-fs@^4.2.0:
5998
- version "4.2.2"
5999
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
6000
- integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
6001
-
2683
graceful-fs@^4.1.11, graceful-fs@^4.1.2:
2684
version "4.2.1"
2685
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.1.tgz#1c1f0c364882c868f5bff6512146328336a11b1d"
2686
integrity sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==
2687
6007
-"graceful-readlink@>= 1.0.0":
6008
- version "1.0.1"
6009
- resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
6010
- integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
6011
-
6012
-graphlib@^2.1.1, graphlib@^2.1.5:
6013
- version "2.1.7"
6014
- resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.7.tgz#b6a69f9f44bd9de3963ce6804a2fc9e73d86aecc"
6015
- integrity sha512-TyI9jIy2J4j0qgPmOOrHTCtpPqJGN/aurBwc6ZT+bRii+di1I+Wv3obRhVrmBEXet+qkMaEX67dXrwsd3QQM6w==
6016
- dependencies:
6017
- lodash "^4.17.5"
6018
-
2688
growly@^1.3.0:
2689
version "1.3.0"
2690
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
@@ -6027,11 +2696,6 @@ gzip-size@^3.0.0:
2696
dependencies:
2697
duplexer "^0.1.1"
2698
6030
-handle-thing@^2.0.0:
6031
- version "2.0.0"
6032
- resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754"
6033
- integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
6034
-
2699
handlebars@^4.0.3:
2700
version "4.1.2"
2701
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
@@ -6057,14 +2721,6 @@ har-validator@~2.0.6:
2721
is-my-json-valid "^2.12.4"
2722
pinkie-promise "^2.0.0"
2723
6060
-har-validator@~5.0.3:
6061
- version "5.0.3"
6062
- resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
6063
- integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=
6064
- dependencies:
6065
- ajv "^5.1.0"
6066
- har-schema "^2.0.0"
6067
-
2724
har-validator@~5.1.0:
2725
version "5.1.3"
2726
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
@@ -6079,11 +2735,6 @@ has-ansi@^2.0.0:
2735
dependencies:
2736
ansi-regex "^2.0.0"
2737
6082
-has-color@~0.1.0:
6083
- version "0.1.7"
6084
- resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f"
6085
- integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=
6086
-
2738
has-flag@^1.0.0:
2739
version "1.0.0"
2740
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
@@ -6138,11 +2789,6 @@ has-values@^1.0.0:
2789
is-number "^3.0.0"
2790
kind-of "^4.0.0"
2791
6141
-has-yarn@^2.1.0:
6142
- version "2.1.0"
6143
- resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
6144
- integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==
6145
-
2792
has@^1.0.1, has@^1.0.3:
2793
version "1.0.3"
2794
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
@@ -6150,22 +2796,6 @@ has@^1.0.1, has@^1.0.3:
2796
dependencies:
2797
function-bind "^1.1.1"
2798
6153
-hash-base@^3.0.0:
6154
- version "3.0.4"
6155
- resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918"
6156
- integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=
6157
- dependencies:
6158
- inherits "^2.0.1"
6159
- safe-buffer "^5.0.1"
6160
-
6161
-hash.js@^1.0.0, hash.js@^1.0.3:
6162
- version "1.1.7"
6163
- resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
6164
- integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
6165
- dependencies:
6166
- inherits "^2.0.3"
6167
- minimalistic-assert "^1.0.1"
6168
-
2799
hawk@~3.1.3:
2800
version "3.1.3"
2801
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
@@ -6175,15 +2805,6 @@ hawk@~3.1.3:
2805
hoek "2.x.x"
2806
sntp "1.x.x"
2807
6178
-hmac-drbg@^1.0.0:
6179
- version "1.0.1"
6180
- resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
6181
- integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
6182
- dependencies:
6183
- hash.js "^1.0.3"
6184
- minimalistic-assert "^1.0.0"
6185
- minimalistic-crypto-utils "^1.0.1"
6186
-
2808
hoek@2.x.x:
2809
version "2.16.3"
2810
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
@@ -6201,32 +2822,10 @@ homedir-polyfill@^1.0.0:
2822
dependencies:
2823
parse-passwd "^1.0.0"
2824
6204
-homedir-polyfill@^1.0.1:
6205
- version "1.0.3"
6206
- resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
6207
- integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==
6208
- dependencies:
6209
- parse-passwd "^1.0.0"
6210
-
2825
hosted-git-info@^2.1.4:
2826
version "2.6.0"
2827
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222"
2828
6215
-hosted-git-info@^2.7.1:
6216
- version "2.8.4"
6217
- resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546"
6218
- integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==
6219
-
6220
-hpack.js@^2.1.6:
6221
- version "2.1.6"
6222
- resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
6223
- integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=
6224
- dependencies:
6225
- inherits "^2.0.1"
6226
- obuf "^1.0.0"
6227
- readable-stream "^2.0.1"
6228
- wbuf "^1.1.0"
6229
-
2829
html-encoding-sniffer@^1.0.2:
2830
version "1.0.2"
2831
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
@@ -6234,105 +2833,6 @@ html-encoding-sniffer@^1.0.2:
2833
dependencies:
2834
whatwg-encoding "^1.0.1"
2835
6237
-html-entities@^1.2.1:
6238
- version "1.2.1"
6239
- resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
6240
- integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=
6241
-
6242
-htmlparser2@^3.9.1:
6243
- version "3.10.1"
6244
- resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
6245
- integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
6246
- dependencies:
6247
- domelementtype "^1.3.1"
6248
- domhandler "^2.3.0"
6249
- domutils "^1.5.1"
6250
- entities "^1.1.1"
6251
- inherits "^2.0.1"
6252
- readable-stream "^3.1.1"
6253
-
6254
-http-browserify@^1.3.2:
6255
- version "1.7.0"
6256
- resolved "https://registry.yarnpkg.com/http-browserify/-/http-browserify-1.7.0.tgz#33795ade72df88acfbfd36773cefeda764735b20"
6257
- integrity sha1-M3la3nLfiKz7/TZ3PO/tp2RzWyA=
6258
- dependencies:
6259
- Base64 "~0.2.0"
6260
- inherits "~2.0.1"
6261
-
6262
-http-cache-semantics@^4.0.0:
6263
- version "4.0.3"
6264
- resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz#495704773277eeef6e43f9ab2c2c7d259dda25c5"
6265
- integrity sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==
6266
-
6267
-http-deceiver@^1.2.7:
6268
- version "1.2.7"
6269
- resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
6270
- integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=
6271
-
6272
-http-errors@1.7.2:
6273
- version "1.7.2"
6274
- resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
6275
- integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
6276
- dependencies:
6277
- depd "~1.1.2"
6278
- inherits "2.0.3"
6279
- setprototypeof "1.1.1"
6280
- statuses ">= 1.5.0 < 2"
6281
- toidentifier "1.0.0"
6282
-
6283
-http-errors@1.7.3, http-errors@~1.7.2:
6284
- version "1.7.3"
6285
- resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
6286
- integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
6287
- dependencies:
6288
- depd "~1.1.2"
6289
- inherits "2.0.4"
6290
- setprototypeof "1.1.1"
6291
- statuses ">= 1.5.0 < 2"
6292
- toidentifier "1.0.0"
6293
-
6294
-http-errors@~1.6.2:
6295
- version "1.6.3"
6296
- resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
6297
- integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
6298
- dependencies:
6299
- depd "~1.1.2"
6300
- inherits "2.0.3"
6301
- setprototypeof "1.1.0"
6302
- statuses ">= 1.4.0 < 2"
6303
-
6304
-"http-parser-js@>=0.4.0 <0.4.11":
6305
- version "0.4.10"
6306
- resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4"
6307
- integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=
6308
-
6309
-http-proxy-agent@^2.1.0:
6310
- version "2.1.0"
6311
- resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
6312
- integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==
6313
- dependencies:
6314
- agent-base "4"
6315
- debug "3.1.0"
6316
-
6317
-http-proxy-middleware@^0.19.1:
6318
- version "0.19.1"
6319
- resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a"
6320
- integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==
6321
- dependencies:
6322
- http-proxy "^1.17.0"
6323
- is-glob "^4.0.0"
6324
- lodash "^4.17.11"
6325
- micromatch "^3.1.10"
6326
-
6327
-http-proxy@^1.17.0:
6328
- version "1.17.0"
6329
- resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a"
6330
- integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==
6331
- dependencies:
6332
- eventemitter3 "^3.0.0"
6333
- follow-redirects "^1.0.0"
6334
- requires-port "^1.0.0"
6335
-
2836
http-signature@~1.1.0:
2837
version "1.1.1"
2838
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
@@ -6350,16 +2850,6 @@ http-signature@~1.2.0:
2850
jsprim "^1.2.2"
2851
sshpk "^1.7.0"
2852
6353
-https-browserify@0.0.0:
6354
- version "0.0.0"
6355
- resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.0.tgz#b3ffdfe734b2a3d4a9efd58e8654c91fce86eafd"
6356
- integrity sha1-s//f5zSyo9Sp79WOhlTJH86G6v0=
6357
-
6358
-https-browserify@^1.0.0:
6359
- version "1.0.0"
6360
- resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
6361
- integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
6362
-
2853
https-proxy-agent@^2.1.0:
2854
version "2.1.1"
2855
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz#a7ce4382a1ba8266ee848578778122d491260fd9"
@@ -6367,23 +2857,10 @@ https-proxy-agent@^2.1.0:
2857
agent-base "^4.1.0"
2858
debug "^3.1.0"
2859
6370
-https-proxy-agent@^2.2.1:
6371
- version "2.2.2"
6372
- resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz#271ea8e90f836ac9f119daccd39c19ff7dfb0793"
6373
- integrity sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==
6374
- dependencies:
6375
- agent-base "^4.3.0"
6376
- debug "^3.1.0"
6377
-
2860
hyperlinker@^1.0.0:
2861
version "1.0.0"
2862
resolved "https://registry.yarnpkg.com/hyperlinker/-/hyperlinker-1.0.0.tgz#23dc9e38a206b208ee49bc2d6c8ef47027df0c0e"
2863
6382
-hyphenate-style-name@^1.0.2:
6383
- version "1.0.3"
6384
- resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48"
6385
- integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==
6386
-
2864
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
2865
version "0.4.24"
2866
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -6391,28 +2868,6 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
2868
dependencies:
2869
safer-buffer ">= 2.1.2 < 3"
2870
6394
-icss-replace-symbols@^1.1.0:
6395
- version "1.1.0"
6396
- resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
6397
- integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=
6398
-
6399
-icss-utils@^2.1.0:
6400
- version "2.1.0"
6401
- resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962"
6402
- integrity sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=
6403
- dependencies:
6404
- postcss "^6.0.1"
6405
-
6406
-ieee754@^1.1.4:
This file is too large to show in full.