Skip to content

Commit 848593c

Browse files
Brian Vaughnfacebook-github-bot
Brian Vaughn
authored andcommitted
Moved takeSnapshot method from UIManager to ReactNative
Reviewed By: spicyj Differential Revision: D4767428 fbshipit-source-id: 77c80c0135641ab46f9dce2763f27499a96373a0
1 parent 30778b6 commit 848593c

File tree

5 files changed

+76
-62
lines changed

5 files changed

+76
-62
lines changed

Examples/UIExplorer/js/ActionSheetIOSExample.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ var ReactNative = require('react-native');
2828
var {
2929
ActionSheetIOS,
3030
StyleSheet,
31+
takeSnapshot,
3132
Text,
32-
UIManager,
3333
View,
3434
} = ReactNative;
3535

@@ -164,7 +164,7 @@ class ShareScreenshotExample extends React.Component {
164164

165165
showShareActionSheet = () => {
166166
// Take the snapshot (returns a temp file uri)
167-
UIManager.takeSnapshot('window').then((uri) => {
167+
takeSnapshot('window').then((uri) => {
168168
// Share image data
169169
ActionSheetIOS.showShareActionSheetWithOptions({
170170
url: uri,

Libraries/ReactNative/UIManager.js

+12-60
Original file line numberDiff line numberDiff line change
@@ -15,72 +15,24 @@ const NativeModules = require('NativeModules');
1515
const Platform = require('Platform');
1616

1717
const defineLazyObjectProperty = require('defineLazyObjectProperty');
18-
const findNodeHandle = require('findNodeHandle');
1918
const invariant = require('fbjs/lib/invariant');
2019

21-
import type React from 'react';
22-
2320
const { UIManager } = NativeModules;
2421

2522
invariant(UIManager, 'UIManager is undefined. The native module config is probably incorrect.');
2623

27-
const _takeSnapshot = UIManager.takeSnapshot;
28-
29-
// findNodeHandle() returns a reference to a wrapper component with viewConfig.
30-
// This wrapper is required for NativeMethodsMixin.setNativeProps, but most
31-
// callers want the native tag (number) and not the wrapper. For this purpose,
32-
// the ReactNative renderer decorates findNodeHandle() and extracts the tag.
33-
// However UIManager can't require ReactNative without introducing a cycle, and
34-
// deferring the require causes a significant performance regression in Wilde
35-
// (along the lines of 17% regression in RN Bridge startup). So as a temporary
36-
// workaround, this wrapper method mimics what the native renderer does.
37-
// TODO (bvaughn) Remove this and use findNodeHandle directly once stack is gone
38-
function findNodeHandleWrapper(componentOrHandle : any) : ?number {
39-
const instance: any = findNodeHandle(componentOrHandle);
40-
41-
if (instance) {
42-
return typeof instance._nativeTag === 'number'
43-
? instance._nativeTag
44-
: instance.getHostNode();
45-
} else {
46-
return null;
47-
}
48-
}
49-
50-
/**
51-
* Capture an image of the screen, window or an individual view. The image
52-
* will be stored in a temporary file that will only exist for as long as the
53-
* app is running.
54-
*
55-
* The `view` argument can be the literal string `window` if you want to
56-
* capture the entire window, or it can be a reference to a specific
57-
* React Native component.
58-
*
59-
* The `options` argument may include:
60-
* - width/height (number) - the width and height of the image to capture.
61-
* - format (string) - either 'png' or 'jpeg'. Defaults to 'png'.
62-
* - quality (number) - the quality when using jpeg. 0.0 - 1.0 (default).
63-
*
64-
* Returns a Promise.
65-
* @platform ios
66-
*/
67-
UIManager.takeSnapshot = async function(
68-
view ?: 'window' | React.Element<any> | number,
69-
options ?: {
70-
width ?: number,
71-
height ?: number,
72-
format ?: 'png' | 'jpeg',
73-
quality ?: number,
74-
},
75-
) {
76-
if (!_takeSnapshot) {
77-
console.warn('UIManager.takeSnapshot is not available on this platform');
78-
return;
79-
}
80-
if (typeof view !== 'number' && view !== 'window') {
81-
view = findNodeHandleWrapper(view) || 'window';
82-
}
83-
return _takeSnapshot(view, options);
24+
// In past versions of ReactNative users called UIManager.takeSnapshot()
25+
// However takeSnapshot was moved to ReactNative in order to support flat
26+
// bundles and to avoid a cyclic dependency between UIManager and ReactNative.
27+
// UIManager.takeSnapshot still exists though. In order to avoid confusion or
28+
// accidental usage, mask the method with a deprecation warning.
29+
UIManager.__takeSnapshot = UIManager.takeSnapshot;
30+
UIManager.takeSnapshot = function() {
31+
invariant(
32+
false,
33+
'UIManager.takeSnapshot should not be called directly. ' +
34+
'Use ReactNative.takeSnapshot instead.'
35+
);
8436
};
8537

8638
/**

Libraries/Renderer/src/renderers/native/ReactNativeFiber.js

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationI
2727
const emptyObject = require('fbjs/lib/emptyObject');
2828
const findNodeHandle = require('findNodeHandle');
2929
const invariant = require('fbjs/lib/invariant');
30+
const takeSnapshot = require('takeSnapshot');
3031

3132
const {injectInternals} = require('ReactFiberDevToolsHook');
3233

@@ -402,6 +403,8 @@ const ReactNative = {
402403
return NativeRenderer.getPublicRootInstance(root);
403404
},
404405

406+
takeSnapshot,
407+
405408
unmountComponentAtNode(containerTag: number) {
406409
const root = roots.get(containerTag);
407410
if (root) {

Libraries/Renderer/src/renderers/native/ReactNativeStack.js

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ var ReactNativeStackInjection = require('ReactNativeStackInjection');
1818
var ReactUpdates = require('ReactUpdates');
1919

2020
var findNodeHandle = require('findNodeHandle');
21+
var takeSnapshot = require('takeSnapshot');
2122

2223
ReactNativeInjection.inject();
2324
ReactNativeStackInjection.inject();
@@ -45,6 +46,9 @@ var ReactNative = {
4546
},
4647

4748
render: render,
49+
50+
takeSnapshot,
51+
4852
unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode,
4953

5054
/* eslint-disable camelcase */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*
9+
* @providesModule takeSnapshot
10+
* @flow
11+
*/
12+
'use strict';
13+
14+
var ReactNative = require('ReactNative');
15+
var UIManager = require('UIManager');
16+
17+
import type {Element} from 'React';
18+
19+
/**
20+
* Capture an image of the screen, window or an individual view. The image
21+
* will be stored in a temporary file that will only exist for as long as the
22+
* app is running.
23+
*
24+
* The `view` argument can be the literal string `window` if you want to
25+
* capture the entire window, or it can be a reference to a specific
26+
* React Native component.
27+
*
28+
* The `options` argument may include:
29+
* - width/height (number) - the width and height of the image to capture.
30+
* - format (string) - either 'png' or 'jpeg'. Defaults to 'png'.
31+
* - quality (number) - the quality when using jpeg. 0.0 - 1.0 (default).
32+
*
33+
* Returns a Promise.
34+
* @platform ios
35+
*/
36+
module.exports = async function takeSnapshot(
37+
view ?: 'window' | Element<any> | number,
38+
options ?: {
39+
width ?: number,
40+
height ?: number,
41+
format ?: 'png' | 'jpeg',
42+
quality ?: number,
43+
},
44+
) {
45+
if (
46+
typeof view !== 'number' &&
47+
view !== 'window'
48+
) {
49+
view = ReactNative.findNodeHandle(view) || 'window';
50+
}
51+
52+
// Call the hidden '__takeSnapshot' method; the main one throws an error to
53+
// prevent accidental backwards-incompatible usage.
54+
return UIManager.__takeSnapshot(view, options);
55+
};

0 commit comments

Comments
 (0)