Compare commits
463 Commits
is-rendera
...
v16.6.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba19844236 | ||
|
|
a24d510287 | ||
|
|
b50e63ef53 | ||
|
|
fd4527dbcd | ||
|
|
bd5a6d3914 | ||
|
|
8f2c89e963 | ||
|
|
2aecbcd6f1 | ||
|
|
b4608dd24c | ||
|
|
3c69a18814 | ||
|
|
b020fb1148 | ||
|
|
b67c1a2ee1 | ||
|
|
f777d196e0 | ||
|
|
e4512991c9 | ||
|
|
affb2b50ca | ||
|
|
0a0f503d57 | ||
|
|
600651e68e | ||
|
|
e9a2ec9156 | ||
|
|
9d47143e85 | ||
|
|
ebdb47d2c1 | ||
|
|
8b87ebf5b0 | ||
|
|
da04058a91 | ||
|
|
fd1256a561 | ||
|
|
b305c4e034 | ||
|
|
ce90ffd045 | ||
|
|
d34d1c3bae | ||
|
|
6c404d82aa | ||
|
|
8eca0eff87 | ||
|
|
293fed8993 | ||
|
|
ae196e84b6 | ||
|
|
c898020e01 | ||
|
|
c84b9bf828 | ||
|
|
595b4f945b | ||
|
|
d5d10d140e | ||
|
|
cdbfa6b5dd | ||
|
|
1ae3f29c20 | ||
|
|
3db8b80e15 | ||
|
|
169f935f78 | ||
|
|
bf9fadfcf4 | ||
|
|
8c67bbf183 | ||
|
|
e02086bfcc | ||
|
|
b92cdef641 | ||
|
|
6efbbe0685 | ||
|
|
5045763064 | ||
|
|
ddbfe2ed50 | ||
|
|
acb4899637 | ||
|
|
933b64710a | ||
|
|
5fc84efacc | ||
|
|
9f34eb79a3 | ||
|
|
f7cb9d2b22 | ||
|
|
63cc7d2b31 | ||
|
|
3a7c6da8d4 | ||
|
|
75a1c2e72a | ||
|
|
55a4b1f377 | ||
|
|
30aa4ad554 | ||
|
|
b772e0e26b | ||
|
|
9e9e3970e4 | ||
|
|
6514697f0c | ||
|
|
dd019d34db | ||
|
|
11d0781eea | ||
|
|
105f2de545 | ||
|
|
7bee9fbdd4 | ||
|
|
37c7fe0a5f | ||
|
|
ae4f3f07e5 | ||
|
|
95f98a1873 | ||
|
|
e217f2f1ac | ||
|
|
275e76e83b | ||
|
|
b5539ad628 | ||
|
|
0cc50b675a | ||
|
|
8b97a9c36f | ||
|
|
c8ade996e9 | ||
|
|
6c29eabf78 | ||
|
|
d520b358d6 | ||
|
|
8f1ec7649e | ||
|
|
5055a83fa4 | ||
|
|
3e8b4a5b8b | ||
|
|
ff5efb0390 | ||
|
|
f4488bee51 | ||
|
|
d42ed60026 | ||
|
|
d8e03de4aa | ||
|
|
fefa1269e2 | ||
|
|
80a0c05ce3 | ||
|
|
915e4eab53 | ||
|
|
508b5fba0e | ||
|
|
c285ea2700 | ||
|
|
eac092ecac | ||
|
|
cbbc2b6c4d | ||
|
|
4947fcd762 | ||
|
|
d75c69e0cf | ||
|
|
c8ef2feda9 | ||
|
|
55444a6f49 | ||
|
|
04c4f2fcea | ||
|
|
409e472fca | ||
|
|
663835a43a | ||
|
|
82710097f6 | ||
|
|
7ebd90c2c3 | ||
|
|
420001cb4e | ||
|
|
b753f76a74 | ||
|
|
d37f595595 | ||
|
|
b5c0852fdd | ||
|
|
769b1f270e | ||
|
|
8ecd4bd4f0 | ||
|
|
15b11d23f9 | ||
|
|
e770af7a3a | ||
|
|
95a313ec0b | ||
|
|
e16cdd5b17 | ||
|
|
7268d97d2b | ||
|
|
0fc0446798 | ||
|
|
36db538226 | ||
|
|
6938dcaacb | ||
|
|
fa65c58e15 | ||
|
|
d9a3cc070c | ||
|
|
d9659e499e | ||
|
|
0648ca618d | ||
|
|
4dd772ac10 | ||
|
|
98bab66c35 | ||
|
|
8ced545e3d | ||
|
|
b738ced477 | ||
|
|
55b8279423 | ||
|
|
dac9202a9c | ||
|
|
4f0bd45905 | ||
|
|
7685b55d27 | ||
|
|
21a79a1d9f | ||
|
|
9ea4bc6ed6 | ||
|
|
4773fdf7cd | ||
|
|
c9be16f5b6 | ||
|
|
3b7ee26925 | ||
|
|
8ca8a594e6 | ||
|
|
6d5d250bef | ||
|
|
4a635785f5 | ||
|
|
d270db1c38 | ||
|
|
a165cf7473 | ||
|
|
30b6076157 | ||
|
|
a68ca9a5b5 | ||
|
|
0af8199709 | ||
|
|
c73497c3c7 | ||
|
|
101ea6b84d | ||
|
|
1a57dc6689 | ||
|
|
77f8dfd81e | ||
|
|
9abb9cd50a | ||
|
|
8af6728c6f | ||
|
|
f47a958ea8 | ||
|
|
b2cea9078d | ||
|
|
e2e7cb9f4c | ||
|
|
d83601080a | ||
|
|
40a521aa72 | ||
|
|
605ab10a4a | ||
|
|
acc7f404ce | ||
|
|
cbc2240288 | ||
|
|
4eabeef11b | ||
|
|
95a3e1c2e7 | ||
|
|
96bcae9d50 | ||
|
|
5c783ee751 | ||
|
|
36c5d69caa | ||
|
|
3e9a5de888 | ||
|
|
3c60f32747 | ||
|
|
8315a30b9b | ||
|
|
ce96e2df4d | ||
|
|
c5212646f8 | ||
|
|
806eebdaee | ||
|
|
a0733fe13d | ||
|
|
4d17c3f051 | ||
|
|
469005d87b | ||
|
|
0dc0ddc1ef | ||
|
|
7601c37654 | ||
|
|
d0c0ec98ef | ||
|
|
4b68a6498b | ||
|
|
f305d2a489 | ||
|
|
970a34baed | ||
|
|
13965b4d30 | ||
|
|
17e703cb96 | ||
|
|
a775a767a1 | ||
|
|
2c7b78f216 | ||
|
|
e1a067dea0 | ||
|
|
518812eeb8 | ||
|
|
eeb817785c | ||
|
|
7ea3ca1d13 | ||
|
|
9b70816642 | ||
|
|
db9d51b65c | ||
|
|
0823f845cf | ||
|
|
bec2ddaf15 | ||
|
|
789e714bd7 | ||
|
|
4269fafb0a | ||
|
|
4380f9ba17 | ||
|
|
72fad84e76 | ||
|
|
39f93f7987 | ||
|
|
c3fad5acf8 | ||
|
|
dd91205617 | ||
|
|
42d12317a7 | ||
|
|
21ceb19ea0 | ||
|
|
489614c4fc | ||
|
|
351c9015c8 | ||
|
|
a210b5b440 | ||
|
|
2f54a0467b | ||
|
|
1d8a75fef0 | ||
|
|
d92114b98e | ||
|
|
0c9c591bfb | ||
|
|
9f819a5ea9 | ||
|
|
9c961c0a27 | ||
|
|
8bc0bcabe7 | ||
|
|
b488a5d9c5 | ||
|
|
4bcee56210 | ||
|
|
9a6c5ba72d | ||
|
|
72217d0819 | ||
|
|
cc66a1aa23 | ||
|
|
8b93a60c5e | ||
|
|
7a5eecc073 | ||
|
|
ecbf7af40b | ||
|
|
2282400850 | ||
|
|
a079011f95 | ||
|
|
a7bd7c3c04 | ||
|
|
7204b636ee | ||
|
|
d3bbfe09cc | ||
|
|
1b2646a403 | ||
|
|
dde0645fcf | ||
|
|
e49f3ca08e | ||
|
|
f6fb03edff | ||
|
|
54bfab5d6d | ||
|
|
ade5e69288 | ||
|
|
f260b14a8f | ||
|
|
4a40d76245 | ||
|
|
03ab1efeb4 | ||
|
|
144328fe81 | ||
|
|
8a8d973d3c | ||
|
|
7d1169b2d7 | ||
|
|
8d1038fc6d | ||
|
|
b87aabdfe1 | ||
|
|
12f3a5475f | ||
|
|
c6dcf46d65 | ||
|
|
7bcc0778fd | ||
|
|
d66505dbc7 | ||
|
|
e417e0bf7c | ||
|
|
8f45a685be | ||
|
|
71c0e05ba7 | ||
|
|
92a620e214 | ||
|
|
6255cc3949 | ||
|
|
5c5fc5f473 | ||
|
|
1bede616d1 | ||
|
|
0a8740db61 | ||
|
|
28cb379782 | ||
|
|
8963118b3c | ||
|
|
b47a28cb9e | ||
|
|
f765f02253 | ||
|
|
0156740610 | ||
|
|
550dd1d2ec | ||
|
|
34348a45b4 | ||
|
|
4e744be6ee | ||
|
|
bb627228ea | ||
|
|
9a110ebd8c | ||
|
|
fb88fd9d8c | ||
|
|
2d5c590cc2 | ||
|
|
955393cab9 | ||
|
|
ff93996028 | ||
|
|
281bd64c00 | ||
|
|
d6b59e3d26 | ||
|
|
52633c84e2 | ||
|
|
2d4705e753 | ||
|
|
25d48a7281 | ||
|
|
877f8bc6b2 | ||
|
|
0a96f90572 | ||
|
|
17a57adde2 | ||
|
|
605da8b420 | ||
|
|
69f9f4127a | ||
|
|
c1ba7b8cfd | ||
|
|
b473d5f864 | ||
|
|
6312efc34f | ||
|
|
b92f947af1 | ||
|
|
3c1dcd349a | ||
|
|
0b74e95d7b | ||
|
|
8a1e3962ab | ||
|
|
9604d26aec | ||
|
|
28b9289022 | ||
|
|
bf8aa60925 | ||
|
|
0040efc8d8 | ||
|
|
46950a3dfc | ||
|
|
0452c9bba5 | ||
|
|
c21bab6940 | ||
|
|
0d3fc9de10 | ||
|
|
0f050ad7cc | ||
|
|
f943423231 | ||
|
|
6ff062e048 | ||
|
|
a3e4d00089 | ||
|
|
b3d8c5376f | ||
|
|
d2123d6569 | ||
|
|
1c0ba70b4b | ||
|
|
6e4f7c7886 | ||
|
|
2967ebdbea | ||
|
|
1664b08f0c | ||
|
|
672e859d31 | ||
|
|
29287f0886 | ||
|
|
bb48622a36 | ||
|
|
d400d6d5ef | ||
|
|
340bfd9393 | ||
|
|
53ddcec4f1 | ||
|
|
5cefd9b1e2 | ||
|
|
3661616c28 | ||
|
|
a1be17140d | ||
|
|
90c92c7007 | ||
|
|
5cb0f2bf51 | ||
|
|
e106b8c44f | ||
|
|
026aa9c978 | ||
|
|
3cae7543be | ||
|
|
d670bdc6b1 | ||
|
|
bf1abf478b | ||
|
|
e8571c798d | ||
|
|
973496b40c | ||
|
|
0beb2ee76b | ||
|
|
004cb21bbb | ||
|
|
f7a538c913 | ||
|
|
d1c42d2f1e | ||
|
|
a869f992a8 | ||
|
|
0cd8d470da | ||
|
|
b3a4cfea57 | ||
|
|
0da5102cf0 | ||
|
|
4b32f525e1 | ||
|
|
d2f5c3fbc2 | ||
|
|
5e0f073d50 | ||
|
|
d14e443d6e | ||
|
|
146c9fb307 | ||
|
|
d5edc1f51e | ||
|
|
4fa20b53b7 | ||
|
|
fe959eea73 | ||
|
|
2b30828000 | ||
|
|
5031ebf6be | ||
|
|
77b7a660b9 | ||
|
|
cb7745c6cf | ||
|
|
9832a1b6d5 | ||
|
|
8862172fa3 | ||
|
|
5816829170 | ||
|
|
1bc975d073 | ||
|
|
83e446e1d8 | ||
|
|
13fa96a547 | ||
|
|
b2adcfba32 | ||
|
|
69e2a0d732 | ||
|
|
ade4dd3f6f | ||
|
|
2c59076d26 | ||
|
|
24b0ed7a2e | ||
|
|
de5102c4cd | ||
|
|
e3d5b5ea7f | ||
|
|
d04d03e470 | ||
|
|
5550ed4a8f | ||
|
|
3938ccc88a | ||
|
|
47e217a77d | ||
|
|
714c78d5a1 | ||
|
|
a0190f828f | ||
|
|
d1e589137f | ||
|
|
33602d435a | ||
|
|
ae855cec22 | ||
|
|
725e499cfb | ||
|
|
e07a3cd28f | ||
|
|
e0204084a0 | ||
|
|
be4533af7d | ||
|
|
0072b59984 | ||
|
|
d59b993a74 | ||
|
|
54d86eb822 | ||
|
|
067cc24f55 | ||
|
|
1209ae50f3 | ||
|
|
3cfab14b96 | ||
|
|
a66217b571 | ||
|
|
212437eaf0 | ||
|
|
3b3b7fcbbd | ||
|
|
43a137d9c1 | ||
|
|
08e32263f9 | ||
|
|
f8456b2ecb | ||
|
|
61122347dd | ||
|
|
c0bf34c9c4 | ||
|
|
ac72388563 | ||
|
|
75491a8f4b | ||
|
|
2d0356a524 | ||
|
|
b179bae0ae | ||
|
|
fa824d0921 | ||
|
|
f265d545a1 | ||
|
|
15a8f03183 | ||
|
|
5cff212072 | ||
|
|
261da3f0a9 | ||
|
|
b565f49531 | ||
|
|
1609cf3432 | ||
|
|
46d5afc54d | ||
|
|
b3b80a4835 | ||
|
|
5e8beec84b | ||
|
|
470377bbdb | ||
|
|
ad17ca639b | ||
|
|
6db080154b | ||
|
|
fddb23601f | ||
|
|
95738e5cfd | ||
|
|
d79238f1ee | ||
|
|
ae63110335 | ||
|
|
e341e503b2 | ||
|
|
00cd4444e2 | ||
|
|
41f6d8cc7a | ||
|
|
0624c719f4 | ||
|
|
f60a7f722c | ||
|
|
ff41519ec2 | ||
|
|
c44c2a2161 | ||
|
|
28cd494bdf | ||
|
|
b381f41411 | ||
|
|
0182a74632 | ||
|
|
2a2ef7e0fd | ||
|
|
840cb1a268 | ||
|
|
bc1ea9cd96 | ||
|
|
0154a79fed | ||
|
|
dbd16c8a96 | ||
|
|
ca0941fce3 | ||
|
|
a32c727f2e | ||
|
|
2b509e2c8c | ||
|
|
5776fa3fcf | ||
|
|
3d3506d37d | ||
|
|
71b4e99901 | ||
|
|
8121212f0d | ||
|
|
2a1bc3f74c | ||
|
|
2c560cb995 | ||
|
|
ead08827d0 | ||
|
|
e4e58343e4 | ||
|
|
0e235bb8f7 | ||
|
|
236f608723 | ||
|
|
acbb4f93f0 | ||
|
|
171e0b7d44 | ||
|
|
606c30aa5f | ||
|
|
9f78913b20 | ||
|
|
6d3e262880 | ||
|
|
82c7ca4cca | ||
|
|
21ac62c77a | ||
|
|
d6a0626b38 | ||
|
|
fd410f43fc | ||
|
|
f9358c51c8 | ||
|
|
854c953905 | ||
|
|
467d139101 | ||
|
|
43ffae2d17 | ||
|
|
659a29cecf | ||
|
|
58f3b29d91 | ||
|
|
1c89cb62fd | ||
|
|
e6076ecf48 | ||
|
|
32f6f258ba | ||
|
|
9ca37f8431 | ||
|
|
f89f25f471 | ||
|
|
7b99ceabec | ||
|
|
6ebc8f3c07 | ||
|
|
d64d1ddb57 | ||
|
|
afd46490d0 | ||
|
|
e79366d549 | ||
|
|
1f32d3c6dc | ||
|
|
377e1a049e | ||
|
|
96d38d178a | ||
|
|
095dd5049c | ||
|
|
5662595677 | ||
|
|
ebbd221432 | ||
|
|
ddc91af795 | ||
|
|
3596e40b39 | ||
|
|
449f6ddd5c | ||
|
|
f762b3abb1 | ||
|
|
6f6b560a64 | ||
|
|
1386ccddd8 | ||
|
|
f5779bbc10 | ||
|
|
9faf389e79 | ||
|
|
85fe4ddce7 | ||
|
|
07fefe3331 | ||
|
|
88d7ed8bfb | ||
|
|
f128fdea48 | ||
|
|
aa8266c4f7 | ||
|
|
c039c16f21 | ||
|
|
6731bfbed7 | ||
|
|
64e1921aab | ||
|
|
bf32a3d195 | ||
|
|
183aefa51f |
@@ -37,10 +37,12 @@ module.exports = {
|
||||
'no-shadow': ERROR,
|
||||
'no-unused-expressions': ERROR,
|
||||
'no-unused-vars': [ERROR, {args: 'none'}],
|
||||
'no-use-before-define': [ERROR, {functions: false, variables: false}],
|
||||
'no-useless-concat': OFF,
|
||||
'quotes': [ERROR, 'single', {avoidEscape: true, allowTemplateLiterals: true }],
|
||||
'space-before-blocks': ERROR,
|
||||
'space-before-function-paren': OFF,
|
||||
'valid-typeof': [ERROR, {requireStringLiterals: true}],
|
||||
|
||||
// React & JSX
|
||||
// Our transforms set this automatically
|
||||
@@ -64,6 +66,7 @@ module.exports = {
|
||||
// CUSTOM RULES
|
||||
// the second argument of warning/invariant should be a literal string
|
||||
'react-internal/no-primitive-constructors': ERROR,
|
||||
'react-internal/no-to-warn-dev-within-to-throw': ERROR,
|
||||
'react-internal/warning-and-invariant-args': ERROR,
|
||||
},
|
||||
|
||||
@@ -82,5 +85,6 @@ module.exports = {
|
||||
spyOnDevAndProd: true,
|
||||
spyOnProd: true,
|
||||
__PROFILE__: true,
|
||||
__UMD__: true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"excludeGlob": [
|
||||
"node_modules/**",
|
||||
"packages/**/__mocks__/*.js",
|
||||
"packages/**/__tests__/*.js"
|
||||
],
|
||||
"includeGlob": [
|
||||
"packages/**/src/**/*.js"
|
||||
],
|
||||
"outputDir": "flow-coverage",
|
||||
"threshold": 90,
|
||||
"type": [
|
||||
"html",
|
||||
"json",
|
||||
"text"
|
||||
]
|
||||
}
|
||||
1
.gitignore
vendored
@@ -9,7 +9,6 @@ __benchmarks__
|
||||
build/
|
||||
remote-repo/
|
||||
coverage/
|
||||
flow-coverage/
|
||||
.module-cache
|
||||
fixtures/dom/public/react-dom.js
|
||||
fixtures/dom/public/react.js
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const {esNextPaths} = require('./scripts/shared/pathsByLanguageVersion');
|
||||
|
||||
module.exports = {
|
||||
@@ -6,6 +8,7 @@ module.exports = {
|
||||
jsxBracketSameLine: true,
|
||||
trailingComma: 'es5',
|
||||
printWidth: 80,
|
||||
parser: 'babylon',
|
||||
|
||||
overrides: [
|
||||
{
|
||||
|
||||
179
CHANGELOG.md
@@ -5,8 +5,161 @@
|
||||
Click to see more.
|
||||
</summary>
|
||||
|
||||
|
||||
### React DOM
|
||||
|
||||
* Fallback should not remount every time a promise resolves. ([@acdlite](https://github.com/acdlite) in [#14083](https://github.com/facebook/react/pull/14083))
|
||||
* Fix bug where Suspense keeps showing fallback even after everything finishes loading. ([@acdlite](https://github.com/acdlite) in [#14083](https://github.com/facebook/react/pull/14083))
|
||||
* Fix unresolved default props in lifecycle methods of a lazy component. ([@gaearon](https://github.com/gaearon) in [#14112](https://github.com/facebook/react/pull/14112))
|
||||
* Fix bug when recovering from an error thrown during complete phase. ([@gaearon](https://github.com/gaearon) in [#14104](https://github.com/facebook/react/pull/14104))
|
||||
|
||||
### Scheduler (Experimental)
|
||||
|
||||
* Switch from deadline object to `shouldYield` API. ([@acdlite](https://github.com/acdlite) in [#14025](https://github.com/facebook/react/pull/14025))
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
## 16.6.0 (October 23, 2018)
|
||||
|
||||
### React
|
||||
|
||||
* Add `React.memo()` as an alternative to `PureComponent` for functions. ([@acdlite](https://github.com/acdlite) in [#13748](https://github.com/facebook/react/pull/13748))
|
||||
* Add `React.lazy()` for code splitting components. ([@acdlite](https://github.com/acdlite) in [#13885](https://github.com/facebook/react/pull/13885))
|
||||
* `React.StrictMode` now warns about legacy context API. ([@bvaughn](https://github.com/bvaughn) in [#13760](https://github.com/facebook/react/pull/13760))
|
||||
* `React.StrictMode` now warns about `findDOMNode`. ([@sebmarkbage](https://github.com/sebmarkbage) in [#13841](https://github.com/facebook/react/pull/13841))
|
||||
* Rename `unstable_AsyncMode` to `unstable_ConcurrentMode`. ([@trueadm](https://github.com/trueadm) in [#13732](https://github.com/facebook/react/pull/13732))
|
||||
* Rename `unstable_Placeholder` to `Suspense`, and `delayMs` to `maxDuration`. ([@gaearon](https://github.com/gaearon) in [#13799](https://github.com/facebook/react/pull/13799) and [@sebmarkbage](https://github.com/sebmarkbage) in [#13922](https://github.com/facebook/react/pull/13922))
|
||||
|
||||
### React DOM
|
||||
|
||||
* Add `contextType` as a more ergonomic way to subscribe to context from a class. ([@bvaughn](https://github.com/bvaughn) in [#13728](https://github.com/facebook/react/pull/13728))
|
||||
* Add `getDerivedStateFromError` lifecycle method for catching errors in a future asynchronous server-side renderer. ([@bvaughn](https://github.com/bvaughn) in [#13746](https://github.com/facebook/react/pull/13746))
|
||||
* Warn when `<Context>` is used instead of `<Context.Consumer>`. ([@trueadm](https://github.com/trueadm) in [#13829](https://github.com/facebook/react/pull/13829))
|
||||
* Fix gray overlay on iOS Safari. ([@philipp-spiess](https://github.com/philipp-spiess) in [#13778](https://github.com/facebook/react/pull/13778))
|
||||
* Fix a bug caused by overwriting `window.event` in development. ([@sergei-startsev](https://github.com/sergei-startsev) in [#13697](https://github.com/facebook/react/pull/13697))
|
||||
|
||||
### React DOM Server
|
||||
|
||||
* Add support for `React.memo()`. ([@alexmckenley](https://github.com/alexmckenley) in [#13855](https://github.com/facebook/react/pull/13855))
|
||||
* Add support for `contextType`. ([@alexmckenley](https://github.com/alexmckenley) and [@sebmarkbage](https://github.com/sebmarkbage) in [#13889](https://github.com/facebook/react/pull/13889))
|
||||
|
||||
### Scheduler (Experimental)
|
||||
|
||||
* Rename the package to `scheduler`. ([@gaearon](https://github.com/gaearon) in [#13683](https://github.com/facebook/react/pull/13683))
|
||||
* Support priority levels, continuations, and wrapped callbacks. ([@acdlite](https://github.com/acdlite) in [#13720](https://github.com/facebook/react/pull/13720) and [#13842](https://github.com/facebook/react/pull/13842))
|
||||
* Improve the fallback mechanism in non-DOM environments. ([@acdlite](https://github.com/acdlite) in [#13740](https://github.com/facebook/react/pull/13740))
|
||||
* Schedule `requestAnimationFrame` earlier. ([@acdlite](https://github.com/acdlite) in [#13785](https://github.com/facebook/react/pull/13785))
|
||||
* Fix the DOM detection to be more thorough. ([@trueadm](https://github.com/trueadm) in [#13731](https://github.com/facebook/react/pull/13731))
|
||||
* Fix bugs with interaction tracing. ([@bvaughn](https://github.com/bvaughn) in [#13590](https://github.com/facebook/react/pull/13590))
|
||||
* Add the `envify` transform to the package. ([@mridgway](https://github.com/mridgway) in [#13766](https://github.com/facebook/react/pull/13766))
|
||||
|
||||
## 16.5.2 (September 18, 2018)
|
||||
|
||||
### React DOM
|
||||
|
||||
* Fixed a recent `<iframe>` regression ([@JSteunou](https://github.com/JSteunou) in [#13650](https://github.com/facebook/react/pull/13650))
|
||||
* Fix `updateWrapper` so that `<textarea>`s no longer re-render when data is unchanged ([@joelbarbosa](https://github.com/joelbarbosa) in [#13643](https://github.com/facebook/react/pull/13643))
|
||||
|
||||
### Schedule (Experimental)
|
||||
|
||||
* Renaming "tracking" API to "tracing" ([@bvaughn](https://github.com/bvaughn) in [#13641](https://github.com/facebook/react/pull/13641))
|
||||
* Add UMD production+profiling entry points ([@bvaughn](https://github.com/bvaughn) in [#13642](https://github.com/facebook/react/pull/13642))
|
||||
* Refactored `schedule` to remove some React-isms and improve performance for when deferred updates time out ([@acdlite](https://github.com/acdlite) in [#13582](https://github.com/facebook/react/pull/13582))
|
||||
|
||||
## 16.5.1 (September 13, 2018)
|
||||
|
||||
### React
|
||||
|
||||
* Improve the warning when `React.forwardRef` receives an unexpected number of arguments. ([@andresroberto](https://github.com/andresroberto) in [#13636](https://github.com/facebook/react/issues/13636))
|
||||
|
||||
### React DOM
|
||||
|
||||
* Fix a regression in unstable exports used by React Native Web. ([@aweary](https://github.com/aweary) in [#13598](https://github.com/facebook/react/issues/13598))
|
||||
* Fix a crash when component defines a method called `isReactComponent`. ([@gaearon](https://github.com/gaearon) in [#13608](https://github.com/facebook/react/issues/13608))
|
||||
* Fix a crash in development mode in IE9 when printing a warning. ([@link-alex](https://github.com/link-alex) in [#13620](https://github.com/facebook/react/issues/13620))
|
||||
* Provide a better error message when running `react-dom/profiling` with `schedule/tracking`. ([@bvaughn](https://github.com/bvaughn) in [#13605](https://github.com/facebook/react/issues/13605))
|
||||
* If a `ForwardRef` component defines a `displayName`, use it in warnings. ([@probablyup](https://github.com/probablyup) in [#13615](https://github.com/facebook/react/issues/13615))
|
||||
|
||||
### Schedule (Experimental)
|
||||
|
||||
* Add a separate profiling entry point at `schedule/tracking-profiling`. ([@bvaughn](https://github.com/bvaughn) in [#13605](https://github.com/facebook/react/issues/13605))
|
||||
|
||||
## 16.5.0 (September 5, 2018)
|
||||
|
||||
### React
|
||||
|
||||
* Add a warning if `React.forwardRef` render function doesn't take exactly two arguments ([@bvaughn](https://github.com/bvaughn) in [#13168](https://github.com/facebook/react/issues/13168))
|
||||
* Improve the error message when passing an element to `createElement` by mistake ([@DCtheTall](https://github.com/DCtheTall) in [#13131](https://github.com/facebook/react/issues/13131))
|
||||
* Don't call profiler `onRender` until after mutations ([@bvaughn](https://github.com/bvaughn) in [#13572](https://github.com/facebook/react/issues/13572))
|
||||
|
||||
### React DOM
|
||||
|
||||
* Add support for React DevTools Profiler ([@bvaughn](https://github.com/bvaughn) in [#13058](https://github.com/facebook/react/issues/13058))
|
||||
* Add `react-dom/profiling` entry point alias for profiling in production ([@bvaughn](https://github.com/bvaughn) in [#13570](https://github.com/facebook/react/issues/13570))
|
||||
* Add `onAuxClick` event for browsers that support it ([@jquense](https://github.com/jquense) in [#11571](https://github.com/facebook/react/issues/11571))
|
||||
* Add `movementX` and `movementY` fields to mouse events ([@jasonwilliams](https://github.com/jasonwilliams) in [#9018](https://github.com/facebook/react/issues/9018))
|
||||
* Add `tangentialPressure` and `twist` fields to pointer events ([@motiz88](https://github.com/motiz88) in [#13374](https://github.com/facebook/react/issues/13374))
|
||||
* Minimally support iframes (nested browsing contexts) in selection event handling ([@acusti](https://github.com/acusti) in [#12037](https://github.com/facebook/react/issues/12037))
|
||||
* Support passing booleans to the `focusable` SVG attribute ([@gaearon](https://github.com/gaearon) in [#13339](https://github.com/facebook/react/issues/13339))
|
||||
* Ignore `<noscript>` on the client when hydrating ([@Ephem](https://github.com/Ephem) in [#13537](https://github.com/facebook/react/issues/13537))
|
||||
* Fix `gridArea` to be treated as a unitless CSS property ([@mgol](https://github.com/mgol) in [#13550](https://github.com/facebook/react/issues/13550))
|
||||
* Fix incorrect data in `compositionend` event when typing Korean on IE11 ([@crux153](https://github.com/crux153) in [#12563](https://github.com/facebook/react/issues/12563))
|
||||
* Fix a crash when using dynamic `children` in the `<option>` tag ([@Slowyn](https://github.com/Slowyn) in [#13261](https://github.com/facebook/react/issues/13261), [@gaearon](https://github.com/gaearon) in [#13465](https://github.com/facebook/react/pull/13465))
|
||||
* Fix the `checked` attribute not getting initially set on the `input` ([@dilidili](https://github.com/dilidili) in [#13114](https://github.com/facebook/react/issues/13114))
|
||||
* Fix hydration of `dangerouslySetInnerHTML` when `__html` is not a string ([@gaearon](https://github.com/gaearon) in [#13353](https://github.com/facebook/react/issues/13353))
|
||||
* Fix a warning about missing controlled `onChange` to fire on falsy values too ([@nicolevy](https://github.com/nicolevy) in [#12628](https://github.com/facebook/react/issues/12628))
|
||||
* Fix `submit` and `reset` buttons getting an empty label ([@ellsclytn](https://github.com/ellsclytn) in [#12780](https://github.com/facebook/react/issues/12780))
|
||||
* Fix the `onSelect` event not being triggered after drag and drop ([@gaearon](https://github.com/gaearon) in [#13422](https://github.com/facebook/react/issues/13422))
|
||||
* Fix the `onClick` event not working inside a portal on iOS ([@aweary](https://github.com/aweary) in [#11927](https://github.com/facebook/react/issues/11927))
|
||||
* Fix a performance issue when thousands of roots are re-rendered ([@gaearon](https://github.com/gaearon) in [#13335](https://github.com/facebook/react/issues/13335))
|
||||
* Fix a performance regression that also caused `onChange` to not fire in some cases ([@gaearon](https://github.com/gaearon) in [#13423](https://github.com/facebook/react/issues/13423))
|
||||
* Handle errors in more edge cases gracefully ([@gaearon](https://github.com/gaearon) in [#13237](https://github.com/facebook/react/issues/13237) and [@acdlite](https://github.com/acdlite) in [#13269](https://github.com/facebook/react/issues/13269))
|
||||
* Don't use proxies for synthetic events in development ([@gaearon](https://github.com/gaearon) in [#12171](https://github.com/facebook/react/issues/12171))
|
||||
* Warn when `"false"` or `"true"` is the value of a boolean DOM prop ([@motiz88](https://github.com/motiz88) in [#13372](https://github.com/facebook/react/issues/13372))
|
||||
* Warn when `this.state` is initialized to `props` ([@veekas](https://github.com/veekas) in [#11658](https://github.com/facebook/react/issues/11658))
|
||||
* Don't compare `style` on hydration in IE due to noisy false positives ([@mgol](https://github.com/mgol) in [#13534](https://github.com/facebook/react/issues/13534))
|
||||
* Include `StrictMode` in the component stack ([@gaearon](https://github.com/gaearon) in [#13240](https://github.com/facebook/react/issues/13240))
|
||||
* Don't overwrite `window.event` in IE ([@ConradIrwin](https://github.com/ConradIrwin) in [#11696](https://github.com/facebook/react/issues/11696))
|
||||
* Improve component stack for the `folder/index.js` naming convention ([@gaearon](https://github.com/gaearon) in [#12059](https://github.com/facebook/react/issues/12059))
|
||||
* Improve a warning when using `getDerivedStateFromProps` without initialized state ([@flxwu](https://github.com/flxwu) in [#13317](https://github.com/facebook/react/issues/13317))
|
||||
* Improve a warning about invalid textarea usage ([@raunofreiberg](https://github.com/raunofreiberg) in [#13361](https://github.com/facebook/react/issues/13361))
|
||||
* Treat invalid Symbol and function values more consistently ([@raunofreiberg](https://github.com/raunofreiberg) in [#13362](https://github.com/facebook/react/issues/13362) and [#13389](https://github.com/facebook/react/issues/13389))
|
||||
* Allow Electron `<webview>` tag without warnings ([@philipp-spiess](https://github.com/philipp-spiess) in [#13301](https://github.com/facebook/react/issues/13301))
|
||||
* Don't show the uncaught error addendum if `e.preventDefault()` was called ([@gaearon](https://github.com/gaearon) in [#13384](https://github.com/facebook/react/issues/13384))
|
||||
* Warn about rendering Generators ([@gaearon](https://github.com/gaearon) in [#13312](https://github.com/facebook/react/issues/13312))
|
||||
* Remove irrelevant suggestion of a legacy method from a warning ([@zx6658](https://github.com/zx6658) in [#13169](https://github.com/facebook/react/issues/13169))
|
||||
* Remove `unstable_deferredUpdates` in favor of `unstable_scheduleWork` from `schedule` ([@gaearon](https://github.com/gaearon) in [#13488](https://github.com/facebook/react/issues/13488))
|
||||
* Fix unstable asynchronous mode from doing unnecessary work when an update takes too long ([@acdlite](https://github.com/acdlite) in [#13503](https://github.com/facebook/react/issues/13503))
|
||||
|
||||
### React DOM Server
|
||||
|
||||
* Fix crash with nullish children when using `dangerouslySetInnerHtml` in a selected `<option>` ([@mridgway](https://github.com/mridgway) in [#13078](https://github.com/facebook/react/issues/13078))
|
||||
* Fix crash when `setTimeout` is missing ([@dustinsoftware](https://github.com/dustinsoftware) in [#13088](https://github.com/facebook/react/issues/13088))
|
||||
|
||||
### React Test Renderer and Test Utils
|
||||
|
||||
* Fix `this` in a functional component for shallow renderer to be `undefined` ([@koba04](https://github.com/koba04) in [#13144](https://github.com/facebook/react/issues/13144))
|
||||
* Deprecate a Jest-specific `ReactTestUtils.mockComponent()` helper ([@bvaughn](https://github.com/bvaughn) in [#13193](https://github.com/facebook/react/issues/13193))
|
||||
* Warn about `ReactDOM.createPortal` usage within the test renderer ([@bvaughn](https://github.com/bvaughn) in [#12895](https://github.com/facebook/react/issues/12895))
|
||||
* Improve a confusing error message ([@gaearon](https://github.com/gaearon) in [#13351](https://github.com/facebook/react/issues/13351))
|
||||
|
||||
### React ART
|
||||
|
||||
* Add support for DevTools ([@yunchancho](https://github.com/yunchancho) in [#13173](https://github.com/facebook/react/issues/13173))
|
||||
|
||||
### Schedule (Experimental)
|
||||
|
||||
* New package for cooperatively scheduling work in a browser environment. It's used by React internally, but its public API is not finalized yet. ([@flarnie](https://github.com/flarnie) in [#12624](https://github.com/facebook/react/pull/12624))
|
||||
|
||||
## 16.4.2 (August 1, 2018)
|
||||
|
||||
### React DOM Server
|
||||
|
||||
* Fix a [potential XSS vulnerability when the attacker controls an attribute name](https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html) (`CVE-2018-6341`). This fix is available in the latest `react-dom@16.4.2`, as well as in previous affected minor versions: `react-dom@16.0.1`, `react-dom@16.1.2`, `react-dom@16.2.1`, and `react-dom@16.3.3`. ([@gaearon](https://github.com/gaearon) in [#13302](https://github.com/facebook/react/pull/13302))
|
||||
|
||||
* Fix a crash in the server renderer when an attribute is called `hasOwnProperty`. This fix is only available in `react-dom@16.4.2`. ([@gaearon](https://github.com/gaearon) in [#13303](https://github.com/facebook/react/pull/13303))
|
||||
|
||||
## 16.4.1 (June 13, 2018)
|
||||
|
||||
### React
|
||||
@@ -70,6 +223,12 @@
|
||||
|
||||
* The [new host config shape](https://github.com/facebook/react/blob/c601f7a64640290af85c9f0e33c78480656b46bc/packages/react-noop-renderer/src/createReactNoop.js#L82-L285) is flat and doesn't use nested objects. ([@gaearon](https://github.com/gaearon) in [#12792](https://github.com/facebook/react/pull/12792))
|
||||
|
||||
## 16.3.3 (August 1, 2018)
|
||||
|
||||
### React DOM Server
|
||||
|
||||
* Fix a [potential XSS vulnerability when the attacker controls an attribute name](https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html) (`CVE-2018-6341`). This fix is available in the latest `react-dom@16.4.2`, as well as in previous affected minor versions: `react-dom@16.0.1`, `react-dom@16.1.2`, `react-dom@16.2.1`, and `react-dom@16.3.3`. ([@gaearon](https://github.com/gaearon) in [#13302](https://github.com/facebook/react/pull/13302))
|
||||
|
||||
## 16.3.2 (April 16, 2018)
|
||||
|
||||
### React
|
||||
@@ -179,6 +338,12 @@
|
||||
|
||||
* Fix a crash on updates. ([@rmhartog](https://github.com/rmhartog) in [#11955](https://github.com/facebook/react/pull/11955))
|
||||
|
||||
## 16.2.1 (August 1, 2018)
|
||||
|
||||
### React DOM Server
|
||||
|
||||
* Fix a [potential XSS vulnerability when the attacker controls an attribute name](https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html) (`CVE-2018-6341`). This fix is available in the latest `react-dom@16.4.2`, as well as in previous affected minor versions: `react-dom@16.0.1`, `react-dom@16.1.2`, `react-dom@16.2.1`, and `react-dom@16.3.3`. ([@gaearon](https://github.com/gaearon) in [#13302](https://github.com/facebook/react/pull/13302))
|
||||
|
||||
## 16.2.0 (November 28, 2017)
|
||||
|
||||
### React
|
||||
@@ -203,6 +368,12 @@
|
||||
|
||||
* Many tests were rewritten against the public API. Big thanks to [everyone who contributed](https://github.com/facebook/react/issues/11299)!
|
||||
|
||||
## 16.1.2 (August 1, 2018)
|
||||
|
||||
### React DOM Server
|
||||
|
||||
* Fix a [potential XSS vulnerability when the attacker controls an attribute name](https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html) (`CVE-2018-6341`). This fix is available in the latest `react-dom@16.4.2`, as well as in previous affected minor versions: `react-dom@16.0.1`, `react-dom@16.1.2`, `react-dom@16.2.1`, and `react-dom@16.3.3`. ([@gaearon](https://github.com/gaearon) in [#13302](https://github.com/facebook/react/pull/13302))
|
||||
|
||||
## 16.1.1 (November 13, 2017)
|
||||
|
||||
### React
|
||||
@@ -293,6 +464,12 @@ Starting with 16.1.0, we will no longer be publishing new releases on Bower. You
|
||||
|
||||
* First release of the [new experimental package](https://github.com/facebook/react/tree/master/packages/react-call-return) for parent-child communication. ([@gaearon](https://github.com/gaearon) in [#11364](https://github.com/facebook/react/pull/11364))
|
||||
|
||||
## 16.0.1 (August 1, 2018)
|
||||
|
||||
### React DOM Server
|
||||
|
||||
* Fix a [potential XSS vulnerability when the attacker controls an attribute name](https://reactjs.org/blog/2018/08/01/react-v-16-4-2.html) (`CVE-2018-6341`). This fix is available in the latest `react-dom@16.4.2`, as well as in previous affected minor versions: `react-dom@16.0.1`, `react-dom@16.1.2`, `react-dom@16.2.1`, and `react-dom@16.3.3`. ([@gaearon](https://github.com/gaearon) in [#13302](https://github.com/facebook/react/pull/13302))
|
||||
|
||||
## 16.0.0 (September 26, 2017)
|
||||
|
||||
### New JS Environment Requirements
|
||||
@@ -779,7 +956,7 @@ Each of these changes will continue to work as before with a new warning until t
|
||||
- `Object.is` is used in a number of places to compare values, which leads to fewer false positives, especially involving `NaN`. In particular, this affects the `shallowCompare` add-on. ([@chicoxyzzy](https://github.com/chicoxyzzy) in [#6132](https://github.com/facebook/react/pull/6132))
|
||||
- Add-Ons: ReactPerf no longer instruments adding or removing an event listener because they don’t really touch the DOM due to event delegation. ([@antoaravinth](https://github.com/antoaravinth) in [#5209](https://github.com/facebook/react/pull/5209))
|
||||
|
||||
### Other improvements
|
||||
### Other improvements
|
||||
|
||||
- React now uses `loose-envify` instead of `envify` so it installs fewer transitive dependencies. ([@qerub](https://github.com/qerub) in [#6303](https://github.com/facebook/react/pull/6303))
|
||||
- Shallow renderer now exposes `getMountedInstance()`. ([@glenjamin](https://github.com/glenjamin) in [#4918](https://github.com/facebook/react/pull/4918))
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Code of Conduct
|
||||
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.facebook.com/pages/876921332402685/open-source-code-of-conduct) so that you can understand what actions will and will not be tolerated.
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.fb.com/codeofconduct/) so that you can understand what actions will and will not be tolerated.
|
||||
|
||||
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-present, Facebook, Inc.
|
||||
Copyright (c) Facebook, Inc. and its affiliates.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -54,7 +54,7 @@ ReactDOM.render(
|
||||
|
||||
This example will render "Hello Taylor" into a container on the page.
|
||||
|
||||
You'll notice that we used an HTML-like syntax; [we call it JSX](https://reactjs.org/docs/introducing-jsx.html). JSX is not required to use React, but it makes code more readable, and writing it feels like writing HTML.
|
||||
You'll notice that we used an HTML-like syntax; [we call it JSX](https://reactjs.org/docs/introducing-jsx.html). JSX is not required to use React, but it makes code more readable, and writing it feels like writing HTML. If you're using React as a `<script>` tag, read [this section](https://reactjs.org/docs/add-react-to-a-website.html#optional-try-react-with-jsx) on integrating JSX; otherwise, the [recommended JavaScript toolchains](https://reactjs.org/docs/create-a-new-react-app.html) handle it automatically.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@ init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
environment:
|
||||
nodejs_version: 8
|
||||
JAVA_HOME: C:\Program Files\Java\jdk1.8.0
|
||||
matrix:
|
||||
- nodejs_version: 10
|
||||
|
||||
# Finish on first failed build
|
||||
matrix:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -277,9 +277,9 @@
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
| `action=(string)`| (changed)| `"https://reactjs.com/"` |
|
||||
| `action=(empty string)`| (changed)| `"http://localhost:3000/"` |
|
||||
| `action=(empty string)`| (initial)| `"http://localhost:3000/"` |
|
||||
| `action=(array with string)`| (changed)| `"https://reactjs.com/"` |
|
||||
| `action=(empty array)`| (changed)| `"http://localhost:3000/"` |
|
||||
| `action=(empty array)`| (initial)| `"http://localhost:3000/"` |
|
||||
| `action=(object)`| (changed)| `"http://localhost:3000/result%20of%20toString()"` |
|
||||
| `action=(numeric string)`| (changed)| `"http://localhost:3000/42"` |
|
||||
| `action=(-1)`| (changed)| `"http://localhost:3000/-1"` |
|
||||
@@ -287,16 +287,16 @@
|
||||
| `action=(integer)`| (changed)| `"http://localhost:3000/1"` |
|
||||
| `action=(NaN)`| (changed, warning)| `"http://localhost:3000/NaN"` |
|
||||
| `action=(float)`| (changed)| `"http://localhost:3000/99.99"` |
|
||||
| `action=(true)`| (initial, warning)| `<empty string>` |
|
||||
| `action=(false)`| (initial, warning)| `<empty string>` |
|
||||
| `action=(true)`| (initial, warning)| `"http://localhost:3000/"` |
|
||||
| `action=(false)`| (initial, warning)| `"http://localhost:3000/"` |
|
||||
| `action=(string 'true')`| (changed)| `"http://localhost:3000/true"` |
|
||||
| `action=(string 'false')`| (changed)| `"http://localhost:3000/false"` |
|
||||
| `action=(string 'on')`| (changed)| `"http://localhost:3000/on"` |
|
||||
| `action=(string 'off')`| (changed)| `"http://localhost:3000/off"` |
|
||||
| `action=(symbol)`| (initial, warning)| `<empty string>` |
|
||||
| `action=(function)`| (initial, warning)| `<empty string>` |
|
||||
| `action=(null)`| (initial)| `<empty string>` |
|
||||
| `action=(undefined)`| (initial)| `<empty string>` |
|
||||
| `action=(symbol)`| (initial, warning)| `"http://localhost:3000/"` |
|
||||
| `action=(function)`| (initial, warning)| `"http://localhost:3000/"` |
|
||||
| `action=(null)`| (initial)| `"http://localhost:3000/"` |
|
||||
| `action=(undefined)`| (initial)| `"http://localhost:3000/"` |
|
||||
|
||||
## `additive` (on `<animate>` inside `<svg>`)
|
||||
| Test Case | Flags | Result |
|
||||
@@ -389,8 +389,8 @@
|
||||
| `allowFullScreen=(float)`| (changed)| `<boolean: true>` |
|
||||
| `allowFullScreen=(true)`| (changed)| `<boolean: true>` |
|
||||
| `allowFullScreen=(false)`| (initial)| `<boolean: false>` |
|
||||
| `allowFullScreen=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `allowFullScreen=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `allowFullScreen=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `allowFullScreen=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `allowFullScreen=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `allowFullScreen=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `allowFullScreen=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -739,8 +739,8 @@
|
||||
| `async=(float)`| (changed)| `<boolean: true>` |
|
||||
| `async=(true)`| (changed)| `<boolean: true>` |
|
||||
| `async=(false)`| (initial)| `<boolean: false>` |
|
||||
| `async=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `async=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `async=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `async=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `async=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `async=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `async=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -802,26 +802,26 @@
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
| `autoCapitalize=(string)`| (changed)| `"words"` |
|
||||
| `autoCapitalize=(empty string)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(empty string)`| (initial)| `<empty string>` |
|
||||
| `autoCapitalize=(array with string)`| (changed)| `"words"` |
|
||||
| `autoCapitalize=(empty array)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(object)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(numeric string)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(-1)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(0)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(integer)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(NaN)`| (initial, warning)| `"sentences"` |
|
||||
| `autoCapitalize=(float)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(true)`| (initial, warning)| `"sentences"` |
|
||||
| `autoCapitalize=(false)`| (initial, warning)| `"sentences"` |
|
||||
| `autoCapitalize=(string 'true')`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(string 'false')`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(string 'on')`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(empty array)`| (initial)| `<empty string>` |
|
||||
| `autoCapitalize=(object)`| (changed)| `"sentences"` |
|
||||
| `autoCapitalize=(numeric string)`| (changed)| `"sentences"` |
|
||||
| `autoCapitalize=(-1)`| (changed)| `"sentences"` |
|
||||
| `autoCapitalize=(0)`| (changed)| `"sentences"` |
|
||||
| `autoCapitalize=(integer)`| (changed)| `"sentences"` |
|
||||
| `autoCapitalize=(NaN)`| (changed, warning)| `"sentences"` |
|
||||
| `autoCapitalize=(float)`| (changed)| `"sentences"` |
|
||||
| `autoCapitalize=(true)`| (initial, warning)| `<empty string>` |
|
||||
| `autoCapitalize=(false)`| (initial, warning)| `<empty string>` |
|
||||
| `autoCapitalize=(string 'true')`| (changed)| `"sentences"` |
|
||||
| `autoCapitalize=(string 'false')`| (changed)| `"sentences"` |
|
||||
| `autoCapitalize=(string 'on')`| (changed)| `"sentences"` |
|
||||
| `autoCapitalize=(string 'off')`| (changed)| `"none"` |
|
||||
| `autoCapitalize=(symbol)`| (initial, warning)| `"sentences"` |
|
||||
| `autoCapitalize=(function)`| (initial, warning)| `"sentences"` |
|
||||
| `autoCapitalize=(null)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(undefined)`| (initial)| `"sentences"` |
|
||||
| `autoCapitalize=(symbol)`| (initial, warning)| `<empty string>` |
|
||||
| `autoCapitalize=(function)`| (initial, warning)| `<empty string>` |
|
||||
| `autoCapitalize=(null)`| (initial)| `<empty string>` |
|
||||
| `autoCapitalize=(undefined)`| (initial)| `<empty string>` |
|
||||
|
||||
## `autoComplete` (on `<input>` inside `<div>`)
|
||||
| Test Case | Flags | Result |
|
||||
@@ -889,8 +889,8 @@
|
||||
| `autoPlay=(float)`| (changed)| `<boolean: true>` |
|
||||
| `autoPlay=(true)`| (changed)| `<boolean: true>` |
|
||||
| `autoPlay=(false)`| (initial)| `<boolean: false>` |
|
||||
| `autoPlay=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `autoPlay=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `autoPlay=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `autoPlay=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `autoPlay=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `autoPlay=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `autoPlay=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -1389,8 +1389,8 @@
|
||||
| `checked=(float)`| (changed)| `<boolean: true>` |
|
||||
| `checked=(true)`| (changed)| `<boolean: true>` |
|
||||
| `checked=(false)`| (initial)| `<boolean: false>` |
|
||||
| `checked=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `checked=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `checked=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `checked=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `checked=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `checked=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `checked=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -1401,23 +1401,23 @@
|
||||
## `Checked` (on `<input>` inside `<div>`)
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
| `Checked=(string)`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(empty string)`| (changed, warning)| `<empty string>` |
|
||||
| `Checked=(array with string)`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(empty array)`| (changed, warning)| `<empty string>` |
|
||||
| `Checked=(object)`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(numeric string)`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(-1)`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(0)`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(integer)`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(NaN)`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(float)`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(string)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(empty string)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(array with string)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(empty array)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(object)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(numeric string)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(-1)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(0)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(integer)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(NaN)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(float)`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(true)`| (initial, warning)| `<null>` |
|
||||
| `Checked=(false)`| (initial, warning)| `<null>` |
|
||||
| `Checked=(string 'true')`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(string 'false')`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(string 'on')`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(string 'off')`| (changed, warning, ssr mismatch)| `<empty string>` |
|
||||
| `Checked=(string 'true')`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(string 'false')`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(string 'on')`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(string 'off')`| (initial, warning, ssr mismatch)| `<null>` |
|
||||
| `Checked=(symbol)`| (initial, warning)| `<null>` |
|
||||
| `Checked=(function)`| (initial, warning)| `<null>` |
|
||||
| `Checked=(null)`| (initial, warning)| `<null>` |
|
||||
@@ -2139,8 +2139,8 @@
|
||||
| `controls=(float)`| (changed)| `<boolean: true>` |
|
||||
| `controls=(true)`| (changed)| `<boolean: true>` |
|
||||
| `controls=(false)`| (initial)| `<boolean: false>` |
|
||||
| `controls=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `controls=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `controls=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `controls=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `controls=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `controls=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `controls=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -2514,8 +2514,8 @@
|
||||
| `default=(float)`| (changed)| `<boolean: true>` |
|
||||
| `default=(true)`| (changed)| `<boolean: true>` |
|
||||
| `default=(false)`| (initial)| `<boolean: false>` |
|
||||
| `default=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `default=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `default=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `default=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `default=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `default=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `default=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -2551,25 +2551,25 @@
|
||||
## `defaultChecked` (on `<input>` inside `<div>`)
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
| `defaultChecked=(string)`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(string)`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(empty string)`| (initial)| `<boolean: false>` |
|
||||
| `defaultChecked=(array with string)`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(empty array)`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(object)`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(numeric string)`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(-1)`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(array with string)`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(empty array)`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(object)`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(numeric string)`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(-1)`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(0)`| (initial)| `<boolean: false>` |
|
||||
| `defaultChecked=(integer)`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(integer)`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(NaN)`| (initial, warning, ssr warning)| `<boolean: false>` |
|
||||
| `defaultChecked=(float)`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(true)`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(float)`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(true)`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(false)`| (initial)| `<boolean: false>` |
|
||||
| `defaultChecked=(string 'true')`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(string 'false')`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(string 'on')`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(string 'off')`| (initial, ssr mismatch)| `<boolean: false>` |
|
||||
| `defaultChecked=(symbol)`| (initial)| `<boolean: false>` |
|
||||
| `defaultChecked=(function)`| (initial)| `<boolean: false>` |
|
||||
| `defaultChecked=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `defaultChecked=(symbol)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `defaultChecked=(function)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `defaultChecked=(null)`| (initial)| `<boolean: false>` |
|
||||
| `defaultChecked=(undefined)`| (initial)| `<boolean: false>` |
|
||||
|
||||
@@ -2639,8 +2639,8 @@
|
||||
| `defer=(float)`| (changed)| `<boolean: true>` |
|
||||
| `defer=(true)`| (changed)| `<boolean: true>` |
|
||||
| `defer=(false)`| (initial)| `<boolean: false>` |
|
||||
| `defer=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `defer=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `defer=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `defer=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `defer=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `defer=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `defer=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -2764,8 +2764,8 @@
|
||||
| `disabled=(float)`| (changed)| `<boolean: true>` |
|
||||
| `disabled=(true)`| (changed)| `<boolean: true>` |
|
||||
| `disabled=(false)`| (initial)| `<boolean: false>` |
|
||||
| `disabled=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `disabled=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `disabled=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `disabled=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `disabled=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `disabled=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `disabled=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -3587,8 +3587,8 @@
|
||||
| `focusable=(integer)`| (changed)| `"1"` |
|
||||
| `focusable=(NaN)`| (changed, warning)| `"NaN"` |
|
||||
| `focusable=(float)`| (changed)| `"99.99"` |
|
||||
| `focusable=(true)`| (initial, warning)| `<null>` |
|
||||
| `focusable=(false)`| (initial, warning)| `<null>` |
|
||||
| `focusable=(true)`| (changed)| `"true"` |
|
||||
| `focusable=(false)`| (changed)| `"false"` |
|
||||
| `focusable=(string 'true')`| (changed)| `"true"` |
|
||||
| `focusable=(string 'false')`| (changed)| `"false"` |
|
||||
| `focusable=(string 'on')`| (changed)| `"on"` |
|
||||
@@ -4139,8 +4139,8 @@
|
||||
| `formNoValidate=(float)`| (changed)| `<boolean: true>` |
|
||||
| `formNoValidate=(true)`| (changed)| `<boolean: true>` |
|
||||
| `formNoValidate=(false)`| (initial)| `<boolean: false>` |
|
||||
| `formNoValidate=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `formNoValidate=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `formNoValidate=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `formNoValidate=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `formNoValidate=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `formNoValidate=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `formNoValidate=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -4764,8 +4764,8 @@
|
||||
| `hidden=(float)`| (changed)| `<boolean: true>` |
|
||||
| `hidden=(true)`| (changed)| `<boolean: true>` |
|
||||
| `hidden=(false)`| (initial)| `<boolean: false>` |
|
||||
| `hidden=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `hidden=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `hidden=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `hidden=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `hidden=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `hidden=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `hidden=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -5489,8 +5489,8 @@
|
||||
| `itemScope=(float)`| (changed)| `<empty string>` |
|
||||
| `itemScope=(true)`| (changed)| `<empty string>` |
|
||||
| `itemScope=(false)`| (initial)| `<null>` |
|
||||
| `itemScope=(string 'true')`| (changed)| `<empty string>` |
|
||||
| `itemScope=(string 'false')`| (changed)| `<empty string>` |
|
||||
| `itemScope=(string 'true')`| (changed, warning)| `<empty string>` |
|
||||
| `itemScope=(string 'false')`| (changed, warning)| `<empty string>` |
|
||||
| `itemScope=(string 'on')`| (changed)| `<empty string>` |
|
||||
| `itemScope=(string 'off')`| (changed)| `<empty string>` |
|
||||
| `itemScope=(symbol)`| (initial, warning)| `<null>` |
|
||||
@@ -6239,8 +6239,8 @@
|
||||
| `loop=(float)`| (changed)| `<boolean: true>` |
|
||||
| `loop=(true)`| (changed)| `<boolean: true>` |
|
||||
| `loop=(false)`| (initial)| `<boolean: false>` |
|
||||
| `loop=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `loop=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `loop=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `loop=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `loop=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `loop=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `loop=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -7064,8 +7064,8 @@
|
||||
| `multiple=(float)`| (changed)| `<boolean: true>` |
|
||||
| `multiple=(true)`| (changed)| `<boolean: true>` |
|
||||
| `multiple=(false)`| (initial)| `<boolean: false>` |
|
||||
| `multiple=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `multiple=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `multiple=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `multiple=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `multiple=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `multiple=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `multiple=(symbol)`| (changed, warning, ssr mismatch)| `<boolean: true>` |
|
||||
@@ -7076,23 +7076,23 @@
|
||||
## `muted` (on `<video>` inside `<div>`)
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
| `muted=(string)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(string)`| (changed)| `<boolean: true>` |
|
||||
| `muted=(empty string)`| (initial)| `<boolean: false>` |
|
||||
| `muted=(array with string)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(empty array)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(object)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(numeric string)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(-1)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(array with string)`| (changed)| `<boolean: true>` |
|
||||
| `muted=(empty array)`| (changed)| `<boolean: true>` |
|
||||
| `muted=(object)`| (changed)| `<boolean: true>` |
|
||||
| `muted=(numeric string)`| (changed)| `<boolean: true>` |
|
||||
| `muted=(-1)`| (changed)| `<boolean: true>` |
|
||||
| `muted=(0)`| (initial)| `<boolean: false>` |
|
||||
| `muted=(integer)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(integer)`| (changed)| `<boolean: true>` |
|
||||
| `muted=(NaN)`| (initial, warning)| `<boolean: false>` |
|
||||
| `muted=(float)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(true)`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(float)`| (changed)| `<boolean: true>` |
|
||||
| `muted=(true)`| (changed)| `<boolean: true>` |
|
||||
| `muted=(false)`| (initial)| `<boolean: false>` |
|
||||
| `muted=(string 'true')`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(string 'false')`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(string 'on')`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(string 'off')`| (changed, ssr mismatch)| `<boolean: true>` |
|
||||
| `muted=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `muted=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `muted=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `muted=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `muted=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
| `muted=(function)`| (initial, warning)| `<boolean: false>` |
|
||||
| `muted=(null)`| (initial)| `<boolean: false>` |
|
||||
@@ -7148,6 +7148,31 @@
|
||||
| `name=(null)`| (initial)| `<null>` |
|
||||
| `name=(undefined)`| (initial)| `<null>` |
|
||||
|
||||
## `noModule` (on `<script>` inside `<div>`)
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
| `noModule=(string)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(empty string)`| (initial)| `<boolean: false>` |
|
||||
| `noModule=(array with string)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(empty array)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(object)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(numeric string)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(-1)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(0)`| (initial)| `<boolean: false>` |
|
||||
| `noModule=(integer)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(NaN)`| (initial, warning)| `<boolean: false>` |
|
||||
| `noModule=(float)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(true)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(false)`| (initial)| `<boolean: false>` |
|
||||
| `noModule=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `noModule=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `noModule=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
| `noModule=(function)`| (initial, warning)| `<boolean: false>` |
|
||||
| `noModule=(null)`| (initial)| `<boolean: false>` |
|
||||
| `noModule=(undefined)`| (initial)| `<boolean: false>` |
|
||||
|
||||
## `nonce` (on `<div>` inside `<div>`)
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
@@ -7173,31 +7198,6 @@
|
||||
| `nonce=(null)`| (initial)| `<null>` |
|
||||
| `nonce=(undefined)`| (initial)| `<null>` |
|
||||
|
||||
## `noModule` (on `<script>` inside `<div>`)
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
| `noModule=(string)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(empty string)`| (initial)| `<boolean: false>` |
|
||||
| `noModule=(array with string)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(empty array)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(object)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(numeric string)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(-1)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(0)`| (initial)| `<boolean: false>` |
|
||||
| `noModule=(integer)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(NaN)`| (initial, warning)| `<boolean: false>` |
|
||||
| `noModule=(float)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(true)`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(false)`| (initial)| `<boolean: false>` |
|
||||
| `noModule=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `noModule=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
| `noModule=(function)`| (initial, warning)| `<boolean: false>` |
|
||||
| `noModule=(null)`| (initial)| `<boolean: false>` |
|
||||
| `noModule=(undefined)`| (initial)| `<boolean: false>` |
|
||||
|
||||
## `noValidate` (on `<form>` inside `<div>`)
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
@@ -7214,8 +7214,8 @@
|
||||
| `noValidate=(float)`| (changed)| `<boolean: true>` |
|
||||
| `noValidate=(true)`| (changed)| `<boolean: true>` |
|
||||
| `noValidate=(false)`| (initial)| `<boolean: false>` |
|
||||
| `noValidate=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `noValidate=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `noValidate=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `noValidate=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `noValidate=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `noValidate=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `noValidate=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -7464,8 +7464,8 @@
|
||||
| `open=(float)`| (changed)| `<boolean: true>` |
|
||||
| `open=(true)`| (changed)| `<boolean: true>` |
|
||||
| `open=(false)`| (initial)| `<boolean: false>` |
|
||||
| `open=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `open=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `open=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `open=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `open=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `open=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `open=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -8014,8 +8014,8 @@
|
||||
| `playsInline=(float)`| (changed)| `<empty string>` |
|
||||
| `playsInline=(true)`| (changed)| `<empty string>` |
|
||||
| `playsInline=(false)`| (initial)| `<null>` |
|
||||
| `playsInline=(string 'true')`| (changed)| `<empty string>` |
|
||||
| `playsInline=(string 'false')`| (changed)| `<empty string>` |
|
||||
| `playsInline=(string 'true')`| (changed, warning)| `<empty string>` |
|
||||
| `playsInline=(string 'false')`| (changed, warning)| `<empty string>` |
|
||||
| `playsInline=(string 'on')`| (changed)| `<empty string>` |
|
||||
| `playsInline=(string 'off')`| (changed)| `<empty string>` |
|
||||
| `playsInline=(symbol)`| (initial, warning)| `<null>` |
|
||||
@@ -8227,26 +8227,26 @@
|
||||
| Test Case | Flags | Result |
|
||||
| --- | --- | --- |
|
||||
| `preload=(string)`| (changed)| `"none"` |
|
||||
| `preload=(empty string)`| (initial)| `"auto"` |
|
||||
| `preload=(empty string)`| (changed)| `"auto"` |
|
||||
| `preload=(array with string)`| (changed)| `"none"` |
|
||||
| `preload=(empty array)`| (initial)| `"auto"` |
|
||||
| `preload=(object)`| (initial)| `"auto"` |
|
||||
| `preload=(numeric string)`| (initial)| `"auto"` |
|
||||
| `preload=(-1)`| (initial)| `"auto"` |
|
||||
| `preload=(0)`| (initial)| `"auto"` |
|
||||
| `preload=(integer)`| (initial)| `"auto"` |
|
||||
| `preload=(NaN)`| (initial, warning)| `"auto"` |
|
||||
| `preload=(float)`| (initial)| `"auto"` |
|
||||
| `preload=(true)`| (initial, warning)| `"auto"` |
|
||||
| `preload=(false)`| (initial, warning)| `"auto"` |
|
||||
| `preload=(string 'true')`| (initial)| `"auto"` |
|
||||
| `preload=(string 'false')`| (initial)| `"auto"` |
|
||||
| `preload=(string 'on')`| (initial)| `"auto"` |
|
||||
| `preload=(string 'off')`| (initial)| `"auto"` |
|
||||
| `preload=(symbol)`| (initial, warning)| `"auto"` |
|
||||
| `preload=(function)`| (initial, warning)| `"auto"` |
|
||||
| `preload=(null)`| (initial)| `"auto"` |
|
||||
| `preload=(undefined)`| (initial)| `"auto"` |
|
||||
| `preload=(empty array)`| (changed)| `"auto"` |
|
||||
| `preload=(object)`| (initial)| `"metadata"` |
|
||||
| `preload=(numeric string)`| (initial)| `"metadata"` |
|
||||
| `preload=(-1)`| (initial)| `"metadata"` |
|
||||
| `preload=(0)`| (initial)| `"metadata"` |
|
||||
| `preload=(integer)`| (initial)| `"metadata"` |
|
||||
| `preload=(NaN)`| (initial, warning)| `"metadata"` |
|
||||
| `preload=(float)`| (initial)| `"metadata"` |
|
||||
| `preload=(true)`| (initial, warning)| `"metadata"` |
|
||||
| `preload=(false)`| (initial, warning)| `"metadata"` |
|
||||
| `preload=(string 'true')`| (initial)| `"metadata"` |
|
||||
| `preload=(string 'false')`| (initial)| `"metadata"` |
|
||||
| `preload=(string 'on')`| (initial)| `"metadata"` |
|
||||
| `preload=(string 'off')`| (initial)| `"metadata"` |
|
||||
| `preload=(symbol)`| (initial, warning)| `"metadata"` |
|
||||
| `preload=(function)`| (initial, warning)| `"metadata"` |
|
||||
| `preload=(null)`| (initial)| `"metadata"` |
|
||||
| `preload=(undefined)`| (initial)| `"metadata"` |
|
||||
|
||||
## `preserveAlpha` (on `<feConvolveMatrix>` inside `<svg>`)
|
||||
| Test Case | Flags | Result |
|
||||
@@ -8489,8 +8489,8 @@
|
||||
| `readOnly=(float)`| (changed)| `<boolean: true>` |
|
||||
| `readOnly=(true)`| (changed)| `<boolean: true>` |
|
||||
| `readOnly=(false)`| (initial)| `<boolean: false>` |
|
||||
| `readOnly=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `readOnly=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `readOnly=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `readOnly=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `readOnly=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `readOnly=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `readOnly=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -8714,8 +8714,8 @@
|
||||
| `required=(float)`| (changed)| `<boolean: true>` |
|
||||
| `required=(true)`| (changed)| `<boolean: true>` |
|
||||
| `required=(false)`| (initial)| `<boolean: false>` |
|
||||
| `required=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `required=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `required=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `required=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `required=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `required=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `required=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -8889,8 +8889,8 @@
|
||||
| `reversed=(float)`| (changed)| `<boolean: true>` |
|
||||
| `reversed=(true)`| (changed)| `<boolean: true>` |
|
||||
| `reversed=(false)`| (initial)| `<boolean: false>` |
|
||||
| `reversed=(string 'true')`| (changed)| `<boolean: true>` |
|
||||
| `reversed=(string 'false')`| (changed)| `<boolean: true>` |
|
||||
| `reversed=(string 'true')`| (changed, warning)| `<boolean: true>` |
|
||||
| `reversed=(string 'false')`| (changed, warning)| `<boolean: true>` |
|
||||
| `reversed=(string 'on')`| (changed)| `<boolean: true>` |
|
||||
| `reversed=(string 'off')`| (changed)| `<boolean: true>` |
|
||||
| `reversed=(symbol)`| (initial, warning)| `<boolean: false>` |
|
||||
@@ -8983,7 +8983,7 @@
|
||||
| `rowSpan=(object)`| (initial, ssr error, ssr mismatch)| `<number: 1>` |
|
||||
| `rowSpan=(numeric string)`| (changed, ssr error, ssr mismatch)| `<number: 42>` |
|
||||
| `rowSpan=(-1)`| (initial, ssr error, ssr mismatch)| `<number: 1>` |
|
||||
| `rowSpan=(0)`| (initial, ssr error, ssr mismatch)| `<number: 1>` |
|
||||
| `rowSpan=(0)`| (changed, ssr error, ssr mismatch)| `<number: 0>` |
|
||||
| `rowSpan=(integer)`| (initial, ssr error, ssr mismatch)| `<number: 1>` |
|
||||
| `rowSpan=(NaN)`| (initial, warning, ssr error, ssr mismatch)| `<number: 1>` |
|
||||
| `rowSpan=(float)`| (changed, ssr error, ssr mismatch)| `<number: 99>` |
|
||||
@@ -9139,8 +9139,8 @@
|
||||
| `scoped=(float)`| (changed)| `<empty string>` |
|
||||
| `scoped=(true)`| (changed)| `<empty string>` |
|
||||
| `scoped=(false)`| (initial)| `<null>` |
|
||||
| `scoped=(string 'true')`| (changed)| `<empty string>` |
|
||||
| `scoped=(string 'false')`| (changed)| `<empty string>` |
|
||||
| `scoped=(string 'true')`| (changed, warning)| `<empty string>` |
|
||||
| `scoped=(string 'false')`| (changed, warning)| `<empty string>` |
|
||||
| `scoped=(string 'on')`| (changed)| `<empty string>` |
|
||||
| `scoped=(string 'off')`| (changed)| `<empty string>` |
|
||||
| `scoped=(symbol)`| (initial, warning)| `<null>` |
|
||||
@@ -9189,8 +9189,8 @@
|
||||
| `seamless=(float)`| (changed)| `<empty string>` |
|
||||
| `seamless=(true)`| (changed)| `<empty string>` |
|
||||
| `seamless=(false)`| (initial)| `<null>` |
|
||||
| `seamless=(string 'true')`| (changed)| `<empty string>` |
|
||||
| `seamless=(string 'false')`| (changed)| `<empty string>` |
|
||||
| `seamless=(string 'true')`| (changed, warning)| `<empty string>` |
|
||||
| `seamless=(string 'false')`| (changed, warning)| `<empty string>` |
|
||||
| `seamless=(string 'on')`| (changed)| `<empty string>` |
|
||||
| `seamless=(string 'off')`| (changed)| `<empty string>` |
|
||||
| `seamless=(symbol)`| (initial, warning)| `<null>` |
|
||||
@@ -9264,8 +9264,8 @@
|
||||
| `selected=(float)`| (initial, warning, ssr warning)| `<boolean: true>` |
|
||||
| `selected=(true)`| (initial, warning, ssr warning)| `<boolean: true>` |
|
||||
| `selected=(false)`| (initial, warning, ssr warning)| `<boolean: true>` |
|
||||
| `selected=(string 'true')`| (initial, warning, ssr warning)| `<boolean: true>` |
|
||||
| `selected=(string 'false')`| (initial, warning, ssr warning)| `<boolean: true>` |
|
||||
| `selected=(string 'true')`| (initial, warning)| `<boolean: true>` |
|
||||
| `selected=(string 'false')`| (initial, warning)| `<boolean: true>` |
|
||||
| `selected=(string 'on')`| (initial, warning, ssr warning)| `<boolean: true>` |
|
||||
| `selected=(string 'off')`| (initial, warning, ssr warning)| `<boolean: true>` |
|
||||
| `selected=(symbol)`| (initial, warning)| `<boolean: true>` |
|
||||
@@ -11868,8 +11868,8 @@
|
||||
| `value=(string 'false')`| (changed)| `"false"` |
|
||||
| `value=(string 'on')`| (changed)| `"on"` |
|
||||
| `value=(string 'off')`| (changed)| `"off"` |
|
||||
| `value=(symbol)`| (changed, error, warning, ssr error)| `` |
|
||||
| `value=(function)`| (changed, warning, ssr warning)| `"function f() {}"` |
|
||||
| `value=(symbol)`| (initial, warning, ssr error, ssr mismatch)| `<empty string>` |
|
||||
| `value=(function)`| (initial, warning, ssr mismatch)| `<empty string>` |
|
||||
| `value=(null)`| (initial, warning, ssr warning)| `<empty string>` |
|
||||
| `value=(undefined)`| (initial)| `<empty string>` |
|
||||
|
||||
@@ -11893,8 +11893,8 @@
|
||||
| `value=(string 'false')`| (changed)| `"false"` |
|
||||
| `value=(string 'on')`| (changed)| `"on"` |
|
||||
| `value=(string 'off')`| (changed)| `"off"` |
|
||||
| `value=(symbol)`| (changed, error, warning, ssr mismatch)| `` |
|
||||
| `value=(function)`| (changed, warning, ssr mismatch)| `"function f() {}"` |
|
||||
| `value=(symbol)`| (initial, warning)| `<empty string>` |
|
||||
| `value=(function)`| (initial, warning)| `<empty string>` |
|
||||
| `value=(null)`| (initial)| `<empty string>` |
|
||||
| `value=(undefined)`| (initial)| `<empty string>` |
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ The left box shows the property (or attribute) assigned by React 15.\*, and the
|
||||
right box shows the property (or attribute) assigned by the latest version of
|
||||
React 16.
|
||||
|
||||
Right now we use a purple outline to call out cases where the assigned property
|
||||
Right now, we use a purple outline to call out cases where the assigned property
|
||||
(or attribute) has changed between React 15 and 16.
|
||||
|
||||
---
|
||||
|
||||
1
fixtures/dom/.gitignore
vendored
@@ -10,6 +10,7 @@ coverage
|
||||
build
|
||||
public/react.development.js
|
||||
public/react-dom.development.js
|
||||
public/react-dom-server.browser.development.js
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
||||
@@ -6,17 +6,19 @@
|
||||
"react-scripts": "^1.0.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/standalone": "^7.0.0",
|
||||
"classnames": "^2.2.5",
|
||||
"codemirror": "^5.40.0",
|
||||
"core-js": "^2.4.1",
|
||||
"prop-types": "^15.6.0",
|
||||
"query-string": "^4.2.3",
|
||||
"react": "^15.4.1",
|
||||
"react-dom": "^15.4.1",
|
||||
"semver": "^5.3.0"
|
||||
"semver": "^5.5.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"prestart": "cp ../../build/dist/react.development.js public/ && cp ../../build/dist/react-dom.development.js public/",
|
||||
"prestart": "cp ../../build/dist/react.development.js ../../build/dist/react-dom.development.js ../../build/dist/react-dom-server.browser.development.js public/",
|
||||
"build": "react-scripts build && cp build/index.html build/200.html",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
|
||||
86
fixtures/dom/public/renderer.html
Normal file
@@ -0,0 +1,86 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Renderer</title>
|
||||
<style>
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
padding-top: 32px;
|
||||
}
|
||||
|
||||
#status {
|
||||
font-size: 12px;
|
||||
left: 8px;
|
||||
letter-spacing: 0.05em;
|
||||
line-height: 16px;
|
||||
margin: -8px 0 0;
|
||||
max-width: 50%;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
top: 50%;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#output {
|
||||
margin: 16px;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: white;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
padding: 4px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
background: #eee;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #aaa;
|
||||
font-size: 11px;
|
||||
padding: 4px 6px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<p id="status">Loading</p>
|
||||
|
||||
<menu class="controls">
|
||||
<button class="button" id="hydrate">Hydrate</button>
|
||||
<button class="button" id="reload">Reload</button>
|
||||
</menu>
|
||||
</header>
|
||||
|
||||
<div id="output"></div>
|
||||
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
141
fixtures/dom/public/renderer.js
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Supports render.html, a piece of the hydration fixture. See /hydration
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var Fixture = null;
|
||||
var output = document.getElementById('output');
|
||||
var status = document.getElementById('status');
|
||||
var hydrate = document.getElementById('hydrate');
|
||||
var reload = document.getElementById('reload');
|
||||
var renders = 0;
|
||||
var failed = false;
|
||||
|
||||
function getQueryParam(key) {
|
||||
var pattern = new RegExp(key + '=([^&]+)(&|$)');
|
||||
var matches = window.location.search.match(pattern);
|
||||
|
||||
if (matches) {
|
||||
return decodeURIComponent(matches[1]);
|
||||
}
|
||||
|
||||
handleError(new Error('No key found for' + key));
|
||||
}
|
||||
|
||||
function getBooleanQueryParam(key) {
|
||||
return getQueryParam(key) === 'true';
|
||||
}
|
||||
|
||||
function setStatus(label) {
|
||||
status.innerHTML = label;
|
||||
}
|
||||
|
||||
function prerender() {
|
||||
setStatus('Generating markup');
|
||||
|
||||
output.innerHTML = ReactDOMServer.renderToString(
|
||||
React.createElement(Fixture)
|
||||
);
|
||||
|
||||
setStatus('Markup only (No React)');
|
||||
}
|
||||
|
||||
function render() {
|
||||
setStatus('Hydrating');
|
||||
|
||||
if (ReactDOM.hydrate) {
|
||||
ReactDOM.hydrate(React.createElement(Fixture), output);
|
||||
} else {
|
||||
ReactDOM.render(React.createElement(Fixture), output);
|
||||
}
|
||||
|
||||
setStatus(renders > 0 ? 'Re-rendered (' + renders + 'x)' : 'Hydrated');
|
||||
renders += 1;
|
||||
hydrate.innerHTML = 'Re-render';
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
console.log(error);
|
||||
failed = true;
|
||||
setStatus('Javascript Error');
|
||||
output.innerHTML = error;
|
||||
}
|
||||
|
||||
function loadScript(src) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var script = document.createElement('script');
|
||||
script.async = true;
|
||||
script.src = src;
|
||||
|
||||
script.onload = resolve;
|
||||
script.onerror = function(error) {
|
||||
reject(new Error('Unable to load ' + src));
|
||||
};
|
||||
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
function injectFixture(src) {
|
||||
Fixture = new Function(src + '\nreturn Fixture;')();
|
||||
|
||||
if (typeof Fixture === 'undefined') {
|
||||
setStatus('Failed');
|
||||
output.innerHTML = 'Please name your root component "Fixture"';
|
||||
} else {
|
||||
prerender();
|
||||
|
||||
if (getBooleanQueryParam('hydrate')) {
|
||||
render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function reloadFixture(code) {
|
||||
renders = 0;
|
||||
ReactDOM.unmountComponentAtNode(output);
|
||||
injectFixture(code);
|
||||
}
|
||||
|
||||
window.onerror = handleError;
|
||||
|
||||
reload.onclick = function() {
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
hydrate.onclick = render;
|
||||
|
||||
loadScript(getQueryParam('reactPath'))
|
||||
.then(function() {
|
||||
return getBooleanQueryParam('needsReactDOM')
|
||||
? loadScript(getQueryParam('reactDOMPath'))
|
||||
: null;
|
||||
})
|
||||
.then(function() {
|
||||
return loadScript(getQueryParam('reactDOMServerPath'));
|
||||
})
|
||||
.then(function() {
|
||||
if (failed) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('message', function(event) {
|
||||
var data = JSON.parse(event.data);
|
||||
|
||||
switch (data.type) {
|
||||
case 'code':
|
||||
reloadFixture(data.payload);
|
||||
break;
|
||||
default:
|
||||
throw new Error(
|
||||
'Renderer Error: Unrecognized message "' + data.type + '"'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
window.parent.postMessage(JSON.stringify({type: 'ready'}), '*');
|
||||
})
|
||||
.catch(handleError);
|
||||
})();
|
||||
@@ -8,9 +8,7 @@ function App() {
|
||||
return (
|
||||
<div>
|
||||
<Header />
|
||||
<div className="container">
|
||||
<Fixtures />
|
||||
</div>
|
||||
<Fixtures />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const PropTypes = window.PropTypes;
|
||||
import PropTypes from 'prop-types';
|
||||
const React = window.React;
|
||||
|
||||
const propTypes = {
|
||||
|
||||
@@ -3,7 +3,7 @@ const React = window.React;
|
||||
|
||||
const propTypes = {
|
||||
title: PropTypes.node.isRequired,
|
||||
description: PropTypes.node.isRequired,
|
||||
description: PropTypes.node,
|
||||
};
|
||||
|
||||
class FixtureSet extends React.Component {
|
||||
@@ -11,7 +11,7 @@ class FixtureSet extends React.Component {
|
||||
const {title, description, children} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="container">
|
||||
<h1>{title}</h1>
|
||||
{description && <p>{description}</p>}
|
||||
|
||||
|
||||
@@ -35,11 +35,11 @@ class Header extends React.Component {
|
||||
<span className="header__logo">
|
||||
<img
|
||||
src={process.env.PUBLIC_URL + '/react-logo.svg'}
|
||||
alt=""
|
||||
width="32"
|
||||
height="32"
|
||||
alt="React"
|
||||
width="20"
|
||||
height="20"
|
||||
/>
|
||||
React Sandbox (v{React.version})
|
||||
<a href="/">DOM Test Fixtures (v{React.version})</a>
|
||||
</span>
|
||||
|
||||
<div className="header-controls">
|
||||
@@ -48,7 +48,8 @@ class Header extends React.Component {
|
||||
<select
|
||||
value={window.location.pathname}
|
||||
onChange={this.handleFixtureChange}>
|
||||
<option value="/">Select a Fixture</option>
|
||||
<option value="/">Home</option>
|
||||
<option value="/hydration">Hydration</option>
|
||||
<option value="/range-inputs">Range Inputs</option>
|
||||
<option value="/text-inputs">Text Inputs</option>
|
||||
<option value="/number-inputs">Number Input</option>
|
||||
@@ -66,6 +67,8 @@ class Header extends React.Component {
|
||||
<option value="/media-events">Media Events</option>
|
||||
<option value="/pointer-events">Pointer Events</option>
|
||||
<option value="/mouse-events">Mouse Events</option>
|
||||
<option value="/selection-events">Selection Events</option>
|
||||
<option value="/suspense">Suspense</option>
|
||||
</select>
|
||||
</label>
|
||||
<label htmlFor="react_version">
|
||||
|
||||
58
fixtures/dom/src/components/Iframe.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const React = window.React;
|
||||
const ReactDOM = window.ReactDOM;
|
||||
|
||||
class IframePortal extends React.Component {
|
||||
iframeRef = null;
|
||||
|
||||
handleRef = ref => {
|
||||
if (ref !== this.iframeRef) {
|
||||
this.iframeRef = ref;
|
||||
if (ref) {
|
||||
if (ref.contentDocument && this.props.head) {
|
||||
ref.contentDocument.head.innerHTML = this.props.head;
|
||||
}
|
||||
// Re-render must take place in the next tick (Firefox)
|
||||
setTimeout(() => {
|
||||
this.forceUpdate();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const ref = this.iframeRef;
|
||||
let portal = null;
|
||||
if (ref && ref.contentDocument) {
|
||||
portal = ReactDOM.createPortal(
|
||||
this.props.children,
|
||||
ref.contentDocument.body
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<iframe
|
||||
title="Iframe portal"
|
||||
style={{border: 'none', height: this.props.height}}
|
||||
ref={this.handleRef}
|
||||
/>
|
||||
{portal}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class IframeSubtree extends React.Component {
|
||||
warned = false;
|
||||
render() {
|
||||
if (!this.warned) {
|
||||
console.error(
|
||||
`IFrame has not yet been implemented for React v${React.version}`
|
||||
);
|
||||
this.warned = true;
|
||||
}
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
export default (ReactDOM.createPortal ? IframePortal : IframeSubtree);
|
||||
@@ -10,7 +10,7 @@ function onButtonClick() {
|
||||
export default class ButtonTestCases extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<FixtureSet title="Buttons" description="">
|
||||
<FixtureSet title="Buttons">
|
||||
<TestCase
|
||||
title="onClick with disabled buttons"
|
||||
description="The onClick event handler should not be invoked when clicking on a disabled buyaton">
|
||||
|
||||
@@ -8,7 +8,7 @@ const React = window.React;
|
||||
class DateInputFixtures extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<FixtureSet title="Dates" description="">
|
||||
<FixtureSet title="Dates">
|
||||
<TestCase title="Switching between date and datetime-local">
|
||||
<TestCase.Steps>
|
||||
<li>Type a date into the date picker</li>
|
||||
|
||||
@@ -7,9 +7,21 @@ const ReactDOM = window.ReactDOM;
|
||||
function BadRender(props) {
|
||||
props.doThrow();
|
||||
}
|
||||
|
||||
class BadDidMount extends React.Component {
|
||||
componentDidMount() {
|
||||
this.props.doThrow();
|
||||
}
|
||||
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class ErrorBoundary extends React.Component {
|
||||
static defaultProps = {
|
||||
buttonText: 'Trigger error',
|
||||
badChildType: BadRender,
|
||||
};
|
||||
state = {
|
||||
shouldThrow: false,
|
||||
@@ -33,7 +45,8 @@ class ErrorBoundary extends React.Component {
|
||||
}
|
||||
}
|
||||
if (this.state.shouldThrow) {
|
||||
return <BadRender doThrow={this.props.doThrow} />;
|
||||
const BadChild = this.props.badChildType;
|
||||
return <BadChild doThrow={this.props.doThrow} />;
|
||||
}
|
||||
return <button onClick={this.triggerError}>{this.props.buttonText}</button>;
|
||||
}
|
||||
@@ -84,10 +97,154 @@ class TriggerErrorAndCatch extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
function silenceWindowError(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
class SilenceErrors extends React.Component {
|
||||
state = {
|
||||
silenceErrors: false,
|
||||
};
|
||||
componentDidMount() {
|
||||
if (this.state.silenceErrors) {
|
||||
window.addEventListener('error', silenceWindowError);
|
||||
}
|
||||
}
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (!prevState.silenceErrors && this.state.silenceErrors) {
|
||||
window.addEventListener('error', silenceWindowError);
|
||||
} else if (prevState.silenceErrors && !this.state.silenceErrors) {
|
||||
window.removeEventListener('error', silenceWindowError);
|
||||
}
|
||||
}
|
||||
componentWillUnmount() {
|
||||
if (this.state.silenceErrors) {
|
||||
window.removeEventListener('error', silenceWindowError);
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
value={this.state.silenceErrors}
|
||||
onChange={() =>
|
||||
this.setState(state => ({
|
||||
silenceErrors: !state.silenceErrors,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
Silence errors
|
||||
</label>
|
||||
{this.state.silenceErrors && (
|
||||
<div>
|
||||
{this.props.children}
|
||||
<br />
|
||||
<hr />
|
||||
<b style={{color: 'red'}}>
|
||||
Don't forget to uncheck "Silence errors" when you're done with
|
||||
this test!
|
||||
</b>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
class GetEventTypeDuringUpdate extends React.Component {
|
||||
state = {};
|
||||
|
||||
onClick = () => {
|
||||
this.expectUpdate = true;
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.expectUpdate) {
|
||||
this.expectUpdate = false;
|
||||
this.setState({eventType: window.event.type});
|
||||
setTimeout(() => {
|
||||
this.setState({cleared: !window.event});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="test-fixture">
|
||||
<button onClick={this.onClick}>Trigger callback in event.</button>
|
||||
{this.state.eventType ? (
|
||||
<p>
|
||||
Got <b>{this.state.eventType}</b> event.
|
||||
</p>
|
||||
) : (
|
||||
<p>Got no event</p>
|
||||
)}
|
||||
{this.state.cleared ? (
|
||||
<p>Event cleared correctly.</p>
|
||||
) : (
|
||||
<p>Event failed to clear.</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SilenceRecoverableError extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SilenceErrors>
|
||||
<ErrorBoundary
|
||||
badChildType={BadRender}
|
||||
buttonText={'Throw (render phase)'}
|
||||
doThrow={() => {
|
||||
throw new Error('Silenced error (render phase)');
|
||||
}}
|
||||
/>
|
||||
<ErrorBoundary
|
||||
badChildType={BadDidMount}
|
||||
buttonText={'Throw (commit phase)'}
|
||||
doThrow={() => {
|
||||
throw new Error('Silenced error (commit phase)');
|
||||
}}
|
||||
/>
|
||||
</SilenceErrors>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TrySilenceFatalError extends React.Component {
|
||||
container = document.createElement('div');
|
||||
|
||||
triggerErrorAndCatch = () => {
|
||||
try {
|
||||
ReactDOM.flushSync(() => {
|
||||
ReactDOM.render(
|
||||
<BadRender
|
||||
doThrow={() => {
|
||||
throw new Error('Caught error');
|
||||
}}
|
||||
/>,
|
||||
this.container
|
||||
);
|
||||
});
|
||||
} catch (e) {}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SilenceErrors>
|
||||
<button onClick={this.triggerErrorAndCatch}>Throw fatal error</button>
|
||||
</SilenceErrors>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default class ErrorHandlingTestCases extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<FixtureSet title="Error handling" description="">
|
||||
<FixtureSet title="Error handling">
|
||||
<TestCase
|
||||
title="Break on uncaught exceptions"
|
||||
description="In DEV, errors should be treated as uncaught, even though React catches them internally">
|
||||
@@ -103,6 +260,12 @@ export default class ErrorHandlingTestCases extends React.Component {
|
||||
the BadRender component. After resuming, the "Trigger error" button
|
||||
should be replaced with "Captured an error: Oops!" Clicking reset
|
||||
should reset the test case.
|
||||
<br />
|
||||
<br />
|
||||
In the console, you should see <b>two</b> messages: the actual error
|
||||
("Oops") printed natively by the browser with its JavaScript stack,
|
||||
and our addendum ("The above error occurred in BadRender component")
|
||||
with a React component stack.
|
||||
</TestCase.ExpectedResult>
|
||||
<Example
|
||||
doThrow={() => {
|
||||
@@ -155,10 +318,59 @@ export default class ErrorHandlingTestCases extends React.Component {
|
||||
</TestCase.Steps>
|
||||
<TestCase.ExpectedResult>
|
||||
Open the console. "Uncaught Error: Caught error" should have been
|
||||
logged by the browser.
|
||||
logged by the browser. You should also see our addendum ("The above
|
||||
error...").
|
||||
</TestCase.ExpectedResult>
|
||||
<TriggerErrorAndCatch />
|
||||
</TestCase>
|
||||
<TestCase
|
||||
title="Recoverable errors can be silenced with preventDefault (development mode only)"
|
||||
description="">
|
||||
<TestCase.Steps>
|
||||
<li>Check the "Silence errors" checkbox below</li>
|
||||
<li>Click the "Throw (render phase)" button</li>
|
||||
<li>Click the "Throw (commit phase)" button</li>
|
||||
<li>Uncheck the "Silence errors" checkbox</li>
|
||||
</TestCase.Steps>
|
||||
<TestCase.ExpectedResult>
|
||||
Open the console. You shouldn't see <b>any</b> messages in the
|
||||
console: neither the browser error, nor our "The above error"
|
||||
addendum, from either of the buttons. The buttons themselves should
|
||||
get replaced by two labels: "Captured an error: Silenced error
|
||||
(render phase)" and "Captured an error: Silenced error (commit
|
||||
phase)".
|
||||
</TestCase.ExpectedResult>
|
||||
<SilenceRecoverableError />
|
||||
</TestCase>
|
||||
<TestCase
|
||||
title="Fatal errors cannot be silenced with preventDefault (development mode only)"
|
||||
description="">
|
||||
<TestCase.Steps>
|
||||
<li>Check the "Silence errors" checkbox below</li>
|
||||
<li>Click the "Throw fatal error" button</li>
|
||||
<li>Uncheck the "Silence errors" checkbox</li>
|
||||
</TestCase.Steps>
|
||||
<TestCase.ExpectedResult>
|
||||
Open the console. "Error: Caught error" should have been logged by
|
||||
React. You should also see our addendum ("The above error...").
|
||||
</TestCase.ExpectedResult>
|
||||
<TrySilenceFatalError />
|
||||
</TestCase>
|
||||
|
||||
{window.hasOwnProperty('event') ? (
|
||||
<TestCase
|
||||
title="Error handling does not interfere with window.event"
|
||||
description="">
|
||||
<TestCase.Steps>
|
||||
<li>Click the "Trigger callback in event" button</li>
|
||||
</TestCase.Steps>
|
||||
<TestCase.ExpectedResult>
|
||||
You should see "Got <b>click</b> event" and "Event cleared
|
||||
successfully" below.
|
||||
</TestCase.ExpectedResult>
|
||||
<GetEventTypeDuringUpdate />
|
||||
</TestCase>
|
||||
) : null}
|
||||
</FixtureSet>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ const React = window.React;
|
||||
class EventPooling extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<FixtureSet title="Event Pooling" description="">
|
||||
<FixtureSet title="Event Pooling">
|
||||
<MouseMove />
|
||||
<Persistence />
|
||||
</FixtureSet>
|
||||
|
||||
117
fixtures/dom/src/components/fixtures/home.js
Normal file
@@ -0,0 +1,117 @@
|
||||
const React = window.React;
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="container">
|
||||
<h1>DOM Test Fixtures</h1>
|
||||
<p>
|
||||
Use this site to test browser quirks and other behavior that can not be
|
||||
captured through unit tests.
|
||||
</p>
|
||||
<section>
|
||||
<h2>Tested Browsers</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Browser</th>
|
||||
<th>Versions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Chrome - Desktop</td>
|
||||
<td>
|
||||
49<sup>*</sup>, Latest
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Chrome - Android</td>
|
||||
<td>Latest</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Firefox Desktop</td>
|
||||
<td>
|
||||
<a href="https://www.mozilla.org/en-US/firefox/organizations/">
|
||||
ESR<sup>†</sup>
|
||||
</a>, Latest
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Internet Explorer</td>
|
||||
<td>9, 10, 11</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft Edge</td>
|
||||
<td>14, Latest</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Safari - Desktop</td>
|
||||
<td>7, Latest</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Safari - iOS</td>
|
||||
<td>7, Latest</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<footer>
|
||||
<small>* Chrome 49 is the last release for Windows XP.</small>
|
||||
<br />
|
||||
<small>
|
||||
† Firefox Extended Support Release (ESR) is used by many
|
||||
institutions.
|
||||
</small>
|
||||
</footer>
|
||||
</section>
|
||||
<section>
|
||||
<h2>How do I test browsers I don't have access to?</h2>
|
||||
<p>
|
||||
Getting test coverage across all of these browsers can be difficult,
|
||||
particularly for older versions of evergreen browsers. Fortunately
|
||||
there are a handful of tools that make browser testing easy.
|
||||
</p>
|
||||
<section>
|
||||
<h3>Paid services</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://browserstack.com">BrowserStack</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://saucelabs.com">Sauce Labs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://crossbrowsertesting.com/">CrossBrowserTesting</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
These services provide access to all browsers we test, however they
|
||||
cost money. There is no obligation to pay for them. Maintainers have
|
||||
access to a BrowserStack subscription; feel free to contact a
|
||||
maintainer or mention browsers where extra testing is required.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Browser downloads</h3>
|
||||
<p>A handful of browsers are available for download directly:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/">
|
||||
Internet Explorer (9-11) and MS Edge virtual machines
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.chromium.org/getting-involved/download-chromium#TOC-Downloading-old-builds-of-Chrome-Chromium">
|
||||
Chromium snapshots (for older versions of Chrome)
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.mozilla.org/en-US/firefox/organizations/">
|
||||
Firefox Extended Support Release (ESR)
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
85
fixtures/dom/src/components/fixtures/hydration/Code.js
Normal file
@@ -0,0 +1,85 @@
|
||||
const React = window.React;
|
||||
|
||||
export class CodeEditor extends React.Component {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// Important: CodeMirror incorrectly lays out the editor
|
||||
// if it executes before CSS has loaded
|
||||
// https://github.com/graphql/graphiql/issues/33#issuecomment-318188555
|
||||
Promise.all([
|
||||
import('codemirror'),
|
||||
import('codemirror/mode/jsx/jsx'),
|
||||
import('codemirror/lib/codemirror.css'),
|
||||
import('./codemirror-paraiso-dark.css'),
|
||||
]).then(([CodeMirror]) => this.install(CodeMirror));
|
||||
}
|
||||
|
||||
install(CodeMirror) {
|
||||
if (!this.textarea) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {onChange} = this.props;
|
||||
|
||||
this.editor = CodeMirror.fromTextArea(this.textarea, {
|
||||
mode: 'jsx',
|
||||
theme: 'paraiso-dark',
|
||||
lineNumbers: true,
|
||||
});
|
||||
|
||||
this.editor.on('change', function(doc) {
|
||||
onChange(doc.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.editor) {
|
||||
this.editor.toTextArea();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<textarea
|
||||
ref={ref => (this.textarea = ref)}
|
||||
defaultValue={this.props.code}
|
||||
autoComplete="off"
|
||||
hidden={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent IE9 from raising an error on an unrecognized element:
|
||||
* See https://github.com/facebook/react/issues/13610
|
||||
*/
|
||||
const supportsDetails = !(
|
||||
document.createElement('details') instanceof HTMLUnknownElement
|
||||
);
|
||||
|
||||
export class CodeError extends React.Component {
|
||||
render() {
|
||||
const {error, className} = this.props;
|
||||
|
||||
if (!error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (supportsDetails) {
|
||||
const [summary, ...body] = error.message.split(/\n+/g);
|
||||
|
||||
return (
|
||||
<details className={className}>
|
||||
<summary>{summary}</summary>
|
||||
{body.join('\n')}
|
||||
</details>
|
||||
);
|
||||
}
|
||||
|
||||
return <div className={className}>{error.message}</div>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Babel works across all browsers, however it requires many polyfills.
|
||||
*/
|
||||
|
||||
import 'core-js/es6/weak-map';
|
||||
import 'core-js/es6/weak-set';
|
||||
import 'core-js/es6/number';
|
||||
import 'core-js/es6/string';
|
||||
import 'core-js/es6/array';
|
||||
import 'core-js/modules/es6.object.set-prototype-of';
|
||||
|
||||
import {transform} from '@babel/standalone';
|
||||
|
||||
const presets = ['es2015', 'stage-3', 'react'];
|
||||
|
||||
export function compile(raw) {
|
||||
return transform(raw, {presets}).code;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Name: Paraíso (Dark)
|
||||
* Author: Jan T. Sott
|
||||
* License: Creative Commons Attribution-ShareAlike 4.0 Unported License.
|
||||
* https://creativecommons.org/licenses/by-sa/4.0/deed.en_US
|
||||
*
|
||||
* Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror)
|
||||
* Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
|
||||
*/
|
||||
|
||||
.cm-s-paraiso-dark.CodeMirror { background: #2f1e2e; color: #b9b6b0; }
|
||||
.cm-s-paraiso-dark div.CodeMirror-selected { background: #41323f; }
|
||||
.cm-s-paraiso-dark .CodeMirror-line::selection, .cm-s-paraiso-dark .CodeMirror-line > span::selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::selection { background: rgba(65, 50, 63, .99); }
|
||||
.cm-s-paraiso-dark .CodeMirror-line::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(65, 50, 63, .99); }
|
||||
.cm-s-paraiso-dark .CodeMirror-gutters { background: #2f1e2e; border-right: 0px; }
|
||||
.cm-s-paraiso-dark .CodeMirror-guttermarker { color: #ef6155; }
|
||||
.cm-s-paraiso-dark .CodeMirror-guttermarker-subtle { color: #776e71; }
|
||||
.cm-s-paraiso-dark .CodeMirror-linenumber { color: #776e71; }
|
||||
.cm-s-paraiso-dark .CodeMirror-cursor { border-left: 1px solid #8d8687; }
|
||||
|
||||
.cm-s-paraiso-dark span.cm-comment { color: #e96ba8; }
|
||||
.cm-s-paraiso-dark span.cm-atom { color: #815ba4; }
|
||||
.cm-s-paraiso-dark span.cm-number { color: #815ba4; }
|
||||
|
||||
.cm-s-paraiso-dark span.cm-property, .cm-s-paraiso-dark span.cm-attribute { color: #48b685; }
|
||||
.cm-s-paraiso-dark span.cm-keyword { color: #ef6155; }
|
||||
.cm-s-paraiso-dark span.cm-string { color: #fec418; }
|
||||
|
||||
.cm-s-paraiso-dark span.cm-variable { color: #48b685; }
|
||||
.cm-s-paraiso-dark span.cm-variable-2 { color: #06b6ef; }
|
||||
.cm-s-paraiso-dark span.cm-def { color: #f99b15; }
|
||||
.cm-s-paraiso-dark span.cm-bracket { color: #b9b6b0; }
|
||||
.cm-s-paraiso-dark span.cm-tag { color: #ef6155; }
|
||||
.cm-s-paraiso-dark span.cm-link { color: #815ba4; }
|
||||
.cm-s-paraiso-dark span.cm-error { background: #ef6155; color: #8d8687; }
|
||||
|
||||
.cm-s-paraiso-dark .CodeMirror-activeline-background { background: #4D344A; }
|
||||
.cm-s-paraiso-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
|
||||
22
fixtures/dom/src/components/fixtures/hydration/data.js
Normal file
@@ -0,0 +1,22 @@
|
||||
export const SAMPLE_CODE = `
|
||||
class Fixture extends React.Component {
|
||||
state = {
|
||||
value: 'asdf'
|
||||
}
|
||||
|
||||
onChange(event) {
|
||||
this.setState({ value: event.target.value });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { value } = this.state;
|
||||
|
||||
return (
|
||||
<form>
|
||||
<input value={value} onChange={this.onChange.bind(this)} />
|
||||
<p>Value: {value}</p>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
`.trim();
|
||||
68
fixtures/dom/src/components/fixtures/hydration/hydration.css
Normal file
@@ -0,0 +1,68 @@
|
||||
.hydration {
|
||||
background: #2f1e2e;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
height: calc(100vh - 40px); /* height of header */
|
||||
overflow: auto;
|
||||
padding-top: 32px;
|
||||
}
|
||||
|
||||
.hydration-options {
|
||||
background: #171717;
|
||||
border-top: 1px dashed rgba(215, 235, 255, 0.12);
|
||||
color: #def5ff;
|
||||
height: 32px;
|
||||
line-height: 28px;
|
||||
padding: 0 8px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.hydration-options label {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.hydration-options input[type=checkbox] {
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.hydration .CodeMirror {
|
||||
font-size: 13px;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 68px;
|
||||
height: calc(100vh - 72px);
|
||||
width: 55%;
|
||||
}
|
||||
|
||||
.hydration-sandbox {
|
||||
background: white;
|
||||
border-radius: 2px;
|
||||
border: 0;
|
||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.54);
|
||||
height: calc(100% - 34px);
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 16px;
|
||||
width: calc(45% - 24px);
|
||||
}
|
||||
|
||||
.hydration-code-error {
|
||||
background: #df3f3f;
|
||||
border-radius: 2px;
|
||||
bottom: 18px;
|
||||
color: white;
|
||||
font-family: monospace;
|
||||
font-size: 13px;
|
||||
left: 16px;
|
||||
line-height: 1.25;
|
||||
overflow: auto;
|
||||
padding: 12px;
|
||||
position: fixed;
|
||||
white-space: pre;
|
||||
max-width: calc(55% - 26px);
|
||||
z-index: 10;
|
||||
}
|
||||
109
fixtures/dom/src/components/fixtures/hydration/index.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import './hydration.css';
|
||||
import {SAMPLE_CODE} from './data';
|
||||
import {CodeEditor, CodeError} from './Code';
|
||||
import {compile} from './code-transformer';
|
||||
import {reactPaths} from '../../../react-loader';
|
||||
import qs from 'query-string';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
class Hydration extends React.Component {
|
||||
state = {
|
||||
error: null,
|
||||
code: SAMPLE_CODE,
|
||||
hydrate: true,
|
||||
};
|
||||
|
||||
ready = false;
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('message', this.handleMessage);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('message', this.handleMessage);
|
||||
}
|
||||
|
||||
handleMessage = event => {
|
||||
var data = JSON.parse(event.data);
|
||||
|
||||
switch (data.type) {
|
||||
case 'ready':
|
||||
this.ready = true;
|
||||
this.injectCode();
|
||||
break;
|
||||
default:
|
||||
throw new Error(
|
||||
'Editor Error: Unrecognized message "' + data.type + '"'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
injectCode = () => {
|
||||
try {
|
||||
this.send({
|
||||
type: 'code',
|
||||
payload: compile(this.state.code),
|
||||
});
|
||||
|
||||
this.setState({error: null});
|
||||
} catch (error) {
|
||||
this.setState({error});
|
||||
}
|
||||
};
|
||||
|
||||
send = message => {
|
||||
if (this.ready) {
|
||||
this.frame.contentWindow.postMessage(JSON.stringify(message), '*');
|
||||
}
|
||||
};
|
||||
|
||||
setFrame = frame => {
|
||||
this.frame = frame;
|
||||
};
|
||||
|
||||
setCode = code => {
|
||||
this.setState({code}, this.injectCode);
|
||||
};
|
||||
|
||||
setCheckbox = event => {
|
||||
this.setState({
|
||||
[event.target.name]: event.target.checked,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const {code, error, hydrate} = this.state;
|
||||
const src = '/renderer.html?' + qs.stringify({hydrate, ...reactPaths()});
|
||||
|
||||
return (
|
||||
<div className="hydration">
|
||||
<header className="hydration-options">
|
||||
<label htmlFor="hydrate">
|
||||
<input
|
||||
id="hydrate"
|
||||
name="hydrate"
|
||||
type="checkbox"
|
||||
checked={hydrate}
|
||||
onChange={this.setCheckbox}
|
||||
/>
|
||||
Auto-Hydrate
|
||||
</label>
|
||||
</header>
|
||||
|
||||
<CodeEditor code={code} onChange={this.setCode} />
|
||||
|
||||
<CodeError error={error} className="hydration-code-error" />
|
||||
|
||||
<iframe
|
||||
ref={this.setFrame}
|
||||
className="hydration-sandbox"
|
||||
title="Hydration Preview"
|
||||
src={src}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Hydration;
|
||||
@@ -1,60 +1,62 @@
|
||||
import RangeInputFixtures from './range-inputs';
|
||||
import TextInputFixtures from './text-inputs';
|
||||
import SelectFixtures from './selects';
|
||||
import TextAreaFixtures from './textareas';
|
||||
import InputChangeEvents from './input-change-events';
|
||||
import NumberInputFixtures from './number-inputs';
|
||||
import PasswordInputFixtures from './password-inputs';
|
||||
import ButtonFixtures from './buttons';
|
||||
import DateInputFixtures from './date-inputs';
|
||||
import ErrorHandling from './error-handling';
|
||||
import EventPooling from './event-pooling';
|
||||
import CustomElementFixtures from './custom-elements';
|
||||
import MediaEventsFixtures from './media-events';
|
||||
import PointerEventsFixtures from './pointer-events';
|
||||
import MouseEventsFixtures from './mouse-events';
|
||||
|
||||
const React = window.React;
|
||||
const fixturePath = window.location.pathname;
|
||||
|
||||
/**
|
||||
* A simple routing component that renders the appropriate
|
||||
* fixture based on the location pathname.
|
||||
*/
|
||||
function FixturesPage() {
|
||||
switch (window.location.pathname) {
|
||||
case '/text-inputs':
|
||||
return <TextInputFixtures />;
|
||||
case '/range-inputs':
|
||||
return <RangeInputFixtures />;
|
||||
case '/selects':
|
||||
return <SelectFixtures />;
|
||||
case '/textareas':
|
||||
return <TextAreaFixtures />;
|
||||
case '/input-change-events':
|
||||
return <InputChangeEvents />;
|
||||
case '/number-inputs':
|
||||
return <NumberInputFixtures />;
|
||||
case '/password-inputs':
|
||||
return <PasswordInputFixtures />;
|
||||
case '/buttons':
|
||||
return <ButtonFixtures />;
|
||||
case '/date-inputs':
|
||||
return <DateInputFixtures />;
|
||||
case '/error-handling':
|
||||
return <ErrorHandling />;
|
||||
case '/event-pooling':
|
||||
return <EventPooling />;
|
||||
case '/custom-elements':
|
||||
return <CustomElementFixtures />;
|
||||
case '/media-events':
|
||||
return <MediaEventsFixtures />;
|
||||
case '/pointer-events':
|
||||
return <PointerEventsFixtures />;
|
||||
case '/mouse-events':
|
||||
return <MouseEventsFixtures />;
|
||||
default:
|
||||
return <p>Please select a test fixture.</p>;
|
||||
class FixturesPage extends React.Component {
|
||||
static defaultProps = {
|
||||
fixturePath: fixturePath === '/' ? '/home' : fixturePath,
|
||||
};
|
||||
|
||||
state = {
|
||||
isLoading: true,
|
||||
error: null,
|
||||
Fixture: null,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.loadFixture();
|
||||
}
|
||||
|
||||
async loadFixture() {
|
||||
const {fixturePath} = this.props;
|
||||
|
||||
try {
|
||||
const module = await import(`.${fixturePath}`);
|
||||
|
||||
this.setState({Fixture: module.default});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
this.setState({error});
|
||||
} finally {
|
||||
this.setState({isLoading: false});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {Fixture, error, isLoading} = this.state;
|
||||
|
||||
if (isLoading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <FixtureError error={error} />;
|
||||
}
|
||||
|
||||
return <Fixture />;
|
||||
}
|
||||
}
|
||||
|
||||
function FixtureError({error}) {
|
||||
return (
|
||||
<section>
|
||||
<h2>Error loading fixture</h2>
|
||||
<p>{error.message}</p>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default FixturesPage;
|
||||
|
||||
@@ -60,7 +60,7 @@ export default class MediaEvents extends React.Component {
|
||||
}, {});
|
||||
|
||||
return (
|
||||
<FixtureSet title="Media Events" description="">
|
||||
<FixtureSet title="Media Events">
|
||||
<TestCase
|
||||
title="Event bubbling"
|
||||
description="Media events should synthetically bubble">
|
||||
|
||||
@@ -6,7 +6,7 @@ const React = window.React;
|
||||
class MouseEvents extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<FixtureSet title="Mouse Events" description="">
|
||||
<FixtureSet title="Mouse Events">
|
||||
<MouseMovement />
|
||||
</FixtureSet>
|
||||
);
|
||||
|
||||
@@ -6,7 +6,7 @@ const React = window.React;
|
||||
|
||||
function NumberInputs() {
|
||||
return (
|
||||
<FixtureSet title="Password inputs" description="">
|
||||
<FixtureSet title="Password inputs">
|
||||
<TestCase
|
||||
title="The show password icon"
|
||||
description={`
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import FixtureSet from '../../FixtureSet';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
class RangeInputs extends React.Component {
|
||||
@@ -7,22 +9,26 @@ class RangeInputs extends React.Component {
|
||||
};
|
||||
render() {
|
||||
return (
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend>Controlled</legend>
|
||||
<input
|
||||
type="range"
|
||||
value={this.state.value}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
<span className="hint">Value: {this.state.value}</span>
|
||||
</fieldset>
|
||||
<FixtureSet
|
||||
title="Range Inputs"
|
||||
description="Note: Range inputs are not supported in IE9.">
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend>Controlled</legend>
|
||||
<input
|
||||
type="range"
|
||||
value={this.state.value}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
<span className="hint">Value: {this.state.value}</span>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Uncontrolled</legend>
|
||||
<input type="range" defaultValue={0.5} />
|
||||
</fieldset>
|
||||
</form>
|
||||
<fieldset>
|
||||
<legend>Uncontrolled</legend>
|
||||
<input type="range" defaultValue={0.5} />
|
||||
</fieldset>
|
||||
</form>
|
||||
</FixtureSet>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import TestCase from '../../TestCase';
|
||||
import Iframe from '../../Iframe';
|
||||
const React = window.React;
|
||||
|
||||
class OnSelectIframe extends React.Component {
|
||||
state = {count: 0, value: 'Select Me!'};
|
||||
|
||||
_onSelect = event => {
|
||||
this.setState(({count}) => ({count: count + 1}));
|
||||
};
|
||||
|
||||
_onChange = event => {
|
||||
this.setState({value: event.target.value});
|
||||
};
|
||||
|
||||
render() {
|
||||
const {count, value} = this.state;
|
||||
return (
|
||||
<Iframe height={60}>
|
||||
Selection Event Count: {count}
|
||||
<input
|
||||
type="text"
|
||||
onSelect={this._onSelect}
|
||||
value={value}
|
||||
onChange={this._onChange}
|
||||
/>
|
||||
</Iframe>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default class OnSelectEventTestCase extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<TestCase
|
||||
title="onSelect events within iframes"
|
||||
description="onSelect events should fire for elements rendered inside iframes">
|
||||
<TestCase.Steps>
|
||||
<li>Highlight some of the text in the input below</li>
|
||||
<li>Move the cursor around using the arrow keys</li>
|
||||
</TestCase.Steps>
|
||||
<TestCase.ExpectedResult>
|
||||
The displayed count should increase as you highlight or move the
|
||||
cursor
|
||||
</TestCase.ExpectedResult>
|
||||
<OnSelectIframe />
|
||||
</TestCase>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import TestCase from '../../TestCase';
|
||||
import Iframe from '../../Iframe';
|
||||
const React = window.React;
|
||||
|
||||
export default class ReorderedInputsTestCase extends React.Component {
|
||||
state = {count: 0};
|
||||
|
||||
componentDidMount() {
|
||||
this.interval = setInterval(() => {
|
||||
this.setState({count: this.state.count + 1});
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
renderInputs() {
|
||||
const inputs = [
|
||||
<input key={1} defaultValue="Foo" />,
|
||||
<input key={2} defaultValue="Bar" />,
|
||||
];
|
||||
if (this.state.count % 2 === 0) {
|
||||
inputs.reverse();
|
||||
}
|
||||
return inputs;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<TestCase title="Reordered input elements in iframes" description="">
|
||||
<TestCase.Steps>
|
||||
<li>The two inputs below swap positions every two seconds</li>
|
||||
<li>Select the text in either of them</li>
|
||||
<li>Wait for the swap to occur</li>
|
||||
</TestCase.Steps>
|
||||
<TestCase.ExpectedResult>
|
||||
The selection you made should be maintained
|
||||
</TestCase.ExpectedResult>
|
||||
<Iframe height={50}>{this.renderInputs()}</Iframe>
|
||||
</TestCase>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import FixtureSet from '../../FixtureSet';
|
||||
import ReorderedInputsTestCase from './ReorderedInputsTestCase';
|
||||
import OnSelectEventTestCase from './OnSelectEventTestCase';
|
||||
const React = window.React;
|
||||
|
||||
export default function SelectionEvents() {
|
||||
return (
|
||||
<FixtureSet
|
||||
title="Selection Restoration"
|
||||
description="
|
||||
When React commits changes it may perform operations which cause existing
|
||||
selection state to be lost. This is manually managed by reading the
|
||||
selection state before commits and then restoring it afterwards.
|
||||
">
|
||||
<ReorderedInputsTestCase />
|
||||
<OnSelectEventTestCase />
|
||||
</FixtureSet>
|
||||
);
|
||||
}
|
||||
@@ -46,7 +46,7 @@ class SelectFixture extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<FixtureSet title="Selects" description="">
|
||||
<FixtureSet title="Selects">
|
||||
<form className="field-group">
|
||||
<fieldset>
|
||||
<legend>Controlled</legend>
|
||||
@@ -158,6 +158,50 @@ class SelectFixture extends React.Component {
|
||||
</form>
|
||||
</div>
|
||||
</TestCase>
|
||||
|
||||
<TestCase title="A multiple select being scrolled to first selected option">
|
||||
<TestCase.ExpectedResult>
|
||||
First selected option should be visible
|
||||
</TestCase.ExpectedResult>
|
||||
|
||||
<div className="test-fixture">
|
||||
<form>
|
||||
<select multiple defaultValue={['tiger']}>
|
||||
<option value="gorilla">gorilla</option>
|
||||
<option value="giraffe">giraffe</option>
|
||||
<option value="monkey">monkey</option>
|
||||
<option value="lion">lion</option>
|
||||
<option value="mongoose">mongoose</option>
|
||||
<option value="tiger">tiget</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</TestCase>
|
||||
|
||||
<TestCase
|
||||
title="An option which contains conditional render fails"
|
||||
relatedIssues="11911">
|
||||
<TestCase.Steps>
|
||||
<li>Select any option</li>
|
||||
</TestCase.Steps>
|
||||
<TestCase.ExpectedResult>
|
||||
Option should be set
|
||||
</TestCase.ExpectedResult>
|
||||
|
||||
<div className="test-fixture">
|
||||
<select value={this.state.value} onChange={this.onChange}>
|
||||
<option value="red">
|
||||
red {this.state.value === 'red' && 'is chosen '} TextNode
|
||||
</option>
|
||||
<option value="blue">
|
||||
blue {this.state.value === 'blue' && 'is chosen '} TextNode
|
||||
</option>
|
||||
<option value="green">
|
||||
green {this.state.value === 'green' && 'is chosen '} TextNode
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</TestCase>
|
||||
</FixtureSet>
|
||||
);
|
||||
}
|
||||
|
||||
321
fixtures/dom/src/components/fixtures/suspense/index.js
Normal file
@@ -0,0 +1,321 @@
|
||||
import Fixture from '../../Fixture';
|
||||
import FixtureSet from '../../FixtureSet';
|
||||
import TestCase from '../../TestCase';
|
||||
|
||||
const React = window.React;
|
||||
const ReactDOM = window.ReactDOM;
|
||||
|
||||
const Suspense = React.Suspense;
|
||||
|
||||
let cache = new Set();
|
||||
|
||||
function AsyncStep({text, ms}) {
|
||||
if (!cache.has(text)) {
|
||||
throw new Promise(resolve =>
|
||||
setTimeout(() => {
|
||||
cache.add(text);
|
||||
resolve();
|
||||
}, ms)
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
let suspendyTreeIdCounter = 0;
|
||||
class SuspendyTreeChild extends React.Component {
|
||||
id = suspendyTreeIdCounter++;
|
||||
state = {
|
||||
step: 1,
|
||||
isHidden: false,
|
||||
};
|
||||
increment = () => this.setState(s => ({step: s.step + 1}));
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('keydown', this.onKeydown);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this.onKeydown);
|
||||
}
|
||||
|
||||
onKeydown = event => {
|
||||
if (event.metaKey && event.key === 'Enter') {
|
||||
this.increment();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Suspense fallback={<div>(display: none)</div>}>
|
||||
<div>
|
||||
<AsyncStep text={`${this.state.step} + ${this.id}`} ms={500} />
|
||||
{this.props.children}
|
||||
</div>
|
||||
</Suspense>
|
||||
<button onClick={this.increment}>Hide</button>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SuspendyTree extends React.Component {
|
||||
parentContainer = React.createRef(null);
|
||||
container = React.createRef(null);
|
||||
componentDidMount() {
|
||||
this.setState({});
|
||||
document.addEventListener('keydown', this.onKeydown);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this.onKeydown);
|
||||
}
|
||||
onKeydown = event => {
|
||||
if (event.metaKey && event.key === '/') {
|
||||
this.removeAndRestore();
|
||||
}
|
||||
};
|
||||
removeAndRestore = () => {
|
||||
const parentContainer = this.parentContainer.current;
|
||||
const container = this.container.current;
|
||||
parentContainer.removeChild(container);
|
||||
parentContainer.textContent = '(removed from DOM)';
|
||||
setTimeout(() => {
|
||||
parentContainer.textContent = '';
|
||||
parentContainer.appendChild(container);
|
||||
}, 500);
|
||||
};
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div ref={this.parentContainer}>
|
||||
<div ref={this.container} />
|
||||
</div>
|
||||
<div>
|
||||
{this.container.current !== null
|
||||
? ReactDOM.createPortal(
|
||||
<React.Fragment>
|
||||
<SuspendyTreeChild>{this.props.children}</SuspendyTreeChild>
|
||||
<button onClick={this.removeAndRestore}>Remove</button>
|
||||
</React.Fragment>,
|
||||
this.container.current
|
||||
)
|
||||
: null}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TextInputFixtures extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<FixtureSet
|
||||
title="Suspense"
|
||||
description="Preserving the state of timed-out children">
|
||||
<p>
|
||||
Clicking "Hide" will hide the fixture context using{' '}
|
||||
<code>display: none</code> for 0.5 seconds, then restore. This is the
|
||||
built-in behavior for timed-out children. Each fixture tests whether
|
||||
the state of the DOM is preserved. Clicking "Remove" will remove the
|
||||
fixture content from the DOM for 0.5 seconds, then restore. This is{' '}
|
||||
<strong>not</strong> how timed-out children are hidden, but is
|
||||
included for comparison purposes.
|
||||
</p>
|
||||
<div className="footnote">
|
||||
As a shortcut, you can use Command + Enter (or Control + Enter on
|
||||
Windows, Linux) to "Hide" all the fixtures, or Command + / to "Remove"
|
||||
them.
|
||||
</div>
|
||||
<TestCase title="Text selection where entire range times out">
|
||||
<TestCase.Steps>
|
||||
<li>Use your cursor to select the text below.</li>
|
||||
<li>Click "Hide" or "Remove".</li>
|
||||
</TestCase.Steps>
|
||||
|
||||
<TestCase.ExpectedResult>
|
||||
Text selection is preserved when hiding, but not when removing.
|
||||
</TestCase.ExpectedResult>
|
||||
|
||||
<Fixture>
|
||||
<SuspendyTree>
|
||||
Select this entire sentence (and only this sentence).
|
||||
</SuspendyTree>
|
||||
</Fixture>
|
||||
</TestCase>
|
||||
<TestCase title="Text selection that extends outside timed-out subtree">
|
||||
<TestCase.Steps>
|
||||
<li>
|
||||
Use your cursor to select a range that includes both the text and
|
||||
the "Go" button.
|
||||
</li>
|
||||
<li>Click "Hide" or "Remove".</li>
|
||||
</TestCase.Steps>
|
||||
|
||||
<TestCase.ExpectedResult>
|
||||
Text selection is preserved when hiding, but not when removing.
|
||||
</TestCase.ExpectedResult>
|
||||
|
||||
<Fixture>
|
||||
<SuspendyTree>
|
||||
Select a range that includes both this sentence and the "Go"
|
||||
button.
|
||||
</SuspendyTree>
|
||||
</Fixture>
|
||||
</TestCase>
|
||||
<TestCase title="Focus">
|
||||
<TestCase.Steps>
|
||||
<li>
|
||||
Use your cursor to select a range that includes both the text and
|
||||
the "Go" button.
|
||||
</li>
|
||||
<li>
|
||||
Intead of clicking "Go", which switches focus, press Command +
|
||||
Enter (or Control + Enter on Windows, Linux).
|
||||
</li>
|
||||
</TestCase.Steps>
|
||||
|
||||
<TestCase.ExpectedResult>
|
||||
The ideal behavior is that the focus would not be lost, but
|
||||
currently it is (both when hiding and removing).
|
||||
</TestCase.ExpectedResult>
|
||||
|
||||
<Fixture>
|
||||
<SuspendyTree>
|
||||
<button>Focus me</button>
|
||||
</SuspendyTree>
|
||||
</Fixture>
|
||||
</TestCase>
|
||||
<TestCase title="Uncontrolled form input">
|
||||
<TestCase.Steps>
|
||||
<li>Type something ("Hello") into the text input.</li>
|
||||
<li>Click "Hide" or "Remove".</li>
|
||||
</TestCase.Steps>
|
||||
|
||||
<TestCase.ExpectedResult>
|
||||
Input is preserved when hiding, but not when removing.
|
||||
</TestCase.ExpectedResult>
|
||||
|
||||
<Fixture>
|
||||
<SuspendyTree>
|
||||
<input type="text" />
|
||||
</SuspendyTree>
|
||||
</Fixture>
|
||||
</TestCase>
|
||||
<TestCase title="Image flicker">
|
||||
<TestCase.Steps>
|
||||
<li>Click "Hide" or "Remove".</li>
|
||||
</TestCase.Steps>
|
||||
|
||||
<TestCase.ExpectedResult>
|
||||
The image should reappear without flickering. The text should not
|
||||
reflow.
|
||||
</TestCase.ExpectedResult>
|
||||
|
||||
<Fixture>
|
||||
<SuspendyTree>
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/e/ee/Atom_%282%29.png" />React
|
||||
is cool
|
||||
</SuspendyTree>
|
||||
</Fixture>
|
||||
</TestCase>
|
||||
<TestCase title="Iframe">
|
||||
<TestCase.Steps>
|
||||
<li>
|
||||
The iframe shows a nested version of this fixtures app. Navigate
|
||||
to the "Text inputs" page.
|
||||
</li>
|
||||
<li>Select one of the checkboxes.</li>
|
||||
<li>Click "Hide" or "Remove".</li>
|
||||
</TestCase.Steps>
|
||||
|
||||
<TestCase.ExpectedResult>
|
||||
When removing, the iframe is reloaded. When hiding, the iframe
|
||||
should still be on the "Text inputs" page. The checkbox should still
|
||||
be checked. (Unfortunately, scroll position is lost.)
|
||||
</TestCase.ExpectedResult>
|
||||
|
||||
<Fixture>
|
||||
<SuspendyTree>
|
||||
<iframe width="500" height="300" src="/" />
|
||||
</SuspendyTree>
|
||||
</Fixture>
|
||||
</TestCase>
|
||||
<TestCase title="Video playback">
|
||||
<TestCase.Steps>
|
||||
<li>Start playing the video, or seek to a specific position.</li>
|
||||
<li>Click "Hide" or "Remove".</li>
|
||||
</TestCase.Steps>
|
||||
|
||||
<TestCase.ExpectedResult>
|
||||
The playback position should stay the same. When hiding, the video
|
||||
plays in the background for the entire duration. When removing, the
|
||||
video stops playing, but the position is not lost.
|
||||
</TestCase.ExpectedResult>
|
||||
|
||||
<Fixture>
|
||||
<SuspendyTree>
|
||||
<video controls>
|
||||
<source
|
||||
src="http://techslides.com/demos/sample-videos/small.webm"
|
||||
type="video/webm"
|
||||
/>
|
||||
<source
|
||||
src="http://techslides.com/demos/sample-videos/small.ogv"
|
||||
type="video/ogg"
|
||||
/>
|
||||
<source
|
||||
src="http://techslides.com/demos/sample-videos/small.mp4"
|
||||
type="video/mp4"
|
||||
/>
|
||||
<source
|
||||
src="http://techslides.com/demos/sample-videos/small.3gp"
|
||||
type="video/3gp"
|
||||
/>
|
||||
</video>
|
||||
</SuspendyTree>
|
||||
</Fixture>
|
||||
</TestCase>
|
||||
<TestCase title="Audio playback">
|
||||
<TestCase.Steps>
|
||||
<li>Start playing the audio, or seek to a specific position.</li>
|
||||
<li>Click "Hide" or "Remove".</li>
|
||||
</TestCase.Steps>
|
||||
|
||||
<TestCase.ExpectedResult>
|
||||
The playback position should stay the same. When hiding, the audio
|
||||
plays in the background for the entire duration. When removing, the
|
||||
audio stops playing, but the position is not lost.
|
||||
</TestCase.ExpectedResult>
|
||||
<Fixture>
|
||||
<SuspendyTree>
|
||||
<audio controls={true}>
|
||||
<source src="https://upload.wikimedia.org/wikipedia/commons/e/ec/Mozart_K448.ogg" />
|
||||
</audio>
|
||||
</SuspendyTree>
|
||||
</Fixture>
|
||||
</TestCase>
|
||||
<TestCase title="Scroll position">
|
||||
<TestCase.Steps>
|
||||
<li>Scroll to a position in the list.</li>
|
||||
<li>Click "Hide" or "Remove".</li>
|
||||
</TestCase.Steps>
|
||||
|
||||
<TestCase.ExpectedResult>
|
||||
Scroll position is preserved when hiding, but not when removing.
|
||||
</TestCase.ExpectedResult>
|
||||
<Fixture>
|
||||
<SuspendyTree>
|
||||
<div style={{height: 200, overflow: 'scroll'}}>
|
||||
{Array(20)
|
||||
.fill()
|
||||
.map((_, i) => <h2 key={i}>{i + 1}</h2>)}
|
||||
</div>
|
||||
</SuspendyTree>
|
||||
</Fixture>
|
||||
</TestCase>
|
||||
</FixtureSet>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TextInputFixtures;
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'core-js/es6/symbol';
|
||||
import 'core-js/es6/promise';
|
||||
import 'core-js/es6/set';
|
||||
import 'core-js/es6/map';
|
||||
|
||||
37
fixtures/dom/src/react-loader.js
vendored
@@ -1,3 +1,5 @@
|
||||
import semver from 'semver';
|
||||
|
||||
/**
|
||||
* Take a version from the window query string and load a specific
|
||||
* version of React.
|
||||
@@ -34,36 +36,51 @@ function loadScript(src) {
|
||||
});
|
||||
}
|
||||
|
||||
export default function loadReact() {
|
||||
let REACT_PATH = 'react.development.js';
|
||||
let DOM_PATH = 'react-dom.development.js';
|
||||
export function reactPaths() {
|
||||
let reactPath = 'react.development.js';
|
||||
let reactDOMPath = 'react-dom.development.js';
|
||||
let reactDOMServerPath = 'react-dom-server.browser.development.js';
|
||||
|
||||
let query = parseQuery(window.location.search);
|
||||
let version = query.version || 'local';
|
||||
|
||||
if (version !== 'local') {
|
||||
const {major, minor, prerelease} = semver(version);
|
||||
const [preReleaseStage] = prerelease;
|
||||
// The file structure was updated in 16. This wasn't the case for alphas.
|
||||
// Load the old module location for anything less than 16 RC
|
||||
if (parseInt(version, 10) >= 16 && version.indexOf('alpha') < 0) {
|
||||
REACT_PATH =
|
||||
if (major >= 16 && !(minor === 0 && preReleaseStage === 'alpha')) {
|
||||
reactPath =
|
||||
'https://unpkg.com/react@' + version + '/umd/react.development.js';
|
||||
DOM_PATH =
|
||||
reactDOMPath =
|
||||
'https://unpkg.com/react-dom@' +
|
||||
version +
|
||||
'/umd/react-dom.development.js';
|
||||
reactDOMServerPath =
|
||||
'https://unpkg.com/react-dom@' +
|
||||
version +
|
||||
'/umd/react-dom-server.browser.development';
|
||||
} else {
|
||||
REACT_PATH = 'https://unpkg.com/react@' + version + '/dist/react.js';
|
||||
DOM_PATH =
|
||||
reactPath = 'https://unpkg.com/react@' + version + '/dist/react.js';
|
||||
reactDOMPath =
|
||||
'https://unpkg.com/react-dom@' + version + '/dist/react-dom.js';
|
||||
reactDOMServerPath =
|
||||
'https://unpkg.com/react-dom@' + version + '/dist/react-dom-server.js';
|
||||
}
|
||||
}
|
||||
|
||||
const needsReactDOM = version === 'local' || parseFloat(version, 10) > 0.13;
|
||||
|
||||
let request = loadScript(REACT_PATH);
|
||||
return {reactPath, reactDOMPath, reactDOMServerPath, needsReactDOM};
|
||||
}
|
||||
|
||||
export default function loadReact() {
|
||||
const {reactPath, reactDOMPath, needsReactDOM} = reactPaths();
|
||||
|
||||
let request = loadScript(reactPath);
|
||||
|
||||
if (needsReactDOM) {
|
||||
request = request.then(() => loadScript(DOM_PATH));
|
||||
request = request.then(() => loadScript(reactDOMPath));
|
||||
} else {
|
||||
// Aliasing React to ReactDOM for compatibility.
|
||||
request = request.then(() => {
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 10px;
|
||||
}
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
color: #333;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Arimo", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
font-size: 1.4rem;
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -26,23 +25,82 @@ button {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: #171717;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
margin: 24px 0 16px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
margin: 8px 0 16px;
|
||||
}
|
||||
|
||||
h4, h5, h6 {
|
||||
font-size: 16px;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:link:hover,
|
||||
a:link:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
textarea {
|
||||
border-radius: 2px;
|
||||
border: 1px solid #d9d9d9;
|
||||
font-size: 12px;
|
||||
min-height: 100px;
|
||||
min-width: 300px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: #222;
|
||||
box-shadow: inset 0 -1px 3px #000;
|
||||
font-size: 1.6rem;
|
||||
line-height: 3.2rem;
|
||||
background: #171717;
|
||||
overflow: hidden;
|
||||
padding: .8rem 1.6rem;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.header a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header a:hover,
|
||||
.header a:focus{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.header select {
|
||||
width: 12rem;
|
||||
margin-left: 8px;
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
.header__inner {
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
max-width: 1000px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
@@ -108,11 +166,11 @@ fieldset {
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 0 0 2rem 0;
|
||||
margin: 0 0 16px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.4rem;
|
||||
p {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.type-subheading {
|
||||
@@ -130,11 +188,10 @@ li {
|
||||
.footnote {
|
||||
border-left: 4px solid #aaa;
|
||||
color: #444;
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 2.4rem;
|
||||
margin-left: 0.4rem;
|
||||
padding-left: 1.6rem;
|
||||
margin-left: 8px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.test-case {
|
||||
@@ -158,7 +215,7 @@ li {
|
||||
}
|
||||
|
||||
.test-case__body {
|
||||
padding: 0 15px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.test-case__desc {
|
||||
@@ -222,3 +279,24 @@ li {
|
||||
.field-group {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
table {
|
||||
border: 1px solid #d9d9d9;
|
||||
border-width: 1px 1px 1px 0;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
text-align: left;
|
||||
border: 1px solid #d9d9d9;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,9 @@ export default function getVersionTags() {
|
||||
cachedTags = JSON.parse(cachedTags);
|
||||
resolve(cachedTags);
|
||||
} else {
|
||||
fetch('https://api.github.com/repos/facebook/react/tags', {mode: 'cors'})
|
||||
fetch('https://api.github.com/repos/facebook/react/tags?per_page=1000', {
|
||||
mode: 'cors',
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(tags => {
|
||||
// A message property indicates an error was sent from the API
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/standalone@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.0.0.tgz#856446641620c1c5f0ca775621d478324ebd1f52"
|
||||
|
||||
abab@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d"
|
||||
@@ -1556,6 +1560,10 @@ code-point-at@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
|
||||
codemirror@^5.40.0:
|
||||
version "5.40.0"
|
||||
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.40.0.tgz#2f5ed47366e514f41349ba0fe34daaa39be4e257"
|
||||
|
||||
color-convert@^1.3.0:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.8.2.tgz#be868184d7c8631766d54e7078e2672d7c7e3339"
|
||||
@@ -5878,6 +5886,10 @@ semver@^5.0.3:
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
|
||||
|
||||
semver@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||
|
||||
send@0.14.1:
|
||||
version "0.14.1"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.14.1.tgz#a954984325392f51532a7760760e459598c89f7a"
|
||||
|
||||
@@ -90,17 +90,17 @@ export default function describeFibers(rootFiber, workInProgress) {
|
||||
const workInProgressID = acknowledgeFiber(workInProgress);
|
||||
|
||||
let currentIDs = new Set();
|
||||
function markAsCurent(id) {
|
||||
function markAsCurrent(id) {
|
||||
currentIDs.add(id);
|
||||
const fiber = descriptions[id];
|
||||
if (fiber.sibling) {
|
||||
markAsCurent(fiber.sibling);
|
||||
markAsCurrent(fiber.sibling);
|
||||
}
|
||||
if (fiber.child) {
|
||||
markAsCurent(fiber.child);
|
||||
markAsCurrent(fiber.child);
|
||||
}
|
||||
}
|
||||
markAsCurent(rootID);
|
||||
markAsCurrent(rootID);
|
||||
|
||||
return {
|
||||
descriptions,
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
"private": true,
|
||||
"name": "browserify-dev-fixture",
|
||||
"dependencies": {
|
||||
"browserify": "^13.3.0",
|
||||
"react": "link:../../../../build/node_modules/react",
|
||||
"react-dom": "link:../../../../build/node_modules/react-dom"
|
||||
"browserify": "^13.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rm -f output.js && browserify ./input.js -o output.js"
|
||||
"build": "rm -f output.js && browserify ./input.js -o output.js",
|
||||
"prebuild": "cp -r ../../../../build/node_modules/* ./node_modules/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,6 @@ array-reduce@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
|
||||
|
||||
asap@~2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
|
||||
asn1.js@^4.0.0:
|
||||
version "4.9.1"
|
||||
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40"
|
||||
@@ -254,10 +250,6 @@ convert-source-map@~1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860"
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@@ -365,12 +357,6 @@ elliptic@^6.0.0:
|
||||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.0"
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
||||
dependencies:
|
||||
iconv-lite "~0.4.13"
|
||||
|
||||
events@~1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
|
||||
@@ -382,18 +368,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
|
||||
md5.js "^1.3.4"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
fbjs@^0.8.16:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
@@ -455,10 +429,6 @@ https-browserify@~0.0.0:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
|
||||
|
||||
iconv-lite@~0.4.13:
|
||||
version "0.4.19"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
||||
|
||||
ieee754@^1.1.4:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
|
||||
@@ -505,10 +475,6 @@ is-buffer@^1.1.0:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
|
||||
|
||||
is-stream@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
|
||||
isarray@^1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
@@ -517,17 +483,6 @@ isarray@~0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
dependencies:
|
||||
node-fetch "^1.0.1"
|
||||
whatwg-fetch ">=0.10.0"
|
||||
|
||||
js-tokens@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
||||
|
||||
json-stable-stringify@~0.0.0:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz#611c23e814db375527df851193db59dd2af27f45"
|
||||
@@ -560,12 +515,6 @@ lodash.memoize@~3.0.3:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f"
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
dependencies:
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
|
||||
@@ -618,17 +567,6 @@ module-deps@^4.0.8:
|
||||
through2 "^2.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
node-fetch@^1.0.1:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
@@ -693,20 +631,6 @@ process@~0.11.0:
|
||||
version "0.11.10"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.6.0:
|
||||
version "15.6.0"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.3.1"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
public-encrypt@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6"
|
||||
@@ -739,14 +663,6 @@ randombytes@^2.0.0, randombytes@^2.0.1:
|
||||
dependencies:
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
"react-dom@link:../../../../build/node_modules/react-dom":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"react@link:../../../../build/node_modules/react":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
read-only-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0"
|
||||
@@ -797,10 +713,6 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0,
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
|
||||
|
||||
setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
|
||||
sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4:
|
||||
version "2.4.9"
|
||||
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d"
|
||||
@@ -910,10 +822,6 @@ typedarray@~0.0.5:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
||||
ua-parser-js@^0.7.9:
|
||||
version "0.7.17"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
|
||||
|
||||
umd@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.1.tgz#8ae556e11011f63c2596708a8837259f01b3d60e"
|
||||
@@ -941,10 +849,6 @@ vm-browserify@~0.0.1:
|
||||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
whatwg-fetch@>=0.10.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
"private": true,
|
||||
"name": "browserify-prod-fixture",
|
||||
"dependencies": {
|
||||
"browserify": "^13.3.0",
|
||||
"react": "link:../../../../build/node_modules/react",
|
||||
"react-dom": "link:../../../../build/node_modules/react-dom"
|
||||
"browserify": "^13.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rm -f output.js && browserify ./input.js -g [envify --NODE_ENV 'production'] -o output.js"
|
||||
"build": "rm -f output.js && browserify ./input.js -g [envify --NODE_ENV 'production'] -o output.js",
|
||||
"prebuild": "cp -r ../../../../build/node_modules/* ./node_modules/"
|
||||
},
|
||||
"devDependencies": {
|
||||
"envify": "^4.0.0"
|
||||
|
||||
@@ -25,10 +25,6 @@ array-reduce@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
|
||||
|
||||
asap@~2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
|
||||
asn1.js@^4.0.0:
|
||||
version "4.9.1"
|
||||
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40"
|
||||
@@ -254,10 +250,6 @@ convert-source-map@~1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860"
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@@ -365,12 +357,6 @@ elliptic@^6.0.0:
|
||||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.0"
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
||||
dependencies:
|
||||
iconv-lite "~0.4.13"
|
||||
|
||||
envify@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e"
|
||||
@@ -393,18 +379,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
|
||||
md5.js "^1.3.4"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
fbjs@^0.8.16:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
@@ -466,10 +440,6 @@ https-browserify@~0.0.0:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
|
||||
|
||||
iconv-lite@~0.4.13:
|
||||
version "0.4.19"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
||||
|
||||
ieee754@^1.1.4:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
|
||||
@@ -516,10 +486,6 @@ is-buffer@^1.1.0:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
|
||||
|
||||
is-stream@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
|
||||
isarray@^1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
@@ -528,17 +494,6 @@ isarray@~0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
dependencies:
|
||||
node-fetch "^1.0.1"
|
||||
whatwg-fetch ">=0.10.0"
|
||||
|
||||
js-tokens@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
||||
|
||||
json-stable-stringify@~0.0.0:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz#611c23e814db375527df851193db59dd2af27f45"
|
||||
@@ -571,12 +526,6 @@ lodash.memoize@~3.0.3:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f"
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
dependencies:
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
|
||||
@@ -629,17 +578,6 @@ module-deps@^4.0.8:
|
||||
through2 "^2.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
node-fetch@^1.0.1:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
@@ -704,20 +642,6 @@ process@~0.11.0:
|
||||
version "0.11.10"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.6.0:
|
||||
version "15.6.0"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.3.1"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
public-encrypt@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6"
|
||||
@@ -750,14 +674,6 @@ randombytes@^2.0.0, randombytes@^2.0.1:
|
||||
dependencies:
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
"react-dom@link:../../../../build/node_modules/react-dom":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"react@link:../../../../build/node_modules/react":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
read-only-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0"
|
||||
@@ -808,10 +724,6 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0,
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
|
||||
|
||||
setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
|
||||
sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4:
|
||||
version "2.4.9"
|
||||
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d"
|
||||
@@ -921,10 +833,6 @@ typedarray@~0.0.5:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
||||
ua-parser-js@^0.7.9:
|
||||
version "0.7.17"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
|
||||
|
||||
umd@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.1.tgz#8ae556e11011f63c2596708a8837259f01b3d60e"
|
||||
@@ -952,10 +860,6 @@ vm-browserify@~0.0.1:
|
||||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
whatwg-fetch@>=0.10.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
"name": "brunch-dev-fixture",
|
||||
"devDependencies": {
|
||||
"brunch": "^2.9.1",
|
||||
"javascript-brunch": "^2.0.0",
|
||||
"react": "link:../../../../build/node_modules/react",
|
||||
"react-dom": "link:../../../../build/node_modules/react-dom"
|
||||
"javascript-brunch": "^2.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rm -rf public && brunch build"
|
||||
"build": "rm -rf public && brunch build",
|
||||
"prebuild": "cp -r ../../../../build/node_modules/* ./node_modules/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,10 +78,6 @@ array-unique@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
|
||||
|
||||
asap@~2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
|
||||
asn1.js@^4.0.0:
|
||||
version "4.9.1"
|
||||
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40"
|
||||
@@ -413,10 +409,6 @@ cookie@0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@@ -604,12 +596,6 @@ encodeurl@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
||||
dependencies:
|
||||
iconv-lite "~0.4.13"
|
||||
|
||||
es-abstract@^1.6.1:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227"
|
||||
@@ -726,18 +712,6 @@ fast-levenshtein@^1.1.3:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9"
|
||||
|
||||
fbjs@^0.8.16:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fcache@~0.3:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/fcache/-/fcache-0.3.0.tgz#d45f2f908642b91b798e88195ec47881a51c3d44"
|
||||
@@ -1027,7 +1001,7 @@ https-browserify@~0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
|
||||
|
||||
iconv-lite@0.4.19, iconv-lite@~0.4.13:
|
||||
iconv-lite@0.4.19:
|
||||
version "0.4.19"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
||||
|
||||
@@ -1152,10 +1126,6 @@ is-regex@^1.0.4:
|
||||
dependencies:
|
||||
has "^1.0.1"
|
||||
|
||||
is-stream@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
|
||||
is-symbol@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
|
||||
@@ -1182,13 +1152,6 @@ isobject@^2.0.0:
|
||||
dependencies:
|
||||
isarray "1.0.0"
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
dependencies:
|
||||
node-fetch "^1.0.1"
|
||||
whatwg-fetch ">=0.10.0"
|
||||
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
@@ -1199,10 +1162,6 @@ javascript-brunch@^2.0.0:
|
||||
dependencies:
|
||||
esprima "~3.0.0"
|
||||
|
||||
js-tokens@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
@@ -1264,12 +1223,6 @@ loggy@~0.3.0:
|
||||
ansicolors "~0.3.2"
|
||||
growl "~1.8.1"
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
dependencies:
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
|
||||
@@ -1423,13 +1376,6 @@ node-browser-modules@^0.1.0:
|
||||
util "~0.10.3"
|
||||
vm-browserify "~0.0.4"
|
||||
|
||||
node-fetch@^1.0.1:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
node-pre-gyp@^0.6.36:
|
||||
version "0.6.38"
|
||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.38.tgz#e92a20f83416415bb4086f6d1fb78b3da73d113d"
|
||||
@@ -1479,7 +1425,7 @@ oauth-sign@~0.8.1:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||
|
||||
object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
object-assign@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
@@ -1605,20 +1551,6 @@ promise.prototype.finally@^2:
|
||||
es-abstract "^1.6.1"
|
||||
function-bind "^1.1.0"
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.6.0:
|
||||
version "15.6.0"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.3.1"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
proxy-addr@~2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
|
||||
@@ -1704,14 +1636,6 @@ rc@^1.1.7:
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
"react-dom@link:../../../../build/node_modules/react-dom":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"react@link:../../../../build/node_modules/react":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
read-components@~0.7:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/read-components/-/read-components-0.7.0.tgz#77dce7adcb72a514240c47a675b9bcf7a3509dd9"
|
||||
@@ -1870,10 +1794,6 @@ set-immediate-shim@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
|
||||
|
||||
setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
|
||||
setprototypeof@1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
|
||||
@@ -2053,10 +1973,6 @@ type-is@~1.6.15:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.15"
|
||||
|
||||
ua-parser-js@^0.7.9:
|
||||
version "0.7.17"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
|
||||
|
||||
uid-number@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
|
||||
@@ -2118,10 +2034,6 @@ vm-browserify@~0.0.4:
|
||||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
whatwg-fetch@>=0.10.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
|
||||
|
||||
which@^1.2.12:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
"name": "brunch-prod-fixture",
|
||||
"devDependencies": {
|
||||
"brunch": "^2.9.1",
|
||||
"javascript-brunch": "^2.0.0",
|
||||
"react": "link:../../../../build/node_modules/react",
|
||||
"react-dom": "link:../../../../build/node_modules/react-dom"
|
||||
"javascript-brunch": "^2.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rm -rf public && brunch build -p"
|
||||
"build": "rm -rf public && brunch build -p",
|
||||
"prebuild": "cp -r ../../../../build/node_modules/* ./node_modules/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,10 +78,6 @@ array-unique@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
|
||||
|
||||
asap@~2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
|
||||
asn1.js@^4.0.0:
|
||||
version "4.9.1"
|
||||
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40"
|
||||
@@ -413,10 +409,6 @@ cookie@0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@@ -604,12 +596,6 @@ encodeurl@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
||||
dependencies:
|
||||
iconv-lite "~0.4.13"
|
||||
|
||||
es-abstract@^1.6.1:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227"
|
||||
@@ -726,18 +712,6 @@ fast-levenshtein@^1.1.3:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9"
|
||||
|
||||
fbjs@^0.8.16:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fcache@~0.3:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/fcache/-/fcache-0.3.0.tgz#d45f2f908642b91b798e88195ec47881a51c3d44"
|
||||
@@ -1027,7 +1001,7 @@ https-browserify@~0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
|
||||
|
||||
iconv-lite@0.4.19, iconv-lite@~0.4.13:
|
||||
iconv-lite@0.4.19:
|
||||
version "0.4.19"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
||||
|
||||
@@ -1152,10 +1126,6 @@ is-regex@^1.0.4:
|
||||
dependencies:
|
||||
has "^1.0.1"
|
||||
|
||||
is-stream@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
|
||||
is-symbol@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
|
||||
@@ -1182,13 +1152,6 @@ isobject@^2.0.0:
|
||||
dependencies:
|
||||
isarray "1.0.0"
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
dependencies:
|
||||
node-fetch "^1.0.1"
|
||||
whatwg-fetch ">=0.10.0"
|
||||
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
@@ -1199,10 +1162,6 @@ javascript-brunch@^2.0.0:
|
||||
dependencies:
|
||||
esprima "~3.0.0"
|
||||
|
||||
js-tokens@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
@@ -1264,12 +1223,6 @@ loggy@~0.3.0:
|
||||
ansicolors "~0.3.2"
|
||||
growl "~1.8.1"
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
dependencies:
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
|
||||
@@ -1423,13 +1376,6 @@ node-browser-modules@^0.1.0:
|
||||
util "~0.10.3"
|
||||
vm-browserify "~0.0.4"
|
||||
|
||||
node-fetch@^1.0.1:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
node-pre-gyp@^0.6.36:
|
||||
version "0.6.38"
|
||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.38.tgz#e92a20f83416415bb4086f6d1fb78b3da73d113d"
|
||||
@@ -1479,7 +1425,7 @@ oauth-sign@~0.8.1:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||
|
||||
object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
object-assign@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
@@ -1605,20 +1551,6 @@ promise.prototype.finally@^2:
|
||||
es-abstract "^1.6.1"
|
||||
function-bind "^1.1.0"
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.6.0:
|
||||
version "15.6.0"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.3.1"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
proxy-addr@~2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
|
||||
@@ -1704,14 +1636,6 @@ rc@^1.1.7:
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
"react-dom@link:../../../../build/node_modules/react-dom":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"react@link:../../../../build/node_modules/react":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
read-components@~0.7:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/read-components/-/read-components-0.7.0.tgz#77dce7adcb72a514240c47a675b9bcf7a3509dd9"
|
||||
@@ -1870,10 +1794,6 @@ set-immediate-shim@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
|
||||
|
||||
setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
|
||||
setprototypeof@1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
|
||||
@@ -2053,10 +1973,6 @@ type-is@~1.6.15:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.15"
|
||||
|
||||
ua-parser-js@^0.7.9:
|
||||
version "0.7.17"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
|
||||
|
||||
uid-number@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
|
||||
@@ -2118,10 +2034,6 @@ vm-browserify@~0.0.4:
|
||||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
whatwg-fetch@>=0.10.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
|
||||
|
||||
which@^1.2.12:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
|
||||
|
||||
@@ -42,51 +42,51 @@
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>browserify (dev)</h2>
|
||||
<iframe src="/fixtures/packaging/browserify/dev/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/browserify/dev/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>browserify (prod)</h2>
|
||||
<iframe src="/fixtures/packaging/browserify/prod/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/browserify/prod/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>brunch (dev)</h2>
|
||||
<iframe src="/fixtures/packaging/brunch/dev/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/brunch/dev/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>brunch (prod)</h2>
|
||||
<iframe src="/fixtures/packaging/brunch/prod/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/brunch/prod/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>rjs (dev)</h2>
|
||||
<iframe src="/fixtures/packaging/rjs/dev/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/rjs/dev/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>rjs (prod)</h2>
|
||||
<iframe src="/fixtures/packaging/rjs/prod/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/rjs/prod/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>systemjs-builder (dev)</h2>
|
||||
<iframe src="/fixtures/packaging/systemjs-builder/dev/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/systemjs-builder/dev/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>systemjs-builder (prod)</h2>
|
||||
<iframe src="/fixtures/packaging/systemjs-builder/prod/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/systemjs-builder/prod/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>webpack (dev)</h2>
|
||||
<iframe src="/fixtures/packaging/webpack/dev/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/webpack/dev/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>webpack (prod)</h2>
|
||||
<iframe src="/fixtures/packaging/webpack/prod/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/webpack/prod/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>webpack-alias (dev)</h2>
|
||||
<iframe src="/fixtures/packaging/webpack-alias/dev/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/webpack-alias/dev/"></iframe>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<h2>webpack-alias (prod)</h2>
|
||||
<iframe src="/fixtures/packaging/webpack-alias/prod/index.html"></iframe>
|
||||
<iframe src="/fixtures/packaging/webpack-alias/prod/"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,5 +6,6 @@ module.exports = {
|
||||
paths: {
|
||||
react: '../../../../build/dist/react.development',
|
||||
'react-dom': '../../../../build/dist/react-dom.development',
|
||||
schedule: '../../../../build/dist/schedule.development',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,5 +6,6 @@ module.exports = {
|
||||
paths: {
|
||||
react: '../../../../build/dist/react.production.min',
|
||||
'react-dom': '../../../../build/dist/react-dom.production.min',
|
||||
schedule: '../../../../build/dist/schedule.development',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2,5 +2,6 @@ System.config({
|
||||
paths: {
|
||||
react: '../../../../build/dist/react.development.js',
|
||||
'react-dom': '../../../../build/dist/react-dom.development.js',
|
||||
schedule: '../../../../build/dist/schedule.development',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2,5 +2,6 @@ System.config({
|
||||
paths: {
|
||||
react: '../../../../build/dist/react.production.min.js',
|
||||
'react-dom': '../../../../build/dist/react-dom.production.min.js',
|
||||
schedule: '../../../../build/dist/schedule.development',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: 100%; height: 100%;">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Schedule Test Page</title>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Scheduler Test Page</title>
|
||||
<style>
|
||||
.correct {
|
||||
border: solid green 2px;
|
||||
@@ -11,88 +12,94 @@
|
||||
border: dashed red 2px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Schedule Fixture</h1>
|
||||
<p>
|
||||
This fixture is for manual testing purposes, and the patterns used in
|
||||
implementing it should not be used as a model. This is mainly for anyone
|
||||
working on making changes to the `schedule` module.
|
||||
</p>
|
||||
<h2>Tests:</h2>
|
||||
<ol>
|
||||
<li>
|
||||
<button onClick="runTestOne()">Run Test 1</button>
|
||||
<p>Calls the callback within the frame when not blocked:</p>
|
||||
<div><b>Expected:</b></div>
|
||||
<div id="test-1-expected">
|
||||
</div>
|
||||
<div> -------------------------------------------------</div>
|
||||
<div> If you see the same above and below it's correct.
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Scheduler Fixture</h1>
|
||||
<p>
|
||||
This fixture is for manual testing purposes, and the patterns used in
|
||||
implementing it should not be used as a model. This is mainly for anyone
|
||||
working on making changes to the `schedule` module.
|
||||
</p>
|
||||
<h2>Tests:</h2>
|
||||
<ol>
|
||||
<li>
|
||||
<button onClick="runTestOne()">Run Test 1</button>
|
||||
<p>Calls the callback within the frame when not blocked:</p>
|
||||
<div><b>Expected:</b></div>
|
||||
<div id="test-1-expected">
|
||||
</div>
|
||||
<div> -------------------------------------------------</div>
|
||||
<div> If you see the same above and below it's correct.
|
||||
<div> -------------------------------------------------</div>
|
||||
<div><b>Actual:</b></div>
|
||||
<div id="test-1"></div>
|
||||
</li>
|
||||
<li>
|
||||
<p>Accepts multiple callbacks and calls within frame when not blocked</p>
|
||||
<button onClick="runTestTwo()">Run Test 2</button>
|
||||
<div><b>Expected:</b></div>
|
||||
<div id="test-2-expected">
|
||||
</div>
|
||||
<div> -------------------------------------------------</div>
|
||||
<div> If you see the same above and below it's correct.
|
||||
</li>
|
||||
<li>
|
||||
<p>Accepts multiple callbacks and calls within frame when not blocked</p>
|
||||
<button onClick="runTestTwo()">Run Test 2</button>
|
||||
<div><b>Expected:</b></div>
|
||||
<div id="test-2-expected">
|
||||
</div>
|
||||
<div> -------------------------------------------------</div>
|
||||
<div> If you see the same above and below it's correct.
|
||||
<div> -------------------------------------------------</div>
|
||||
<div><b>Actual:</b></div>
|
||||
<div id="test-2"></div>
|
||||
</li>
|
||||
<li>
|
||||
<p>Schedules callbacks in correct order when they use scheduleWork to schedule themselves</p>
|
||||
<button onClick="runTestThree()">Run Test 3</button>
|
||||
<div><b>Expected:</b></div>
|
||||
<div id="test-3-expected">
|
||||
</div>
|
||||
<div> -------------------------------------------------</div>
|
||||
<div> If you see the same above and below it's correct.
|
||||
</li>
|
||||
<li>
|
||||
<p>Schedules callbacks in correct order when they use scheduleCallback to schedule themselves</p>
|
||||
<button onClick="runTestThree()">Run Test 3</button>
|
||||
<div><b>Expected:</b></div>
|
||||
<div id="test-3-expected">
|
||||
</div>
|
||||
<div> -------------------------------------------------</div>
|
||||
<div> If you see the same above and below it's correct.
|
||||
<div> -------------------------------------------------</div>
|
||||
<div><b>Actual:</b></div>
|
||||
<div id="test-3"></div>
|
||||
</li>
|
||||
<li>
|
||||
<p>Calls timed out callbacks and then any more pending callbacks, defers others if time runs out</p>
|
||||
<button onClick="runTestFour()">Run Test 4</button>
|
||||
<div><b>Expected:</b></div>
|
||||
<div id="test-4-expected">
|
||||
</div>
|
||||
<div> -------------------------------------------------</div>
|
||||
<div> If you see the same above and below it's correct.
|
||||
</li>
|
||||
<li>
|
||||
<p>Calls timed out callbacks and then any more pending callbacks, defers others if time runs out</p>
|
||||
<button onClick="runTestFour()">Run Test 4</button>
|
||||
<div><b>Expected:</b></div>
|
||||
<div id="test-4-expected">
|
||||
</div>
|
||||
<div> -------------------------------------------------</div>
|
||||
<div> If you see the same above and below it's correct.
|
||||
<div> -------------------------------------------------</div>
|
||||
<div><b>Actual:</b></div>
|
||||
<div id="test-4"></div>
|
||||
</li>
|
||||
<li>
|
||||
<p>When some callbacks throw errors, still calls them all within the same frame</p>
|
||||
<p><b>IMPORTANT:</b> Open the console when you run this! Inspect the logs there!</p>
|
||||
<button onClick="runTestFive()">Run Test 5</button>
|
||||
</li>
|
||||
<li>
|
||||
<p>When some callbacks throw errors <b> and some also time out</b>, still calls them all within the same frame</p>
|
||||
<p><b>IMPORTANT:</b> Open the console when you run this! Inspect the logs there!</p>
|
||||
<button onClick="runTestSix()">Run Test 6</button>
|
||||
</li>
|
||||
<li>
|
||||
<p>Continues calling callbacks even when user switches away from this tab</p>
|
||||
<button onClick="runTestSeven()">Run Test 7</button>
|
||||
<div><b>Click the button above, observe the counter, then switch to
|
||||
another tab and switch back:</b></div>
|
||||
<div id="test-7">
|
||||
</div>
|
||||
<div> If the counter advanced while you were away from this tab, it's correct.</div>
|
||||
</li>
|
||||
</ol>
|
||||
<script src="../../build/dist/react-scheduler.development.js"></script>
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
|
||||
<script type="text/babel">
|
||||
const {scheduleWork, cancelWork, now} = ReactScheduler;
|
||||
</li>
|
||||
<li>
|
||||
<p>When some callbacks throw errors, still calls them all within the same frame</p>
|
||||
<p><b>IMPORTANT:</b> Open the console when you run this! Inspect the logs there!</p>
|
||||
<button onClick="runTestFive()">Run Test 5</button>
|
||||
</li>
|
||||
<li>
|
||||
<p>When some callbacks throw errors <b> and some also time out</b>, still calls them all within the same frame</p>
|
||||
<p><b>IMPORTANT:</b> Open the console when you run this! Inspect the logs there!</p>
|
||||
<button onClick="runTestSix()">Run Test 6</button>
|
||||
</li>
|
||||
<li>
|
||||
<p>Continues calling callbacks even when user switches away from this tab</p>
|
||||
<button onClick="runTestSeven()">Run Test 7</button>
|
||||
<div><b>Click the button above, observe the counter, then switch to
|
||||
another tab and switch back:</b></div>
|
||||
<div id="test-7">
|
||||
</div>
|
||||
<div> If the counter advanced while you were away from this tab, it's correct.</div>
|
||||
</li>
|
||||
</ol>
|
||||
<script src="../../build/dist/react.development.js"></script>
|
||||
<script src="../../build/node_modules/scheduler/umd/scheduler.development.js"></script>
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
|
||||
<script type="text/babel">
|
||||
const {
|
||||
unstable_scheduleCallback: scheduleCallback,
|
||||
unstable_cancelCallback: cancelCallback,
|
||||
unstable_now: now
|
||||
} = Scheduler;
|
||||
function displayTestResult(testNumber) {
|
||||
const expectationNode = document.getElementById('test-' + testNumber + '-expected');
|
||||
const resultNode = document.getElementById('test-' + testNumber);
|
||||
@@ -218,7 +225,7 @@ function runTestOne() {
|
||||
const cb1 = (x) => {
|
||||
updateTestResult(1, 'cb1 called with argument of ' + JSON.stringify(x));
|
||||
}
|
||||
scheduleWork(cb1);
|
||||
scheduleCallback(cb1);
|
||||
updateTestResult(1, 'scheduled Cb1');
|
||||
logWhenFramesStart(1, () => {
|
||||
displayTestResult(1);
|
||||
@@ -236,9 +243,9 @@ function runTestTwo() {
|
||||
const cbB = (x) => {
|
||||
updateTestResult(2, 'cbB called with argument of ' + JSON.stringify(x));
|
||||
}
|
||||
scheduleWork(cbA);
|
||||
scheduleCallback(cbA);
|
||||
updateTestResult(2, 'scheduled CbA');
|
||||
scheduleWork(cbB);
|
||||
scheduleCallback(cbB);
|
||||
updateTestResult(2, 'scheduled CbB');
|
||||
logWhenFramesStart(2, () => {
|
||||
displayTestResult(2);
|
||||
@@ -248,12 +255,12 @@ function runTestTwo() {
|
||||
|
||||
function runTestThree() {
|
||||
// Test 3
|
||||
// Schedules callbacks in correct order when they use scheduleWork to schedule themselves
|
||||
// Schedules callbacks in correct order when they use scheduleCallback to schedule themselves
|
||||
clearTestResult(3);
|
||||
let callbackAIterations = 0;
|
||||
const cbA = (x) => {
|
||||
if (callbackAIterations < 1) {
|
||||
scheduleWork(cbA);
|
||||
scheduleCallback(cbA);
|
||||
updateTestResult(3, 'scheduled CbA again');
|
||||
}
|
||||
updateTestResult(3, 'cbA' + callbackAIterations + ' called with argument of ' + JSON.stringify(x));
|
||||
@@ -262,9 +269,9 @@ function runTestThree() {
|
||||
const cbB = (x) => {
|
||||
updateTestResult(3, 'cbB called with argument of ' + JSON.stringify(x));
|
||||
}
|
||||
scheduleWork(cbA);
|
||||
scheduleCallback(cbA);
|
||||
updateTestResult(3, 'scheduled CbA');
|
||||
scheduleWork(cbB);
|
||||
scheduleCallback(cbB);
|
||||
updateTestResult(3, 'scheduled CbB');
|
||||
logWhenFramesStart(3, () => {
|
||||
displayTestResult(3);
|
||||
@@ -298,13 +305,13 @@ function runTestFour() {
|
||||
const cbD = (x) => {
|
||||
updateTestResult(4, 'cbD called with argument of ' + JSON.stringify(x));
|
||||
}
|
||||
scheduleWork(cbA); // won't time out
|
||||
scheduleCallback(cbA); // won't time out
|
||||
updateTestResult(4, 'scheduled cbA');
|
||||
scheduleWork(cbB, {timeout: 100}); // times out later
|
||||
scheduleCallback(cbB, {timeout: 100}); // times out later
|
||||
updateTestResult(4, 'scheduled cbB');
|
||||
scheduleWork(cbC, {timeout: 1}); // will time out fast
|
||||
scheduleCallback(cbC, {timeout: 1}); // will time out fast
|
||||
updateTestResult(4, 'scheduled cbC');
|
||||
scheduleWork(cbD); // won't time out
|
||||
scheduleCallback(cbD); // won't time out
|
||||
updateTestResult(4, 'scheduled cbD');
|
||||
|
||||
// should have run in order of C, A, B, D
|
||||
@@ -383,15 +390,15 @@ function runTestFive() {
|
||||
});
|
||||
});
|
||||
});
|
||||
scheduleWork(cbA);
|
||||
scheduleCallback(cbA);
|
||||
console.log('scheduled cbA');
|
||||
scheduleWork(cbB); // will throw error
|
||||
scheduleCallback(cbB); // will throw error
|
||||
console.log('scheduled cbB');
|
||||
scheduleWork(cbC);
|
||||
scheduleCallback(cbC);
|
||||
console.log('scheduled cbC');
|
||||
scheduleWork(cbD); // will throw error
|
||||
scheduleCallback(cbD); // will throw error
|
||||
console.log('scheduled cbD');
|
||||
scheduleWork(cbE);
|
||||
scheduleCallback(cbE);
|
||||
console.log('scheduled cbE');
|
||||
};
|
||||
}
|
||||
@@ -461,15 +468,15 @@ function runTestSix() {
|
||||
});
|
||||
});
|
||||
});
|
||||
scheduleWork(cbA);
|
||||
scheduleCallback(cbA);
|
||||
console.log('scheduled cbA');
|
||||
scheduleWork(cbB); // will throw error
|
||||
scheduleCallback(cbB); // will throw error
|
||||
console.log('scheduled cbB');
|
||||
scheduleWork(cbC, {timeout: 1});
|
||||
scheduleCallback(cbC, {timeout: 1});
|
||||
console.log('scheduled cbC');
|
||||
scheduleWork(cbD, {timeout: 1}); // will throw error
|
||||
scheduleCallback(cbD, {timeout: 1}); // will throw error
|
||||
console.log('scheduled cbD');
|
||||
scheduleWork(cbE, {timeout: 1});
|
||||
scheduleCallback(cbE, {timeout: 1});
|
||||
console.log('scheduled cbE');
|
||||
};
|
||||
}
|
||||
@@ -485,10 +492,10 @@ function runTestSeven() {
|
||||
counter++;
|
||||
counterNode.innerHTML = counter;
|
||||
waitForTimeToPass(100);
|
||||
scheduleWork(incrementCounterAndScheduleNextCallback);
|
||||
scheduleCallback(incrementCounterAndScheduleNextCallback);
|
||||
}
|
||||
scheduleWork(incrementCounterAndScheduleNextCallback);
|
||||
scheduleCallback(incrementCounterAndScheduleNextCallback);
|
||||
}
|
||||
</script type="text/babel">
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -1334,10 +1334,6 @@ cookie@0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
|
||||
core-js@^2.4.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
|
||||
@@ -2057,18 +2053,6 @@ fb-watchman@^1.8.0, fb-watchman@^1.9.0:
|
||||
dependencies:
|
||||
bser "1.0.2"
|
||||
|
||||
fbjs@^0.8.16:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
figures@^1.3.5:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
|
||||
@@ -2753,13 +2737,6 @@ isobject@^2.0.0:
|
||||
dependencies:
|
||||
isarray "1.0.0"
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
dependencies:
|
||||
node-fetch "^1.0.1"
|
||||
whatwg-fetch ">=0.10.0"
|
||||
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
@@ -3265,7 +3242,7 @@ longest@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
|
||||
loose-envify@^1.0.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
dependencies:
|
||||
@@ -3446,13 +3423,6 @@ node-emoji@^1.4.1:
|
||||
dependencies:
|
||||
string.prototype.codepointat "^0.2.0"
|
||||
|
||||
node-fetch@^1.0.1:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
node-fetch@^1.6.3:
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04"
|
||||
@@ -3588,7 +3558,7 @@ oauth-sign@~0.8.1:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||
|
||||
object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
@@ -4101,20 +4071,6 @@ promise@7.1.1:
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.6.0:
|
||||
version "15.6.0"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.3.1"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
proxy-addr@~1.1.3:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.4.tgz#27e545f6960a44a627d9b44467e35c1b6b4ce2f3"
|
||||
@@ -4590,7 +4546,7 @@ set-immediate-shim@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
|
||||
|
||||
setimmediate@^1.0.4, setimmediate@^1.0.5:
|
||||
setimmediate@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
|
||||
@@ -4985,10 +4941,6 @@ typedarray@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
||||
ua-parser-js@^0.7.9:
|
||||
version "0.7.17"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
|
||||
|
||||
uglify-js@2.8.x, uglify-js@^2.6:
|
||||
version "2.8.21"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.21.tgz#1733f669ae6f82fc90c7b25ec0f5c783ee375314"
|
||||
@@ -5242,10 +5194,6 @@ whatwg-fetch@2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.2.tgz#fe294d1d89e36c5be8b3195057f2e4bc74fc980e"
|
||||
|
||||
whatwg-fetch@>=0.10.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
|
||||
|
||||
whatwg-url@^4.3.0:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.7.0.tgz#202035ac1955b087cdd20fa8b58ded3ab1cd2af5"
|
||||
|
||||
72
fixtures/tracing/index.html
Normal file
@@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: 100%; height: 100%;">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test tracing UMD</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
ol {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
li {
|
||||
background-color: #F7F7F7;
|
||||
border: solid #CCC 0.125rem;
|
||||
margin-bottom: 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
li:after {
|
||||
content: attr(data-value);
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
.correct {
|
||||
border-color: #0C0;
|
||||
border-style: solid;
|
||||
background: #EFE;
|
||||
}
|
||||
.incorrect {
|
||||
border-color: #F00;
|
||||
border-style: dashed;
|
||||
background-color: #FEE;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test tracing UMD</h1>
|
||||
<p>
|
||||
This fixture tests that the new tracing API is accessible via UMD build using the UMD shim.
|
||||
It does not exhaustively test API functionality, only that the forwarded methods can be called.
|
||||
</p>
|
||||
<p>
|
||||
Before running the tests below, check the console to make sure there are no errors.
|
||||
</p>
|
||||
<h3>
|
||||
Tests
|
||||
<button onClick="runAllTests()">Run all tests</button>
|
||||
</h3>
|
||||
<ol>
|
||||
<li id="checkSchedulerAPI" data-value="...">
|
||||
<strong>Test scheduler API</strong>
|
||||
</li>
|
||||
<li id="checkSchedulerTracingAPI" data-value="...">
|
||||
<strong>Test tracing API</strong>
|
||||
</li>
|
||||
<li id="checkSchedulerTracingSubscriptionsAPI" data-value="...">
|
||||
<strong>Test tracing subscriptions API</strong>
|
||||
</li>
|
||||
<li id="checkEndToEndIntegration" data-value="...">
|
||||
<strong>Test end-to-end integration</strong>
|
||||
</li>
|
||||
</ol>
|
||||
<!-- Load the tracing API before react to test that it's lazily evaluated -->
|
||||
<script src="../../build/node_modules/scheduler/umd/scheduler.development.js"></script>
|
||||
<script src="../../build/node_modules/scheduler/umd/scheduler-tracing.development.js"></script>
|
||||
<script src="../../build/node_modules/react/umd/react.development.js"></script>
|
||||
<script src="../../build/node_modules/react-dom/umd/react-dom.development.js"></script>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
205
fixtures/tracing/script.js
Normal file
@@ -0,0 +1,205 @@
|
||||
function runTest(listItem, callback) {
|
||||
try {
|
||||
callback();
|
||||
listItem.className = 'correct';
|
||||
listItem.setAttribute('data-value', 'All checks pass');
|
||||
} catch (error) {
|
||||
listItem.className = 'incorrect';
|
||||
listItem.setAttribute('data-value', error);
|
||||
}
|
||||
}
|
||||
|
||||
function runAllTests() {
|
||||
try {
|
||||
checkSchedulerAPI();
|
||||
} finally {
|
||||
try {
|
||||
checkSchedulerTracingAPI();
|
||||
} finally {
|
||||
try {
|
||||
checkSchedulerTracingSubscriptionsAPI();
|
||||
} finally {
|
||||
checkEndToEndIntegration();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkSchedulerAPI() {
|
||||
runTest(document.getElementById('checkSchedulerAPI'), () => {
|
||||
if (
|
||||
typeof Scheduler === 'undefined' ||
|
||||
typeof Scheduler.unstable_now !== 'function' ||
|
||||
typeof Scheduler.unstable_scheduleCallback !== 'function' ||
|
||||
typeof Scheduler.unstable_cancelCallback !== 'function'
|
||||
) {
|
||||
throw 'API is not defined';
|
||||
}
|
||||
|
||||
if (Scheduler.unstable_now() !== performance.now()) {
|
||||
throw 'API does not work';
|
||||
}
|
||||
|
||||
// There is no real way to verify that the two APIs are connected.
|
||||
});
|
||||
}
|
||||
|
||||
function checkSchedulerTracingAPI() {
|
||||
runTest(document.getElementById('checkSchedulerTracingAPI'), () => {
|
||||
if (
|
||||
typeof SchedulerTracing === 'undefined' ||
|
||||
typeof SchedulerTracing.unstable_clear !== 'function' ||
|
||||
typeof SchedulerTracing.unstable_getCurrent !== 'function' ||
|
||||
typeof SchedulerTracing.unstable_getThreadID !== 'function' ||
|
||||
typeof SchedulerTracing.unstable_trace !== 'function' ||
|
||||
typeof SchedulerTracing.unstable_wrap !== 'function'
|
||||
) {
|
||||
throw 'API is not defined';
|
||||
}
|
||||
|
||||
try {
|
||||
let interactionsSet;
|
||||
SchedulerTracing.unstable_trace('test', 123, () => {
|
||||
interactionsSet = SchedulerTracing.unstable_getCurrent();
|
||||
});
|
||||
if (interactionsSet.size !== 1) {
|
||||
throw null;
|
||||
}
|
||||
const interaction = Array.from(interactionsSet)[0];
|
||||
if (interaction.name !== 'test' || interaction.timestamp !== 123) {
|
||||
throw null;
|
||||
}
|
||||
} catch (error) {
|
||||
throw 'API does not work';
|
||||
}
|
||||
|
||||
const ForwardedSchedulerTracing =
|
||||
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.SchedulerTracing;
|
||||
|
||||
if (
|
||||
SchedulerTracing.unstable_getThreadID() ===
|
||||
ForwardedSchedulerTracing.unstable_getThreadID()
|
||||
) {
|
||||
throw 'API forwarding is broken';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkSchedulerTracingSubscriptionsAPI() {
|
||||
runTest(
|
||||
document.getElementById('checkSchedulerTracingSubscriptionsAPI'),
|
||||
() => {
|
||||
if (
|
||||
typeof SchedulerTracing === 'undefined' ||
|
||||
typeof SchedulerTracing.unstable_subscribe !== 'function' ||
|
||||
typeof SchedulerTracing.unstable_unsubscribe !== 'function'
|
||||
) {
|
||||
throw 'API is not defined';
|
||||
}
|
||||
|
||||
const onInteractionScheduledWorkCompletedCalls = [];
|
||||
const onInteractionTracedCalls = [];
|
||||
const onWorkCanceledCalls = [];
|
||||
const onWorkScheduledCalls = [];
|
||||
const onWorkStartedCalls = [];
|
||||
const onWorkStoppedCalls = [];
|
||||
const subscriber = {
|
||||
onInteractionScheduledWorkCompleted: (...args) =>
|
||||
onInteractionScheduledWorkCompletedCalls.push(args),
|
||||
onInteractionTraced: (...args) => onInteractionTracedCalls.push(args),
|
||||
onWorkCanceled: (...args) => onWorkCanceledCalls.push(args),
|
||||
onWorkScheduled: (...args) => onWorkScheduledCalls.push(args),
|
||||
onWorkStarted: (...args) => onWorkStartedCalls.push(args),
|
||||
onWorkStopped: (...args) => onWorkStoppedCalls.push(args),
|
||||
};
|
||||
|
||||
try {
|
||||
SchedulerTracing.unstable_subscribe(subscriber);
|
||||
SchedulerTracing.unstable_trace('foo', 123, () => {});
|
||||
SchedulerTracing.unstable_unsubscribe(subscriber);
|
||||
if (onInteractionTracedCalls.length !== 1) {
|
||||
throw null;
|
||||
}
|
||||
const interaction = onInteractionTracedCalls[0][0];
|
||||
if (interaction.name !== 'foo' || interaction.timestamp !== 123) {
|
||||
throw null;
|
||||
}
|
||||
SchedulerTracing.unstable_trace('bar', 456, () => {});
|
||||
if (onInteractionTracedCalls.length !== 1) {
|
||||
throw null;
|
||||
}
|
||||
} catch (error) {
|
||||
throw 'API does not forward methods';
|
||||
}
|
||||
|
||||
const ForwardedSchedulerTracing =
|
||||
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
|
||||
.SchedulerTracing;
|
||||
|
||||
try {
|
||||
ForwardedSchedulerTracing.unstable_subscribe(subscriber);
|
||||
SchedulerTracing.unstable_trace('foo', 123, () => {});
|
||||
ForwardedSchedulerTracing.unstable_trace('bar', 456, () => {});
|
||||
SchedulerTracing.unstable_unsubscribe(subscriber);
|
||||
if (onInteractionTracedCalls.length !== 3) {
|
||||
throw null;
|
||||
}
|
||||
const interactionFoo = onInteractionTracedCalls[1][0];
|
||||
const interactionBar = onInteractionTracedCalls[2][0];
|
||||
if (
|
||||
interactionFoo.name !== 'foo' ||
|
||||
interactionFoo.timestamp !== 123 ||
|
||||
interactionBar.name !== 'bar' ||
|
||||
interactionBar.timestamp !== 456
|
||||
) {
|
||||
throw null;
|
||||
}
|
||||
ForwardedSchedulerTracing.unstable_trace('baz', 789, () => {});
|
||||
if (onInteractionTracedCalls.length !== 3) {
|
||||
throw null;
|
||||
}
|
||||
} catch (error) {
|
||||
throw 'API forwarding is broken';
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function checkEndToEndIntegration() {
|
||||
runTest(document.getElementById('checkEndToEndIntegration'), () => {
|
||||
try {
|
||||
const onRenderCalls = [];
|
||||
const onRender = (...args) => onRenderCalls.push(args);
|
||||
const container = document.createElement('div');
|
||||
|
||||
SchedulerTracing.unstable_trace('render', 123, () => {
|
||||
ReactDOM.render(
|
||||
React.createElement(
|
||||
React.unstable_Profiler,
|
||||
{id: 'profiler', onRender},
|
||||
React.createElement('div', null, 'hi')
|
||||
),
|
||||
container
|
||||
);
|
||||
});
|
||||
|
||||
if (container.textContent !== 'hi') {
|
||||
throw null;
|
||||
}
|
||||
|
||||
if (onRenderCalls.length !== 1) {
|
||||
throw null;
|
||||
}
|
||||
const call = onRenderCalls[0];
|
||||
if (call.length !== 7) {
|
||||
throw null;
|
||||
}
|
||||
const interaction = Array.from(call[6])[0];
|
||||
if (interaction.name !== 'render' || interaction.timestamp !== 123) {
|
||||
throw null;
|
||||
}
|
||||
} catch (error) {
|
||||
throw 'End to end integration is broken';
|
||||
}
|
||||
});
|
||||
}
|
||||
21
fixtures/tracing/test.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: 100%; height: 100%;">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test tracing UMD</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<!-- Load the tracing API before react to test that it's lazily evaluated -->
|
||||
<script src="../../build/node_modules/scheduler/umd/scheduler.development.js"></script>
|
||||
<script src="../../build/node_modules/scheduler/umd/scheduler-tracing.development.js"></script>
|
||||
<script src="../../build/node_modules/react/umd/react.development.js"></script>
|
||||
<script src="../../build/node_modules/react-dom/umd/react-dom.development.js"></script>
|
||||
<script src="./test.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
103
fixtures/tracing/test.js
Normal file
@@ -0,0 +1,103 @@
|
||||
const {createElement, Component, Placeholder} = React;
|
||||
const {unstable_createRoot: createRoot} = ReactDOM;
|
||||
const {
|
||||
unstable_subscribe: subscribe,
|
||||
unstable_trace: trace,
|
||||
unstable_wrap: wrap,
|
||||
} = SchedulerTracing;
|
||||
|
||||
const createLogger = (backgroundColor, color, enabled) => (
|
||||
message,
|
||||
...args
|
||||
) => {
|
||||
if (enabled === false) return;
|
||||
console.groupCollapsed(
|
||||
`%c${message}`,
|
||||
`background-color: ${backgroundColor}; color: ${color}; padding: 2px 4px;`,
|
||||
...args
|
||||
);
|
||||
console.log(
|
||||
new Error('stack').stack
|
||||
.split('\n')
|
||||
.slice(2)
|
||||
.join('\n')
|
||||
);
|
||||
console.groupEnd();
|
||||
};
|
||||
|
||||
window.log = {
|
||||
app: createLogger('#37474f', '#fff'),
|
||||
interaction: createLogger('#6a1b9a', '#fff'),
|
||||
react: createLogger('#ff5722', '#fff'),
|
||||
tracing: createLogger('#2962ff', '#fff'),
|
||||
work: createLogger('#e1bee7', '#000'),
|
||||
};
|
||||
|
||||
// Fake suspense
|
||||
const resolvedValues = {};
|
||||
const read = key => {
|
||||
if (!resolvedValues[key]) {
|
||||
log.app(`Suspending for "${key}" ...`);
|
||||
throw new Promise(
|
||||
wrap(resolve => {
|
||||
setTimeout(
|
||||
wrap(() => {
|
||||
log.app(`Loaded "${key}" ...`);
|
||||
resolvedValues[key] = true;
|
||||
resolve(key);
|
||||
}),
|
||||
1000
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
return key;
|
||||
};
|
||||
|
||||
const TestApp = () =>
|
||||
createElement(
|
||||
Placeholder,
|
||||
{delayMs: 100, fallback: createElement(PlaceholderText)},
|
||||
createElement(SuspendingChild, {text: 'foo'}),
|
||||
createElement(SuspendingChild, {text: 'bar'}),
|
||||
createElement(SuspendingChild, {text: 'baz'})
|
||||
);
|
||||
|
||||
const PlaceholderText = () => 'Loading ...';
|
||||
|
||||
const SuspendingChild = ({text}) => {
|
||||
const resolvedValue = read(text);
|
||||
return resolvedValue;
|
||||
};
|
||||
|
||||
subscribe({
|
||||
onInteractionScheduledWorkCompleted: interaction =>
|
||||
log.interaction(
|
||||
'onInteractionScheduledWorkCompleted',
|
||||
JSON.stringify(interaction)
|
||||
),
|
||||
onInteractionTraced: interaction =>
|
||||
log.interaction('onInteractionTraced', JSON.stringify(interaction)),
|
||||
onWorkCanceled: interactions =>
|
||||
log.work('onWorkCanceled', JSON.stringify(Array.from(interactions))),
|
||||
onWorkScheduled: interactions =>
|
||||
log.work('onWorkScheduled', JSON.stringify(Array.from(interactions))),
|
||||
onWorkStarted: interactions =>
|
||||
log.work('onWorkStarted', JSON.stringify(Array.from(interactions))),
|
||||
onWorkStopped: interactions =>
|
||||
log.work('onWorkStopped', JSON.stringify(Array.from(interactions))),
|
||||
});
|
||||
|
||||
const element = document.getElementById('root');
|
||||
trace('initial_render', performance.now(), () => {
|
||||
const root = createRoot(element);
|
||||
const batch = root.createBatch();
|
||||
log.app('batch.render()');
|
||||
batch.render(createElement(TestApp));
|
||||
batch.then(
|
||||
wrap(() => {
|
||||
log.app('batch.commit()');
|
||||
batch.commit();
|
||||
})
|
||||
);
|
||||
});
|
||||
14
fixtures/unstable-async/suspense/.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
# testing
|
||||
coverage
|
||||
|
||||
# production
|
||||
build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
npm-debug.log
|
||||
31
fixtures/unstable-async/suspense/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# IO "suspense" demo
|
||||
|
||||
## What is this fixture?
|
||||
|
||||
This is a demo application based on [Dan Abramov's](https://github.com/gaearon) recent [JSConf Iceland talk](https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html) about React.
|
||||
|
||||
It depends on a local build of React and enables us to easily test async and "suspense" APIs in a more "real world app" like context.
|
||||
|
||||
## Can I use this code in production?
|
||||
|
||||
No. The APIs being tested here are unstable and some of them have still not been released to NPM. For now, this fixture is only a test harness.
|
||||
|
||||
## How do I run this fixture?
|
||||
|
||||
Clone the React repository.
|
||||
|
||||
Follow these steps:
|
||||
|
||||
```shell
|
||||
# 1: Build react from source
|
||||
cd /path/to/react
|
||||
yarn
|
||||
yarn build dom-client,core,react-cache,scheduler --type=NODE
|
||||
|
||||
# 2: Install fixture dependencies
|
||||
cd fixtures/unstable-async/suspense/
|
||||
yarn
|
||||
|
||||
# 3: Run the app
|
||||
yarn start
|
||||
```
|
||||
40
fixtures/unstable-async/suspense/package.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "io-demo",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"homepage": ".",
|
||||
"devDependencies": {
|
||||
"gh-pages": "^1.1.0",
|
||||
"react-scripts": "^1.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"clipboard": "^1.7.1",
|
||||
"github-fork-ribbon-css": "^0.2.1",
|
||||
"react-draggable": "^3.0.5"
|
||||
},
|
||||
"scripts": {
|
||||
"prestart": "cp -r ../../../build/node_modules/* ./node_modules/",
|
||||
"prebuild": "cp -r ../../../build/node_modules/* ./node_modules/",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject",
|
||||
"deploy": "gh-pages -d build"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "./node_modules/react-scripts/config/eslint.js"
|
||||
},
|
||||
"browserslist": {
|
||||
"development": [
|
||||
"last 2 chrome versions",
|
||||
"last 2 firefox versions",
|
||||
"last 2 edge versions"
|
||||
],
|
||||
"production": [
|
||||
">1%",
|
||||
"last 4 versions",
|
||||
"Firefox ESR",
|
||||
"not ie < 11"
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
fixtures/unstable-async/suspense/public/favicon.ico
Executable file
|
After Width: | Height: | Size: 24 KiB |
BIN
fixtures/unstable-async/suspense/public/img/acdlite.jpeg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
fixtures/unstable-async/suspense/public/img/bvaughn.jpeg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
fixtures/unstable-async/suspense/public/img/flarnie.jpeg
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
fixtures/unstable-async/suspense/public/img/gaearon.jpeg
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
fixtures/unstable-async/suspense/public/img/sebmarkbage.jpeg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
fixtures/unstable-async/suspense/public/img/sophiebits.jpeg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
fixtures/unstable-async/suspense/public/img/trueadm.jpeg
Normal file
|
After Width: | Height: | Size: 26 KiB |
13
fixtures/unstable-async/suspense/public/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="./src/favicon.ico">
|
||||
<title>React Core Team</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<div id="debugger"></div>
|
||||
</body>
|
||||
</html>
|
||||
15
fixtures/unstable-async/suspense/public/manifest.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "Emoji Search",
|
||||
"name": "Emoji Search Example App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
334
fixtures/unstable-async/suspense/src/api/data.js
Normal file
@@ -0,0 +1,334 @@
|
||||
export const coreContributorListJSON = [
|
||||
{
|
||||
id: 'acdlite',
|
||||
name: 'Andrew Clark',
|
||||
},
|
||||
{
|
||||
id: 'bvaughn',
|
||||
name: 'Brian Vaughn',
|
||||
},
|
||||
{
|
||||
id: 'gaearon',
|
||||
name: 'Dan Abramov',
|
||||
},
|
||||
{
|
||||
id: 'trueadm',
|
||||
name: 'Dominic Gannaway',
|
||||
},
|
||||
{
|
||||
id: 'flarnie',
|
||||
name: 'Flarnie Marchan',
|
||||
},
|
||||
{
|
||||
id: 'sebmarkbage',
|
||||
name: 'Sebastian Markbåge',
|
||||
},
|
||||
{
|
||||
id: 'sophiebits',
|
||||
name: 'Sophie Alpert',
|
||||
},
|
||||
];
|
||||
|
||||
export const userProfileJSON = {
|
||||
acdlite: {
|
||||
id: 'acdlite',
|
||||
name: 'Andrew Clark',
|
||||
image: '/img/acdlite.jpeg',
|
||||
location: 'Redwood City, CA',
|
||||
email: 'acdlite@me.com',
|
||||
tagline: 'React core at Facebook. Hi!',
|
||||
},
|
||||
bvaughn: {
|
||||
id: 'bvaughn',
|
||||
name: 'Brian Vaughn',
|
||||
image: '/img/bvaughn.jpeg',
|
||||
location: 'Mountain View, CA',
|
||||
email: 'brian.david.vaughn@gmail.com',
|
||||
tagline:
|
||||
'React JS core team at @facebook; formerly at @treasure-data and @google.',
|
||||
},
|
||||
gaearon: {
|
||||
id: 'gaearon',
|
||||
name: 'Dan Abramov',
|
||||
image: '/img/gaearon.jpeg',
|
||||
location: 'London, UK',
|
||||
email: 'dan.abramov@me.com',
|
||||
tagline:
|
||||
'Working on @reactjs. Co-author of Redux and Create React App. Building tools for humans.',
|
||||
},
|
||||
flarnie: {
|
||||
id: 'flarnie',
|
||||
name: 'Flarnie Marchan',
|
||||
image: '/img/flarnie.jpeg',
|
||||
location: 'Oakland, CA',
|
||||
email: null,
|
||||
tagline:
|
||||
'Software Engineer at Facebook React Core Team & Co-maintainer of Draft.js',
|
||||
},
|
||||
sebmarkbage: {
|
||||
id: 'sebmarkbage',
|
||||
name: 'Sebastian Markbåge',
|
||||
image: '/img/sebmarkbage.jpeg',
|
||||
location: 'San Francisco',
|
||||
email: 'sebastian@calyptus.eu',
|
||||
tagline: null,
|
||||
},
|
||||
sophiebits: {
|
||||
id: 'sophiebits',
|
||||
name: 'Sophie Alpert',
|
||||
image: '/img/sophiebits.jpeg',
|
||||
location: 'California',
|
||||
email: 'hi@sophiebits.com',
|
||||
tagline:
|
||||
'I like fixing things. eng manager of @reactjs at Facebook. ex-@khanacademy. 💎🌸 she/her. kindness, intersectional feminism, music.',
|
||||
},
|
||||
trueadm: {
|
||||
id: 'trueadm',
|
||||
name: 'Dominic Gannaway',
|
||||
image: '/img/trueadm.jpeg',
|
||||
location: 'London, United Kingdom',
|
||||
email: null,
|
||||
tagline:
|
||||
'Currently an engineer on the React core team at @facebook. Author of @infernojs and t7. Enjoys coding + being a Dad.',
|
||||
},
|
||||
};
|
||||
export const userRepositoriesListJSON = {
|
||||
acdlite: [
|
||||
{
|
||||
name: 'recompose',
|
||||
url: 'https://github.com/acdlite/recompose',
|
||||
description:
|
||||
'A React utility belt for function components and higher-order components.',
|
||||
},
|
||||
{
|
||||
name: 'react-fiber-architecture',
|
||||
url: 'https://github.com/acdlite/react-fiber-architecture',
|
||||
description: "A description of React's new core algorithm, React Fiber",
|
||||
},
|
||||
{
|
||||
name: 'redux-router',
|
||||
url: 'https://github.com/acdlite/redux-router',
|
||||
description:
|
||||
'Redux bindings for React Router – keep your router state inside your Redux store',
|
||||
},
|
||||
{
|
||||
name: 'flummox',
|
||||
url: 'https://github.com/acdlite/flummox',
|
||||
description: 'Minimal, isomorphic Flux.',
|
||||
},
|
||||
{
|
||||
name: 'redux-rx',
|
||||
url: 'https://github.com/acdlite/redux-rx',
|
||||
description: 'RxJS utilities for Redux.',
|
||||
},
|
||||
{
|
||||
name: 'react-remarkable',
|
||||
url: 'https://github.com/acdlite/react-remarkable',
|
||||
description: 'A React component for rendering Markdown with remarkable',
|
||||
},
|
||||
],
|
||||
bvaughn: [
|
||||
{
|
||||
name: 'react-virtualized',
|
||||
url: 'https://github.com/bvaughn/react-virtualized',
|
||||
description:
|
||||
'React components for efficiently rendering large lists and tabular data',
|
||||
},
|
||||
{
|
||||
name: 'redux-search',
|
||||
url: 'https://github.com/bvaughn/redux-search',
|
||||
description: 'Redux bindings for client-side search',
|
||||
},
|
||||
{
|
||||
name: 'react-window',
|
||||
url: 'https://github.com/bvaughn/react-window',
|
||||
description:
|
||||
'React components for efficiently rendering large lists and tabular data',
|
||||
},
|
||||
{
|
||||
name: 'react-virtualized-select',
|
||||
url: 'https://github.com/bvaughn/react-virtualized-select',
|
||||
description:
|
||||
'HOC that uses react-virtualized and react-select to display large lists of options in a drop-down',
|
||||
},
|
||||
{
|
||||
name: 'js-search',
|
||||
url: 'https://github.com/bvaughn/js-search',
|
||||
description:
|
||||
'JS Search is an efficient, client-side search library for JavaScript and JSON objects',
|
||||
},
|
||||
{
|
||||
name: 'react-highlight-words',
|
||||
url: 'https://github.com/bvaughn/react-highlight-words',
|
||||
description:
|
||||
'React component to highlight words within a larger body of text',
|
||||
},
|
||||
],
|
||||
gaearon: [
|
||||
{
|
||||
name: 'facebook/react',
|
||||
url: 'https://github.com/facebook/react',
|
||||
description:
|
||||
'A declarative, efficient, and flexible JavaScript library for building user interfaces.',
|
||||
},
|
||||
{
|
||||
name: 'reduxjs/redux',
|
||||
url: 'https://github.com/reduxjs/redux',
|
||||
description: 'Predictable state container for JavaScript apps',
|
||||
},
|
||||
{
|
||||
name: 'facebook/create-react-app',
|
||||
url: 'https://github.com/facebook/create-react-app',
|
||||
description: 'Create React apps with no build configuration.',
|
||||
},
|
||||
{
|
||||
name: 'reduxjs/redux-devtools',
|
||||
url: 'https://github.com/reduxjs/redux-devtools',
|
||||
description:
|
||||
'DevTools for Redux with hot reloading, action replay, and customizable UI',
|
||||
},
|
||||
{
|
||||
name: 'react-dnd/react-dnd',
|
||||
url: 'https://github.com/react-dnd/react-dnd',
|
||||
description: 'Drag and Drop for React',
|
||||
},
|
||||
{
|
||||
name: 'paularmstrong/normalizr',
|
||||
url: 'https://github.com/paularmstrong/normalizr',
|
||||
description: 'Normalizes nested JSON according to a schema',
|
||||
},
|
||||
],
|
||||
flarnie: [
|
||||
{
|
||||
name: 'diffux/diffux',
|
||||
url: 'https://github.com/diffux/diffux',
|
||||
description: 'Perceptual diffs of responsive screenshots made simple.',
|
||||
},
|
||||
{
|
||||
name: 'facebook/draft-js',
|
||||
url: 'https://github.com/facebook/draft-js',
|
||||
description: 'A React framework for building text editors.',
|
||||
},
|
||||
{
|
||||
name: 'facebook/react',
|
||||
url: 'https://github.com/facebook/react',
|
||||
description:
|
||||
'A declarative, efficient, and flexible JavaScript library for building user interfaces.',
|
||||
},
|
||||
{
|
||||
name: 'facebook/jest',
|
||||
url: 'https://github.com/facebook/jest',
|
||||
description: '🃏 Delightful JavaScript Testing.',
|
||||
},
|
||||
{
|
||||
name: 'Galooshi/import-js',
|
||||
url: 'https://github.com/Galooshi/import-js',
|
||||
description: 'A tool to simplify importing JS modules',
|
||||
},
|
||||
{
|
||||
name: 'webpack_rails_demo',
|
||||
url: 'https://github.com/flarnie/webpack_rails_demo',
|
||||
description: 'Setting up webpack with Ruby on Rails: a basic demo',
|
||||
},
|
||||
],
|
||||
sebmarkbage: [
|
||||
{
|
||||
name: 'art',
|
||||
url: 'https://github.com/sebmarkbage/art',
|
||||
description:
|
||||
"Retained mode vector drawing API designed for multiple output modes. There's also a built-in SVG parser.",
|
||||
},
|
||||
{
|
||||
name: 'ecmascript-immutable-data-structures',
|
||||
url:
|
||||
'https://github.com/sebmarkbage/ecmascript-immutable-data-structures',
|
||||
description: null,
|
||||
},
|
||||
{
|
||||
name: 'ocamlrun-wasm',
|
||||
url: 'https://github.com/sebmarkbage/ocamlrun-wasm',
|
||||
description: 'OCamlrun WebAssembly - OCaml Bytecode Interpreter in WASM',
|
||||
},
|
||||
{
|
||||
name: 'ecmascript-generator-expression',
|
||||
url: 'https://github.com/sebmarkbage/ecmascript-generator-expression',
|
||||
description:
|
||||
'Proposal for do Generator Expressions in ECMAScript. Work in progress. Edit Add topics',
|
||||
},
|
||||
{
|
||||
name: 'ecmascript-undefined-propagation',
|
||||
url: 'https://github.com/sebmarkbage/ecmascript-undefined-propagation',
|
||||
description:
|
||||
'ECMAScript proposal to relax the rules to return `undefined` for property access on `null` or `undefined` instead of throwing.',
|
||||
},
|
||||
{
|
||||
name: 'ecmascript-shallow-equal',
|
||||
url: 'https://github.com/sebmarkbage/ecmascript-shallow-equal',
|
||||
description: 'A proposal for ECMAScript for Object.shallowEqual',
|
||||
},
|
||||
],
|
||||
sophiebits: [
|
||||
{
|
||||
name: 'facebook/react',
|
||||
url: 'https://github.com/facebook/react',
|
||||
description:
|
||||
'A declarative, efficient, and flexible JavaScript library for building user interfaces.',
|
||||
},
|
||||
{
|
||||
name: 'Khan/KaTeX',
|
||||
url: 'https://github.com/Khan/KaTeX',
|
||||
description: 'Fast math typesetting for the web.',
|
||||
},
|
||||
{
|
||||
name: 'facebook/react-devtools',
|
||||
url: 'https://github.com/facebook/react-devtools',
|
||||
description:
|
||||
'An extension that allows inspection of React component hierarchy in the Chrome and Firefox Developer Tools.',
|
||||
},
|
||||
{
|
||||
name: 'vim-awesome/vim-awesome',
|
||||
url: 'https://github.com/vim-awesome/vim-awesome',
|
||||
description: 'Awesome Vim plugins from across the universe',
|
||||
},
|
||||
{
|
||||
name: 'facebook/draft-js',
|
||||
url: 'https://github.com/facebook/draft-js',
|
||||
description: 'A React framework for building text editors.',
|
||||
},
|
||||
{
|
||||
name: 'es3ify',
|
||||
url: 'https://github.com/sophiebits/es3ify',
|
||||
description:
|
||||
'Browserify transform to convert ES5 syntax to be ES3-compatible.',
|
||||
},
|
||||
],
|
||||
trueadm: [
|
||||
{
|
||||
name: 'facebook/react',
|
||||
url: 'https://github.com/facebook/react',
|
||||
description:
|
||||
'A declarative, efficient, and flexible JavaScript library for building user interfaces.',
|
||||
},
|
||||
{
|
||||
name: 'infernojs/inferno',
|
||||
url: 'https://github.com/infernojs/inferno',
|
||||
description:
|
||||
'An extremely fast, React-like JavaScript library for building modern user interfaces',
|
||||
},
|
||||
{
|
||||
name: 'facebook/prepack',
|
||||
url: 'https://github.com/facebook/prepack',
|
||||
description: 'A JavaScript bundle optimizer.',
|
||||
},
|
||||
{
|
||||
name: 't7',
|
||||
url: 'https://github.com/trueadm/t7',
|
||||
description: 'Lightweight virtual DOM templating library',
|
||||
},
|
||||
{
|
||||
name: 'infernojs/babel-plugin-inferno',
|
||||
url: 'https://github.com/infernojs/babel-plugin-inferno',
|
||||
description: null,
|
||||
},
|
||||
],
|
||||
};
|
||||
67
fixtures/unstable-async/suspense/src/api/index.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import {
|
||||
coreContributorListJSON,
|
||||
userProfileJSON,
|
||||
userRepositoriesListJSON,
|
||||
} from './data';
|
||||
|
||||
export function fetchCoreContributorListJSON() {
|
||||
return makeFakeAPICall('/react/contributors', coreContributorListJSON);
|
||||
}
|
||||
|
||||
export function fetchUserProfileJSON(id) {
|
||||
return makeFakeAPICall(`/${id}/details`, userProfileJSON[id]);
|
||||
}
|
||||
|
||||
export function fetchUserRepositoriesListJSON(id) {
|
||||
return makeFakeAPICall(`/${id}/repositories`, userRepositoriesListJSON[id]);
|
||||
}
|
||||
|
||||
let fakeRequestTime = 1000;
|
||||
let onProgress = () => true;
|
||||
|
||||
export function setFakeRequestTime(val) {
|
||||
fakeRequestTime = val;
|
||||
}
|
||||
|
||||
export function setProgressHandler(handler) {
|
||||
onProgress = handler;
|
||||
}
|
||||
|
||||
export function setPauseNewRequests(value) {
|
||||
shouldPauseNewRequests = value;
|
||||
}
|
||||
|
||||
let shouldPauseNewRequests = false;
|
||||
let notifiers = {};
|
||||
let isPausedUrl = {};
|
||||
|
||||
export function setPaused(url, isPaused) {
|
||||
const wasPaused = isPausedUrl[url];
|
||||
isPausedUrl[url] = isPaused;
|
||||
if (isPaused !== wasPaused) {
|
||||
notifiers[url]();
|
||||
}
|
||||
}
|
||||
|
||||
function makeFakeAPICall(url, result) {
|
||||
let i = 1;
|
||||
return new Promise(resolve => {
|
||||
isPausedUrl[url] = shouldPauseNewRequests;
|
||||
function notify() {
|
||||
if (!isPausedUrl[url]) {
|
||||
i++;
|
||||
}
|
||||
onProgress(url, i, isPausedUrl[url]);
|
||||
if (isPausedUrl[url]) {
|
||||
return;
|
||||
}
|
||||
if (i === 100) {
|
||||
resolve(result);
|
||||
} else {
|
||||
setTimeout(notify, fakeRequestTime / 100);
|
||||
}
|
||||
}
|
||||
notifiers[url] = notify;
|
||||
notify();
|
||||
});
|
||||
}
|
||||
89
fixtures/unstable-async/suspense/src/components/App.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import React, {lazy, Suspense, PureComponent} from 'react';
|
||||
import {unstable_scheduleCallback} from 'scheduler';
|
||||
import {
|
||||
unstable_trace as trace,
|
||||
unstable_wrap as wrap,
|
||||
} from 'scheduler/tracing';
|
||||
import Spinner from './Spinner';
|
||||
import ContributorListPage from './ContributorListPage';
|
||||
|
||||
const UserPage = lazy(() => import('./UserPage'));
|
||||
|
||||
export default class App extends PureComponent {
|
||||
state = {
|
||||
currentId: null,
|
||||
showDetail: false,
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (
|
||||
prevState.showDetail !== this.state.showDetail ||
|
||||
(prevState.currentId !== this.state.currentId && this.state.showDetail)
|
||||
) {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
handleUserClick = id => {
|
||||
trace(`View ${id}`, performance.now(), () => {
|
||||
trace(`View ${id} (high-pri)`, performance.now(), () =>
|
||||
this.setState({
|
||||
currentId: id,
|
||||
})
|
||||
);
|
||||
unstable_scheduleCallback(
|
||||
wrap(() =>
|
||||
trace(`View ${id} (low-pri)`, performance.now(), () =>
|
||||
this.setState({
|
||||
showDetail: true,
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
handleBackClick = () =>
|
||||
trace('View list', performance.now(), () =>
|
||||
this.setState({
|
||||
currentId: null,
|
||||
showDetail: false,
|
||||
})
|
||||
);
|
||||
|
||||
render() {
|
||||
const {currentId, showDetail} = this.state;
|
||||
return showDetail
|
||||
? this.renderDetail(currentId)
|
||||
: this.renderList(currentId);
|
||||
}
|
||||
|
||||
renderDetail(id) {
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
onClick={this.handleBackClick}
|
||||
style={{
|
||||
display: 'block',
|
||||
marginBottom: '1rem',
|
||||
}}>
|
||||
Return to list
|
||||
</button>
|
||||
<Suspense maxDuration={2000} fallback={<Spinner size="large" />}>
|
||||
<UserPage id={id} />
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderList(loadingId) {
|
||||
return (
|
||||
<Suspense maxDuration={1500} fallback={<Spinner size="large" />}>
|
||||
<ContributorListPage
|
||||
loadingId={loadingId}
|
||||
onUserClick={this.handleUserClick}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import React, {Fragment} from 'react';
|
||||
import {unstable_createResource} from 'react-cache';
|
||||
import Spinner from './Spinner';
|
||||
import {fetchCoreContributorListJSON} from '../api';
|
||||
|
||||
const ContributorListResource = unstable_createResource(
|
||||
fetchCoreContributorListJSON
|
||||
);
|
||||
|
||||
const ContributorListPage = ({loadingId, onUserClick}) => (
|
||||
<Fragment>
|
||||
<h1>React Core Team</h1>
|
||||
<ul
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridGap: '0.5rem',
|
||||
gridTemplateColumns: 'repeat(auto-fill, 20rem)',
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
}}>
|
||||
{ContributorListResource.read().map(user => (
|
||||
<ContributorListItem
|
||||
key={user.id}
|
||||
onClick={() => onUserClick(user.id)}
|
||||
isLoading={loadingId && user.id === loadingId}
|
||||
user={user}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
const ContributorListItem = ({isLoading, onClick, user}) => (
|
||||
<li
|
||||
onClick={onClick}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
padding: '1rem',
|
||||
backgroundColor: 'var(--color-buttonBg)',
|
||||
border: '1px solid var(--color-buttonBorder)',
|
||||
borderRadius: '1rem',
|
||||
opacity: isLoading === false ? 0.5 : 1,
|
||||
cursor: isLoading ? 'default' : 'pointer',
|
||||
}}
|
||||
tabIndex="0">
|
||||
<div>
|
||||
<strong>{user.name}</strong>
|
||||
<div style={{marginTop: '0.5rem'}}>{user.id}</div>
|
||||
</div>
|
||||
{isLoading ? (
|
||||
<Spinner size="small" />
|
||||
) : (
|
||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" d="M0 0h24v24H0z" />
|
||||
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" />
|
||||
</svg>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
|
||||
export default ContributorListPage;
|
||||
75
fixtures/unstable-async/suspense/src/components/Spinner.css
Normal file
@@ -0,0 +1,75 @@
|
||||
.Spinner {
|
||||
animation: rotate 1.3s linear infinite;
|
||||
}
|
||||
|
||||
.SpinnerContainer-large {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(270deg); }
|
||||
}
|
||||
|
||||
.SmallSpinnerPath {
|
||||
stroke-dasharray: 100;
|
||||
stroke-dashoffset: 0;
|
||||
transform-origin: center;
|
||||
animation:
|
||||
SmallDash 1.3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes SmallDash {
|
||||
0% { stroke-dashoffset: 100; }
|
||||
50% {
|
||||
stroke-dashoffset: 50;
|
||||
transform:rotate(135deg);
|
||||
}
|
||||
100% {
|
||||
stroke-dashoffset: 100;
|
||||
transform:rotate(450deg);
|
||||
}
|
||||
}
|
||||
|
||||
.MediumSpinnerPath {
|
||||
stroke-dasharray: 150;
|
||||
stroke-dashoffset: 0;
|
||||
transform-origin: center;
|
||||
animation:
|
||||
MediumDash 1.3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes MediumDash {
|
||||
0% { stroke-dashoffset: 150; }
|
||||
50% {
|
||||
stroke-dashoffset: 50;
|
||||
transform:rotate(135deg);
|
||||
}
|
||||
100% {
|
||||
stroke-dashoffset: 150;
|
||||
transform:rotate(450deg);
|
||||
}
|
||||
}
|
||||
|
||||
.LargeSpinnerPath {
|
||||
stroke-dasharray: 200;
|
||||
stroke-dashoffset: 0;
|
||||
transform-origin: center;
|
||||
animation:
|
||||
LargeDash 1.3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes LargeDash {
|
||||
0% { stroke-dashoffset: 200; }
|
||||
50% {
|
||||
stroke-dashoffset: 50;
|
||||
transform:rotate(135deg);
|
||||
}
|
||||
100% {
|
||||
stroke-dashoffset: 200;
|
||||
transform:rotate(450deg);
|
||||
}
|
||||
}
|
||||
51
fixtures/unstable-async/suspense/src/components/Spinner.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import './Spinner.css';
|
||||
|
||||
const SPINNER_SIZES = {
|
||||
small: 30,
|
||||
medium: 50,
|
||||
large: 70,
|
||||
};
|
||||
|
||||
const STROKE_WIDTHS = {
|
||||
small: 4,
|
||||
medium: 5,
|
||||
large: 6,
|
||||
};
|
||||
|
||||
const PATH_CLASS_NAMES = {
|
||||
small: 'SmallSpinnerPath',
|
||||
medium: 'MediumSpinnerPath',
|
||||
large: 'LargeSpinnerPath',
|
||||
};
|
||||
|
||||
// Heavily inspired by https://codepen.io/mrrocks/pen/EiplA
|
||||
export default function Spinner({size = 'small'}) {
|
||||
const baseSize = SPINNER_SIZES[size];
|
||||
const pathSize = baseSize / 2;
|
||||
const strokeWidth = STROKE_WIDTHS[size];
|
||||
const pathRadius = `${baseSize / 2 - strokeWidth}px`;
|
||||
const className = PATH_CLASS_NAMES[size];
|
||||
const containerClassName = `SpinnerContainer SpinnerContainer-${size}`;
|
||||
|
||||
return (
|
||||
<div className={containerClassName}>
|
||||
<svg
|
||||
className={className}
|
||||
width={baseSize}
|
||||
height={baseSize}
|
||||
viewBox={`0 0 ${baseSize} ${baseSize}`}>
|
||||
<circle
|
||||
className="SpinnerPath"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={strokeWidth}
|
||||
strokeLinecap="round"
|
||||
cx={pathSize}
|
||||
cy={pathSize}
|
||||
r={pathRadius}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
170
fixtures/unstable-async/suspense/src/components/UserPage.js
Normal file
@@ -0,0 +1,170 @@
|
||||
import React, {Suspense} from 'react';
|
||||
import {unstable_createResource} from 'react-cache';
|
||||
import Spinner from './Spinner';
|
||||
import {fetchUserProfileJSON, fetchUserRepositoriesListJSON} from '../api';
|
||||
|
||||
export default function UserPage({id}) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fill, 20rem)',
|
||||
gridGap: '1rem',
|
||||
alignItems: 'start',
|
||||
}}>
|
||||
<UserDetails id={id} />
|
||||
<Suspense maxDuration={1000} fallback={<Spinner size="medium" />}>
|
||||
<Repositories id={id} />
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const UserDetailsResource = unstable_createResource(fetchUserProfileJSON);
|
||||
|
||||
function UserDetails({id}) {
|
||||
const user = UserDetailsResource.read(id);
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridGap: '0.5rem',
|
||||
width: '20rem',
|
||||
padding: '1rem',
|
||||
backgroundColor: 'var(--color-buttonBg)',
|
||||
border: '1px solid var(--color-buttonBorder)',
|
||||
borderRadius: '1rem',
|
||||
}}>
|
||||
<UserPicture source={user.image} />
|
||||
<div
|
||||
style={{
|
||||
fontSize: '1.5rem',
|
||||
fontWeight: 'bold',
|
||||
color: 'var(--color-pageTextDark)',
|
||||
}}>
|
||||
{user.name}
|
||||
</div>
|
||||
<div style={{fontSize: '1.25rem'}}>{user.id}</div>
|
||||
{user.tagline !== null && <div>{user.tagline}</div>}
|
||||
<hr
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '1px',
|
||||
border: 'none',
|
||||
backgroundColor: '#ddd',
|
||||
}}
|
||||
/>
|
||||
{user.location && <Location location={user.location} />}
|
||||
{user.email && <Email email={user.email} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const Location = ({location}) => (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}}>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
style={{
|
||||
width: '24px',
|
||||
height: '24px',
|
||||
marginRight: '0.5rem',
|
||||
fill: 'currentColor',
|
||||
}}>
|
||||
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" />
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
</svg>
|
||||
{location}
|
||||
</div>
|
||||
);
|
||||
|
||||
const Email = ({email}) => (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}}>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
style={{
|
||||
width: '24px',
|
||||
height: '24px',
|
||||
marginRight: '0.5rem',
|
||||
fill: 'currentColor',
|
||||
}}>
|
||||
<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z" />
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
</svg>
|
||||
<a href={`mailto:${email}`}>{email}</a>
|
||||
</div>
|
||||
);
|
||||
|
||||
const ImageResource = unstable_createResource(
|
||||
src =>
|
||||
new Promise(resolve => {
|
||||
const img = new Image();
|
||||
img.onload = () => resolve(src);
|
||||
img.src = src;
|
||||
})
|
||||
);
|
||||
|
||||
function Img({src, alt, ...rest}) {
|
||||
return <img src={ImageResource.read(src)} alt={alt} {...rest} />;
|
||||
}
|
||||
|
||||
function UserPicture({source}) {
|
||||
return (
|
||||
<Suspense maxDuration={1500} fallback={<img src={source} alt="poster" />}>
|
||||
<Img
|
||||
src={source}
|
||||
alt="profile picture"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: 'auto',
|
||||
borderRadius: '0.5rem',
|
||||
}}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
const UserRepositoriesResource = unstable_createResource(
|
||||
fetchUserRepositoriesListJSON
|
||||
);
|
||||
|
||||
function Repositories({id}) {
|
||||
const repos = UserRepositoriesResource.read(id);
|
||||
return (
|
||||
<ul
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridGap: '1rem',
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
}}>
|
||||
{repos.map(repo => <Repository key={repo.name} {...repo} />)}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
function Repository({description, name, url}) {
|
||||
return (
|
||||
<li
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridGap: '0.5rem',
|
||||
padding: '1rem',
|
||||
backgroundColor: 'var(--color-buttonBg)',
|
||||
border: '1px solid var(--color-buttonBorder)',
|
||||
borderRadius: '1rem',
|
||||
}}>
|
||||
<strong>
|
||||
<a href={url}>{name}</a>
|
||||
</strong>
|
||||
<div>{description}</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
90
fixtures/unstable-async/suspense/src/index.css
Normal file
@@ -0,0 +1,90 @@
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
--color-debuggerBg: #f7f7f7;
|
||||
--color-debuggerText: #333;
|
||||
--color-debuggerBorder: #e7e7e7;
|
||||
|
||||
--color-panelBg: #f7f7f7;
|
||||
--color-panelText: #333;
|
||||
|
||||
--color-pageTextDark: #000;
|
||||
--color-pageText: #333;
|
||||
--color-pageBg: #fff;
|
||||
|
||||
--color-buttonBg: #f7f7f7;
|
||||
--color-buttonBorder: #e7e7e7;
|
||||
|
||||
--pt: 8px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: calc(var(--pt)*4);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
color: var(--color-pageText);
|
||||
background-color: var(--color-pageBg);
|
||||
}
|
||||
|
||||
/* -------------------------------- */
|
||||
/* Debugger */
|
||||
/* -------------------------------- */
|
||||
|
||||
#debugger {
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
/* width: 100vw; */
|
||||
/* height: 100vh; */
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.🎛 {
|
||||
position: fixed;
|
||||
max-width: calc(var(--pt)*28);
|
||||
border-radius: var(--pt);
|
||||
padding: calc(var(--pt)*2);
|
||||
background-color: var(--color-debuggerBg);
|
||||
border: 1px solid var(--color-debuggerBorder);
|
||||
border-radius: 0.5rem;
|
||||
color: var(--color-debuggerText);
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.🕹 {
|
||||
background-color: var(--color-buttonBg);
|
||||
border: 1px solid var(--color-buttonBorder);
|
||||
border-radius: var(--pt);
|
||||
padding: 0;
|
||||
width: calc(var(--pt)*5);
|
||||
height: calc(var(--pt)*5);
|
||||
font-size: calc(var(--pt)*3);
|
||||
line-height: 1;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.🕹.👶 {
|
||||
width: calc(var(--pt)*3);
|
||||
height: calc(var(--pt)*3);
|
||||
font-size: calc(var(--pt)*2);
|
||||
}
|
||||
|
||||
.🕹.🐘 {
|
||||
width: auto;
|
||||
height: calc(var(--pt)*7);
|
||||
padding: var(--pt) calc(var(--pt)*2);
|
||||
}
|
||||
|
||||
.🕹:hover {
|
||||
background-color: white;
|
||||
top: -4px;
|
||||
left: -4px;
|
||||
box-shadow: 4px 4px 0 var(--color-buttonBorder);
|
||||
}
|
||||
|
||||
.🕹:active {
|
||||
box-shadow: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
275
fixtures/unstable-async/suspense/src/index.js
Normal file
@@ -0,0 +1,275 @@
|
||||
import React, {Fragment, PureComponent} from 'react';
|
||||
import {unstable_createRoot, render} from 'react-dom';
|
||||
import {unstable_trace as trace} from 'scheduler/tracing';
|
||||
import {
|
||||
setFakeRequestTime,
|
||||
setPaused,
|
||||
setPauseNewRequests,
|
||||
setProgressHandler,
|
||||
} from './api';
|
||||
import App from './components/App';
|
||||
import Draggable from 'react-draggable';
|
||||
import './index.css';
|
||||
|
||||
let handleReset;
|
||||
|
||||
class Shell extends PureComponent {
|
||||
state = {
|
||||
iteration: 0,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
handleReset = this.handleReset;
|
||||
}
|
||||
|
||||
handleReset = () =>
|
||||
this.setState(prevState => ({
|
||||
iteration: prevState.iteration + 1,
|
||||
}));
|
||||
|
||||
render() {
|
||||
return <App key={this.state.iteration} />;
|
||||
}
|
||||
}
|
||||
|
||||
class Debugger extends PureComponent {
|
||||
state = {
|
||||
iteration: 0,
|
||||
strategy: 'async',
|
||||
requestTime: 1,
|
||||
showDebugger: false,
|
||||
pauseNewRequests: false,
|
||||
waitTime: 0,
|
||||
requests: {},
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
setFakeRequestTime(this.state.requestTime * 1000);
|
||||
setProgressHandler(this.handleProgress);
|
||||
window.addEventListener('keydown', e => {
|
||||
if (e.key.toLowerCase() === '/') {
|
||||
this.setState(state => ({
|
||||
showDebugger: !state.showDebugger,
|
||||
}));
|
||||
} else if (e.key.toLowerCase() === 'p') {
|
||||
this.togglePauseRequests();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (prevState.requestTime !== this.state.requestTime) {
|
||||
setFakeRequestTime(this.state.requestTime * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
handleReset = () => {
|
||||
trace('Clear cache', performance.now(), () => {
|
||||
// TODO: this is not implemented.
|
||||
// cache.invalidate();
|
||||
this.setState(state => ({
|
||||
requests: {},
|
||||
}));
|
||||
handleReset();
|
||||
});
|
||||
};
|
||||
|
||||
handleProgress = (url, progress, isPaused) => {
|
||||
this.setState(state => ({
|
||||
requests: {
|
||||
...state.requests,
|
||||
[url]: {
|
||||
url,
|
||||
progress,
|
||||
isPaused,
|
||||
},
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
togglePauseRequests = () => {
|
||||
this.setState(
|
||||
prevState => {
|
||||
return {pauseNewRequests: !prevState.pauseNewRequests};
|
||||
},
|
||||
() => {
|
||||
setPauseNewRequests(this.state.pauseNewRequests);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.state.showDebugger) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Draggable cancel="input">
|
||||
<div
|
||||
className="🎛"
|
||||
style={{
|
||||
bottom: 20,
|
||||
right: 20,
|
||||
}}>
|
||||
<div>
|
||||
Latency: {this.state.requestTime} second{this.state.requestTime !==
|
||||
1
|
||||
? 's'
|
||||
: ''}{' '}
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="3"
|
||||
step="0.5"
|
||||
style={{width: '100%'}}
|
||||
value={this.state.requestTime}
|
||||
onChange={e => {
|
||||
e.stopPropagation();
|
||||
this.setState({requestTime: parseFloat(e.target.value)});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={this.state.pauseNewRequests}
|
||||
onChange={this.togglePauseRequests}
|
||||
/>
|
||||
Pause new requests
|
||||
</label>
|
||||
<br />
|
||||
<br />
|
||||
{Object.values(this.state.requests).filter(x => x.progress !== 100)
|
||||
.length > 0 ? (
|
||||
<Fragment>
|
||||
<div style={{marginBottom: 10}}>
|
||||
<b>Loading</b>
|
||||
</div>
|
||||
</Fragment>
|
||||
) : (
|
||||
<Fragment>
|
||||
<div style={{marginBottom: 10}}>
|
||||
<b>Loading</b>
|
||||
</div>
|
||||
<small style={{height: 20, display: 'block'}}>(None)</small>
|
||||
</Fragment>
|
||||
)}
|
||||
{Object.keys(this.state.requests)
|
||||
.reverse()
|
||||
.map(url => {
|
||||
const {progress, isPaused} = this.state.requests[url];
|
||||
if (progress === 100) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={url}
|
||||
style={{
|
||||
height: 20,
|
||||
width: '100%',
|
||||
position: 'relative',
|
||||
cursor: 'pointer',
|
||||
title: isPaused ? 'Resume' : 'Pause',
|
||||
}}
|
||||
onClick={e => {
|
||||
setPaused(url, !isPaused);
|
||||
}}>
|
||||
<div
|
||||
style={{
|
||||
height: '100%',
|
||||
width: progress + '%',
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
backgroundColor: isPaused ? '#fbfb0e' : '#61dafb',
|
||||
zIndex: -1,
|
||||
opacity: 0.8,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: 'monospace',
|
||||
fontWeight: 'bold',
|
||||
color: 'black',
|
||||
}}>
|
||||
{url}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{Object.values(this.state.requests).filter(x => x.progress === 100)
|
||||
.length > 0 ? (
|
||||
<Fragment>
|
||||
<br />
|
||||
<div style={{marginBottom: 10}}>
|
||||
<b>Cached</b>{' '}
|
||||
<button
|
||||
style={{
|
||||
height: 16,
|
||||
outline: 'none',
|
||||
border: 'none',
|
||||
background: 'none',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={this.handleReset}>
|
||||
🗑
|
||||
</button>
|
||||
</div>
|
||||
</Fragment>
|
||||
) : (
|
||||
<Fragment>
|
||||
<br />
|
||||
<div style={{marginBottom: 10}}>
|
||||
<b>Cached</b>
|
||||
</div>
|
||||
<small style={{height: 20, display: 'block'}}>(None)</small>
|
||||
</Fragment>
|
||||
)}
|
||||
{Object.keys(this.state.requests)
|
||||
.reverse()
|
||||
.map(url => {
|
||||
const {progress} = this.state.requests[url];
|
||||
if (progress !== 100) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
key={url}
|
||||
style={{
|
||||
height: 20,
|
||||
width: '100%',
|
||||
position: 'relative',
|
||||
}}>
|
||||
<div
|
||||
style={{
|
||||
height: '100%',
|
||||
width: progress + '%',
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
backgroundColor:
|
||||
progress !== 100 ? '#61dafb' : 'lightgreen',
|
||||
zIndex: -1,
|
||||
opacity: 0.8,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: 'monospace',
|
||||
fontWeight: 'bold',
|
||||
color: 'black',
|
||||
}}>
|
||||
{url}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Draggable>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
unstable_createRoot(document.getElementById('root')).render(<Shell />);
|
||||
|
||||
render(<Debugger />, document.getElementById('debugger'));
|
||||
7418
fixtures/unstable-async/suspense/yarn.lock
Normal file
21
fixtures/unstable-async/time-slicing/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
29
fixtures/unstable-async/time-slicing/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# CPU async rendering demo
|
||||
|
||||
## What is this fixture?
|
||||
|
||||
This is a demo application based on [Dan Abramov's](https://github.com/gaearon) recent [JSConf Iceland talk](https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html) about React.
|
||||
|
||||
It depends on a local build of React and enables us to easily test async "time slicing" APIs in a more "real world app" like context.
|
||||
|
||||
## Can I use this code in production?
|
||||
|
||||
No. The APIs being tested here are unstable and some of them have still not been released to NPM. For now, this fixture is only a test harness.
|
||||
|
||||
There are also known bugs and inefficiencies in master so **don't use this fixture for demonstration purposes either yet**. Until they are fixed, this fixture is **not** indicative of React async rendering performance.
|
||||
|
||||
## How do I run this fixture?
|
||||
|
||||
```shell
|
||||
# 1: Build react from source
|
||||
cd /path/to/react
|
||||
yarn
|
||||
yarn build dom-client,core,react-cache,scheduler --type=NODE
|
||||
|
||||
# 2: Install fixture dependencies
|
||||
cd fixtures/unstable-async/time-slicing/
|
||||
yarn
|
||||
|
||||
# 3: Run the app
|
||||
yarn start
|
||||
```
|
||||
19
fixtures/unstable-async/time-slicing/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "cpu-demo",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"glamor": "^2.20.40",
|
||||
"react-markdown": "^3.2.0",
|
||||
"react-scripts": "^1.1.4",
|
||||
"victory": "^0.25.6"
|
||||
},
|
||||
"scripts": {
|
||||
"prestart": "cp -r ../../../build/node_modules/* ./node_modules/",
|
||||
"prebuild": "cp -r ../../../build/node_modules/* ./node_modules/",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
BIN
fixtures/unstable-async/time-slicing/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
40
fixtures/unstable-async/time-slicing/public/index.html
Normal file
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
15
fixtures/unstable-async/time-slicing/public/manifest.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
126
fixtures/unstable-async/time-slicing/src/Charts.js
Normal file
@@ -0,0 +1,126 @@
|
||||
import React, {PureComponent} from 'react';
|
||||
import {
|
||||
VictoryArea,
|
||||
VictoryAxis,
|
||||
VictoryChart,
|
||||
VictoryBar,
|
||||
VictoryTheme,
|
||||
VictoryScatter,
|
||||
VictoryStack,
|
||||
} from 'victory';
|
||||
|
||||
const colors = ['#fff489', '#fa57c1', '#b166cc', '#7572ff', '#69a6f9'];
|
||||
|
||||
export default class Charts extends PureComponent {
|
||||
render() {
|
||||
const streamData = this.props.data;
|
||||
return (
|
||||
<div>
|
||||
<div style={{display: 'flex'}}>
|
||||
<VictoryChart
|
||||
theme={VictoryTheme.material}
|
||||
width={400}
|
||||
height={400}
|
||||
style={{
|
||||
parent: {
|
||||
backgroundColor: '#222',
|
||||
},
|
||||
}}>
|
||||
<VictoryAxis
|
||||
style={{
|
||||
axis: {stroke: 'white'},
|
||||
tickLabels: {fill: 'white'},
|
||||
}}
|
||||
/>
|
||||
<VictoryAxis
|
||||
style={{
|
||||
axis: {stroke: 'white'},
|
||||
tickLabels: {fill: 'white'},
|
||||
}}
|
||||
dependentAxis
|
||||
/>
|
||||
<VictoryScatter
|
||||
data={streamData[0]}
|
||||
size={6}
|
||||
style={{
|
||||
data: {
|
||||
fill: d => colors[d.x % 5],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</VictoryChart>
|
||||
|
||||
<VictoryChart
|
||||
theme={VictoryTheme.material}
|
||||
width={400}
|
||||
height={400}
|
||||
style={{
|
||||
parent: {
|
||||
backgroundColor: '#222',
|
||||
},
|
||||
}}
|
||||
domainPadding={[20, 20]}>
|
||||
<VictoryAxis
|
||||
style={{
|
||||
axis: {stroke: 'white'},
|
||||
tickLabels: {fill: 'white'},
|
||||
}}
|
||||
/>
|
||||
<VictoryAxis
|
||||
style={{
|
||||
axis: {stroke: 'white'},
|
||||
tickLabels: {fill: 'white'},
|
||||
}}
|
||||
dependentAxis
|
||||
/>
|
||||
<VictoryBar
|
||||
data={streamData[0]}
|
||||
style={{
|
||||
data: {
|
||||
fill: d => colors[d.x % 5],
|
||||
stroke: 'none',
|
||||
padding: 5,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</VictoryChart>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
position: 'relative',
|
||||
top: '-50px',
|
||||
}}>
|
||||
<VictoryChart
|
||||
theme={VictoryTheme.material}
|
||||
width={800}
|
||||
height={350}
|
||||
style={{
|
||||
parent: {
|
||||
backgroundColor: '#222',
|
||||
},
|
||||
}}>
|
||||
<VictoryAxis
|
||||
style={{
|
||||
axis: {stroke: 'white'},
|
||||
tickLabels: {fill: 'white'},
|
||||
}}
|
||||
/>
|
||||
<VictoryAxis
|
||||
style={{
|
||||
axis: {stroke: 'white'},
|
||||
tickLabels: {fill: 'white'},
|
||||
}}
|
||||
dependentAxis
|
||||
/>
|
||||
<VictoryStack>
|
||||
{streamData.map((data, i) => (
|
||||
<VictoryArea key={i} data={data} colorScale={colors} />
|
||||
))}
|
||||
</VictoryStack>
|
||||
</VictoryChart>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
105
fixtures/unstable-async/time-slicing/src/Clock.js
Normal file
@@ -0,0 +1,105 @@
|
||||
import React, {createRef, PureComponent} from 'react';
|
||||
|
||||
const SPEED = 0.003 / Math.PI;
|
||||
const FRAMES = 10;
|
||||
|
||||
export default class Clock extends PureComponent {
|
||||
faceRef = createRef();
|
||||
arcGroupRef = createRef();
|
||||
clockHandRef = createRef();
|
||||
frame = null;
|
||||
hitCounter = 0;
|
||||
rotation = 0;
|
||||
t0 = Date.now();
|
||||
arcs = [];
|
||||
|
||||
animate = () => {
|
||||
const now = Date.now();
|
||||
const td = now - this.t0;
|
||||
this.rotation = (this.rotation + SPEED * td) % (2 * Math.PI);
|
||||
this.t0 = now;
|
||||
|
||||
this.arcs.push({rotation: this.rotation, td});
|
||||
|
||||
let lx, ly, tx, ty;
|
||||
if (this.arcs.length > FRAMES) {
|
||||
this.arcs.forEach(({rotation, td}, i) => {
|
||||
lx = tx;
|
||||
ly = ty;
|
||||
const r = 145;
|
||||
tx = 155 + r * Math.cos(rotation);
|
||||
ty = 155 + r * Math.sin(rotation);
|
||||
const bigArc = SPEED * td < Math.PI ? '0' : '1';
|
||||
const path = `M${tx} ${ty}A${r} ${r} 0 ${bigArc} 0 ${lx} ${ly}L155 155`;
|
||||
const hue = 120 - Math.min(120, td / 4);
|
||||
const colour = `hsl(${hue}, 100%, ${60 - i * (30 / FRAMES)}%)`;
|
||||
if (i !== 0) {
|
||||
const arcEl = this.arcGroupRef.current.children[i - 1];
|
||||
arcEl.setAttribute('d', path);
|
||||
arcEl.setAttribute('fill', colour);
|
||||
}
|
||||
});
|
||||
this.clockHandRef.current.setAttribute('d', `M155 155L${tx} ${ty}`);
|
||||
this.arcs.shift();
|
||||
}
|
||||
|
||||
if (this.hitCounter > 0) {
|
||||
this.faceRef.current.setAttribute(
|
||||
'fill',
|
||||
`hsla(0, 0%, ${this.hitCounter}%, 0.95)`
|
||||
);
|
||||
this.hitCounter -= 1;
|
||||
} else {
|
||||
this.hitCounter = 0;
|
||||
this.faceRef.current.setAttribute('fill', 'hsla(0, 0%, 5%, 0.95)');
|
||||
}
|
||||
|
||||
this.frame = requestAnimationFrame(this.animate);
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.frame = requestAnimationFrame(this.animate);
|
||||
if (this.faceRef.current) {
|
||||
this.faceRef.current.addEventListener('click', this.handleClick);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
console.log('componentDidUpdate()', this.faceRef.current);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.faceRef.current.removeEventListener('click', this.handleClick);
|
||||
if (this.frame) {
|
||||
cancelAnimationFrame(this.frame);
|
||||
}
|
||||
}
|
||||
|
||||
handleClick = e => {
|
||||
e.stopPropagation();
|
||||
this.hitCounter = 50;
|
||||
};
|
||||
|
||||
render() {
|
||||
const paths = new Array(FRAMES);
|
||||
for (let i = 0; i < FRAMES; i++) {
|
||||
paths.push(<path className="arcHand" key={i} />);
|
||||
}
|
||||
return (
|
||||
<div className="stutterer">
|
||||
<svg height="310" width="310">
|
||||
<circle
|
||||
className="clockFace"
|
||||
onClick={this.handleClick}
|
||||
cx={155}
|
||||
cy={155}
|
||||
r={150}
|
||||
ref={this.faceRef}
|
||||
/>
|
||||
<g ref={this.arcGroupRef}>{paths}</g>
|
||||
<path className="clockHand" ref={this.clockHandRef} />
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
143
fixtures/unstable-async/time-slicing/src/index.css
Normal file
@@ -0,0 +1,143 @@
|
||||
html,
|
||||
body {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
user-select: none;
|
||||
font-family: Karla, Helvetica Neue, Helvetica, sans-serif;
|
||||
background: rgb(34, 34, 34);
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.VictoryContainer {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#root {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 960px;
|
||||
margin: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.rendering {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
zoom: 1.8;
|
||||
}
|
||||
|
||||
label {
|
||||
zoom: 1;
|
||||
margin-right: 50px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
label.selected {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
label:nth-child(1).selected {
|
||||
color: rgb(253, 25, 153);
|
||||
}
|
||||
|
||||
label:nth-child(2).selected {
|
||||
color: rgb(255, 240, 1);
|
||||
}
|
||||
|
||||
label:nth-child(3).selected {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.input {
|
||||
padding: 16px;
|
||||
font-size: 30px;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.input.sync {
|
||||
outline-color: rgba(253, 25, 153, 0.1);
|
||||
}
|
||||
.input.debounced {
|
||||
outline-color: rgba(255, 240, 1, 0.1);
|
||||
}
|
||||
.input.async {
|
||||
outline-color: rgba(97, 218, 251, 0.1);
|
||||
}
|
||||
|
||||
|
||||
label {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
label label {
|
||||
display: 'inline-block';
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.row {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
margin-top: 20px;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.column {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.demo {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.stutterer {
|
||||
transform: scale(1.5);
|
||||
height: 310px;
|
||||
width: 310px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: -256px;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 200px;
|
||||
}
|
||||
|
||||
.clockHand {
|
||||
stroke: white;
|
||||
stroke-width: 10px;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
.clockFace {
|
||||
stroke: white;
|
||||
stroke-width: 10px;
|
||||
}
|
||||
|
||||
.arcHand {
|
||||
}
|
||||
|
||||
.innerLine {
|
||||
border-radius: 6px;
|
||||
position: absolute;
|
||||
height: 149px;
|
||||
left: 47.5%;
|
||||
top: 0%;
|
||||
width: 5%;
|
||||
background-color: red;
|
||||
transform-origin: bottom center;
|
||||
}
|
||||