Compare commits

...

53 Commits

Author SHA1 Message Date
Brian Vaughn
bec2ddaf15 Update bundle sizes for 16.5.2 release 2018-09-18 11:30:50 -07:00
Brian Vaughn
789e714bd7 Update error codes for 16.5.2 release 2018-09-18 11:30:50 -07:00
Brian Vaughn
4269fafb0a Updating package versions for release 16.5.2 2018-09-18 11:24:33 -07:00
Brian Vaughn
4380f9ba17 Revert "Updating package versions for release 16.6.0-alpha.0"
This reverts commit 351c9015c8.
2018-09-18 11:00:13 -07:00
Brian Vaughn
72fad84e76 Revert "Updating dependencies for react-noop-renderer"
This reverts commit 489614c4fc.
2018-09-18 11:00:09 -07:00
Brian Vaughn
39f93f7987 Revert "Update error codes for 16.6.0-alpha.0 release"
This reverts commit 21ceb19ea0.
2018-09-18 11:00:04 -07:00
Brian Vaughn
c3fad5acf8 Revert "Update bundle sizes for 16.6.0-alpha.0 release"
This reverts commit 42d12317a7.
2018-09-18 10:59:57 -07:00
Heaven
dd91205617 Kepp calling peformWork consistent (#13596) 2018-09-18 07:48:18 -07:00
Brian Vaughn
42d12317a7 Update bundle sizes for 16.6.0-alpha.0 release 2018-09-17 15:05:46 -07:00
Brian Vaughn
21ceb19ea0 Update error codes for 16.6.0-alpha.0 release 2018-09-17 15:05:46 -07:00
Brian Vaughn
489614c4fc Updating dependencies for react-noop-renderer 2018-09-17 14:59:57 -07:00
Brian Vaughn
351c9015c8 Updating package versions for release 16.6.0-alpha.0 2018-09-17 14:59:57 -07:00
Dan Abramov
a210b5b440 Revert "Do not bind topLevelType to dispatch" (#13674)
* Revert "Do not bind topLevelType to dispatch (#13618)"

This reverts commit 0c9c591bfb.
2018-09-17 18:43:16 +01:00
Sam Kvale
2f54a0467b docs(changelog): Fix misspelling (#13663)
dangerouslySetInnerHTML was misspelled dangerousSetInnerHTML
2018-09-15 08:16:58 -07:00
Alexey Raspopov
1d8a75fef0 remove flow typings from Schedule.js (#13662) 2018-09-15 03:55:23 +01:00
Nathan Hunzaker
d92114b98e Resubmit: Fix updateWrapper causing re-render textarea, even though their data (#13643)
* fix updateWrapper causing re-render textarea, even though their data has not changed

* fix updateWrapper causing re-render textarea, even though their data, prettier-all

* minor changes to updateWrapper, add test
2018-09-14 16:09:07 -07:00
Nathan Hunzaker
0c9c591bfb Do not bind topLevelType to dispatch (#13618)
* Do not bind topLevelType to dispatch

A previous change made it such that all top level event types
correspond to their associated native event string values. This commit
eliminates the .bind attached to dispatch and fixes a related flow
type.

* Add note about why casting event.type to a topLevelType is safe

* Move interactiveUpdates comment to point of assignment
2018-09-14 16:08:37 -07:00
Andrew Clark
9f819a5ea9 [schedule] Refactor Schedule, remove React-isms (#13582)
* Refactor Schedule, remove React-isms

Once the API stabilizes, we will move Schedule this into a separate
repo. To promote adoption, especially by projects outside the React
ecosystem, we'll remove all React-isms from the source and keep it as
simple as possible:

- No build step.
- No static types.
- Everything is in a single file.

If we end up needing to support multiple targets, like CommonJS and ESM,
we can still avoid a build step by maintaining two copies of the same
file, but with different exports.

This commit also refactors the implementation to split out the DOM-
specific parts (essentially a requestIdleCallback polyfill). Aside from
the architectural benefits, this also makes it possible to write host-
agnostic tests. If/when we publish a version of Schedule that targets
other environments, like React Native, we can run these same tests
across all implementations.

* Edits in response to Dan's PR feedback
2018-09-14 14:05:55 -07:00
Jérôme Steunou
9c961c0a27 Fix some iframe edge cases (#13650)
Should fix #13648 by fallback on `window` when `document.defaultView` does not exists anymore
2018-09-14 16:44:14 +01:00
Brian Vaughn
8bc0bcabe7 Add UMD production+profiling entry points (#13642)
* Added UMD_PROFILING type to react-dom and scheduling package. Added UMD shim to schedule package.
* Added new schedule umd prod+prof bundle to API test
2018-09-13 17:44:08 -07:00
Heaven
b488a5d9c5 Fix test comment typo (#13568) 2018-09-13 17:33:16 -07:00
Brian Vaughn
4bcee56210 Rename "tracking" API to "tracing" (#13641)
* Replaced "tracking" with "tracing" in all directory and file names
* Global rename of track/tracking/tracked to trace/tracing/traced
2018-09-13 14:23:16 -07:00
Dan Abramov
9a6c5ba72d Fix packaging fixtures 2018-09-13 19:31:18 +01:00
Dan Abramov
72217d0819 Update bundle sizes for 16.5.1 release 2018-09-13 19:31:18 +01:00
Dan Abramov
cc66a1aa23 Update error codes for 16.5.1 release 2018-09-13 19:31:18 +01:00
Dan Abramov
8b93a60c5e Updating package versions for release 16.5.1 2018-09-13 19:31:18 +01:00
Dan Abramov
7a5eecc073 Add 16.5.1 changelog (#13638) 2018-09-13 19:31:00 +01:00
Andres Rojas
ecbf7af40b Enhance dev warnings for forwardRef render function (#13627) (#13636)
* Enhance dev warnings for forwardRef render function

- For 0 parameters: Do not warn because it may be due to usage of the
  arguments object.

- For 1 parameter: Warn about missing the 'ref' parameter.

- For 2 parameters: This is the ideal. Do not warn.

- For more than 2 parameters: Warn about undefined parameters.

* Make test cases for forwardRef warnings more realistic

* Add period to warning sentence
2018-09-13 16:12:34 +01:00
Dan Abramov
2282400850 Delete TapEventPlugin (#13630) 2018-09-12 19:53:29 +01:00
Nathan Hunzaker
a079011f95 🔥 Stop syncing the value attribute on inputs (behind a feature flag) (#13526)
* 🔥 Stop syncing the value attribute on inputs

* Eliminate some additional checks

* Remove initialValue and initialWrapper from wrapperState flow type

* Update tests with new sync logic, reduce some operations

* Update tests, add some caveats for SSR mismatches

* Revert newline change

* Remove unused type

* Call toString to safely type string values

* Add disableInputAttributeSyncing feature flag

Reverts tests to original state, adds attribute sync feature flag,
then moves all affected tests to ReactFire-test.js.

* Revert position of types in toStringValues

* Invert flag on number input blur

* Add clarification why double blur is necessary

* Update ReactFire number cases to be more explicite about blur

* Move comments to reduce diff size

* Add comments to clarify behavior in each branch

* There is no need to assign a different checked behavior in Fire

* Use checked reference

* Format

* Avoid precomputing stringable values

* Revert getToStringValue comment

* Revert placement of undefined in getToStringValue

* Do not eagerly stringify value

* Unify Fire test cases with normal ones

* Revert toString change. Only assign unsynced values when not nully
2018-09-12 19:29:23 +01:00
Dan Abramov
a7bd7c3c04 Allow reading default feature flags from bundle tests (#13629) 2018-09-12 16:56:04 +01:00
Dan Abramov
7204b636ee Run tests for Fire feature flags (#13628)
* Run tests for Fire feature flags

* Only run ReactDOM tests for Fire
2018-09-12 16:17:36 +01:00
Dan Abramov
d3bbfe09cc Fix IE version in comment 2018-09-12 15:10:28 +01:00
Aliaksandr Manzhula
1b2646a403 Fix warning without stack for ie9 (#13620)
* Fix warning without stack for ie9

Where console methods like log, error etc. don't have 'apply' method.
Because of the lot of tests already expect that exactly console['method']
will be called - had to reapply references for console.error method

https://github.com/facebook/react/issues/13610

* pass parameters explicitly to avoid using .apply
which is not supported for console methods in ie9

* Minor tweaks
2018-09-12 15:09:57 +01:00
Héctor Ramos
dde0645fcf Switch to @sizebot token (#13622) 2018-09-11 21:06:44 +01:00
Evan Jacobs
e49f3ca08e honor displayName set on ForwardRef if available (#13615)
* add failing test

* honor displayName set on ForwardRef if available

Since React.forwardRef returns a component object, some users
(including styled-components and react-native) are starting to
decorate them with various statics including displayName.

This adjusts React's various name-getters to honor this if set and
surface the name in warnings and hopefully DevTools.

* fix typing

* Refine later
2018-09-11 20:19:54 +01:00
Nathan Hunzaker
f6fb03edff Hydration DOM Fixture (#13521)
* Add home component. Async load fixtures.

This commit adds a homepage to the DOM fixtures that includes browser
testing information and asynchronously loads fixtures.

This should make it easier to find DOM testing information and keep
the payload size in check as we add more components to the fixtures.

* Adds experimental hydration fixture

This commit adds a first pass at a fixture that makes it easier to
debug the process of hydrating static markup. This is not complete:

1. It needs to be verified across multiple browsers
2. It needs to render with the current version of react

Still, it at least demonstrates the idea. A fixture like this will
also be helpful for debugging change events for hydrated inputs, which
presently do not fire if the user changes an input's text before
hydration.

* Tweak select width

* Manually join extra attributes in warning

This prevents a bug where Chrome reports `Array(n)` where `n` is the
size of the array.

* Transform with buble

* Eliminate dependencies

* Pull in react-live for better editing

* Handle encoding errors, pass react version

* Load the correct version of React

* Tweaks

* Revert style change

* Revert warning update

* Properly handle script errors. Fix dom-server CDN loading

* Fix 15.x releases

* Use postMessage to reduce latency, support older browsers

This commit makes a few tweaks to support older browsers and updates
the code transition process to use window.postMessage. This avoids
loading React on every single change.

* Fix fixture renamespacing bug

* Gracefully fallback to textarea in React 14

* Replace buble with babel, react-live with codemirror

* Simplify layout to resolve production code-mirror issues

* Tweak height rules for code-mirror

* Update theme to paraiso

* Format Code.js

* Adjust viewport to fix CodeMirror resize issue in production build

* Eliminate react-code-mirror

* Improve error state. Make full stack collapsable

* Add link to license in codemirror stylesheet

* Make code example more concise

* Replace "Hydrate" with "Auto-hydrate" for clarity

* Remove border below hydration header

* Rename query function in render.js

* Use Function(code) to evaluate hydration fixture

For clarity, and so that the Fixture component does not need to be
assigned to the window, this commit changes the way code is executed
such that it evaluates using a Function constructor.

* Extend hydration fixture to fill width. Design adjustments

This commit extends the hydration fixture such that it takes up the
full screen view. To accomplish this, the container that wraps all
fixtures has been moved to the FixtureSet component, utilized by all
other fixtures.

* Improve error scroll state

* Lazy load CodeMirror together before executing

This commit fixes an issue where CodeMirror wouldn't layout correctly
in production builds because the editor executes before the stylesheet
loaded. CodeMirror needs layout information, and was rendering
off-screen without correct CSS layout measurements.

* Fix indentation on error message

* Do not highlight errors from Babel. Add setPrototypeOf polyfill

This commit fixes an error in Safari 7.1 where Chalk highlighted Babel
errors caused a crash when setPrototypeOf was called within the
library.

This is also an issue on IE9, however this fix does not resolve issues
in that browser.

* Increase resilience to bad errors in Hydration fixture

- Reverts highlighting change. Polyfilling Safari 7.1 is sufficient
- Do not render a details tag in IE9
2018-09-10 14:04:14 -07:00
Brian Vaughn
54bfab5d6d Release script updates private package dependencies also (#13612) 2018-09-10 13:14:34 -07:00
Brian Vaughn
ade5e69288 Manually update schedule dep in react-native-renderer (#13609) 2018-09-10 11:07:08 -07:00
Dan Abramov
f260b14a8f Fix host bailout for the persistent mode (#13611)
* Add regression test for persistent bailout bug

* Fork more logic into updateHostComponent

This is mostly copy paste. But I added a bailout only to mutation mode. Persistent mode doesn't have that props equality bailout anymore, so the Fabric test now passes.

* Add failing test for persistence host minimalism

* Add bailouts to the persistent host updates
2018-09-10 19:05:40 +01:00
Dan Abramov
4a40d76245 Fix a regression related to isReactComponent prototype check (#13608) 2018-09-10 17:54:45 +01:00
Brian Vaughn
03ab1efeb4 Improve DX when combining react-dom/profiling and schedule/tracking (#13605)
* Added blessed production+profiling entry point for schedule/tracking
* Add invariant when profiling renderer is used with non-profiling schedule/tracking
2018-09-10 08:32:56 -07:00
Dan Abramov
144328fe81 Enable no-use-before-define rule (#13606) 2018-09-10 16:15:18 +01:00
Dan
8a8d973d3c Use clearer wording
Fixes #13604
2018-09-09 16:54:31 +01:00
Brandon Dail
7d1169b2d7 Remove injectComponentTree from unstable-native-dependencies, add EventPluginHub (#13598)
* Remove injectComponentTree from unstable-native-dependencies, add
EventPluginHub

injectComponentTree was exposed for react-native-web, but wasn't
actually being used by the project. They were using EventPluginHub
through ReactDOM's secret internals, but that was removed in https://github.com/facebook/react/pull/13539

This removes the unused injectComponentTree export, refactors the
ResponderEventPlugin test so it doesn't depend on it, and also adds
EventPluginHub to the exports to unbreak react-native-web

* Re-export injectEventPluginsByName from ReactDOM internals
2018-09-08 12:07:59 -07:00
Nathan Hunzaker
8d1038fc6d Break up ReactDOMServerIntegrationForm-test (#13600)
In https://github.com/facebook/react/pull/13394, I encountered an
issue where the ReactDOMServerIntegrationForm test suite consumed
sufficient memory to crash CircleCI. Breaking up this test suite by
form element type resolved the issue.

This commit performs that change separate from the Symbol/Function
stringification changes in #13394.
2018-09-08 11:31:32 -07:00
Héctor Ramos
b87aabdfe1 Drop the year from Facebook copyright headers and the LICENSE file. (#13593) 2018-09-07 15:11:23 -07:00
Ali Torki
12f3a5475f chore: remove duplicate **when** (#13587) 2018-09-07 07:52:31 -10:00
Nish
c6dcf46d65 Build schedule which is required for time slicing demo (#13588)
* Build schedule which is required for time slicing demo

* Update suspense demo README too

* Update README.md

* Update README.md

* Update README.md
2018-09-07 17:11:19 +01:00
Brian Vaughn
7bcc0778fd Fixed small CHANGELOG error (#13583) 2018-09-06 18:03:58 -07:00
Brian Vaughn
d66505dbc7 Updated 16.5 changelog 2018-09-06 12:59:22 -07:00
Timothy Yung
e417e0bf7c Update ReactNativeViewConfigRegistry Flow Types (#13579) 2018-09-06 12:27:44 -07:00
Brian Vaughn
8f45a685be Add 2fa OTP code to npm dist-tag command too 2018-09-06 09:49:42 -07:00
589 changed files with 5159 additions and 3615 deletions

View File

@@ -37,6 +37,7 @@ 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,

View File

@@ -7,12 +7,31 @@
</details>
## 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
@@ -23,12 +42,12 @@
* 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 when hydrating ([@Ephem](https://github.com/Ephem) in [#13537](https://github.com/facebook/react/issues/13537))
* 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 ([@robbertbrak](https://github.com/robbertbrak) in [#10217](https://github.com/facebook/react/issues/10217))
* 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 `dangerousSetInnerHTML` when `__html` is not a string ([@gaearon](https://github.com/gaearon) in [#13353](https://github.com/facebook/react/issues/13353))
* 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))

View File

@@ -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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -6,7 +6,9 @@
"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",
@@ -16,7 +18,7 @@
},
"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"

View 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>

View 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);
})();

View File

@@ -8,9 +8,7 @@ function App() {
return (
<div>
<Header />
<div className="container">
<Fixtures />
</div>
<Fixtures />
</div>
);
}

View File

@@ -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>}

View File

@@ -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>

View File

@@ -2,7 +2,7 @@ const React = window.React;
export default function Home() {
return (
<main>
<main className="container">
<h1>DOM Test Fixtures</h1>
<p>
Use this site to test browser quirks and other behavior that can not be

View 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>;
}
}

View File

@@ -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;
}

View File

@@ -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; }

View 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();

View 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;
}

View 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;

View File

@@ -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>
);
}
}

View File

@@ -1,3 +1,4 @@
import 'core-js/es6/symbol';
import 'core-js/es6/promise';
import 'core-js/es6/set';
import 'core-js/es6/map';

View File

@@ -36,9 +36,10 @@ 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';
@@ -49,25 +50,37 @@ export default function loadReact() {
// 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 (major >= 16 && !(minor === 0 && preReleaseStage === 'alpha')) {
REACT_PATH =
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(() => {

View File

@@ -79,7 +79,6 @@ textarea {
.header {
background: #171717;
box-shadow: inset 0 -1px 3px #000;
overflow: hidden;
padding: 8px;
}
@@ -102,7 +101,6 @@ textarea {
.header__inner {
display: table;
margin: 0 auto;
max-width: 1000px;
overflow: hidden;
text-align: center;
width: 100%;

View File

@@ -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"

View File

@@ -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>

View File

@@ -2,7 +2,7 @@
<html style="width: 100%; height: 100%;">
<head>
<meta charset="utf-8">
<title>Test tracking UMD</title>
<title>Test tracing UMD</title>
<style>
body {
font-family: sans-serif;
@@ -36,9 +36,9 @@
</style>
</head>
<body>
<h1>Test tracking UMD</h1>
<h1>Test tracing UMD</h1>
<p>
This fixture tests that the new tracking API is accessible via UMD build using the UMD shim.
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>
@@ -52,19 +52,19 @@
<li id="checkSchedulerAPI" data-value="...">
<strong>Test scheduler API</strong>
</li>
<li id="checkSchedulerTrackingAPI" data-value="...">
<strong>Test tracking API</strong>
<li id="checkSchedulerTracingAPI" data-value="...">
<strong>Test tracing API</strong>
</li>
<li id="checkSchedulerTrackingSubscriptionsAPI" data-value="...">
<strong>Test tracking subscriptions API</strong>
<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 tracking API before react to test that it's lazily evaluated -->
<!-- Load the tracing API before react to test that it's lazily evaluated -->
<script src="../../build/node_modules/schedule/umd/schedule.development.js"></script>
<script src="../../build/node_modules/schedule/umd/schedule-tracking.development.js"></script>
<script src="../../build/node_modules/schedule/umd/schedule-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>

View File

@@ -14,10 +14,10 @@ function runAllTests() {
checkSchedulerAPI();
} finally {
try {
checkSchedulerTrackingAPI();
checkSchedulerTracingAPI();
} finally {
try {
checkSchedulerTrackingSubscriptionsAPI();
checkSchedulerTracingSubscriptionsAPI();
} finally {
checkEndToEndIntegration();
}
@@ -44,23 +44,23 @@ function checkSchedulerAPI() {
});
}
function checkSchedulerTrackingAPI() {
runTest(document.getElementById('checkSchedulerTrackingAPI'), () => {
function checkSchedulerTracingAPI() {
runTest(document.getElementById('checkSchedulerTracingAPI'), () => {
if (
typeof ScheduleTracking === 'undefined' ||
typeof ScheduleTracking.unstable_clear !== 'function' ||
typeof ScheduleTracking.unstable_getCurrent !== 'function' ||
typeof ScheduleTracking.unstable_getThreadID !== 'function' ||
typeof ScheduleTracking.unstable_track !== 'function' ||
typeof ScheduleTracking.unstable_wrap !== 'function'
typeof ScheduleTracing === 'undefined' ||
typeof ScheduleTracing.unstable_clear !== 'function' ||
typeof ScheduleTracing.unstable_getCurrent !== 'function' ||
typeof ScheduleTracing.unstable_getThreadID !== 'function' ||
typeof ScheduleTracing.unstable_trace !== 'function' ||
typeof ScheduleTracing.unstable_wrap !== 'function'
) {
throw 'API is not defined';
}
try {
let interactionsSet;
ScheduleTracking.unstable_track('test', 123, () => {
interactionsSet = ScheduleTracking.unstable_getCurrent();
ScheduleTracing.unstable_trace('test', 123, () => {
interactionsSet = ScheduleTracing.unstable_getCurrent();
});
if (interactionsSet.size !== 1) {
throw null;
@@ -73,32 +73,32 @@ function checkSchedulerTrackingAPI() {
throw 'API does not work';
}
const ForwardedSchedulerTracking =
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ScheduleTracking;
const ForwardedSchedulerTracing =
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ScheduleTracing;
if (
ScheduleTracking.unstable_getThreadID() ===
ForwardedSchedulerTracking.unstable_getThreadID()
ScheduleTracing.unstable_getThreadID() ===
ForwardedSchedulerTracing.unstable_getThreadID()
) {
throw 'API forwarding is broken';
}
});
}
function checkSchedulerTrackingSubscriptionsAPI() {
function checkSchedulerTracingSubscriptionsAPI() {
runTest(
document.getElementById('checkSchedulerTrackingSubscriptionsAPI'),
document.getElementById('checkSchedulerTracingSubscriptionsAPI'),
() => {
if (
typeof ScheduleTracking === 'undefined' ||
typeof ScheduleTracking.unstable_subscribe !== 'function' ||
typeof ScheduleTracking.unstable_unsubscribe !== 'function'
typeof ScheduleTracing === 'undefined' ||
typeof ScheduleTracing.unstable_subscribe !== 'function' ||
typeof ScheduleTracing.unstable_unsubscribe !== 'function'
) {
throw 'API is not defined';
}
const onInteractionScheduledWorkCompletedCalls = [];
const onInteractionTrackedCalls = [];
const onInteractionTracedCalls = [];
const onWorkCanceledCalls = [];
const onWorkScheduledCalls = [];
const onWorkStartedCalls = [];
@@ -106,7 +106,7 @@ function checkSchedulerTrackingSubscriptionsAPI() {
const subscriber = {
onInteractionScheduledWorkCompleted: (...args) =>
onInteractionScheduledWorkCompletedCalls.push(args),
onInteractionTracked: (...args) => onInteractionTrackedCalls.push(args),
onInteractionTraced: (...args) => onInteractionTracedCalls.push(args),
onWorkCanceled: (...args) => onWorkCanceledCalls.push(args),
onWorkScheduled: (...args) => onWorkScheduledCalls.push(args),
onWorkStarted: (...args) => onWorkStartedCalls.push(args),
@@ -114,38 +114,38 @@ function checkSchedulerTrackingSubscriptionsAPI() {
};
try {
ScheduleTracking.unstable_subscribe(subscriber);
ScheduleTracking.unstable_track('foo', 123, () => {});
ScheduleTracking.unstable_unsubscribe(subscriber);
if (onInteractionTrackedCalls.length !== 1) {
ScheduleTracing.unstable_subscribe(subscriber);
ScheduleTracing.unstable_trace('foo', 123, () => {});
ScheduleTracing.unstable_unsubscribe(subscriber);
if (onInteractionTracedCalls.length !== 1) {
throw null;
}
const interaction = onInteractionTrackedCalls[0][0];
const interaction = onInteractionTracedCalls[0][0];
if (interaction.name !== 'foo' || interaction.timestamp !== 123) {
throw null;
}
ScheduleTracking.unstable_track('bar', 456, () => {});
if (onInteractionTrackedCalls.length !== 1) {
ScheduleTracing.unstable_trace('bar', 456, () => {});
if (onInteractionTracedCalls.length !== 1) {
throw null;
}
} catch (error) {
throw 'API does not forward methods';
}
const ForwardedSchedulerTracking =
const ForwardedSchedulerTracing =
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
.ScheduleTracking;
.ScheduleTracing;
try {
ForwardedSchedulerTracking.unstable_subscribe(subscriber);
ScheduleTracking.unstable_track('foo', 123, () => {});
ForwardedSchedulerTracking.unstable_track('bar', 456, () => {});
ScheduleTracking.unstable_unsubscribe(subscriber);
if (onInteractionTrackedCalls.length !== 3) {
ForwardedSchedulerTracing.unstable_subscribe(subscriber);
ScheduleTracing.unstable_trace('foo', 123, () => {});
ForwardedSchedulerTracing.unstable_trace('bar', 456, () => {});
ScheduleTracing.unstable_unsubscribe(subscriber);
if (onInteractionTracedCalls.length !== 3) {
throw null;
}
const interactionFoo = onInteractionTrackedCalls[1][0];
const interactionBar = onInteractionTrackedCalls[2][0];
const interactionFoo = onInteractionTracedCalls[1][0];
const interactionBar = onInteractionTracedCalls[2][0];
if (
interactionFoo.name !== 'foo' ||
interactionFoo.timestamp !== 123 ||
@@ -154,8 +154,8 @@ function checkSchedulerTrackingSubscriptionsAPI() {
) {
throw null;
}
ForwardedSchedulerTracking.unstable_track('baz', 789, () => {});
if (onInteractionTrackedCalls.length !== 3) {
ForwardedSchedulerTracing.unstable_trace('baz', 789, () => {});
if (onInteractionTracedCalls.length !== 3) {
throw null;
}
} catch (error) {
@@ -172,7 +172,7 @@ function checkEndToEndIntegration() {
const onRender = (...args) => onRenderCalls.push(args);
const container = document.createElement('div');
ScheduleTracking.unstable_track('render', 123, () => {
ScheduleTracing.unstable_trace('render', 123, () => {
ReactDOM.render(
React.createElement(
React.unstable_Profiler,

View File

@@ -26,7 +26,7 @@ Set [the `enableSuspense` flag](https://github.com/facebook/react/blob/d79238f1e
# 1: Build react from source
cd /path/to/react
yarn
yarn build dom,core,interaction,simple-cache-provider --type=NODE
yarn build dom-client,core,simple-cache-provider,schedule --type=NODE
# 2: Install fixture dependencies
cd fixtures/unstable-async/suspense/

View File

@@ -1,9 +1,6 @@
import React, {Placeholder, PureComponent} from 'react';
import {unstable_scheduleWork} from 'schedule';
import {
unstable_track as track,
unstable_wrap as wrap,
} from 'schedule/tracking';
import {unstable_trace as trace, unstable_wrap as wrap} from 'schedule/tracing';
import {createResource} from 'simple-cache-provider';
import {cache} from '../cache';
import Spinner from './Spinner';
@@ -32,15 +29,15 @@ export default class App extends PureComponent {
}
handleUserClick = id => {
track(`View ${id}`, performance.now(), () => {
track(`View ${id} (high-pri)`, performance.now(), () =>
trace(`View ${id}`, performance.now(), () => {
trace(`View ${id} (high-pri)`, performance.now(), () =>
this.setState({
currentId: id,
})
);
unstable_scheduleWork(
wrap(() =>
track(`View ${id} (low-pri)`, performance.now(), () =>
trace(`View ${id} (low-pri)`, performance.now(), () =>
this.setState({
showDetail: true,
})
@@ -51,7 +48,7 @@ export default class App extends PureComponent {
};
handleBackClick = () =>
track('View list', performance.now(), () =>
trace('View list', performance.now(), () =>
this.setState({
currentId: null,
showDetail: false,

View File

@@ -1,6 +1,6 @@
import React, {Fragment, PureComponent} from 'react';
import {unstable_createRoot, render} from 'react-dom';
import {unstable_track as track} from 'schedule/tracking';
import {unstable_trace as trace} from 'schedule/tracing';
import {cache} from './cache';
import {
setFakeRequestTime,
@@ -65,7 +65,7 @@ class Debugger extends PureComponent {
}
handleReset = () => {
track('Clear cache', () => {
trace('Clear cache', () => {
cache.invalidate();
this.setState(state => ({
requests: {},

View File

@@ -18,7 +18,7 @@ There are also known bugs and inefficiencies in master so **don't use this fixtu
# 1: Build react from source
cd /path/to/react
yarn
yarn build dom,core,interaction,simple-cache-provider --type=NODE
yarn build dom-client,core,simple-cache-provider,schedule --type=NODE
# 2: Install fixture dependencies
cd fixtures/unstable-async/time-slicing/

View File

@@ -1,6 +1,6 @@
{
"private": true,
"version": "16.5.0",
"version": "16.5.2",
"workspaces": [
"packages/*"
],
@@ -99,7 +99,9 @@
"postinstall": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json && node ./scripts/flow/createFlowConfigs.js",
"debug-test": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.source.js --runInBand",
"test": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source.js",
"test-fire": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source-fire.js",
"test-prod": "cross-env NODE_ENV=production jest --config ./scripts/jest/config.source.js",
"test-fire-prod": "cross-env NODE_ENV=production jest --config ./scripts/jest/config.source-fire.js",
"test-prod-build": "yarn test-build-prod",
"test-build": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.build.js",
"test-build-prod": "cross-env NODE_ENV=production jest --config ./scripts/jest/config.build.js",

View File

@@ -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.

View File

@@ -1,7 +1,7 @@
{
"name": "create-subscription",
"description": "utility for subscribing to external data sources inside React components",
"version": "16.5.0",
"version": "16.5.2",
"repository": "facebook/react",
"files": [
"LICENSE",

View File

@@ -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.

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.
@@ -12,12 +12,21 @@
const {HostComponent} = require('shared/ReactWorkTags');
let EventPluginHub;
let EventPluginUtils;
let ResponderEventPlugin;
const touch = function(nodeHandle, i) {
return {target: nodeHandle, identifier: i};
};
function injectComponentTree(ComponentTree) {
EventPluginUtils.setComponentTree(
ComponentTree.getFiberCurrentPropsFromNode,
ComponentTree.getInstanceFromNode,
ComponentTree.getNodeFromInstance,
);
}
/**
* @param {NodeHandle} nodeHandle @see NodeHandle. Handle of target.
* @param {Array<Touch>} touches All active touches.
@@ -395,8 +404,7 @@ describe('ResponderEventPlugin', () => {
const ReactDOMUnstableNativeDependencies = require('react-dom/unstable-native-dependencies');
EventPluginHub = require('events/EventPluginHub');
const injectComponentTree =
ReactDOMUnstableNativeDependencies.injectComponentTree;
EventPluginUtils = require('events/EventPluginUtils');
ResponderEventPlugin =
ReactDOMUnstableNativeDependencies.ResponderEventPlugin;

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-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.

View File

@@ -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.

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2014-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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -1,7 +1,7 @@
{
"name": "react-art",
"description": "React ART is a JavaScript library for drawing vector graphics using React. It provides declarative and reactive bindings to the ART library. Using the same declarative API you can render the output to either Canvas, SVG or VML (IE8).",
"version": "16.5.0",
"version": "16.5.2",
"main": "index.js",
"repository": "facebook/react",
"keywords": [
@@ -23,7 +23,7 @@
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"schedule": "^0.3.0"
"schedule": "^0.5.0"
},
"peerDependencies": {
"react": "^16.0.0"

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -1,6 +1,6 @@
{
"name": "react-dom",
"version": "16.5.0",
"version": "16.5.2",
"description": "React package for working with the DOM.",
"main": "index.js",
"repository": "facebook/react",
@@ -16,7 +16,7 @@
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"schedule": "^0.3.0"
"schedule": "^0.5.0"
},
"peerDependencies": {
"react": "^16.0.0"

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.
@@ -9,6 +9,9 @@
'use strict';
// Set by `yarn test-fire`.
const {disableInputAttributeSyncing} = require('shared/ReactFeatureFlags');
describe('DOMPropertyOperations', () => {
let React;
let ReactDOM;
@@ -80,7 +83,11 @@ describe('DOMPropertyOperations', () => {
it('should not remove empty attributes for special input properties', () => {
const container = document.createElement('div');
ReactDOM.render(<input value="" onChange={() => {}} />, container);
expect(container.firstChild.getAttribute('value')).toBe('');
if (disableInputAttributeSyncing) {
expect(container.firstChild.hasAttribute('value')).toBe(false);
} else {
expect(container.firstChild.getAttribute('value')).toBe('');
}
expect(container.firstChild.value).toBe('');
});
@@ -165,7 +172,11 @@ describe('DOMPropertyOperations', () => {
<input type="text" value="foo" onChange={function() {}} />,
container,
);
expect(container.firstChild.getAttribute('value')).toBe('foo');
if (disableInputAttributeSyncing) {
expect(container.firstChild.hasAttribute('value')).toBe(false);
} else {
expect(container.firstChild.getAttribute('value')).toBe('foo');
}
expect(container.firstChild.value).toBe('foo');
expect(() =>
ReactDOM.render(
@@ -175,7 +186,11 @@ describe('DOMPropertyOperations', () => {
).toWarnDev(
'A component is changing a controlled input of type text to be uncontrolled',
);
expect(container.firstChild.getAttribute('value')).toBe('foo');
if (disableInputAttributeSyncing) {
expect(container.firstChild.hasAttribute('value')).toBe(false);
} else {
expect(container.firstChild.getAttribute('value')).toBe('foo');
}
expect(container.firstChild.value).toBe('foo');
});

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.
@@ -1762,4 +1762,18 @@ describe('ReactCompositeComponent', () => {
{withoutStack: true},
);
});
// Regression test for accidental breaking change
// https://github.com/facebook/react/issues/13580
it('should support classes shadowing isReactComponent', () => {
class Shadow extends React.Component {
isReactComponent() {}
render() {
return <div />;
}
}
const container = document.createElement('div');
ReactDOM.render(<Shadow />, container);
expect(container.firstChild.tagName).toBe('DIV');
});
});

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.
@@ -455,9 +455,11 @@ describe('ReactDOM', () => {
try {
delete global.requestAnimationFrame;
jest.resetModules();
expect(() => require('react-dom')).toWarnDev(
spyOnDevAndProd(console, 'error');
require('react-dom');
expect(console.error.calls.count()).toEqual(1);
expect(console.error.calls.argsFor(0)[0]).toMatch(
"This browser doesn't support requestAnimationFrame.",
{withoutStack: true},
);
} finally {
global.requestAnimationFrame = previousRAF;

View File

@@ -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.

View File

@@ -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.

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2015-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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.
@@ -9,6 +9,9 @@
'use strict';
// Set by `yarn test-fire`.
const {disableInputAttributeSyncing} = require('shared/ReactFeatureFlags');
function emptyFunction() {}
describe('ReactDOMInput', () => {
@@ -230,11 +233,14 @@ describe('ReactDOMInput', () => {
const node = ReactDOM.render(stub, container);
setUntrackedValue.call(node, '2.0');
dispatchEventOnNode(node, 'input');
expect(node.getAttribute('value')).toBe('2');
expect(node.value).toBe('2');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.getAttribute('value')).toBe('2');
}
});
it('does change the string "2" to "2.0" with no change handler', () => {
@@ -242,11 +248,14 @@ describe('ReactDOMInput', () => {
const node = ReactDOM.render(stub, container);
setUntrackedValue.call(node, '2.0');
dispatchEventOnNode(node, 'input');
expect(node.getAttribute('value')).toBe('2');
expect(node.value).toBe('2');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.getAttribute('value')).toBe('2');
}
});
it('changes the number 2 to "2.0" using a change handler', () => {
@@ -268,11 +277,14 @@ describe('ReactDOMInput', () => {
const node = ReactDOM.findDOMNode(stub);
setUntrackedValue.call(node, '2.0');
dispatchEventOnNode(node, 'input');
expect(node.getAttribute('value')).toBe('2.0');
expect(node.value).toBe('2.0');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.getAttribute('value')).toBe('2.0');
}
});
});
@@ -419,11 +431,17 @@ describe('ReactDOMInput', () => {
);
expect(node.value).toBe('0');
expect(node.defaultValue).toBe('0');
ReactDOM.render(<input type="text" defaultValue="1" />, container);
expect(node.value).toBe('0');
expect(node.defaultValue).toBe('1');
if (disableInputAttributeSyncing) {
expect(node.value).toBe('1');
expect(node.defaultValue).toBe('1');
} else {
expect(node.value).toBe('0');
expect(node.defaultValue).toBe('1');
}
});
it('should update `defaultValue` for uncontrolled date/time input', () => {
@@ -433,11 +451,17 @@ describe('ReactDOMInput', () => {
);
expect(node.value).toBe('1980-01-01');
expect(node.defaultValue).toBe('1980-01-01');
ReactDOM.render(<input type="date" defaultValue="2000-01-01" />, container);
expect(node.value).toBe('1980-01-01');
expect(node.defaultValue).toBe('2000-01-01');
if (disableInputAttributeSyncing) {
expect(node.value).toBe('2000-01-01');
expect(node.defaultValue).toBe('2000-01-01');
} else {
expect(node.value).toBe('1980-01-01');
expect(node.defaultValue).toBe('2000-01-01');
}
ReactDOM.render(<input type="date" />, container);
});
@@ -651,7 +675,16 @@ describe('ReactDOMInput', () => {
setUntrackedValue.call(node, '0.0');
dispatchEventOnNode(node, 'input');
expect(node.value).toBe('0.0');
if (disableInputAttributeSyncing) {
expect(node.value).toBe('0.0');
expect(node.hasAttribute('value')).toBe(false);
} else {
dispatchEventOnNode(node, 'blur');
expect(node.value).toBe('0.0');
expect(node.getAttribute('value')).toBe('0.0');
}
});
it('should properly transition from an empty value to 0', function() {
@@ -665,9 +698,13 @@ describe('ReactDOMInput', () => {
);
const node = container.firstChild;
expect(node.value).toBe('0');
expect(node.defaultValue).toBe('0');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.defaultValue).toBe('0');
}
});
it('should properly transition from 0 to an empty value', function() {
@@ -699,7 +736,11 @@ describe('ReactDOMInput', () => {
const node = container.firstChild;
expect(node.value).toBe('0.0');
expect(node.defaultValue).toBe('0.0');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.defaultValue).toBe('0.0');
}
});
it('should properly transition a number input from "" to 0', function() {
@@ -715,7 +756,11 @@ describe('ReactDOMInput', () => {
const node = container.firstChild;
expect(node.value).toBe('0');
expect(node.defaultValue).toBe('0');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.defaultValue).toBe('0');
}
});
it('should properly transition a number input from "" to "0"', function() {
@@ -731,7 +776,11 @@ describe('ReactDOMInput', () => {
const node = container.firstChild;
expect(node.value).toBe('0');
expect(node.defaultValue).toBe('0');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.defaultValue).toBe('0');
}
});
it('should have the correct target value', () => {
@@ -956,21 +1005,34 @@ describe('ReactDOMInput', () => {
const cNode = stub.refs.c;
expect(aNode.checked).toBe(true);
expect(aNode.hasAttribute('checked')).toBe(true);
expect(bNode.checked).toBe(false);
expect(bNode.hasAttribute('checked')).toBe(false);
// c is in a separate form and shouldn't be affected at all here
expect(cNode.checked).toBe(true);
expect(cNode.hasAttribute('checked')).toBe(true);
if (disableInputAttributeSyncing) {
expect(aNode.hasAttribute('checked')).toBe(false);
expect(bNode.hasAttribute('checked')).toBe(false);
expect(cNode.hasAttribute('checked')).toBe(true);
} else {
expect(aNode.hasAttribute('checked')).toBe(true);
expect(bNode.hasAttribute('checked')).toBe(false);
expect(cNode.hasAttribute('checked')).toBe(true);
}
setUntrackedChecked.call(bNode, true);
expect(aNode.checked).toBe(false);
expect(cNode.checked).toBe(true);
// The original 'checked' attribute should be unchanged
expect(aNode.hasAttribute('checked')).toBe(true);
expect(bNode.hasAttribute('checked')).toBe(false);
expect(cNode.hasAttribute('checked')).toBe(true);
if (disableInputAttributeSyncing) {
expect(aNode.hasAttribute('checked')).toBe(false);
expect(bNode.hasAttribute('checked')).toBe(false);
expect(cNode.hasAttribute('checked')).toBe(true);
} else {
expect(aNode.hasAttribute('checked')).toBe(true);
expect(bNode.hasAttribute('checked')).toBe(false);
expect(cNode.hasAttribute('checked')).toBe(true);
}
// Now let's run the actual ReactDOMInput change event handler
dispatchEventOnNode(bNode, 'click');
@@ -1516,15 +1578,26 @@ describe('ReactDOMInput', () => {
/>,
container,
);
expect(log).toEqual([
'set attribute type',
'set attribute min',
'set attribute max',
'set attribute step',
'set property value',
'set attribute value',
'set attribute checked',
]);
if (disableInputAttributeSyncing) {
expect(log).toEqual([
'set attribute type',
'set attribute min',
'set attribute max',
'set attribute step',
'set property value',
]);
} else {
expect(log).toEqual([
'set attribute type',
'set attribute min',
'set attribute max',
'set attribute step',
'set property value',
'set attribute value',
'set attribute checked',
]);
}
});
it('sets value properly with type coming later in props', () => {
@@ -1579,12 +1652,20 @@ describe('ReactDOMInput', () => {
});
ReactDOM.render(<input type="date" defaultValue="1980-01-01" />, container);
expect(log).toEqual([
'node.setAttribute("type", "date")',
'node.value = "1980-01-01"',
'node.setAttribute("value", "1980-01-01")',
'node.setAttribute("checked", "")',
]);
if (disableInputAttributeSyncing) {
expect(log).toEqual([
'node.setAttribute("type", "date")',
'node.setAttribute("value", "1980-01-01")',
]);
} else {
expect(log).toEqual([
'node.setAttribute("type", "date")',
'node.value = "1980-01-01"',
'node.setAttribute("value", "1980-01-01")',
'node.setAttribute("checked", "")',
]);
}
});
describe('assigning the value attribute on controlled inputs', function() {
@@ -1613,7 +1694,11 @@ describe('ReactDOMInput', () => {
setUntrackedValue.call(node, '2');
dispatchEventOnNode(node, 'input');
expect(node.getAttribute('value')).toBe('2');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.getAttribute('value')).toBe('2');
}
});
it('does not set the value attribute on number inputs if focused', () => {
@@ -1629,7 +1714,11 @@ describe('ReactDOMInput', () => {
setUntrackedValue.call(node, '2');
dispatchEventOnNode(node, 'input');
expect(node.getAttribute('value')).toBe('1');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.getAttribute('value')).toBe('1');
}
});
it('sets the value attribute on number inputs on blur', () => {
@@ -1640,11 +1729,23 @@ describe('ReactDOMInput', () => {
);
const node = ReactDOM.findDOMNode(stub);
node.focus();
setUntrackedValue.call(node, '2');
dispatchEventOnNode(node, 'input');
// TODO: it is unclear why blur must be triggered twice,
// manual testing in the fixtures shows that the active element
// is no longer the input, however blur() + a blur event seem to
// be the only way to remove focus in JSDOM
node.blur();
dispatchEventOnNode(node, 'blur');
expect(node.getAttribute('value')).toBe('2');
if (disableInputAttributeSyncing) {
expect(node.value).toBe('2');
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.value).toBe('2');
expect(node.getAttribute('value')).toBe('2');
}
});
it('an uncontrolled number input will not update the value attribute on blur', () => {
@@ -1653,8 +1754,14 @@ describe('ReactDOMInput', () => {
container,
);
node.focus();
setUntrackedValue.call(node, 4);
dispatchEventOnNode(node, 'input');
// TODO: it is unclear why blur must be triggered twice,
// manual testing in the fixtures shows that the active element
// is no longer the input, however blur() + a blur event seem to
// be the only way to remove focus in JSDOM
node.blur();
dispatchEventOnNode(node, 'blur');
expect(node.getAttribute('value')).toBe('1');
@@ -1666,8 +1773,14 @@ describe('ReactDOMInput', () => {
container,
);
node.focus();
setUntrackedValue.call(node, 4);
dispatchEventOnNode(node, 'input');
// TODO: it is unclear why blur must be triggered twice,
// manual testing in the fixtures shows that the active element
// is no longer the input, however blur() + a blur event seem to
// be the only way to remove focus in JSDOM
node.blur();
dispatchEventOnNode(node, 'blur');
expect(node.getAttribute('value')).toBe('1');
@@ -1707,7 +1820,11 @@ describe('ReactDOMInput', () => {
'Input elements should not switch from controlled to ' +
'uncontrolled (or vice versa).',
);
expect(input.getAttribute('value')).toBe('first');
if (disableInputAttributeSyncing) {
expect(input.getAttribute('value')).toBe(null);
} else {
expect(input.getAttribute('value')).toBe('first');
}
});
it('preserves the value property', () => {
@@ -1755,7 +1872,11 @@ describe('ReactDOMInput', () => {
'Input elements should not switch from controlled ' +
'to uncontrolled (or vice versa).',
]);
expect(input.getAttribute('value')).toBe('first');
if (disableInputAttributeSyncing) {
expect(input.hasAttribute('value')).toBe(false);
} else {
expect(input.getAttribute('value')).toBe('first');
}
});
it('preserves the value property', () => {
@@ -1781,7 +1902,11 @@ describe('ReactDOMInput', () => {
const node = container.firstChild;
expect(node.value).toBe('');
expect(node.getAttribute('value')).toBe('');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.getAttribute('value')).toBe('');
}
});
it('treats updated Symbol value as an empty string', function() {
@@ -1795,7 +1920,11 @@ describe('ReactDOMInput', () => {
const node = container.firstChild;
expect(node.value).toBe('');
expect(node.getAttribute('value')).toBe('');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.getAttribute('value')).toBe('');
}
});
it('treats initial Symbol defaultValue as an empty string', function() {
@@ -1812,7 +1941,11 @@ describe('ReactDOMInput', () => {
ReactDOM.render(<input defaultValue={Symbol('foobar')} />, container);
const node = container.firstChild;
expect(node.value).toBe('foo');
if (disableInputAttributeSyncing) {
expect(node.value).toBe('');
} else {
expect(node.value).toBe('foo');
}
expect(node.getAttribute('value')).toBe('');
// TODO: we should warn here.
});
@@ -1829,7 +1962,11 @@ describe('ReactDOMInput', () => {
const node = container.firstChild;
expect(node.value).toBe('');
expect(node.getAttribute('value')).toBe('');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.getAttribute('value')).toBe('');
}
});
it('treats updated function value as an empty string', function() {
@@ -1843,7 +1980,11 @@ describe('ReactDOMInput', () => {
const node = container.firstChild;
expect(node.value).toBe('');
expect(node.getAttribute('value')).toBe('');
if (disableInputAttributeSyncing) {
expect(node.hasAttribute('value')).toBe(false);
} else {
expect(node.getAttribute('value')).toBe('');
}
});
it('treats initial function defaultValue as an empty string', function() {
@@ -1860,8 +2001,13 @@ describe('ReactDOMInput', () => {
ReactDOM.render(<input defaultValue={() => {}} />, container);
const node = container.firstChild;
expect(node.value).toBe('foo');
expect(node.getAttribute('value')).toBe('');
if (disableInputAttributeSyncing) {
expect(node.value).toBe('');
expect(node.getAttribute('value')).toBe('');
} else {
expect(node.value).toBe('foo');
expect(node.getAttribute('value')).toBe('');
}
// TODO: we should warn here.
});
});

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

Some files were not shown because too many files have changed in this diff Show More