Skip to content

Commit b43494b

Browse files
committed
Merge branch 'master' into remove-event-pooling
# Conflicts: # fixtures/dom/.gitignore # fixtures/dom/package.json # fixtures/dom/src/react-loader.js
2 parents f128797 + f6fb03e commit b43494b

File tree

22 files changed

+668
-39
lines changed

22 files changed

+668
-39
lines changed

fixtures/dom/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public/react.development.js
1212
public/react.production.min.js
1313
public/react-dom.development.js
1414
public/react-dom.production.min.js
15+
public/react-dom-server.browser.development.js
1516

1617
# misc
1718
.DS_Store

fixtures/dom/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
"react-scripts": "^1.0.11"
77
},
88
"dependencies": {
9+
"@babel/standalone": "^7.0.0",
910
"classnames": "^2.2.5",
11+
"codemirror": "^5.40.0",
1012
"core-js": "^2.4.1",
1113
"prop-types": "^15.6.0",
1214
"query-string": "^4.2.3",
@@ -16,7 +18,7 @@
1618
},
1719
"scripts": {
1820
"start": "react-scripts start",
19-
"prestart": "cp ../../build/dist/react.development.js public/ && cp ../../build/dist/react-dom.development.js public/ && cp ../../build/dist/react.production.min.js public/ && cp ../../build/dist/react-dom.production.min.js public/",
21+
"prestart": "cp ../../build/dist/react.development.js ../../build/dist/react-dom.development.js ../../build/dist/react.production.min.js ../../build/dist/react-dom.production.min.js ../../build/dist/react-dom-server.browser.development.js public/",
2022
"build": "react-scripts build && cp build/index.html build/200.html",
2123
"test": "react-scripts test --env=jsdom",
2224
"eject": "react-scripts eject"

fixtures/dom/public/renderer.html

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>Renderer</title>
7+
<style>
8+
*,
9+
*:before,
10+
*:after {
11+
box-sizing: border-box;
12+
}
13+
14+
html,
15+
body {
16+
font-family: sans-serif;
17+
margin: 0;
18+
height: 100%;
19+
}
20+
21+
body {
22+
padding-top: 32px;
23+
}
24+
25+
#status {
26+
font-size: 12px;
27+
left: 8px;
28+
letter-spacing: 0.05em;
29+
line-height: 16px;
30+
margin: -8px 0 0;
31+
max-width: 50%;
32+
overflow: hidden;
33+
position: absolute;
34+
text-align: left;
35+
text-overflow: ellipsis;
36+
top: 50%;
37+
white-space: nowrap;
38+
width: 100%;
39+
}
40+
41+
#output {
42+
margin: 16px;
43+
}
44+
45+
.header {
46+
background: white;
47+
border-bottom: 1px solid #d9d9d9;
48+
padding: 4px;
49+
top: 0;
50+
left: 0;
51+
position: fixed;
52+
width: 100%;
53+
text-align: right;
54+
}
55+
56+
.controls {
57+
display: inline-block;
58+
margin: 0;
59+
}
60+
61+
.button {
62+
background: #eee;
63+
border-radius: 2px;
64+
border: 1px solid #aaa;
65+
font-size: 11px;
66+
padding: 4px 6px;
67+
text-transform: uppercase;
68+
}
69+
</style>
70+
</head>
71+
<body>
72+
<header class="header">
73+
<p id="status">Loading</p>
74+
75+
<menu class="controls">
76+
<button class="button" id="hydrate">Hydrate</button>
77+
<button class="button" id="reload">Reload</button>
78+
</menu>
79+
</header>
80+
81+
<div id="output"></div>
82+
83+
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
84+
<script src="renderer.js"></script>
85+
</body>
86+
</html>

fixtures/dom/public/renderer.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/**
2+
* Supports render.html, a piece of the hydration fixture. See /hydration
3+
*/
4+
5+
'use strict';
6+
7+
(function() {
8+
var Fixture = null;
9+
var output = document.getElementById('output');
10+
var status = document.getElementById('status');
11+
var hydrate = document.getElementById('hydrate');
12+
var reload = document.getElementById('reload');
13+
var renders = 0;
14+
var failed = false;
15+
16+
function getQueryParam(key) {
17+
var pattern = new RegExp(key + '=([^&]+)(&|$)');
18+
var matches = window.location.search.match(pattern);
19+
20+
if (matches) {
21+
return decodeURIComponent(matches[1]);
22+
}
23+
24+
handleError(new Error('No key found for' + key));
25+
}
26+
27+
function getBooleanQueryParam(key) {
28+
return getQueryParam(key) === 'true';
29+
}
30+
31+
function setStatus(label) {
32+
status.innerHTML = label;
33+
}
34+
35+
function prerender() {
36+
setStatus('Generating markup');
37+
38+
output.innerHTML = ReactDOMServer.renderToString(
39+
React.createElement(Fixture)
40+
);
41+
42+
setStatus('Markup only (No React)');
43+
}
44+
45+
function render() {
46+
setStatus('Hydrating');
47+
48+
if (ReactDOM.hydrate) {
49+
ReactDOM.hydrate(React.createElement(Fixture), output);
50+
} else {
51+
ReactDOM.render(React.createElement(Fixture), output);
52+
}
53+
54+
setStatus(renders > 0 ? 'Re-rendered (' + renders + 'x)' : 'Hydrated');
55+
renders += 1;
56+
hydrate.innerHTML = 'Re-render';
57+
}
58+
59+
function handleError(error) {
60+
console.log(error);
61+
failed = true;
62+
setStatus('Javascript Error');
63+
output.innerHTML = error;
64+
}
65+
66+
function loadScript(src) {
67+
return new Promise(function(resolve, reject) {
68+
var script = document.createElement('script');
69+
script.async = true;
70+
script.src = src;
71+
72+
script.onload = resolve;
73+
script.onerror = function(error) {
74+
reject(new Error('Unable to load ' + src));
75+
};
76+
77+
document.body.appendChild(script);
78+
});
79+
}
80+
81+
function injectFixture(src) {
82+
Fixture = new Function(src + '\nreturn Fixture;')();
83+
84+
if (typeof Fixture === 'undefined') {
85+
setStatus('Failed');
86+
output.innerHTML = 'Please name your root component "Fixture"';
87+
} else {
88+
prerender();
89+
90+
if (getBooleanQueryParam('hydrate')) {
91+
render();
92+
}
93+
}
94+
}
95+
96+
function reloadFixture(code) {
97+
renders = 0;
98+
ReactDOM.unmountComponentAtNode(output);
99+
injectFixture(code);
100+
}
101+
102+
window.onerror = handleError;
103+
104+
reload.onclick = function() {
105+
window.location.reload();
106+
};
107+
108+
hydrate.onclick = render;
109+
110+
loadScript(getQueryParam('reactPath'))
111+
.then(function() {
112+
return getBooleanQueryParam('needsReactDOM')
113+
? loadScript(getQueryParam('reactDOMPath'))
114+
: null;
115+
})
116+
.then(function() {
117+
return loadScript(getQueryParam('reactDOMServerPath'));
118+
})
119+
.then(function() {
120+
if (failed) {
121+
return;
122+
}
123+
124+
window.addEventListener('message', function(event) {
125+
var data = JSON.parse(event.data);
126+
127+
switch (data.type) {
128+
case 'code':
129+
reloadFixture(data.payload);
130+
break;
131+
default:
132+
throw new Error(
133+
'Renderer Error: Unrecognized message "' + data.type + '"'
134+
);
135+
}
136+
});
137+
138+
window.parent.postMessage(JSON.stringify({type: 'ready'}), '*');
139+
})
140+
.catch(handleError);
141+
})();

fixtures/dom/src/components/App.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ function App() {
88
return (
99
<div>
1010
<Header />
11-
<div className="container">
12-
<Fixtures />
13-
</div>
11+
<Fixtures />
1412
</div>
1513
);
1614
}

fixtures/dom/src/components/FixtureSet.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class FixtureSet extends React.Component {
1111
const {title, description, children} = this.props;
1212

1313
return (
14-
<div>
14+
<div className="container">
1515
<h1>{title}</h1>
1616
{description && <p>{description}</p>}
1717

fixtures/dom/src/components/Header.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class Header extends React.Component {
5757
<select
5858
value={window.location.pathname}
5959
onChange={this.handleFixtureChange}>
60-
<option value="/">Select a Fixture</option>
60+
<option value="/">Home</option>
61+
<option value="/hydration">Hydration</option>
6162
<option value="/range-inputs">Range Inputs</option>
6263
<option value="/text-inputs">Text Inputs</option>
6364
<option value="/number-inputs">Number Input</option>

fixtures/dom/src/components/fixtures/home.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const React = window.React;
22

33
export default function Home() {
44
return (
5-
<main>
5+
<main className="container">
66
<h1>DOM Test Fixtures</h1>
77
<p>
88
Use this site to test browser quirks and other behavior that can not be
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
const React = window.React;
2+
3+
export class CodeEditor extends React.Component {
4+
shouldComponentUpdate() {
5+
return false;
6+
}
7+
8+
componentDidMount() {
9+
// Important: CodeMirror incorrectly lays out the editor
10+
// if it executes before CSS has loaded
11+
// https://github.com/graphql/graphiql/issues/33#issuecomment-318188555
12+
Promise.all([
13+
import('codemirror'),
14+
import('codemirror/mode/jsx/jsx'),
15+
import('codemirror/lib/codemirror.css'),
16+
import('./codemirror-paraiso-dark.css'),
17+
]).then(([CodeMirror]) => this.install(CodeMirror));
18+
}
19+
20+
install(CodeMirror) {
21+
if (!this.textarea) {
22+
return;
23+
}
24+
25+
const {onChange} = this.props;
26+
27+
this.editor = CodeMirror.fromTextArea(this.textarea, {
28+
mode: 'jsx',
29+
theme: 'paraiso-dark',
30+
lineNumbers: true,
31+
});
32+
33+
this.editor.on('change', function(doc) {
34+
onChange(doc.getValue());
35+
});
36+
}
37+
38+
componentWillUnmount() {
39+
if (this.editor) {
40+
this.editor.toTextArea();
41+
}
42+
}
43+
44+
render() {
45+
return (
46+
<textarea
47+
ref={ref => (this.textarea = ref)}
48+
defaultValue={this.props.code}
49+
autoComplete="off"
50+
hidden={true}
51+
/>
52+
);
53+
}
54+
}
55+
56+
/**
57+
* Prevent IE9 from raising an error on an unrecognized element:
58+
* See https://github.com/facebook/react/issues/13610
59+
*/
60+
const supportsDetails = !(
61+
document.createElement('details') instanceof HTMLUnknownElement
62+
);
63+
64+
export class CodeError extends React.Component {
65+
render() {
66+
const {error, className} = this.props;
67+
68+
if (!error) {
69+
return null;
70+
}
71+
72+
if (supportsDetails) {
73+
const [summary, ...body] = error.message.split(/\n+/g);
74+
75+
return (
76+
<details className={className}>
77+
<summary>{summary}</summary>
78+
{body.join('\n')}
79+
</details>
80+
);
81+
}
82+
83+
return <div className={className}>{error.message}</div>;
84+
}
85+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* Babel works across all browsers, however it requires many polyfills.
3+
*/
4+
5+
import 'core-js/es6/weak-map';
6+
import 'core-js/es6/weak-set';
7+
import 'core-js/es6/number';
8+
import 'core-js/es6/string';
9+
import 'core-js/es6/array';
10+
import 'core-js/modules/es6.object.set-prototype-of';
11+
12+
import {transform} from '@babel/standalone';
13+
14+
const presets = ['es2015', 'stage-3', 'react'];
15+
16+
export function compile(raw) {
17+
return transform(raw, {presets}).code;
18+
}

0 commit comments

Comments
 (0)