Skip to content

Commit 429fcc8

Browse files
Dmitry Zakharovfacebook-github-bot
authored andcommitted
Migrate DeviceInfoModule from RN Module to Native Function.
Reviewed By: danzimm Differential Revision: D6750934 fbshipit-source-id: f453801737e41632c6b84ff894e7f0eb66b575dc
1 parent 6224ef5 commit 429fcc8

File tree

5 files changed

+165
-45
lines changed

5 files changed

+165
-45
lines changed

Libraries/Utilities/Dimensions.js

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
*/
1212
'use strict';
1313

14-
var DeviceInfo = require('DeviceInfo');
1514
var EventEmitter = require('EventEmitter');
1615
var Platform = require('Platform');
1716
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
@@ -21,22 +20,59 @@ var invariant = require('fbjs/lib/invariant');
2120
var eventEmitter = new EventEmitter();
2221
var dimensionsInitialized = false;
2322
var dimensions = {};
23+
24+
var dimensionsProvider: ?(() => {[key:string]: Object});
25+
2426
class Dimensions {
25-
/**
26-
* This should only be called from native code by sending the
27-
* didUpdateDimensions event.
28-
*
29-
* @param {object} dims Simple string-keyed object of dimensions to set
30-
*/
31-
static set(dims: {[key:string]: any}): void {
27+
static setProvider(value: () => {[key:string]: Object}): void {
28+
dimensionsProvider = value;
29+
dimensionsInitialized = false;
30+
dimensions = {};
31+
}
32+
33+
static getDimensions(): {[key:string]: Object} {
34+
if (dimensionsInitialized) {
35+
return dimensions;
36+
}
37+
3238
// We calculate the window dimensions in JS so that we don't encounter loss of
3339
// precision in transferring the dimensions (which could be non-integers) over
3440
// the bridge.
41+
const dims = (dimensionsProvider || defaultDimProvider)();
42+
const result = Dimensions.updateDimensions(dims);
43+
RCTDeviceEventEmitter.addListener('didUpdateDimensions', function(update) {
44+
Dimensions.updateDimensions(update);
45+
});
46+
return result;
47+
}
48+
49+
/**
50+
* Initial dimensions are set before `runApplication` is called so they should
51+
* be available before any other require's are run, but may be updated later.
52+
*
53+
* Note: Although dimensions are available immediately, they may change (e.g
54+
* due to device rotation) so any rendering logic or styles that depend on
55+
* these constants should try to call this function on every render, rather
56+
* than caching the value (for example, using inline styles rather than
57+
* setting a value in a `StyleSheet`).
58+
*
59+
* Example: `var {height, width} = Dimensions.get('window');`
60+
*
61+
* @param {string} dim Name of dimension as defined when calling `set`.
62+
* @returns {Object?} Value for the dimension.
63+
*/
64+
static get(dim: string): Object {
65+
const dims = Dimensions.getDimensions();
66+
invariant(dims[dim], 'No dimension set for key ' + dim);
67+
return dims[dim];
68+
}
69+
70+
static updateDimensions(dims: ?{[key:string]: Object}): {[key:string]: Object} {
3571
if (dims && dims.windowPhysicalPixels) {
3672
// parse/stringify => Clone hack
3773
dims = JSON.parse(JSON.stringify(dims));
3874

39-
var windowPhysicalPixels = dims.windowPhysicalPixels;
75+
const windowPhysicalPixels = dims.windowPhysicalPixels;
4076
dims.window = {
4177
width: windowPhysicalPixels.width / windowPhysicalPixels.scale,
4278
height: windowPhysicalPixels.height / windowPhysicalPixels.scale,
@@ -45,7 +81,7 @@ class Dimensions {
4581
};
4682
if (Platform.OS === 'android') {
4783
// Screen and window dimensions are different on android
48-
var screenPhysicalPixels = dims.screenPhysicalPixels;
84+
const screenPhysicalPixels = dims.screenPhysicalPixels;
4985
dims.screen = {
5086
width: screenPhysicalPixels.width / screenPhysicalPixels.scale,
5187
height: screenPhysicalPixels.height / screenPhysicalPixels.scale,
@@ -72,26 +108,7 @@ class Dimensions {
72108
} else {
73109
dimensionsInitialized = true;
74110
}
75-
}
76-
77-
/**
78-
* Initial dimensions are set before `runApplication` is called so they should
79-
* be available before any other require's are run, but may be updated later.
80-
*
81-
* Note: Although dimensions are available immediately, they may change (e.g
82-
* due to device rotation) so any rendering logic or styles that depend on
83-
* these constants should try to call this function on every render, rather
84-
* than caching the value (for example, using inline styles rather than
85-
* setting a value in a `StyleSheet`).
86-
*
87-
* Example: `var {height, width} = Dimensions.get('window');`
88-
*
89-
* @param {string} dim Name of dimension as defined when calling `set`.
90-
* @returns {Object?} Value for the dimension.
91-
*/
92-
static get(dim: string): Object {
93-
invariant(dimensions[dim], 'No dimension set for key ' + dim);
94-
return dimensions[dim];
111+
return dimensions;
95112
}
96113

97114
/**
@@ -128,9 +145,8 @@ class Dimensions {
128145
}
129146
}
130147

131-
Dimensions.set(DeviceInfo.Dimensions);
132-
RCTDeviceEventEmitter.addListener('didUpdateDimensions', function(update) {
133-
Dimensions.set(update);
134-
});
148+
function defaultDimProvider(): {[key:string]: Object} {
149+
return require('DeviceInfo').Dimensions;
150+
}
135151

136152
module.exports = Dimensions;

React/Modules/RCTDeviceInfo.m

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#import "RCTAccessibilityManager.h"
1313
#import "RCTAssert.h"
1414
#import "RCTEventDispatcher.h"
15+
#import "RCTUIUtils.h"
1516
#import "RCTUtils.h"
1617

1718
@implementation RCTDeviceInfo {
@@ -72,18 +73,18 @@ static BOOL RCTIsIPhoneX() {
7273
{
7374
RCTAssertMainQueue();
7475

75-
// Don't use RCTScreenSize since it the interface orientation doesn't apply to it
76-
CGRect screenSize = [[UIScreen mainScreen] bounds];
77-
NSDictionary *dims = @{
78-
@"width": @(screenSize.size.width),
79-
@"height": @(screenSize.size.height),
80-
@"scale": @(RCTScreenScale()),
81-
@"fontScale": @(bridge.accessibilityManager.multiplier)
82-
};
76+
RCTDimensions dimensions = RCTGetDimensions(bridge.accessibilityManager.multiplier);
77+
typeof (dimensions.window) window = dimensions.window; // Window and Screen are considered equal for iOS.
78+
NSDictionary<NSString *, NSNumber *> *dims = @{
79+
@"width": @(window.width),
80+
@"height": @(window.height),
81+
@"scale": @(window.scale),
82+
@"fontScale": @(window.fontScale)
83+
};
8384
return @{
84-
@"window": dims,
85-
@"screen": dims
86-
};
85+
@"window": dims,
86+
@"screen": dims
87+
};
8788
}
8889

8990
- (void)dealloc

React/React.xcodeproj/project.pbxproj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,7 @@
12031203
EBF21BFE1FC499840052F4D5 /* InspectorInterfaces.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = EBF21BBA1FC498270052F4D5 /* InspectorInterfaces.h */; };
12041204
EBF21BFF1FC4998E0052F4D5 /* InspectorInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */; };
12051205
EBF21C001FC499A80052F4D5 /* InspectorInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */; };
1206+
F1EFDA50201F661000EE6E4C /* RCTUIUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = F1EFDA4E201F660F00EE6E4C /* RCTUIUtils.m */; };
12061207
FEFAAC9E1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FEFAAC9C1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.m */; };
12071208
FEFAAC9F1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFAAC9D1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.h */; };
12081209
/* End PBXBuildFile section */
@@ -2279,6 +2280,8 @@
22792280
EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorInterfaces.cpp; sourceTree = "<group>"; };
22802281
EBF21BDC1FC498900052F4D5 /* libjsinspector.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjsinspector.a; sourceTree = BUILT_PRODUCTS_DIR; };
22812282
EBF21BFA1FC4989A0052F4D5 /* libjsinspector-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libjsinspector-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
2283+
F1EFDA4E201F660F00EE6E4C /* RCTUIUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIUtils.m; sourceTree = "<group>"; };
2284+
F1EFDA4F201F660F00EE6E4C /* RCTUIUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUIUtils.h; sourceTree = "<group>"; };
22822285
FEFAAC9C1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRedBoxExtraDataViewController.m; sourceTree = "<group>"; };
22832286
FEFAAC9D1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRedBoxExtraDataViewController.h; sourceTree = "<group>"; };
22842287
/* End PBXFileReference section */
@@ -2888,6 +2891,7 @@
28882891
657734881EE8352500A0E9EA /* Inspector */,
28892892
13B07FE01A69315300A75B9A /* Modules */,
28902893
1450FF7F1BCFF28A00208362 /* Profiler */,
2894+
F1EFDA4D201F660F00EE6E4C /* UIUtils */,
28912895
13B07FF31A6947C200A75B9A /* Views */,
28922896
);
28932897
name = React;
@@ -3048,6 +3052,15 @@
30483052
path = jsinspector;
30493053
sourceTree = "<group>";
30503054
};
3055+
F1EFDA4D201F660F00EE6E4C /* UIUtils */ = {
3056+
isa = PBXGroup;
3057+
children = (
3058+
F1EFDA4F201F660F00EE6E4C /* RCTUIUtils.h */,
3059+
F1EFDA4E201F660F00EE6E4C /* RCTUIUtils.m */,
3060+
);
3061+
path = UIUtils;
3062+
sourceTree = "<group>";
3063+
};
30513064
/* End PBXGroup section */
30523065

30533066
/* Begin PBXHeadersBuildPhase section */
@@ -4508,6 +4521,7 @@
45084521
13AB90C11B6FA36700713B4F /* RCTComponentData.m in Sources */,
45094522
13B0801B1A69489C00A75B9A /* RCTNavigatorManager.m in Sources */,
45104523
916F9C2D1F743F57002E5920 /* RCTModalManager.m in Sources */,
4524+
F1EFDA50201F661000EE6E4C /* RCTUIUtils.m in Sources */,
45114525
);
45124526
runOnlyForDeploymentPostprocessing = 0;
45134527
};

React/UIUtils/RCTUIUtils.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
10+
#import <CoreGraphics/CoreGraphics.h>
11+
#import <Foundation/Foundation.h>
12+
#import <UIKit/UIKit.h>
13+
14+
NS_ASSUME_NONNULL_BEGIN
15+
16+
#ifdef __cplusplus
17+
extern "C" {
18+
#endif
19+
20+
// Get window and screen dimensions
21+
typedef struct {
22+
struct {
23+
CGFloat width, height, scale, fontScale;
24+
} window, screen;
25+
} RCTDimensions;
26+
extern __attribute__((visibility("default")))
27+
RCTDimensions RCTGetDimensions(CGFloat fontScale);
28+
29+
// Get font size multiplier for font base size (Large) by content size category
30+
extern __attribute__((visibility("default")))
31+
CGFloat RCTGetMultiplierForContentSizeCategory(UIContentSizeCategory category);
32+
33+
#ifdef __cplusplus
34+
}
35+
#endif
36+
37+
NS_ASSUME_NONNULL_END

React/UIUtils/RCTUIUtils.m

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
10+
#import "RCTUIUtils.h"
11+
12+
RCTDimensions RCTGetDimensions(CGFloat fontScale)
13+
{
14+
UIScreen *mainScreen = UIScreen.mainScreen;
15+
CGSize screenSize = mainScreen.bounds.size;
16+
RCTDimensions result;
17+
typeof (result.window) dims = {
18+
.width = screenSize.width,
19+
.height = screenSize.height,
20+
.scale = mainScreen.scale,
21+
.fontScale = fontScale
22+
};
23+
result.window = dims;
24+
result.screen = dims;
25+
26+
return result;
27+
}
28+
29+
CGFloat RCTGetMultiplierForContentSizeCategory(UIContentSizeCategory category)
30+
{
31+
static NSDictionary<NSString *, NSNumber *> *multipliers = nil;
32+
static dispatch_once_t token;
33+
dispatch_once(&token, ^{
34+
multipliers = @{
35+
UIContentSizeCategoryExtraSmall: @0.823,
36+
UIContentSizeCategorySmall: @0.882,
37+
UIContentSizeCategoryMedium: @0.941,
38+
UIContentSizeCategoryLarge: @1.0,
39+
UIContentSizeCategoryExtraLarge: @1.118,
40+
UIContentSizeCategoryExtraExtraLarge: @1.235,
41+
UIContentSizeCategoryExtraExtraExtraLarge: @1.353,
42+
UIContentSizeCategoryAccessibilityMedium: @1.786,
43+
UIContentSizeCategoryAccessibilityLarge: @2.143,
44+
UIContentSizeCategoryAccessibilityExtraLarge: @2.643,
45+
UIContentSizeCategoryAccessibilityExtraExtraLarge: @3.143,
46+
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @3.571
47+
};
48+
});
49+
50+
double value = multipliers[category].doubleValue;
51+
return value > 0.0 ? value : 1.0;
52+
}

0 commit comments

Comments
 (0)