Use HostContext to warn about invalid View/Text nesting (#12766)
This commit is contained in:
parent
c5d3104fc0
commit
c802d29bd1
|
@ -22,7 +22,7 @@ import * as ReactNativeViewConfigRegistry from 'ReactNativeViewConfigRegistry';
|
|||
import ReactFiberReconciler from 'react-reconciler';
|
||||
|
||||
import deepFreezeAndThrowOnMutationInDev from 'deepFreezeAndThrowOnMutationInDev';
|
||||
import emptyObject from 'fbjs/lib/emptyObject';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
// Modules provided by RN:
|
||||
import TextInputState from 'TextInputState';
|
||||
|
@ -35,6 +35,10 @@ import UIManager from 'UIManager';
|
|||
// This means that they never overlap.
|
||||
let nextReactTag = 2;
|
||||
|
||||
type HostContext = $ReadOnly<{|
|
||||
isInAParentText: boolean,
|
||||
|}>;
|
||||
|
||||
/**
|
||||
* This is used for refs on host components.
|
||||
*/
|
||||
|
@ -135,7 +139,7 @@ const ReactFabricRenderer = ReactFiberReconciler({
|
|||
type: string,
|
||||
props: Props,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
hostContext: HostContext,
|
||||
internalInstanceHandle: Object,
|
||||
): Instance {
|
||||
const tag = nextReactTag;
|
||||
|
@ -151,6 +155,11 @@ const ReactFabricRenderer = ReactFiberReconciler({
|
|||
}
|
||||
}
|
||||
|
||||
invariant(
|
||||
type !== 'RCTView' || !hostContext.isInAParentText,
|
||||
'Nesting of <View> within <Text> is not currently supported.',
|
||||
);
|
||||
|
||||
const updatePayload = ReactNativeAttributePayload.create(
|
||||
props,
|
||||
viewConfig.validAttributes,
|
||||
|
@ -175,9 +184,14 @@ const ReactFabricRenderer = ReactFiberReconciler({
|
|||
createTextInstance(
|
||||
text: string,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
hostContext: HostContext,
|
||||
internalInstanceHandle: Object,
|
||||
): TextInstance {
|
||||
invariant(
|
||||
hostContext.isInAParentText,
|
||||
'Text strings must be rendered within a <Text> component.',
|
||||
);
|
||||
|
||||
const tag = nextReactTag;
|
||||
nextReactTag += 2;
|
||||
|
||||
|
@ -203,12 +217,27 @@ const ReactFabricRenderer = ReactFiberReconciler({
|
|||
return false;
|
||||
},
|
||||
|
||||
getRootHostContext(): {} {
|
||||
return emptyObject;
|
||||
getRootHostContext(rootContainerInstance: Container): HostContext {
|
||||
return {isInAParentText: false};
|
||||
},
|
||||
|
||||
getChildHostContext(): {} {
|
||||
return emptyObject;
|
||||
getChildHostContext(
|
||||
parentHostContext: HostContext,
|
||||
type: string,
|
||||
): HostContext {
|
||||
const prevIsInAParentText = parentHostContext.isInAParentText;
|
||||
const isInAParentText =
|
||||
type === 'AndroidTextInput' || // Android
|
||||
type === 'RCTMultilineTextInputView' || // iOS
|
||||
type === 'RCTSinglelineTextInputView' || // iOS
|
||||
type === 'RCTText' ||
|
||||
type === 'RCTVirtualText';
|
||||
|
||||
if (prevIsInAParentText !== isInAParentText) {
|
||||
return {isInAParentText};
|
||||
} else {
|
||||
return parentHostContext;
|
||||
}
|
||||
},
|
||||
|
||||
getPublicInstance(instance) {
|
||||
|
@ -230,7 +259,7 @@ const ReactFabricRenderer = ReactFiberReconciler({
|
|||
oldProps: Props,
|
||||
newProps: Props,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
hostContext: HostContext,
|
||||
): null | Object {
|
||||
const viewConfig = instance.canonical.viewConfig;
|
||||
const updatePayload = ReactNativeAttributePayload.diff(
|
||||
|
|
|
@ -12,6 +12,7 @@ import type {ReactNativeBaseComponentViewConfig} from './ReactNativeTypes';
|
|||
import ReactFiberReconciler from 'react-reconciler';
|
||||
import emptyObject from 'fbjs/lib/emptyObject';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
// Modules provided by RN:
|
||||
import UIManager from 'UIManager';
|
||||
import deepFreezeAndThrowOnMutationInDev from 'deepFreezeAndThrowOnMutationInDev';
|
||||
|
@ -35,6 +36,10 @@ export type Instance = {
|
|||
type Props = Object;
|
||||
type TextInstance = number;
|
||||
|
||||
type HostContext = $ReadOnly<{|
|
||||
isInAParentText: boolean,
|
||||
|}>;
|
||||
|
||||
// Counter for uniquely identifying views.
|
||||
// % 10 === 1 means it is a rootTag.
|
||||
// % 2 === 0 means it is a Fabric tag.
|
||||
|
@ -71,7 +76,7 @@ const NativeRenderer = ReactFiberReconciler({
|
|||
type: string,
|
||||
props: Props,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
hostContext: HostContext,
|
||||
internalInstanceHandle: Object,
|
||||
): Instance {
|
||||
const tag = allocateTag();
|
||||
|
@ -85,6 +90,11 @@ const NativeRenderer = ReactFiberReconciler({
|
|||
}
|
||||
}
|
||||
|
||||
invariant(
|
||||
type !== 'RCTView' || !hostContext.isInAParentText,
|
||||
'Nesting of <View> within <Text> is not currently supported.',
|
||||
);
|
||||
|
||||
const updatePayload = ReactNativeAttributePayload.create(
|
||||
props,
|
||||
viewConfig.validAttributes,
|
||||
|
@ -110,9 +120,14 @@ const NativeRenderer = ReactFiberReconciler({
|
|||
createTextInstance(
|
||||
text: string,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
hostContext: HostContext,
|
||||
internalInstanceHandle: Object,
|
||||
): TextInstance {
|
||||
invariant(
|
||||
hostContext.isInAParentText,
|
||||
'Text strings must be rendered within a <Text> component.',
|
||||
);
|
||||
|
||||
const tag = allocateTag();
|
||||
|
||||
UIManager.createView(
|
||||
|
@ -155,12 +170,27 @@ const NativeRenderer = ReactFiberReconciler({
|
|||
return false;
|
||||
},
|
||||
|
||||
getRootHostContext(): {} {
|
||||
return emptyObject;
|
||||
getRootHostContext(rootContainerInstance: Container): HostContext {
|
||||
return {isInAParentText: false};
|
||||
},
|
||||
|
||||
getChildHostContext(): {} {
|
||||
return emptyObject;
|
||||
getChildHostContext(
|
||||
parentHostContext: HostContext,
|
||||
type: string,
|
||||
): HostContext {
|
||||
const prevIsInAParentText = parentHostContext.isInAParentText;
|
||||
const isInAParentText =
|
||||
type === 'AndroidTextInput' || // Android
|
||||
type === 'RCTMultilineTextInputView' || // iOS
|
||||
type === 'RCTSinglelineTextInputView' || // iOS
|
||||
type === 'RCTText' ||
|
||||
type === 'RCTVirtualText';
|
||||
|
||||
if (prevIsInAParentText !== isInAParentText) {
|
||||
return {isInAParentText};
|
||||
} else {
|
||||
return parentHostContext;
|
||||
}
|
||||
},
|
||||
|
||||
getPublicInstance(instance) {
|
||||
|
@ -181,7 +211,7 @@ const NativeRenderer = ReactFiberReconciler({
|
|||
oldProps: Props,
|
||||
newProps: Props,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
hostContext: HostContext,
|
||||
): null | Object {
|
||||
return emptyObject;
|
||||
},
|
||||
|
|
|
@ -33,9 +33,9 @@ describe('ReactFabric', () => {
|
|||
});
|
||||
|
||||
it('should be able to create and render a native component', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
ReactFabric.render(<View foo="test" />, 1);
|
||||
|
@ -45,9 +45,9 @@ describe('ReactFabric', () => {
|
|||
});
|
||||
|
||||
it('should be able to create and update a native component', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
const firstNode = {};
|
||||
|
@ -67,9 +67,9 @@ describe('ReactFabric', () => {
|
|||
});
|
||||
|
||||
it('should not call FabricUIManager.cloneNode after render for properties that have not changed', () => {
|
||||
const Text = createReactNativeComponentClass('Text', () => ({
|
||||
const Text = createReactNativeComponentClass('RCTText', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'Text',
|
||||
uiViewClassName: 'RCTText',
|
||||
}));
|
||||
|
||||
ReactFabric.render(<Text foo="a">1</Text>, 11);
|
||||
|
@ -110,15 +110,15 @@ describe('ReactFabric', () => {
|
|||
});
|
||||
|
||||
it('should only pass props diffs to FabricUIManager.cloneNode', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const Text = createReactNativeComponentClass('RCTText', () => ({
|
||||
validAttributes: {foo: true, bar: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTText',
|
||||
}));
|
||||
|
||||
ReactFabric.render(
|
||||
<View foo="a" bar="a">
|
||||
<Text foo="a" bar="a">
|
||||
1
|
||||
</View>,
|
||||
</Text>,
|
||||
11,
|
||||
);
|
||||
expect(FabricUIManager.cloneNode).not.toBeCalled();
|
||||
|
@ -127,9 +127,9 @@ describe('ReactFabric', () => {
|
|||
expect(FabricUIManager.cloneNodeWithNewChildrenAndProps).not.toBeCalled();
|
||||
|
||||
ReactFabric.render(
|
||||
<View foo="a" bar="b">
|
||||
<Text foo="a" bar="b">
|
||||
1
|
||||
</View>,
|
||||
</Text>,
|
||||
11,
|
||||
);
|
||||
expect(FabricUIManager.cloneNodeWithNewProps.mock.calls[0][1]).toEqual({
|
||||
|
@ -138,9 +138,9 @@ describe('ReactFabric', () => {
|
|||
expect(FabricUIManager.__dumpHierarchyForJestTestsOnly()).toMatchSnapshot();
|
||||
|
||||
ReactFabric.render(
|
||||
<View foo="b" bar="b">
|
||||
<Text foo="b" bar="b">
|
||||
2
|
||||
</View>,
|
||||
</Text>,
|
||||
11,
|
||||
);
|
||||
expect(
|
||||
|
@ -152,9 +152,9 @@ describe('ReactFabric', () => {
|
|||
});
|
||||
|
||||
it('should not call UIManager.updateView from setNativeProps for properties that have not changed', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
class Subclass extends ReactFabric.NativeComponent {
|
||||
|
@ -187,9 +187,9 @@ describe('ReactFabric', () => {
|
|||
});
|
||||
|
||||
it('returns the correct instance and calls it in the callback', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
let a;
|
||||
|
@ -208,9 +208,9 @@ describe('ReactFabric', () => {
|
|||
});
|
||||
|
||||
it('renders and reorders children', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {title: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
class Component extends React.Component {
|
||||
|
@ -249,9 +249,9 @@ describe('ReactFabric', () => {
|
|||
});
|
||||
|
||||
it('should call complete after inserting children', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
const snapshots = [];
|
||||
|
@ -272,4 +272,80 @@ describe('ReactFabric', () => {
|
|||
);
|
||||
expect(snapshots).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should throw when <View> is used inside of a <Text> ancestor', () => {
|
||||
const Image = createReactNativeComponentClass('RCTImage', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTImage',
|
||||
}));
|
||||
const Text = createReactNativeComponentClass('RCTText', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTText',
|
||||
}));
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
expect(() =>
|
||||
ReactFabric.render(
|
||||
<Text>
|
||||
<View />
|
||||
</Text>,
|
||||
11,
|
||||
),
|
||||
).toThrow('Nesting of <View> within <Text> is not currently supported.');
|
||||
|
||||
// Non-View things (e.g. Image) are fine
|
||||
ReactFabric.render(
|
||||
<Text>
|
||||
<Image />
|
||||
</Text>,
|
||||
11,
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw for text not inside of a <Text> ancestor', () => {
|
||||
const ScrollView = createReactNativeComponentClass('RCTScrollView', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTScrollView',
|
||||
}));
|
||||
const Text = createReactNativeComponentClass('RCTText', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTText',
|
||||
}));
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
expect(() => ReactFabric.render(<View>this should warn</View>, 11)).toThrow(
|
||||
'Text strings must be rendered within a <Text> component.',
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
ReactFabric.render(
|
||||
<Text>
|
||||
<ScrollView>hi hello hi</ScrollView>
|
||||
</Text>,
|
||||
11,
|
||||
),
|
||||
).toThrow('Text strings must be rendered within a <Text> component.');
|
||||
});
|
||||
|
||||
it('should not throw for text inside of an indirect <Text> ancestor', () => {
|
||||
const Text = createReactNativeComponentClass('RCTText', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTText',
|
||||
}));
|
||||
|
||||
const Indirection = () => 'Hi';
|
||||
|
||||
ReactFabric.render(
|
||||
<Text>
|
||||
<Indirection />
|
||||
</Text>,
|
||||
11,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -31,9 +31,9 @@ describe('ReactFabric', () => {
|
|||
});
|
||||
|
||||
it('find Fabric nodes with the RN renderer', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {title: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
let ref = React.createRef();
|
||||
|
|
|
@ -153,7 +153,7 @@ it('handles events', () => {
|
|||
it('handles events on text nodes', () => {
|
||||
expect(RCTEventEmitter.register.mock.calls.length).toBe(1);
|
||||
const EventEmitter = RCTEventEmitter.register.mock.calls[0][0];
|
||||
const Text = fakeRequireNativeComponent('Text', {});
|
||||
const Text = fakeRequireNativeComponent('RCTText', {});
|
||||
|
||||
class ContextHack extends React.Component {
|
||||
static childContextTypes = {isInAParentText: PropTypes.bool};
|
||||
|
|
|
@ -27,9 +27,9 @@ describe('ReactNative', () => {
|
|||
});
|
||||
|
||||
it('should be able to create and render a native component', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
ReactNative.render(<View foo="test" />, 1);
|
||||
|
@ -40,9 +40,9 @@ describe('ReactNative', () => {
|
|||
});
|
||||
|
||||
it('should be able to create and update a native component', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
ReactNative.render(<View foo="foo" />, 11);
|
||||
|
@ -57,13 +57,13 @@ describe('ReactNative', () => {
|
|||
expect(UIManager.createView.mock.calls.length).toBe(1);
|
||||
expect(UIManager.setChildren.mock.calls.length).toBe(1);
|
||||
expect(UIManager.manageChildren).not.toBeCalled();
|
||||
expect(UIManager.updateView).toBeCalledWith(3, 'View', {foo: 'bar'});
|
||||
expect(UIManager.updateView).toBeCalledWith(3, 'RCTView', {foo: 'bar'});
|
||||
});
|
||||
|
||||
it('should not call UIManager.updateView after render for properties that have not changed', () => {
|
||||
const Text = createReactNativeComponentClass('Text', () => ({
|
||||
const Text = createReactNativeComponentClass('RCTText', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'Text',
|
||||
uiViewClassName: 'RCTText',
|
||||
}));
|
||||
|
||||
ReactNative.render(<Text foo="a">1</Text>, 11);
|
||||
|
@ -87,9 +87,9 @@ describe('ReactNative', () => {
|
|||
});
|
||||
|
||||
it('should not call UIManager.updateView from setNativeProps for properties that have not changed', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
class Subclass extends ReactNative.NativeComponent {
|
||||
|
@ -122,9 +122,9 @@ describe('ReactNative', () => {
|
|||
});
|
||||
|
||||
it('returns the correct instance and calls it in the callback', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {foo: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
let a;
|
||||
|
@ -143,9 +143,9 @@ describe('ReactNative', () => {
|
|||
});
|
||||
|
||||
it('renders and reorders children', () => {
|
||||
const View = createReactNativeComponentClass('View', () => ({
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {title: true},
|
||||
uiViewClassName: 'View',
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
class Component extends React.Component {
|
||||
|
@ -182,4 +182,80 @@ describe('ReactNative', () => {
|
|||
ReactNative.render(<Component />, 11);
|
||||
expect(mockArgs.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should throw when <View> is used inside of a <Text> ancestor', () => {
|
||||
const Image = createReactNativeComponentClass('RCTImage', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTImage',
|
||||
}));
|
||||
const Text = createReactNativeComponentClass('RCTText', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTText',
|
||||
}));
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
expect(() =>
|
||||
ReactNative.render(
|
||||
<Text>
|
||||
<View />
|
||||
</Text>,
|
||||
11,
|
||||
),
|
||||
).toThrow('Nesting of <View> within <Text> is not currently supported.');
|
||||
|
||||
// Non-View things (e.g. Image) are fine
|
||||
ReactNative.render(
|
||||
<Text>
|
||||
<Image />
|
||||
</Text>,
|
||||
11,
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw for text not inside of a <Text> ancestor', () => {
|
||||
const ScrollView = createReactNativeComponentClass('RCTScrollView', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTScrollView',
|
||||
}));
|
||||
const Text = createReactNativeComponentClass('RCTText', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTText',
|
||||
}));
|
||||
const View = createReactNativeComponentClass('RCTView', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTView',
|
||||
}));
|
||||
|
||||
expect(() => ReactNative.render(<View>this should warn</View>, 11)).toThrow(
|
||||
'Text strings must be rendered within a <Text> component.',
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
ReactNative.render(
|
||||
<Text>
|
||||
<ScrollView>hi hello hi</ScrollView>
|
||||
</Text>,
|
||||
11,
|
||||
),
|
||||
).toThrow('Text strings must be rendered within a <Text> component.');
|
||||
});
|
||||
|
||||
it('should not throw for text inside of an indirect <Text> ancestor', () => {
|
||||
const Text = createReactNativeComponentClass('RCTText', () => ({
|
||||
validAttributes: {},
|
||||
uiViewClassName: 'RCTText',
|
||||
}));
|
||||
|
||||
const Indirection = () => 'Hi';
|
||||
|
||||
ReactNative.render(
|
||||
<Text>
|
||||
<Indirection />
|
||||
</Text>,
|
||||
11,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,69 +2,69 @@
|
|||
|
||||
exports[`ReactFabric renders and reorders children 1`] = `
|
||||
"11
|
||||
View null
|
||||
View {\\"title\\":\\"a\\"}
|
||||
View {\\"title\\":\\"b\\"}
|
||||
View {\\"title\\":\\"c\\"}
|
||||
View {\\"title\\":\\"d\\"}
|
||||
View {\\"title\\":\\"e\\"}
|
||||
View {\\"title\\":\\"f\\"}
|
||||
View {\\"title\\":\\"g\\"}
|
||||
View {\\"title\\":\\"h\\"}
|
||||
View {\\"title\\":\\"i\\"}
|
||||
View {\\"title\\":\\"j\\"}
|
||||
View {\\"title\\":\\"k\\"}
|
||||
View {\\"title\\":\\"l\\"}
|
||||
View {\\"title\\":\\"m\\"}
|
||||
View {\\"title\\":\\"n\\"}
|
||||
View {\\"title\\":\\"o\\"}
|
||||
View {\\"title\\":\\"p\\"}
|
||||
View {\\"title\\":\\"q\\"}
|
||||
View {\\"title\\":\\"r\\"}
|
||||
View {\\"title\\":\\"s\\"}
|
||||
View {\\"title\\":\\"t\\"}"
|
||||
RCTView null
|
||||
RCTView {\\"title\\":\\"a\\"}
|
||||
RCTView {\\"title\\":\\"b\\"}
|
||||
RCTView {\\"title\\":\\"c\\"}
|
||||
RCTView {\\"title\\":\\"d\\"}
|
||||
RCTView {\\"title\\":\\"e\\"}
|
||||
RCTView {\\"title\\":\\"f\\"}
|
||||
RCTView {\\"title\\":\\"g\\"}
|
||||
RCTView {\\"title\\":\\"h\\"}
|
||||
RCTView {\\"title\\":\\"i\\"}
|
||||
RCTView {\\"title\\":\\"j\\"}
|
||||
RCTView {\\"title\\":\\"k\\"}
|
||||
RCTView {\\"title\\":\\"l\\"}
|
||||
RCTView {\\"title\\":\\"m\\"}
|
||||
RCTView {\\"title\\":\\"n\\"}
|
||||
RCTView {\\"title\\":\\"o\\"}
|
||||
RCTView {\\"title\\":\\"p\\"}
|
||||
RCTView {\\"title\\":\\"q\\"}
|
||||
RCTView {\\"title\\":\\"r\\"}
|
||||
RCTView {\\"title\\":\\"s\\"}
|
||||
RCTView {\\"title\\":\\"t\\"}"
|
||||
`;
|
||||
|
||||
exports[`ReactFabric renders and reorders children 2`] = `
|
||||
"11
|
||||
View null
|
||||
View {\\"title\\":\\"m\\"}
|
||||
View {\\"title\\":\\"x\\"}
|
||||
View {\\"title\\":\\"h\\"}
|
||||
View {\\"title\\":\\"p\\"}
|
||||
View {\\"title\\":\\"g\\"}
|
||||
View {\\"title\\":\\"w\\"}
|
||||
View {\\"title\\":\\"f\\"}
|
||||
View {\\"title\\":\\"r\\"}
|
||||
View {\\"title\\":\\"a\\"}
|
||||
View {\\"title\\":\\"l\\"}
|
||||
View {\\"title\\":\\"k\\"}
|
||||
View {\\"title\\":\\"e\\"}
|
||||
View {\\"title\\":\\"o\\"}
|
||||
View {\\"title\\":\\"i\\"}
|
||||
View {\\"title\\":\\"v\\"}
|
||||
View {\\"title\\":\\"c\\"}
|
||||
View {\\"title\\":\\"s\\"}
|
||||
View {\\"title\\":\\"t\\"}
|
||||
View {\\"title\\":\\"z\\"}
|
||||
View {\\"title\\":\\"y\\"}"
|
||||
RCTView null
|
||||
RCTView {\\"title\\":\\"m\\"}
|
||||
RCTView {\\"title\\":\\"x\\"}
|
||||
RCTView {\\"title\\":\\"h\\"}
|
||||
RCTView {\\"title\\":\\"p\\"}
|
||||
RCTView {\\"title\\":\\"g\\"}
|
||||
RCTView {\\"title\\":\\"w\\"}
|
||||
RCTView {\\"title\\":\\"f\\"}
|
||||
RCTView {\\"title\\":\\"r\\"}
|
||||
RCTView {\\"title\\":\\"a\\"}
|
||||
RCTView {\\"title\\":\\"l\\"}
|
||||
RCTView {\\"title\\":\\"k\\"}
|
||||
RCTView {\\"title\\":\\"e\\"}
|
||||
RCTView {\\"title\\":\\"o\\"}
|
||||
RCTView {\\"title\\":\\"i\\"}
|
||||
RCTView {\\"title\\":\\"v\\"}
|
||||
RCTView {\\"title\\":\\"c\\"}
|
||||
RCTView {\\"title\\":\\"s\\"}
|
||||
RCTView {\\"title\\":\\"t\\"}
|
||||
RCTView {\\"title\\":\\"z\\"}
|
||||
RCTView {\\"title\\":\\"y\\"}"
|
||||
`;
|
||||
|
||||
exports[`ReactFabric should call complete after inserting children 1`] = `
|
||||
Array [
|
||||
"View {\\"foo\\":\\"a\\"}
|
||||
View {\\"foo\\":\\"b\\"}",
|
||||
"RCTView {\\"foo\\":\\"a\\"}
|
||||
RCTView {\\"foo\\":\\"b\\"}",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`ReactFabric should only pass props diffs to FabricUIManager.cloneNode 1`] = `
|
||||
"11
|
||||
View {\\"foo\\":\\"a\\",\\"bar\\":\\"b\\"}
|
||||
RCTText {\\"foo\\":\\"a\\",\\"bar\\":\\"b\\"}
|
||||
RCTRawText {\\"text\\":\\"1\\"}"
|
||||
`;
|
||||
|
||||
exports[`ReactFabric should only pass props diffs to FabricUIManager.cloneNode 2`] = `
|
||||
"11
|
||||
View {\\"foo\\":\\"b\\",\\"bar\\":\\"b\\"}
|
||||
RCTText {\\"foo\\":\\"b\\",\\"bar\\":\\"b\\"}
|
||||
RCTRawText {\\"text\\":\\"2\\"}"
|
||||
`;
|
||||
|
|
|
@ -2,50 +2,50 @@
|
|||
|
||||
exports[`ReactNative renders and reorders children 1`] = `
|
||||
"<native root> {}
|
||||
View null
|
||||
View {\\"title\\":\\"a\\"}
|
||||
View {\\"title\\":\\"b\\"}
|
||||
View {\\"title\\":\\"c\\"}
|
||||
View {\\"title\\":\\"d\\"}
|
||||
View {\\"title\\":\\"e\\"}
|
||||
View {\\"title\\":\\"f\\"}
|
||||
View {\\"title\\":\\"g\\"}
|
||||
View {\\"title\\":\\"h\\"}
|
||||
View {\\"title\\":\\"i\\"}
|
||||
View {\\"title\\":\\"j\\"}
|
||||
View {\\"title\\":\\"k\\"}
|
||||
View {\\"title\\":\\"l\\"}
|
||||
View {\\"title\\":\\"m\\"}
|
||||
View {\\"title\\":\\"n\\"}
|
||||
View {\\"title\\":\\"o\\"}
|
||||
View {\\"title\\":\\"p\\"}
|
||||
View {\\"title\\":\\"q\\"}
|
||||
View {\\"title\\":\\"r\\"}
|
||||
View {\\"title\\":\\"s\\"}
|
||||
View {\\"title\\":\\"t\\"}"
|
||||
RCTView null
|
||||
RCTView {\\"title\\":\\"a\\"}
|
||||
RCTView {\\"title\\":\\"b\\"}
|
||||
RCTView {\\"title\\":\\"c\\"}
|
||||
RCTView {\\"title\\":\\"d\\"}
|
||||
RCTView {\\"title\\":\\"e\\"}
|
||||
RCTView {\\"title\\":\\"f\\"}
|
||||
RCTView {\\"title\\":\\"g\\"}
|
||||
RCTView {\\"title\\":\\"h\\"}
|
||||
RCTView {\\"title\\":\\"i\\"}
|
||||
RCTView {\\"title\\":\\"j\\"}
|
||||
RCTView {\\"title\\":\\"k\\"}
|
||||
RCTView {\\"title\\":\\"l\\"}
|
||||
RCTView {\\"title\\":\\"m\\"}
|
||||
RCTView {\\"title\\":\\"n\\"}
|
||||
RCTView {\\"title\\":\\"o\\"}
|
||||
RCTView {\\"title\\":\\"p\\"}
|
||||
RCTView {\\"title\\":\\"q\\"}
|
||||
RCTView {\\"title\\":\\"r\\"}
|
||||
RCTView {\\"title\\":\\"s\\"}
|
||||
RCTView {\\"title\\":\\"t\\"}"
|
||||
`;
|
||||
|
||||
exports[`ReactNative renders and reorders children 2`] = `
|
||||
"<native root> {}
|
||||
View null
|
||||
View {\\"title\\":\\"m\\"}
|
||||
View {\\"title\\":\\"x\\"}
|
||||
View {\\"title\\":\\"h\\"}
|
||||
View {\\"title\\":\\"p\\"}
|
||||
View {\\"title\\":\\"g\\"}
|
||||
View {\\"title\\":\\"w\\"}
|
||||
View {\\"title\\":\\"f\\"}
|
||||
View {\\"title\\":\\"r\\"}
|
||||
View {\\"title\\":\\"a\\"}
|
||||
View {\\"title\\":\\"l\\"}
|
||||
View {\\"title\\":\\"k\\"}
|
||||
View {\\"title\\":\\"e\\"}
|
||||
View {\\"title\\":\\"o\\"}
|
||||
View {\\"title\\":\\"i\\"}
|
||||
View {\\"title\\":\\"v\\"}
|
||||
View {\\"title\\":\\"c\\"}
|
||||
View {\\"title\\":\\"s\\"}
|
||||
View {\\"title\\":\\"t\\"}
|
||||
View {\\"title\\":\\"z\\"}
|
||||
View {\\"title\\":\\"y\\"}"
|
||||
RCTView null
|
||||
RCTView {\\"title\\":\\"m\\"}
|
||||
RCTView {\\"title\\":\\"x\\"}
|
||||
RCTView {\\"title\\":\\"h\\"}
|
||||
RCTView {\\"title\\":\\"p\\"}
|
||||
RCTView {\\"title\\":\\"g\\"}
|
||||
RCTView {\\"title\\":\\"w\\"}
|
||||
RCTView {\\"title\\":\\"f\\"}
|
||||
RCTView {\\"title\\":\\"r\\"}
|
||||
RCTView {\\"title\\":\\"a\\"}
|
||||
RCTView {\\"title\\":\\"l\\"}
|
||||
RCTView {\\"title\\":\\"k\\"}
|
||||
RCTView {\\"title\\":\\"e\\"}
|
||||
RCTView {\\"title\\":\\"o\\"}
|
||||
RCTView {\\"title\\":\\"i\\"}
|
||||
RCTView {\\"title\\":\\"v\\"}
|
||||
RCTView {\\"title\\":\\"c\\"}
|
||||
RCTView {\\"title\\":\\"s\\"}
|
||||
RCTView {\\"title\\":\\"t\\"}
|
||||
RCTView {\\"title\\":\\"z\\"}
|
||||
RCTView {\\"title\\":\\"y\\"}"
|
||||
`;
|
||||
|
|
Loading…
Reference in New Issue