12 |
13 | #import "RCTLog.h"
14 | #import "RCTRootView.h"
15 |
16 | #define TIMEOUT_SECONDS 240
17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
18 |
19 | @interface ReactNativeARTTests : XCTestCase
20 |
21 | @end
22 |
23 | @implementation ReactNativeARTTests
24 |
25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
26 | {
27 | if (test(view)) {
28 | return YES;
29 | }
30 | for (UIView *subview in [view subviews]) {
31 | if ([self findSubviewInView:subview matching:test]) {
32 | return YES;
33 | }
34 | }
35 | return NO;
36 | }
37 |
38 | - (void)testRendersWelcomeScreen
39 | {
40 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
42 | BOOL foundElement = NO;
43 |
44 | __block NSString *redboxError = nil;
45 | RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) {
46 | if (level >= RCTLogLevelError) {
47 | redboxError = message;
48 | }
49 | });
50 |
51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
54 |
55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
57 | return YES;
58 | }
59 | return NO;
60 | }];
61 | }
62 |
63 | RCTSetLogFunction(RCTDefaultLogFunction);
64 |
65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
67 | }
68 |
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/examples/ReactNativeART/ios/main.jsbundle:
--------------------------------------------------------------------------------
1 | // Offline JS
2 | // To re-generate the offline bundle, run this from the root of your project:
3 | //
4 | // $ react-native bundle --minify
5 | //
6 | // See http://facebook.github.io/react-native/docs/runningondevice.html for more details.
7 |
8 | throw new Error('Offline JS file is empty. See iOS/main.jsbundle for instructions');
9 |
--------------------------------------------------------------------------------
/examples/ReactNativeART/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ReactNativeART",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "node_modules/react-native/packager/packager.sh"
7 | },
8 | "dependencies": {
9 | "art": "~0.10.0",
10 | "d3": "~3.5.6",
11 | "react-native": "^0.11.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/examples/animate.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yiminghe/learning-react/1b541e47021f4e7f5ffff413e6d0fd9440a13ca0/examples/animate.html
--------------------------------------------------------------------------------
/examples/animate.js:
--------------------------------------------------------------------------------
1 | import '../src/animate/index';
2 |
--------------------------------------------------------------------------------
/examples/code-share/Component.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Component = React.createClass({
4 | propTypes: {
5 | count: React.PropTypes.number,
6 | },
7 | getDefaultProps() {
8 | return {
9 | count: 0,
10 | disabled: true,
11 | };
12 | },
13 | getInitialState() {
14 | return {
15 | count: this.props.count,
16 | };
17 | },
18 | componentDidMount() {
19 | this.turnOn();
20 | },
21 | componentWillReceiveProps(nextProps) {
22 | this.setState({
23 | count: nextProps.count,
24 | });
25 | },
26 | turnOn() {
27 | this.setState({
28 | disabled: false,
29 | });
30 | },
31 | increase() {
32 | this.setState({
33 | count: this.state.count + 1,
34 | });
35 | },
36 | render() {
37 | return (
38 |
39 |
count
40 |
41 |
42 |
{this.state.count}
43 |
44 |
45 |
46 | );
47 | },
48 | });
49 |
50 | export default Component;
51 |
--------------------------------------------------------------------------------
/examples/code-share/Page.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | var consolePolyfill = `
3 | window.process = {
4 | env: {}
5 | };
6 | (function(global) {
7 | 'use strict';
8 | global.console = global.console || {};
9 | var con = global.console;
10 | var prop, method;
11 | var empty = {};
12 | var dummy = function() {};
13 | var properties = 'memory'.split(',');
14 | var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' +
15 | 'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +
16 | 'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(',');
17 | while (prop = properties.pop())
18 | if (!con[prop]) con[prop] = empty;
19 | while (method = methods.pop())
20 | if (!con[method]) con[method] = dummy;
21 | })(typeof window === 'undefined' ? this : window);
22 | `;
23 |
24 | var app = `
25 | require('./index');
26 | `;
27 |
28 | class Page extends React.Component {
29 | render() {
30 | return (
31 |
32 |
33 |
36 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | );
46 | }
47 | }
48 |
49 | Page.propTypes = {
50 | content: React.PropTypes.string,
51 | script: React.PropTypes.string,
52 | };
53 |
54 | export default Page;
55 |
--------------------------------------------------------------------------------
/examples/code-share/demo.html:
--------------------------------------------------------------------------------
1 | node 4
2 |
3 |
4 | node examples/code-share/server
5 |
6 |
7 |
8 |
9 | http://localhost:9001/examples/code-share/demo.html
10 |
--------------------------------------------------------------------------------
/examples/code-share/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import Component from './Component';
4 | const appData = window.appData;
5 | ReactDOM.render(, document.body);
6 |
--------------------------------------------------------------------------------
/examples/code-share/server.js:
--------------------------------------------------------------------------------
1 | require('babel-core/register')({
2 | extensions: ['.jsx'],
3 | });
4 |
5 | const serverRender = require('./serverRender');
6 | const app = require('rc-server')();
7 |
8 | app.get('/examples/code-share/demo.html', function *() {
9 | const count = 10;
10 | const content = serverRender.renderComponent(count);
11 | const appData = JSON.stringify({ count });
12 | this.body = serverRender.renderPage(content, `window.appData = ${appData};`);
13 | });
14 |
15 | var port = 9001;
16 |
17 | app.listen(port);
18 |
19 | console.log(`listening at ${port}`);
20 |
--------------------------------------------------------------------------------
/examples/code-share/serverRender.jsx:
--------------------------------------------------------------------------------
1 | const Component = require('./Component');
2 | const React = require('react');
3 | const ReactDOM = require('react-dom');
4 | const Page = require('./Page');
5 | module.exports = {
6 | renderComponent(count) {
7 | return ReactDOM.renderToString();
8 | },
9 |
10 | renderPage(content, script) {
11 | return ReactDOM.renderToStaticMarkup();
12 | },
13 | };
14 |
--------------------------------------------------------------------------------
/examples/diff-children.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yiminghe/learning-react/1b541e47021f4e7f5ffff413e6d0fd9440a13ca0/examples/diff-children.html
--------------------------------------------------------------------------------
/examples/diff-children.js:
--------------------------------------------------------------------------------
1 | import 'normalize.css';
2 |
3 | var content = document.getElementById('__react-content');
4 |
5 | content.innerHTML = `
6 | diff children demo
7 |
8 |
9 |
10 |
11 | `;
12 |
13 | var result = document.getElementById('result');
14 |
15 | var tmp = document.createElement('div');
16 |
17 | function getNode(html) {
18 | tmp.innerHTML = html;
19 | return tmp.firstChild;
20 | }
21 |
22 | function removeNode(node) {
23 | node.parentNode.removeChild(node);
24 | }
25 |
26 | function insertAtIndex(parent, child, index) {
27 | var after = parent.childNodes[index] || null;
28 | parent.insertBefore(child, after);
29 | }
30 |
31 | var node7 = {
32 | key: '.7',
33 | tag: 'div',
34 | _mountIndex: 0,
35 | };
36 |
37 | var node6 = {
38 | key: '.6',
39 | tag: 'div',
40 | _mountIndex: 1,
41 | };
42 |
43 | var node8 = {
44 | key: '.8',
45 | tag: 'div',
46 | _mountIndex: 2,
47 | };
48 |
49 | var node9 = {
50 | key: '.9',
51 | tag: 'div',
52 | _mountIndex: 3,
53 | };
54 |
55 |
56 | var prevChildren = {
57 | [node7.key]: node7,
58 | [node6.key]: node6,
59 | [node8.key]: node8,
60 | [node9.key]: node9,
61 | };
62 |
63 | var nodes = Object.keys(prevChildren).map((k) => {
64 | var node = prevChildren[k];
65 | return `<${node.tag}>${node.key} - ${node.tag}${node.tag}>`;
66 | });
67 |
68 | result.innerHTML = nodes.join('');
69 |
70 | var prevDOMChildNodes = result.childNodes;
71 |
72 | node7.dom = prevDOMChildNodes[0];
73 | node6.dom = prevDOMChildNodes[1];
74 | node8.dom = prevDOMChildNodes[2];
75 | node9.dom = prevDOMChildNodes[3];
76 |
77 | var newNode8 = {
78 | key: '.8',
79 | tag: 'p',
80 | };
81 |
82 | newNode8.dom = getNode(`<${newNode8.tag}>${newNode8.key} - ${newNode8.tag}${newNode8.tag}>`);
83 |
84 | var newNodeX = {
85 | key: '.x',
86 | tag: 'div',
87 | };
88 |
89 | newNodeX.dom = getNode(`<${newNodeX.tag}>${newNodeX.key} - ${newNodeX.tag}${newNodeX.tag}>`);
90 |
91 | var nextChildren = {
92 | [node9.key]: node9,
93 | [node7.key]: node7,
94 | [newNode8.key]: newNode8,
95 | [newNodeX.key]: newNodeX,
96 | };
97 |
98 | document.getElementById('action').onclick = function () {
99 | document.getElementById('action').disabled = true;
100 |
101 | var lastIndex = 0;
102 | var nextIndex = 0;
103 | var queue = [];
104 | for (var name in nextChildren) {
105 | if (!nextChildren.hasOwnProperty(name)) {
106 | continue;
107 | }
108 | var prevChild = prevChildren && prevChildren[name];
109 | var nextChild = nextChildren[name];
110 | if (prevChild === nextChild) {
111 | if (prevChild._mountIndex < lastIndex) {
112 | queue.push({
113 | type: 'move',
114 | child: prevChild,
115 | toIndex: nextIndex,
116 | });
117 | }
118 | lastIndex = Math.max(prevChild._mountIndex, lastIndex);
119 | prevChild._mountIndex = nextIndex;
120 | } else {
121 | if (prevChild) {
122 | // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
123 | lastIndex = Math.max(prevChild._mountIndex, lastIndex);
124 | queue.push({
125 | type: 'remove',
126 | child: prevChild,
127 | });
128 | }
129 | queue.push({
130 | type: 'new',
131 | child: nextChild,
132 | toIndex: nextIndex,
133 | });
134 | }
135 | nextIndex++;
136 | }
137 | // Remove children that are no longer present.
138 | for (const childName in prevChildren) {
139 | if (prevChildren.hasOwnProperty(childName) &&
140 | !(nextChildren && nextChildren.hasOwnProperty(childName))) {
141 | queue.push({
142 | type: 'remove',
143 | child: prevChildren[childName],
144 | });
145 | }
146 | }
147 |
148 | queue.forEach((q) => {
149 | if (q.type === 'remove' || q.type === 'move') {
150 | removeNode(q.child.dom);
151 |
152 | if (q.type === 'remove') {
153 | console.log('remove', q.child);
154 | }
155 | }
156 | });
157 |
158 | queue.forEach((q) => {
159 | if (q.type === 'new' || q.type === 'move') {
160 | insertAtIndex(result, q.child.dom, q.toIndex);
161 | console.log(q.type, q.child, 'to', q.toIndex);
162 | }
163 | });
164 | };
165 |
--------------------------------------------------------------------------------
/examples/flux.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yiminghe/learning-react/1b541e47021f4e7f5ffff413e6d0fd9440a13ca0/examples/flux.html
--------------------------------------------------------------------------------
/examples/flux.js:
--------------------------------------------------------------------------------
1 | import '../src/flux/index';
2 |
--------------------------------------------------------------------------------
/examples/key-lifecycle.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yiminghe/learning-react/1b541e47021f4e7f5ffff413e6d0fd9440a13ca0/examples/key-lifecycle.html
--------------------------------------------------------------------------------
/examples/key-lifecycle.js:
--------------------------------------------------------------------------------
1 | import '../src/key-lifecycle/index';
2 |
--------------------------------------------------------------------------------
/examples/load-on-demand.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yiminghe/learning-react/1b541e47021f4e7f5ffff413e6d0fd9440a13ca0/examples/load-on-demand.html
--------------------------------------------------------------------------------
/examples/load-on-demand.js:
--------------------------------------------------------------------------------
1 | import '../src/load-on-demand/index';
2 |
--------------------------------------------------------------------------------
/examples/react-art.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yiminghe/learning-react/1b541e47021f4e7f5ffff413e6d0fd9440a13ca0/examples/react-art.html
--------------------------------------------------------------------------------
/examples/react-art.js:
--------------------------------------------------------------------------------
1 | import '../src/react-art/index';
2 |
--------------------------------------------------------------------------------
/examples/react-intl.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yiminghe/learning-react/1b541e47021f4e7f5ffff413e6d0fd9440a13ca0/examples/react-intl.html
--------------------------------------------------------------------------------
/examples/react-intl.js:
--------------------------------------------------------------------------------
1 | import 'normalize.css';
2 |
3 | import qs from 'qs';
4 | import { addLocaleData, IntlProvider, FormattedMessage } from 'react-intl';
5 | import React from 'react';
6 | import ReactDOM from 'react-dom';
7 | import scriptjs from 'scriptjs';
8 |
9 | const locale = qs.parse(location.search && location.search.slice(1)).locale || 'en-US';
10 | const localePrefix = locale.slice(0, locale.indexOf('-'));
11 |
12 | const scripts = [];
13 |
14 | if (!window.Intl) {
15 | // should output by server by
118 |
119 |
120 |
128 |
129 |