Commit Graph
94 Commits
Author SHA1 Message Date
Sebastian Markbåge 9fcaf88d58 Remove rootContainerInstance from unnecessary places (#25024)
We only really use this for the create APIs since the DOM requires it.

We could probably use the Host Context for this instead since they're
updated at the same time and the namespace is related to this concept.
2022-08-01 23:30:04 -04:00
Andrew Clark 229c86af07 Revert "Land enableClientRenderFallbackOnTextMismatch" (#24738)
This reverts commit 327e4a1f96.

Turns out we hadn't rolled this out internally yet — I mistook
enableClientRenderFallbackOnHydrationMismatch for
said enableClientRenderFallbackOnTextMismatch. Need to revert
until we finish rolling out the change.
2022-06-16 11:38:37 -04:00
Andrew Clark 327e4a1f96 [Follow-up] Land enableClientRenderFallbackOnTextMismatch
This was meant to land in the previous commit; forgot to stage the
changes when I was rebasing.
2022-06-13 12:01:44 -04:00
Sebastian Silbermann 82c64e1a49 Match Preact behavior for boolean props on custom elements (#24541)
* Log unexpected warnings when testing with ReactDOMServerIntegrationTestUtils

* Add test

Following https://github.com/facebook/react/issues/9230#issuecomment-322007671 except that `foo={true}` renders an empty string.
See https://github.com/facebook/react/issues/9230#issuecomment-1123464720 for rationale.

* Match Preact behavior for boolean props on custom elements

* Poke CircleCI
2022-05-20 18:10:43 +01:00
dan fc47cb1b61 Fix suppressHydrationWarning not working in production (#24271) 2022-04-04 16:23:58 +01:00
Sebastian Markbåge 1c44437355 Fix createRoot container signature (#24110)
The internal Container type represents the types of containers that React
can support in its internals that deal with containers.

This didn't include DocumentFragment which we support specifically for
rendering into shadow roots.

However, not all types makes sense to pass into the createRoot API.

One of those is comment nodes that is deprecated and we don't really fully
support. It really only exists for FB legacy.

For createRoot it doesn't make sense to pass a Document since that will try
to empty the document which removes the HTML tag which doesn't work.
Documents can only be passed to hydrateRoot.

Conversely I'm not sure we actually support hydrating a shadow root properly
so I excluded DocumentFragment from hydrateRoot.
2022-03-16 20:06:00 -04:00
salazarm ef23a9ee81 Flag for text hydration mismatch (#24107)
* flag for text hydration mismatch

* rm unused import
2022-03-16 10:12:59 -04:00
Andrew ClarkandMarcel Laverdet f468816ef1 Fix false positive hydration warnings (#23364)
* Failing test for react#23331

* Don't warn on hydration mismatch if suspended

When something suspends during hydration, we continue rendering the
siblings to warm up the cache and fire off any lazy network requests.
However, if there are any mismatches while rendering the siblings, it's
likely a false positive caused by the earlier suspended component. So
we should suppress any hydration warnings until the tree no
longer suspends.

Fixes #23332

Co-authored-by: Marcel Laverdet <marcel@laverdet.com>
2022-02-25 18:10:10 -05:00
Andrew Clark 52c393b5d2 Revert to client render on text mismatch (#23354)
* Refactor warnForTextDifference

We're going to fork the behavior of this function between concurrent
roots and legacy roots.

The legacy behavior is to warn in dev when the text mismatches during
hydration. In concurrent roots, we'll log a recoverable error and revert
to client rendering. That means this is no longer a development-only
function — it affects the prod behavior, too.

I haven't changed any behavior in this commit. I only rearranged the
code slightly so that the dev environment check is inside the body
instead of around the function call. I also threaded through an
isConcurrentMode argument.

* Revert to client render on text content mismatch

Expands the behavior of enableClientRenderFallbackOnHydrationMismatch to
check text content, too.

If the text is different from what was rendered on the server, we will
recover the UI by falling back to client rendering, up to the nearest
Suspense boundary.
2022-02-24 00:23:56 -05:00
Joey Arhar 24dd07bd26 Add custom element property support behind a flag (#22184)
* custom element props

* custom element events

* use function type for on*

* tests, htmlFor

* className

* fix ReactDOMComponent-test

* started on adding feature flag

* added feature flag to all feature flag files

* everything passes

* tried to fix getPropertyInfo

* used @gate and __experimental__

* remove flag gating for test which already passes

* fix onClick test

* add __EXPERIMENTAL__ to www flags, rename eventProxy

* Add innerText and textContent to reservedProps

* Emit warning when assigning to read only properties in client

* Revert "Emit warning when assigning to read only properties in client"

This reverts commit 1a093e584c.

* Emit warning when assigning to read only properties during hydration

* yarn prettier-all

* Gate hydration warning test on flag

* Fix gating in hydration warning test

* Fix assignment to boolean properties

* Replace _listeners with random suffix matching

* Improve gating for hydration warning test

* Add outerText and outerHTML to server warning properties

* remove nameLower logic

* fix capture event listener test

* Add coverage for changing custom event listeners

* yarn prettier-all

* yarn lint --fix

* replace getCustomElementEventHandlersFromNode with getFiberCurrentPropsFromNode

* Remove previous value when adding event listener

* flow, lint, prettier

* Add dispatchEvent to make sure nothing crashes

* Add state change to reserved attribute tests

* Add missing feature flag test gate

* Reimplement SSR changes in ReactDOMServerFormatConfig

* Test hydration for objects and functions

* add missing test gate

* remove extraneous comment

* Add attribute->property test
2021-12-08 15:11:42 +00:00
Andrew Clark 75f3ddebfa Remove experimental useOpaqueIdentifier API (#22672)
useId is the updated version of this API.
2021-11-01 15:02:39 -07:00
Justin Grant c88fb49d37 Improve DEV errors if string coercion throws (Temporal.*, Symbol, etc.) (#22064)
* Revise ESLint rules for string coercion

Currently, react uses `'' + value` to coerce mixed values to strings.
This code will throw for Temporal objects or symbols.

To make string-coercion safer and to improve user-facing error messages,
This commit adds a new ESLint rule called `safe-string-coercion`.

This rule has two modes: a production mode and a non-production mode.
* If the `isProductionUserAppCode` option is true, then `'' + value`
  coercions are allowed (because they're faster, although they may
  throw) and `String(value)` coercions are disallowed. Exception:
  when building error messages or running DEV-only code in prod
  files, `String()` should be used because it won't throw.
* If the `isProductionUserAppCode` option is false, then `'' + value`
  coercions are disallowed (because they may throw, and in non-prod
  code it's not worth the risk) and `String(value)` are allowed.

Production mode is used for all files which will be bundled with
developers' userland apps. Non-prod mode is used for all other React
code: tests, DEV blocks, devtools extension, etc.

In production mode, in addiiton to flagging `String(value)` calls,
the rule will also flag `'' + value` or `value + ''` coercions that may
throw. The rule is smart enough to silence itself in the following
"will never throw" cases:
* When the coercion is wrapped in a `typeof` test that restricts to safe
  (non-symbol, non-object) types. Example:
    if (typeof value === 'string' || typeof value === 'number') {
      thisWontReport('' + value);
    }
* When what's being coerced is a unary function result, because unary
   functions never return an object or a symbol.
* When the coerced value is a commonly-used numeric identifier:
  `i`, `idx`, or `lineNumber`.
* When the statement immeidately before the coercion is a DEV-only
  call to a function from shared/CheckStringCoercion.js. This call is a
  no-op in production, but in DEV it will show a console error
  explaining the problem, then will throw right after a long explanatory
  code comment so that debugger users will have an idea what's going on.
  The check function call must be in the following format:
    if (__DEV__) {
      checkXxxxxStringCoercion(value);
    };

Manually disabling the rule is usually not necessary because almost all
prod use of the `'' + value` pattern falls into one of the categories
above. But in the rare cases where the rule isn't smart enough to detect
safe usage (e.g. when a coercion is inside a nested ternary operator),
manually disabling the rule will be needed.

The rule should also be manually disabled in prod error handling code
where `String(value)` should be used for coercions, because it'd be
bad to throw while building an error message or stack trace!

The prod and non-prod modes have differentiated error messages to
explain how to do a proper coercion in that mode.

If a production check call is needed but is missing or incorrect
(e.g. not in a DEV block or not immediately before the coercion), then
a context-sensitive error message will be reported so that developers
can figure out what's wrong and how to fix the problem.

Because string coercions are now handled by the `safe-string-coercion`
rule, the `no-primitive-constructor` rule no longer flags `String()`
usage. It still flags `new String(value)` because that usage is almost
always a bug.

* Add DEV-only string coercion check functions

This commit adds DEV-only functions to check whether coercing
values to strings using the `'' + value` pattern will throw. If it will
throw, these functions will:
1. Display a console error with a friendly error message describing
   the problem and the developer can fix it.
2. Perform the coercion, which will throw. Right before the line where
   the throwing happens, there's a long code comment that will help
   debugger users (or others looking at the exception call stack) figure
   out what happened and how to fix the problem.

One of these check functions should be called before all string coercion
of user-provided values, except when the the coercion is guaranteed not
to throw, e.g.
* if inside a typeof check like `if (typeof value === 'string')`
* if coercing the result of a unary function like `+value` or `value++`
* if coercing a variable named in a whitelist of numeric identifiers:
  `i`, `idx`, or `lineNumber`.

The new `safe-string-coercion` internal ESLint rule enforces that
these check functions are called when they are required.

Only use these check functions in production code that will be bundled
with user apps.  For non-prod code (and for production error-handling
code), use `String(value)` instead which may be a little slower but will
never throw.

* Add failing tests for string coercion

Added failing tests to verify:
* That input, select, and textarea elements with value and defaultValue
  set to Temporal-like objects which will throw when coerced to string
  using the `'' + value` pattern.
* That text elements will throw for Temporal-like objects
* That dangerouslySetInnerHTML will *not* throw for Temporal-like
  objects because this value is not cast to a string before passing to
  the DOM.
* That keys that are Temporal-like objects will throw

All tests above validate the friendly error messages thrown.

* Use `String(value)` for coercion in non-prod files

This commit switches non-production code from `'' + value` (which
throws for Temporal objects and symbols) to instead use `String(value)`
which won't throw for these or other future plus-phobic types.

"Non-produciton code" includes anything not bundled into user apps:
* Tests and test utilities. Note that I didn't change legacy React
  test fixtures because I assumed it was good for those files to
  act just like old React, including coercion behavior.
* Build scripts
* Dev tools package - In addition to switching to `String`, I also
  removed special-case code for coercing symbols which is now
  unnecessary.

* Add DEV-only string coercion checks to prod files

This commit adds DEV-only function calls to to check if string coercion
using `'' + value` will throw, which it will if the value is a Temporal
object or a symbol because those types can't be added with `+`.

If it will throw, then in DEV these checks will show a console error
to help the user undertsand what went wrong and how to fix the
problem. After emitting the console error, the check functions will
retry the coercion which will throw with a call stack that's easy (or
at least easier!) to troubleshoot because the exception happens right
after a long comment explaining the issue. So whether the user is in
a debugger, looking at the browser console, or viewing the in-browser
DEV call stack, it should be easy to understand and fix the problem.

In most cases, the safe-string-coercion ESLint rule is smart enough to
detect when a coercion is safe. But in rare cases (e.g. when a coercion
is inside a ternary) this rule will have to be manually disabled.

This commit also switches error-handling code to use `String(value)`
for coercion, because it's bad to crash when you're trying to build
an error message or a call stack!  Because `String()` is usually
disallowed by the `safe-string-coercion` ESLint rule in production
code, the rule must be disabled when `String()` is used.
2021-09-27 10:05:07 -07:00
Sebastian Markbåge 5890e0e692 Remove data-reactroot from server rendering and hydration heuristic (#20996)
This was used to implicitly hydrate if you call ReactDOM.render.

We've had a warning to explicitly use ReactDOM.hydrate(...) instead of
ReactDOM.render(...). We can now remove this from the generated markup.
(And avoid adding it to Fizz.)

This is a little strange to do now since we're trying hard to make the
root API work the same.

But if we kept it, we'd need to keep it in the generated output which adds
unnecessary bytes. It also risks people relying on it, in the Fizz world
where as this is an opportunity to create that clean state.

We could possibly only keep it in the old server rendering APIs but then
that creates an implicit dependency between which server API and which
client API that you use. Currently you can really mix and match either way.
2021-05-13 10:18:21 -07:00
Sebastian Markbåge 8ea11306ad Allow complex objects as children of option only if value is provided (#21431) 2021-05-05 08:40:54 -07:00
Behnam Mohammadi 2c9fef32db Remove redundant initial of hasOwnProperty (#21134)
* remove redundant initial of hasOwnProperty

* remove redundant initial of hasOwnProperty part 2

* remove redundant initial of hasOwnProperty part 3
2021-04-01 09:05:10 -07:00
Sebastian Markbåge 8e76371241 Move not shared to client (#21135) 2021-03-29 19:35:34 -07:00
Sebastian Markbåge fb8c1917e9 Don't use nested objects to "namespace" namespace constants (#21073) 2021-03-24 09:58:23 -07:00
Dan Abramov 993ca533b4 Enable eager listeners statically (#19983) 2020-10-08 19:32:28 +01:00
Shivam Sandbhor 4ead6b5305 Treat <time> tag as a normal HTML tag. (#19951)
<time> tag has been supported by Chrome since Chrome 62.0.
Remove workarounds which were in place to avoid friction with
versions before Chrome 62.

Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
2020-10-06 03:15:32 +01:00
Dan Abramov a08ae9f147 Listen to onScroll during hydration (#19803) 2020-09-10 11:00:02 +01:00
Dan Abramovandkoba04 848bb2426e Attach Listeners Eagerly to Roots and Portal Containers (#19659)
* Failing test for #19608

* Attach Listeners Eagerly to Roots and Portal Containers

* Forbid createEventHandle with custom events

We can't support this without adding more complexity. It's not clear that this is even desirable, as none of our existing use cases need custom events. This API primarily exists as a deprecation strategy for Flare, so I don't think it is important to expand its support beyond what Flare replacement code currently needs. We can later revisit it with a better understanding of the eager/lazy tradeoff but for now let's remove the inconsistency.

* Reduce risk by changing condition only under the flag

Co-authored-by: koba04 <koba0004@gmail.com>
2020-08-24 16:50:20 +01:00
Jack WorksandDan Abramov 1287670191 Fix: React cannot render in ShadowRoot (#15894)
* fix: render in shadow root

* fix: flow typing

* Remove types and turn invariant into warning

Co-authored-by: Dan Abramov <dan.abramov@me.com>
2020-08-17 15:47:49 +01:00
Dominic Gannaway b61174fb7b Remove the deprecated React Flare event system (#19520) 2020-08-05 15:13:29 +01:00
Dan Abramov 22d16cc15d Remove event constants (#19276)
* Remove opaque event type

* Rename type and merge files

* Use literals where we have Flow coverage

* Flowify some plugins

* Remove constants except necessary ones
2020-07-30 21:52:37 +01:00
Dominic Gannaway ef22aecfc5 Add invalid/close events to <dialog> element (#19439)
Support dialog

Fix
2020-07-24 20:36:46 +01:00
Dan Abramov 125d1a19a2 Move event things around (#19433)
* Put all synthetic events in one file

* Inline other helpers

* Remove Modern from filenames
2020-07-22 22:12:15 +01:00
Dominic GannawayandDan Abramov 356c17108f Remove capturePhaseEvents and separate events by bubbling (#19278)
* Remove capturePhaseEvents and separate events by bubbling

WIP

Refine all logic

Revise types

Fix

Fix conflicts

Fix flags

Fix

Fix

Fix test

Revise

Cleanup

Refine

Deal with replaying

Fix

* Add non delegated listeners unconditionally

* Add media events

* Fix a previously ignored test

* Address feedback

Co-authored-by: Dan Abramov <dan.abramov@me.com>
2020-07-21 22:40:50 +01:00
Dominic Gannaway 61dd00db24 Extract some of the tidy up changes from 19278 (#19315) 2020-07-10 22:33:42 +01:00
Dominic Gannaway f5ea39c182 Modern Event System: make on*Capture events use capture phase (#19221) 2020-07-08 17:10:06 +01:00
Dominic Gannaway 26071abbe1 Refine event registration + event signatures (#19244)
* Refine event registration + event signatures

* Address feedback
2020-07-06 17:42:01 +01:00
Dan Abramov b6df4417c7 Remove event config (#19237) 2020-07-02 00:26:29 +01:00
Dan Abramov 991c3b8193 Make event config an implementation detail of each plugin (#19236)
* Merge two variables with same purpose

* Replace dispatchConfig with _reactName on event object
2020-07-02 00:03:17 +01:00
Dan Abramov 9e7f5c02ca Make event plugin injection statically resolvable (#19234)
* Make plugins ESM

* Resolve extractEvents statically

* Resolve eventTypes statically

* Fix flow types and inconsistent naming

* Move injection into the plugin system itself

* Fix Flow
2020-07-01 22:11:05 +01:00
Dan Abramov 75b6921d64 Remove dead code from modern event system (#19233)
* Remove dead code from modern event system

* Remove SSR dependency on EventPluginRegistry
2020-07-01 21:04:14 +01:00
Dan Abramov 9fba65efa5 Enable modern event system and delete dead code (#19230) 2020-07-01 17:43:34 +01:00
Dan Abramov e3f4eb7272 Fork legacy-events folder into react-dom and react-native (#19228) 2020-07-01 16:37:13 +01:00
Vetrivel Chinnasamy b621dab5d4 make link https (#19147) 2020-06-30 12:43:52 +01:00
Rick Hanlonandshengxinjing 655affa302 Clarifications
Co-authored-by: shengxinjing <316783812@qq.com>
2020-06-12 21:09:29 -04:00
Dan Abramov b41beb1a35 Revert "Fix mistyped script arbitrary code execution vulnerability (#18660)" (#19018)
This reverts commit e5cc1462b3.
2020-05-27 17:37:27 +01:00
Dominic Gannaway 823dc581fe Modern Event System: fix EnterLeave plugin logic (#18830) 2020-05-05 22:10:07 +01:00
Dominic Gannaway 88d0be6da5 Refactor ElementListenerMap (#18766) 2020-04-28 21:53:51 +01:00
Dominic Gannaway 4e3545fd6f ReactDOMEventListener: clean up module (#18713) 2020-04-23 20:19:28 +01:00
Nick ReileyandBrian Vaughn e5cc1462b3 Fix mistyped script arbitrary code execution vulnerability (#18660)
* add test to trustedTypes-test.internal.js

* fix mistyped script arbitrary code execution

* Removed redundant .toLowerCase() call

Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
2020-04-21 12:10:25 -07:00
Sebastian Silbermann ffb6c6c07b fix: skip dangerouslySetInnerHtml hydration warning if it's undefined (#18676)
* test: Add failing case for dangerouslySetInnerHtml=undefined

* fix: skip dangerouslySetInnerHtml warning if it's undefined

* test: add similar test that should trigger the warning

* chore: Remove redundant nullish check

* Poke yarn_test_www_variant which timed out

* test: Add smaller test for innerHTML=string to innerHTML=undefined
2020-04-20 18:46:55 +01:00
Dominic Gannaway 1078029af6 Revert "Revert focus event PRs (#18655)" (#18671)
This reverts commit 58c895e59c.
2020-04-20 16:00:33 +01:00
Dominic Gannaway 58c895e59c Revert focus event PRs (#18655)
* Revert "Further cleanup to before/after blur (#18649)"

This reverts commit e2ccbf0358.

* Revert "Unify Flare FocusWithin responder with useFocusWithin (#18636)"

This reverts commit f24a9e7098.
2020-04-17 16:27:19 +01:00
Dominic Gannaway e2ccbf0358 Further cleanup to before/after blur (#18649) 2020-04-17 11:52:29 +01:00
BetaSu 1d7bd52688 remove unnecessary variable comparation (#18598)
Since it will continue when the props are equal in line 767, there is no need to compare whether they are not equal.
2020-04-14 14:53:47 +01:00
Luna RuanandAndrew Clark 3278d24218 Add useOpaqueIdentifier Hook (#17322)
* Add useOpaqueIdentifier Hook

We currently use unique IDs in a lot of places. Examples are:
  * `<label for="ID">`
  * `aria-labelledby`

This can cause some issues:
  1. If we server side render and then hydrate, this could cause an
     hydration ID mismatch
  2. If we server side render one part of the page and client side
     render another part of the page, the ID for one part could be
     different than the ID for another part even though they are
     supposed to be the same
  3. If we conditionally render something with an ID ,  this might also
     cause an ID mismatch because the ID will be different on other
     parts of the page

This PR creates a new hook `useUniqueId` that generates a different
unique ID based on whether the hook was called on the server or client.
If the hook is called during hydration, it generates an opaque object
that will rerender the hook so that the IDs match.

Co-authored-by: Andrew Clark <git@andrewclark.io>
2020-04-06 17:17:27 -07:00
Dominic Gannaway dc3c6c9565 ReactDOM.useEvent: revert and add guard for null stateNode (#18441) 2020-04-01 12:45:26 +01:00