I inline it into performAsyncWork instead.
Code that was only relevant to the async callback had leaked into the
performWork call which is an indication that this was a bad abstraction
and therefore the wrong place to DRY.
By inlining I also discovered that minExpirationTime is actually irrelevant
in the yieldy case so we can clean that up.
* Isolate ReactUpdates-test cases
This ensures their behavior is consistent when run in isolation, and that they actually test the cases they're describing.
* Add coverage for cases where we reset nestedUpdateCounter
These cases explicitly verify that we reset the counter in right places.
* Add a mutually recursive test case
* Add test coverage for useLayoutEffect loop
Adds a feature flag `enableNewScheduler` that toggles between two
implementations of ReactFiberScheduler. This will let us land changes in
master while preserving the ability to quickly rollback.
Ideally this will be a short-lived fork. Once we've tested the new
scheduler for a week or so without issues, we will get rid of it. Until
then, we'll need to maintain two parallel implementations and run tests
against both of them. We rarely land changes to ReactFiberScheduler, so
I don't expect this will be a huge burden.
This commit does not implement anything new. The flag is still off and
tests run against the existing implementation.
Use `yarn test-new-scheduler` to run tests against the new one.
MDN has a list of methods for obtaining the window reference of an
iframe:
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#Syntax
fix(react-dom): check if iframe belongs to the same origin
Accessing the contentDocument of a HTMLIframeElement can cause the browser
to throw, e.g. if it has a cross-origin src attribute.
Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
```javascript
try {
$0.contentDocument.defaultView
} catch (err) {
console.log('err', err)
}
> Blocked a frame with origin X from accessing a frame with origin Y. Protocols, domains, and ports must match.
> err – TypeError: null is not an object (evaluating '$0.contentDocument.defaultView')
```
A safety way is to access one of the cross origin properties: Window or Location
Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
```javascript
try {
$0.contentWindow.location.href
} catch (err) {
console.log('err', err)
}
> err – SecurityError: Blocked a frame with origin "http://localhost:3001" from accessing a cross-origin frame. Protocols, domains, and ports must match.
```
https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
* Transform invariant to custom error type
This transforms calls to the invariant module:
```js
invariant(condition, 'A %s message that contains %s', adj, noun);
```
Into throw statements:
```js
if (!condition) {
if (__DEV__) {
throw ReactError(`A ${adj} message that contains ${noun}`);
} else {
throw ReactErrorProd(ERR_CODE, adj, noun);
}
}
```
The only thing ReactError does is return an error whose name is set
to "Invariant Violation" to match the existing behavior.
ReactErrorProd is a special version used in production that throws
a minified error code, with a link to see to expanded form. This
replaces the reactProdInvariant module.
As a next step, I would like to replace our use of the invariant module
for user facing errors by transforming normal Error constructors to
ReactError and ReactErrorProd. (We can continue using invariant for
internal React errors that are meant to be unreachable, which was the
original purpose of invariant.)
* Use numbers instead of strings for error codes
* Use arguments instead of an array
I wasn't sure about this part so I asked Sebastian, and his rationale
was that using arguments will make ReactErrorProd slightly slower, but
using an array will likely make all the functions that throw slightly
slower to compile, so it's hard to say which way is better. But since
ReactErrorProd is in an error path, and fewer bytes is generally better,
no array is good.
* Casing nit
* Add more info to invalid hook call error message
* Update other renderers + change call to action
* Update related tests for new hooks error message
* Fix lint errors
* Eager bailout optimization should always compare to latest reducer
* queue.eagerReducer -> queue.lastRenderedReducer
This name is a bit more descriptive.
* Add test case that uses preceding render phase update
* Throw away old shallow renderer state on type change
This worked in function components but was broken for classes. It incorrectly retained the old instance even if the type was different.
* Remove _previousComponentIdentity
We only needed this because we didn't correctly reset based on type. Now we do so this can go away.
* Use _reset when unmounting
* Use arbitrary componentIdentity
There was no particular reason it was set to element.type. We just wanted to check if something is a render phase update.
* Support Hook state updates in shallow renderer
* Support React.memo in ReactShallowRenderer
ReactShallowRenderer uses element.type frequently, but with React.memo
elements the actual type is element.type.type. This updates
ReactShallowRenderer so it uses the correct element type for Memo
components and also validates the inner props for the wrapped
components.
* Allow Rect.memo to prevent re-renders
* Support memo(forwardRef())
* Dont call memo comparison function on initial render
* Fix test
* Small tweaks
* Set 'size' attribute to select tag if it occurs before appending options
* Add comment about why size is assigned on select create. Tests
I added some more clarification for why size must be set on select
element creation:
- In the source code
- In the DOM test fixture
- In a unit test
* Use let, not const in select tag stub assignment
* Hydration Fixture: Only load ReactDOMServer if it exists
Fixes an issue where the hydration fixture would try to load in
ReactDOMServer below version 14. In version 13, string markup methods
exist on the React namespace.
* DOM Fixtures: Use class component for App.js
This was breaking React 0.13.0.
* Hydration Fixture: better findDOMNode compatibility
This commit fixes an issue where the Hydration DOM fixture was
unusable in React 0.13.0 or lower because of newer API usage.
It fixes that by avoiding the use of refs to get the textarea
reference in the code editor component, using various versions of
findDOMNode as required.
* Hydration Fixture: Do not show dropdown for single-line errors
If an error showed for the hydration fixture, a detail element was
used even if no additional lines could display. In that case, this
commit changes the component such that it returns a div.
* Deeper React version support for hydration fixture
This commit adds support for versions 0.4.0 of React and higher for
the hydration fixture.
The DOM test fixtures themselves do not support down to React 0.4.0,
which would be exhaustive. Instead, the Hydration fixture can pick a
version to use for its own purposes. By default, this is the version
of React used by the fixtures.
In the process of doing this, I had to make some updates to the
renderer.html document associated with the hydration fixture, and I've
added some comments to better document the history of API changes.
* Prevent javascript protocol URLs
* Just warn when disableJavaScriptURLs is false
This avoids a breaking change.
* Allow framesets
* Allow <html> to be used in integration tests
Full document renders requires server rendering so the client path
just uses the hydration path in this case to simplify writing these tests.
* Detect leading and intermediate characters and test mixed case
These are considered valid javascript urls by browser so they must be
included in the filter.
This is an exact match according to the spec but maybe we should include
a super set to be safer?
* Test updates to ensure we have coverage there too
* Fix toString invocation and Flow types
Right now we invoke toString twice when we hydrate (three times
with the flag off). Ideally we should only do it once even in this case
but the code structure doesn't really allow for that right now.
* s/itRejects/itRejectsRendering
* Dedupe warning and add the unsafe URL to the warning message
* Add test that fails if g is added to the sanitizer
This only affects the prod version since the warning is deduped anyway.
* Fix prod test
* Split props changing from permanent fallback state
These will need different logic. In this commit, no logic has changed,
only moved.
* Delete terminal fallback content in first pass
If the dehydrated suspense boundary's fallback content is terminal there
is nothing to show. We need to get actual content on the screen soon.
If we deprioritize that work to offscreen, then the timeout heuristics will
be wrong.
Therefore, if we have no current and we're already at terminal fallback
state we'll immediately schedule a deletion and upgrade to real suspense.
* Show failing case when there is another wrapper boundary
* Revert "Delete terminal fallback content in first pass"
This reverts commit ad67ba8928.
* Use the new approach of leaving work at normal pri to replace fallback
* Add command to run tests in persistent mode
* Convert Suspense fuzz tester to use noop renderer
So we can run it in persistent mode, too.
* Don't mutate stateNode in appendAllChildren
We can't mutate the stateNode in appendAllChildren because the children
could be current.
This is a bit weird because now the child that we append is different
from the one on the fiber stateNode. I think this makes conceptual
sense, but I suspect this likely breaks an assumption in Fabric.
With this approach, we no longer need to clone to unhide the children,
so I removed those host config methods.
Fixes bug surfaced by fuzz tester. (The test case that failed was the
one that's already hard coded.)
* In persistent mode, disable test that reads a ref
Refs behave differently in persistent mode. I added a TODO to write
a persistent mode version of this test.
* Run persistent mode tests in CI
* test-persistent should skip files without noop
If a file doesn't reference react-noop-renderer, we shouldn't bother
running it in persistent mode, since the results will be identical to
the normal test run.
* Remove module constructor from placeholder tests
We don't need this now that we have the ability to run any test file in
either mutation or persistent mode.
* Revert "test-persistent should skip files without noop"
Seb objected to adding shelljs as a dep and I'm too lazy to worry about
Windows support so whatever I'll just revert this.
* Delete duplicate file
* Convert ReactSuspensePlaceholder tests to use noop
Instead of the test renderer, since test renderer does not support
running in persistent mode.
* Run Placeholder tests in persistent mode, too
* Fix Flow and lint
* Hidden text instances should have correct host context
Adds a test for a subtle edge case that only occurs in persistent mode.
* createHiddenTextInstance -> cloneHiddenTextInstance
This sidesteps the problem where createHiddenTextInstance needs access
to the host context.
* A clearer message for props destructuring where applicable
* Add line number to the "move function" message
* Add a hint for how to fix callbacks from props
* Simplify code and harden tests
* Collect all dependency references for better warnings
* Suggest updater or reducer where appropriate