Updates from Wed 24 Jun

This commit is contained in:
Alex Kotliarskyi
2015-06-24 10:49:09 -07:00
151 changed files with 7164 additions and 4079 deletions

View File

@@ -77,12 +77,14 @@ var SearchScreen = React.createClass({
var apiKey = API_KEYS[this.state.queryNumber % API_KEYS.length];
if (query) {
return (
// $FlowFixMe(>=0.13.0) - pageNumber may be null or undefined
API_URL + 'movies.json?apikey=' + apiKey + '&q=' +
encodeURIComponent(query) + '&page_limit=20&page=' + pageNumber
);
} else {
// With no query, load latest movies
return (
// $FlowFixMe(>=0.13.0) - pageNumber may be null or undefined
API_URL + 'lists/movies/in_theaters.json?apikey=' + apiKey +
'&page_limit=20&page=' + pageNumber
);

View File

@@ -600,7 +600,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../React/**",
);
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist";
INFOPLIST_FILE = "iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = SampleApp;
@@ -616,7 +616,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../React/**",
);
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist";
INFOPLIST_FILE = "iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = SampleApp;

View File

@@ -125,6 +125,7 @@ var Heading = React.createClass({
}
});
exports.displayName = (undefined: ?string);
exports.title = '<DatePickerIOS>';
exports.description = 'Select dates and times using the native UIDatePicker.';
exports.examples = [

View File

@@ -25,6 +25,7 @@ var {
var ImageCapInsetsExample = require('./ImageCapInsetsExample');
exports.displayName = (undefined: ?string);
exports.framework = 'React';
exports.title = '<Image>';
exports.description = 'Base component for displaying different types of images.';

View File

@@ -236,6 +236,7 @@ var styles = StyleSheet.create({
},
});
exports.displayName = (undefined: ?string);
exports.title = '<MapView>';
exports.description = 'Base component to display maps';
exports.examples = [

View File

@@ -92,6 +92,31 @@ function newRandomRoute() {
var NavigationBarSample = React.createClass({
componentWillMount: function() {
var navigator = this.props.navigator;
var callback = (event) => {
console.log(
`NavigationBarSample : event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from this component.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
},
componentWillUnmount: function() {
this._listeners && this._listeners.forEach(listener => listener.remove());
},
render: function() {
return (
<Navigator

View File

@@ -132,6 +132,7 @@ var TabBarExample = React.createClass({
render: function() {
return (
<Navigator
ref={this._setNavigatorRef}
style={styles.container}
initialRoute={{ message: "First Scene", }}
renderScene={this.renderScene}
@@ -145,6 +146,34 @@ var TabBarExample = React.createClass({
);
},
componentWillUnmount: function() {
this._listeners && this._listeners.forEach(listener => listener.remove());
},
_setNavigatorRef: function(navigator) {
if (navigator !== this._navigator) {
this._navigator = navigator;
if (navigator) {
var callback = (event) => {
console.log(
`TabBarExample: event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from the owner.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
}
}
},
});
var styles = StyleSheet.create({

View File

@@ -112,6 +112,7 @@ var PickerExample = React.createClass({
},
});
exports.displayName = (undefined: ?string);
exports.title = '<PickerIOS>';
exports.description = 'Render lists of selectable options with UIPickerView.';
exports.examples = [

View File

@@ -60,6 +60,7 @@ var ProgressViewExample = React.createClass({
},
});
exports.displayName = (undefined: ?string);
exports.framework = 'React';
exports.title = 'ProgressViewIOS';
exports.description = 'ProgressViewIOS';

View File

@@ -23,6 +23,7 @@ var {
Image
} = React;
exports.displayName = (undefined: ?string);
exports.title = '<ScrollView>';
exports.description = 'Component that enables scrolling through child components';
exports.examples = [

View File

@@ -25,7 +25,7 @@ var {
var Entity = React.createClass({
render: function() {
return (
<Text style={styles.entity}>
<Text style={{fontWeight: '500', color: '#527fe4'}}>
{this.props.children}
</Text>
);
@@ -34,7 +34,12 @@ var Entity = React.createClass({
var AttributeToggler = React.createClass({
getInitialState: function() {
return {fontWeight: '500', fontSize: 15};
return {fontWeight: 'bold', fontSize: 15};
},
toggleWeight: function() {
this.setState({
fontWeight: this.state.fontWeight === 'bold' ? 'normal' : 'bold'
});
},
increaseSize: function() {
this.setState({
@@ -42,22 +47,26 @@ var AttributeToggler = React.createClass({
});
},
render: function() {
var curStyle = {fontSize: this.state.fontSize};
var curStyle = {fontWeight: this.state.fontWeight, fontSize: this.state.fontSize};
return (
<Text>
<View>
<Text style={curStyle}>
Tap the controls below to change attributes.
</Text>
<Text>
See how it will even work on{' '}
<Text style={curStyle}>
this nested text
</Text>
<Text onPress={this.increaseSize}>
{'>> Increase Size <<'}
</Text>
<Text>See how it will even work on <Text style={curStyle}>this nested text</Text></Text>
</Text>
</Text>
<Text
style={{backgroundColor: '#ffaaaa', marginTop: 5}}
onPress={this.toggleWeight}>
Toggle Weight
</Text>
<Text
style={{backgroundColor: '#aaaaff', marginTop: 5}}
onPress={this.increaseSize}>
Increase Size
</Text>
</View>
);
}
});
@@ -206,6 +215,12 @@ exports.examples = [
render: function() {
return (
<View>
<Text>
auto (default) - english LTR
</Text>
<Text>
أحب اللغة العربية auto (default) - arabic RTL
</Text>
<Text style={{textAlign: 'left'}}>
left left left left left left left left left left left left left left left
</Text>
@@ -282,43 +297,21 @@ exports.examples = [
description: 'backgroundColor is inherited from all types of views.',
render: function() {
return (
<View style={{backgroundColor: 'yellow'}}>
<Text>
Yellow background inherited from View parent,
<Text style={{backgroundColor: '#ffaaaa'}}>
{' '}red background,
<Text style={{backgroundColor: '#aaaaff'}}>
{' '}blue background,
<Text>
{' '}inherited blue background,
<Text style={{backgroundColor: '#aaffaa'}}>
{' '}nested green background.
</Text>
<Text style={{backgroundColor: 'yellow'}}>
Yellow container background,
<Text style={{backgroundColor: '#ffaaaa'}}>
{' '}red background,
<Text style={{backgroundColor: '#aaaaff'}}>
{' '}blue background,
<Text>
{' '}inherited blue background,
<Text style={{backgroundColor: '#aaffaa'}}>
{' '}nested green background.
</Text>
</Text>
</Text>
</Text>
</View>
);
},
}, {
title: 'containerBackgroundColor attribute',
render: function() {
return (
<View style={{backgroundColor: 'yellow'}}>
<View style={{flexDirection: 'row', position: 'absolute', height: 80}}>
<View style={{backgroundColor: '#ffaaaa', width: 140}} />
<View style={{backgroundColor: '#aaaaff', width: 140}} />
</View>
<Text style={styles.backgroundColorText}>
Default containerBackgroundColor (inherited) + backgroundColor wash
</Text>
<Text style={[
styles.backgroundColorText,
{marginBottom: 5, containerBackgroundColor: 'transparent'}]}>
{"containerBackgroundColor: 'transparent' + backgroundColor wash"}
</Text>
</View>
</Text>
);
},
}, {
@@ -346,8 +339,4 @@ var styles = StyleSheet.create({
marginBottom: 0,
backgroundColor: 'rgba(100, 100, 100, 0.3)'
},
entity: {
fontWeight: '500',
color: '#527fe4',
},
});

View File

@@ -133,6 +133,7 @@ var styles = StyleSheet.create({
},
});
exports.displayName = (undefined: ?string);
exports.title = '<TextInput>';
exports.description = 'Single and multi-line text inputs.';
exports.examples = [

View File

@@ -26,6 +26,7 @@ var {
View,
} = React;
exports.displayName = (undefined: ?string);
exports.title = '<Touchable*> and onPress';
exports.examples = [
{

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
version = "1.3">
version = "1.8">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
@@ -22,10 +22,10 @@
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "004D289D1AAF61C70097A701"
@@ -36,10 +36,10 @@
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "143BC5941B21E3E100462512"

View File

@@ -26,16 +26,12 @@
- (void)setUp
{
#if __LP64__
#error Tests should be run on 32-bit device simulators (e.g. iPhone 5)
RCTAssert(false, @"Tests should be run on 32-bit device simulators (e.g. iPhone 5)");
#endif
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
RCTAssert(version.majorVersion == 8 || version.minorVersion == 3, @"Tests should be run on iOS 8.3, found %zd.%zd.%zd", version.majorVersion, version.minorVersion, version.patchVersion);
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp");
// If tests have changes, set recordMode = YES below and run the affected
// tests on an iPhone5, iOS 8.3 simulator.
_runner.recordMode = NO;
}
#pragma mark Logic Tests
@@ -53,8 +49,7 @@
expectErrorBlock:nil];
}
// TODO: this seems to stall forever - figure out why
- (void)DISABLED_testTheTester_ExpectError
- (void)testTheTester_ExpectError
{
[_runner runTest:_cmd
module:@"IntegrationTestHarnessTest"
@@ -91,12 +86,9 @@
- (void)testSimpleSnapshot
{
// If tests have changes, set recordMode = YES below and re-run
_runner.recordMode = NO;
[_runner runTest:_cmd module:@"SimpleSnapshotTest"];
}
- (void)testZZZ_NotInRecordMode
{
RCTAssert(_runner.recordMode == NO, @"Don't forget to turn record mode back to NO before commit.");
}
@end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 264 KiB

View File

@@ -21,8 +21,6 @@
#import "RCTRedBox.h"
#import "RCTRootView.h"
#define TIMEOUT_SECONDS 240
@interface UIExplorerTests : XCTestCase
{
RCTTestRunner *_runner;
@@ -40,52 +38,6 @@
NSString *version = [[UIDevice currentDevice] systemVersion];
RCTAssert([version isEqualToString:@"8.3"], @"Snapshot tests should be run on iOS 8.3, found %@", version);
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerApp.ios");
// If tests have changes, set recordMode = YES below and run the affected
// tests on an iPhone5, iOS 8.3 simulator.
_runner.recordMode = NO;
}
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
{
if (test(view)) {
return YES;
}
for (UIView *subview in [view subviews]) {
if ([self findSubviewInView:subview matching:test]) {
return YES;
}
}
return NO;
}
// Make sure this test runs first because the other tests will tear out the rootView
- (void)testAAA_RootViewLoadsAndRenders
{
// TODO (t7296305) Fix and Re-Enable this UIExplorer Test
return;
UIViewController *vc = [UIApplication sharedApplication].delegate.window.rootViewController;
RCTAssert([vc.view isKindOfClass:[RCTRootView class]], @"This test must run first.");
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
BOOL foundElement = NO;
NSString *redboxError = nil;
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
redboxError = [[RCTRedBox sharedInstance] currentErrorMessage];
foundElement = [self findSubviewInView:vc.view matching:^(UIView *view) {
if ([view.accessibilityLabel isEqualToString:@"<View>"]) {
return YES;
}
return NO;
}];
}
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
XCTAssertTrue(foundElement, @"Couldn't find element with '<View>' text in %d seconds", TIMEOUT_SECONDS);
}
#define RCT_SNAPSHOT_TEST(name, reRecord) \
@@ -102,10 +54,4 @@ RCT_SNAPSHOT_TEST(SwitchExample, NO)
RCT_SNAPSHOT_TEST(SliderExample, NO)
RCT_SNAPSHOT_TEST(TabBarExample, NO)
// Make sure this test runs last
- (void)testZZZ_NotInRecordMode
{
RCTAssert(_runner.recordMode == NO, @"Don't forget to turn record mode back to NO before commit.");
}
@end

View File

@@ -53,6 +53,8 @@ var AppEventsTest = React.createClass({
}
});
AppEventsTest.displayName = 'AppEventsTest';
var styles = StyleSheet.create({
container: {
margin: 40,

View File

@@ -53,15 +53,18 @@ function expectEqual(lhs, rhs, testname) {
);
}
function expectAsyncNoError(err) {
expectTrue(err === null, 'Unexpected Async error: ' + JSON.stringify(err));
function expectAsyncNoError(place, err) {
if (err instanceof Error) {
err = err.message;
}
expectTrue(err === null, 'Unexpected error in ' + place + ': ' + JSON.stringify(err));
}
function testSetAndGet() {
AsyncStorage.setItem(KEY_1, VAL_1, (err1) => {
expectAsyncNoError(err1);
expectAsyncNoError('testSetAndGet/setItem', err1);
AsyncStorage.getItem(KEY_1, (err2, result) => {
expectAsyncNoError(err2);
expectAsyncNoError('testSetAndGet/getItem', err2);
expectEqual(result, VAL_1, 'testSetAndGet setItem');
updateMessage('get(key_1) correctly returned ' + result);
runTestCase('should get null for missing key', testMissingGet);
@@ -71,7 +74,7 @@ function testSetAndGet() {
function testMissingGet() {
AsyncStorage.getItem(KEY_2, (err, result) => {
expectAsyncNoError(err);
expectAsyncNoError('testMissingGet/setItem', err);
expectEqual(result, null, 'testMissingGet');
updateMessage('missing get(key_2) correctly returned ' + result);
runTestCase('check set twice results in a single key', testSetTwice);
@@ -82,7 +85,7 @@ function testSetTwice() {
AsyncStorage.setItem(KEY_1, VAL_1, ()=>{
AsyncStorage.setItem(KEY_1, VAL_1, ()=>{
AsyncStorage.getItem(KEY_1, (err, result) => {
expectAsyncNoError(err);
expectAsyncNoError('testSetTwice/setItem', err);
expectEqual(result, VAL_1, 'testSetTwice');
updateMessage('setTwice worked as expected');
runTestCase('test removeItem', testRemoveItem);
@@ -95,17 +98,17 @@ function testRemoveItem() {
AsyncStorage.setItem(KEY_1, VAL_1, ()=>{
AsyncStorage.setItem(KEY_2, VAL_2, ()=>{
AsyncStorage.getAllKeys((err, result) => {
expectAsyncNoError(err);
expectAsyncNoError('testRemoveItem/getAllKeys', err);
expectTrue(
result.indexOf(KEY_1) >= 0 && result.indexOf(KEY_2) >= 0,
'Missing KEY_1 or KEY_2 in ' + '(' + result + ')'
);
updateMessage('testRemoveItem - add two items');
AsyncStorage.removeItem(KEY_1, (err2) => {
expectAsyncNoError(err2);
expectAsyncNoError('testRemoveItem/removeItem', err2);
updateMessage('delete successful ');
AsyncStorage.getItem(KEY_1, (err3, result2) => {
expectAsyncNoError(err3);
expectAsyncNoError('testRemoveItem/getItem', err3);
expectEqual(
result2,
null,
@@ -113,7 +116,7 @@ function testRemoveItem() {
);
updateMessage('key properly removed ');
AsyncStorage.getAllKeys((err4, result3) => {
expectAsyncNoError(err4);
expectAsyncNoError('testRemoveItem/getAllKeys', err4);
expectTrue(
result3.indexOf(KEY_1) === -1,
'Unexpected: KEY_1 present in ' + result3
@@ -130,11 +133,11 @@ function testRemoveItem() {
function testMerge() {
AsyncStorage.setItem(KEY_MERGE, JSON.stringify(VAL_MERGE_1), (err1) => {
expectAsyncNoError(err1);
expectAsyncNoError('testMerge/setItem', err1);
AsyncStorage.mergeItem(KEY_MERGE, JSON.stringify(VAL_MERGE_2), (err2) => {
expectAsyncNoError(err2);
expectAsyncNoError('testMerge/mergeItem', err2);
AsyncStorage.getItem(KEY_MERGE, (err3, result) => {
expectAsyncNoError(err3);
expectAsyncNoError('testMerge/setItem', err3);
expectEqual(JSON.parse(result), VAL_MERGE_EXPECT, 'testMerge');
updateMessage('objects deeply merged\nDone!');
done();
@@ -173,4 +176,6 @@ var AsyncStorageTest = React.createClass({
}
});
AsyncStorageTest.displayName = 'AsyncStorageTest';
module.exports = AsyncStorageTest;

View File

@@ -59,4 +59,6 @@ var IntegrationTestHarnessTest = React.createClass({
}
});
IntegrationTestHarnessTest.displayName = 'IntegrationTestHarnessTest';
module.exports = IntegrationTestHarnessTest;

View File

@@ -164,4 +164,6 @@ var styles = StyleSheet.create({
},
});
LayoutEventsTest.displayName = 'LayoutEventsTest';
module.exports = LayoutEventsTest;

View File

@@ -22,7 +22,7 @@ var PromiseTest = React.createClass({
Promise.all([
this.testShouldResolve(),
this.testShouldReject(),
]).then(() => RCTTestModule.finish(
]).then(() => RCTTestModule.markTestPassed(
this.shouldResolve && this.shouldReject
));
},
@@ -42,9 +42,11 @@ var PromiseTest = React.createClass({
},
render() {
return <React.View />;
return <React.View />;
}
});
PromiseTest.displayName = 'PromiseTest';
module.exports = PromiseTest;

View File

@@ -24,8 +24,8 @@ var SimpleSnapshotTest = React.createClass({
requestAnimationFrame(() => TestModule.verifySnapshot(this.done));
},
done() {
TestModule.markTestCompleted();
done(success) {
TestModule.markTestPassed(success);
},
render() {
@@ -53,4 +53,6 @@ var styles = StyleSheet.create({
},
});
SimpleSnapshotTest.displayName = 'SimpleSnapshotTest';
module.exports = SimpleSnapshotTest;

View File

@@ -152,4 +152,6 @@ var styles = StyleSheet.create({
},
});
TimersTest.displayName = 'TimersTest';
module.exports = TimersTest;

View File

@@ -115,7 +115,7 @@ COMPONENTS.concat(APIS).forEach((Example) => {
// View is still blank after first RAF :\
global.requestAnimationFrame(() =>
global.requestAnimationFrame(() => TestModule.verifySnapshot(
TestModule.markTestCompleted
TestModule.markTestPassed
)
));
},

View File

@@ -79,25 +79,19 @@ RCT_EXPORT_MODULE()
{
RCTBridge *_bridge;
BOOL _testMethodCalled;
dispatch_queue_t _queue;
}
@end
@implementation RCTBridgeTests
RCT_EXPORT_MODULE(TestModule)
@synthesize methodQueue = _methodQueue;
- (dispatch_queue_t)methodQueue
{
return _queue;
}
RCT_EXPORT_MODULE(TestModule)
- (void)setUp
{
[super setUp];
_queue = dispatch_queue_create("com.facebook.React.TestQueue", DISPATCH_QUEUE_SERIAL);
_bridge = [[RCTBridge alloc] initWithBundleURL:nil
moduleProvider:^{ return @[self]; }
launchOptions:nil];
@@ -151,7 +145,7 @@ RCT_EXPORT_MODULE(TestModule)
[_bridge.batchedBridge _handleBuffer:buffer context:RCTGetExecutorID(executor)];
dispatch_sync(_queue, ^{
dispatch_sync(_methodQueue, ^{
// clear the queue
XCTAssertTrue(_testMethodCalled);
});

View File

@@ -0,0 +1,99 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import <XCTest/XCTest.h>
#import "RCTShadowView.h"
@interface RCTShadowViewTests : XCTestCase
@end
@implementation RCTShadowViewTests
// Just a basic sanity test to ensure css-layout is applied correctly in the context of our shadow view hierarchy.
//
// ====================================
// || header ||
// ====================================
// || || || ||
// || left || center || right ||
// || || || ||
// ====================================
// || footer ||
// ====================================
//
- (void)testApplyingLayoutRecursivelyToShadowView
{
RCTShadowView *leftView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex = 1;
}];
RCTShadowView *centerView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex = 2;
style->margin[0] = 10;
style->margin[2] = 10;
}];
RCTShadowView *rightView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex = 1;
}];
RCTShadowView *mainView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex_direction = CSS_FLEX_DIRECTION_ROW;
style->flex = 2;
style->margin[1] = 10;
style->margin[3] = 10;
}];
[mainView insertReactSubview:leftView atIndex:0];
[mainView insertReactSubview:centerView atIndex:1];
[mainView insertReactSubview:rightView atIndex:2];
RCTShadowView *headerView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex = 1;
}];
RCTShadowView *footerView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex = 1;
}];
RCTShadowView *parentView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex_direction = CSS_FLEX_DIRECTION_COLUMN;
style->padding[0] = 10;
style->padding[1] = 10;
style->padding[2] = 10;
style->padding[3] = 10;
style->dimensions[0] = 440;
style->dimensions[1] = 440;
}];
[parentView insertReactSubview:headerView atIndex:0];
[parentView insertReactSubview:mainView atIndex:1];
[parentView insertReactSubview:footerView atIndex:2];
[parentView collectRootUpdatedFrames:nil parentConstraint:CGSizeZero];
XCTAssertTrue(CGRectEqualToRect([parentView measureLayoutRelativeToAncestor:parentView], CGRectMake(0, 0, 440, 440)));
XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets([parentView paddingAsInsets], UIEdgeInsetsMake(10, 10, 10, 10)));
XCTAssertTrue(CGRectEqualToRect([headerView measureLayoutRelativeToAncestor:parentView], CGRectMake(10, 10, 420, 100)));
XCTAssertTrue(CGRectEqualToRect([mainView measureLayoutRelativeToAncestor:parentView], CGRectMake(10, 120, 420, 200)));
XCTAssertTrue(CGRectEqualToRect([footerView measureLayoutRelativeToAncestor:parentView], CGRectMake(10, 330, 420, 100)));
XCTAssertTrue(CGRectEqualToRect([leftView measureLayoutRelativeToAncestor:parentView], CGRectMake(10, 120, 100, 200)));
XCTAssertTrue(CGRectEqualToRect([centerView measureLayoutRelativeToAncestor:parentView], CGRectMake(120, 120, 200, 200)));
XCTAssertTrue(CGRectEqualToRect([rightView measureLayoutRelativeToAncestor:parentView], CGRectMake(330, 120, 100, 200)));
}
- (RCTShadowView *)_shadowViewWithStyle:(void(^)(css_style_t *style))styleBlock
{
RCTShadowView *shadowView = [[RCTShadowView alloc] init];
css_style_t style = shadowView.cssNode->style;
styleBlock(&style);
shadowView.cssNode->style = style;
return shadowView;
}
@end

View File

@@ -43,6 +43,7 @@ var WebViewExample = React.createClass({
backButtonEnabled: false,
forwardButtonEnabled: false,
loading: true,
scalesPageToFit: true,
};
},
@@ -97,6 +98,7 @@ var WebViewExample = React.createClass({
javaScriptEnabledAndroid={true}
onNavigationStateChange={this.onNavigationStateChange}
startInLoadingState={true}
scalesPageToFit={this.state.scalesPageToFit}
/>
<View style={styles.statusBar}>
<Text style={styles.statusBarText}>{this.state.status}</Text>
@@ -124,6 +126,7 @@ var WebViewExample = React.createClass({
url: navState.url,
status: navState.title,
loading: navState.loading,
scalesPageToFit: true
});
},
@@ -217,6 +220,7 @@ var styles = StyleSheet.create({
},
});
exports.displayName = (undefined: ?string);
exports.title = '<WebView>';
exports.description = 'Base component to display web content';
exports.examples = [