Skip to content

Commit 95c13bf

Browse files
committed
decorate RCTDevMenu
1 parent efec185 commit 95c13bf

File tree

12 files changed

+188
-86
lines changed

12 files changed

+188
-86
lines changed

packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ - (RCTHost *)createReactHost:(NSDictionary *)launchOptions
253253
jsEngineProvider:^std::shared_ptr<facebook::react::JSRuntimeFactory>() {
254254
return [weakSelf createJSRuntimeFactory];
255255
}
256-
launchOptions:launchOptions];
256+
launchOptions:launchOptions
257+
devMenuConfiguration:devMenuConfiguration];
257258
[reactHost setBundleURLProvider:^NSURL *() {
258259
return [weakSelf bundleURL];
259260
}];
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#import <React/RCTDevMenu.h>
9+
10+
@interface RCTDevMenuConfigurationDecorator : NSObject
11+
@property (nonatomic, strong, readonly) RCTDevMenuConfiguration *devMenuConfiguration;
12+
13+
- (instancetype)initWithDevMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration;
14+
- (void)decorate:(RCTDevMenu *)devMenuModule;
15+
@end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#import <RCTDevMenuConfigurationDecorator.h>
9+
10+
@implementation RCTDevMenuConfigurationDecorator
11+
12+
- (instancetype)initWithDevMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
13+
{
14+
if (self = [super init]) {
15+
_devMenuConfiguration = devMenuConfiguration;
16+
}
17+
18+
return self;
19+
}
20+
21+
- (void)decorate:(RCTDevMenu *)devMenuModule
22+
{
23+
if (_devMenuConfiguration != nil) {
24+
devMenuModule.isDevMenuEnabled = _devMenuConfiguration.isDevMenuEnabled;
25+
[devMenuModule setShakeToShow:_devMenuConfiguration.isShakeGestureEnabled];
26+
}
27+
}
28+
29+
@end

packages/react-native/React/CoreModules/RCTDevMenu.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ RCT_EXTERN NSString *const RCTShowDevMenuNotification;
2020

2121
@class RCTDevMenuItem;
2222

23-
@interface RCTDevMenuConfiguration
23+
@interface RCTDevMenuConfiguration : NSObject
2424
@property (nonatomic, readonly) BOOL isDevMenuEnabled;
25+
@property (nonatomic, readonly) BOOL isShakeGestureEnabled;
26+
@property (nonatomic, readonly) BOOL areKeyboardShortcutsEnabled;
27+
28+
- (instancetype)initWithDevMenuEnabled:(BOOL) isDevMenuEnabled
29+
shakeGestureEnabled:(BOOL) isShakeGestureEnabled
30+
keyboardShortcutsEnabled:(BOOL) areKeyboardShortcutsEnabled;
2531
@end
2632

2733
/**
@@ -54,6 +60,8 @@ RCT_EXTERN NSString *const RCTShowDevMenuNotification;
5460
*/
5561
@property (nonatomic, copy, readonly) NSArray<RCTDevMenuItem *> *presentedItems;
5662

63+
@property (nonatomic, assign) BOOL isDevMenuEnabled;
64+
5765
/**
5866
* Detect if actions sheet (development menu) is shown
5967
*/

packages/react-native/React/CoreModules/RCTDevMenu.mm

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ - (RCTDevMenuItem *)devMenuItem;
2929

3030
NSString *const RCTShowDevMenuNotification = @"RCTShowDevMenuNotification";
3131

32+
@interface RCTDevMenuConfiguration ()
33+
@end
34+
35+
@implementation RCTDevMenuConfiguration
36+
- (instancetype)initWithDevMenuEnabled:(BOOL) isDevMenuEnabled
37+
shakeGestureEnabled:(BOOL) isShakeGestureEnabled
38+
keyboardShortcutsEnabled:(BOOL) areKeyboardShortcutsEnabled
39+
{
40+
if (self = [super init]) {
41+
_isDevMenuEnabled = isDevMenuEnabled;
42+
_isShakeGestureEnabled = isShakeGestureEnabled;
43+
_areKeyboardShortcutsEnabled = areKeyboardShortcutsEnabled;
44+
}
45+
return self;
46+
}
47+
@end
48+
3249
@implementation UIWindow (RCTDevMenu)
3350

3451
- (void)RCT_motionEnded:(__unused UIEventSubtype)motion withEvent:(UIEvent *)event
@@ -102,6 +119,7 @@ @implementation RCTDevMenu {
102119
@synthesize moduleRegistry = _moduleRegistry;
103120
@synthesize callableJSModules = _callableJSModules;
104121
@synthesize bundleManager = _bundleManager;
122+
@synthesize isDevMenuEnabled = _isDevMenuEnabled;
105123

106124
RCT_EXPORT_MODULE()
107125

@@ -379,7 +397,7 @@ - (void)setDefaultJSBundle
379397

380398
RCT_EXPORT_METHOD(show)
381399
{
382-
if (_actionSheet || RCTRunningInAppExtension()) {
400+
if (_actionSheet || RCTRunningInAppExtension() || !_isDevMenuEnabled) {
383401
return;
384402
}
385403

packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#import <memory>
1111

1212
#import <React/RCTBridgeModuleDecorator.h>
13+
#import <React/RCTDevMenuConfigurationDecorator.h>
1314
#import <React/RCTDefines.h>
1415
#import <React/RCTTurboModuleRegistry.h>
1516
#import <ReactCommon/RuntimeExecutor.h>
@@ -71,7 +72,8 @@
7172
- (instancetype)initWithBridgeProxy:(RCTBridgeProxy *)bridgeProxy
7273
bridgeModuleDecorator:(RCTBridgeModuleDecorator *)bridgeModuleDecorator
7374
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
74-
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker;
75+
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
76+
devMenuConfigurationDecorator:(RCTDevMenuConfigurationDecorator *)devMenuConfigurationDecorator;
7577

7678
- (void)installJSBindings:(facebook::jsi::Runtime &)runtime;
7779

packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,17 @@ @implementation RCTTurboModuleManager {
215215

216216
RCTBridgeProxy *_bridgeProxy;
217217
RCTBridgeModuleDecorator *_bridgeModuleDecorator;
218+
RCTDevMenuConfigurationDecorator *_devMenuConfigurationDecorator;
218219

219220
dispatch_queue_t _sharedModuleQueue;
220221
}
221222

222223
- (instancetype)initWithBridge:(RCTBridge *)bridge
223-
bridgeProxy:(RCTBridgeProxy *)bridgeProxy
224-
bridgeModuleDecorator:(RCTBridgeModuleDecorator *)bridgeModuleDecorator
225-
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
226-
jsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
224+
bridgeProxy:(RCTBridgeProxy *)bridgeProxy
225+
bridgeModuleDecorator:(RCTBridgeModuleDecorator *)bridgeModuleDecorator
226+
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
227+
jsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
228+
devMenuConfigurationDecorator:(RCTDevMenuConfigurationDecorator *)devMenuConfigurationDecorator
227229
{
228230
if (self = [super init]) {
229231
_jsInvoker = std::move(jsInvoker);
@@ -233,6 +235,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
233235
_bridgeModuleDecorator = bridgeModuleDecorator;
234236
_invalidating = false;
235237
_sharedModuleQueue = dispatch_queue_create("com.meta.react.turbomodulemanager.queue", DISPATCH_QUEUE_SERIAL);
238+
_devMenuConfigurationDecorator = devMenuConfigurationDecorator;
236239

237240
if (RCTTurboModuleInteropEnabled()) {
238241
// TODO(T174674274): Implement lazy loading of legacy modules in the new architecture.
@@ -273,22 +276,25 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
273276
jsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
274277
{
275278
return [self initWithBridge:bridge
276-
bridgeProxy:nil
277-
bridgeModuleDecorator:[bridge bridgeModuleDecorator]
278-
delegate:delegate
279-
jsInvoker:jsInvoker];
279+
bridgeProxy:nil
280+
bridgeModuleDecorator:[bridge bridgeModuleDecorator]
281+
delegate:delegate
282+
jsInvoker:jsInvoker
283+
devMenuConfigurationDecorator:nil];
280284
}
281285

282286
- (instancetype)initWithBridgeProxy:(RCTBridgeProxy *)bridgeProxy
283287
bridgeModuleDecorator:(RCTBridgeModuleDecorator *)bridgeModuleDecorator
284288
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
285289
jsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
290+
devMenuConfigurationDecorator:(RCTDevMenuConfigurationDecorator *)devMenuConfigurationDecorator
286291
{
287292
return [self initWithBridge:nil
288-
bridgeProxy:bridgeProxy
289-
bridgeModuleDecorator:bridgeModuleDecorator
290-
delegate:delegate
291-
jsInvoker:jsInvoker];
293+
bridgeProxy:bridgeProxy
294+
bridgeModuleDecorator:bridgeModuleDecorator
295+
delegate:delegate
296+
jsInvoker:jsInvoker
297+
devMenuConfigurationDecorator:devMenuConfigurationDecorator];
292298
}
293299

294300
/**
@@ -770,6 +776,11 @@ - (BOOL)_shouldCreateObjCModule:(Class)moduleClass
770776
[(id<RCTInitializing>)module initialize];
771777
}
772778

779+
if ([module isKindOfClass:[RCTDevMenu class]]) {
780+
RCTDevMenu *devMenu = (RCTDevMenu *)module;
781+
[_devMenuConfigurationDecorator decorate:devMenu];
782+
}
783+
773784
/**
774785
* Attach method queue to id<RCTBridgeModule> object.
775786
* This is necessary because the id<RCTBridgeModule> object can be eagerly created/initialized before the method

packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ @implementation RCTHost {
123123
std::vector<__weak RCTFabricSurface *> _attachedSurfaces;
124124

125125
RCTModuleRegistry *_moduleRegistry;
126+
RCTDevMenuConfiguration *_devMenuConfiguration;
126127

127128
std::unique_ptr<RCTHostHostTargetDelegate> _inspectorHostDelegate;
128129
std::shared_ptr<jsinspector_modern::HostTarget> _inspectorTarget;
@@ -203,6 +204,7 @@ - (instancetype)initWithBundleURLProvider:(RCTHostBundleURLProvider)provider
203204
});
204205

205206
_inspectorHostDelegate = std::make_unique<RCTHostHostTargetDelegate>(self);
207+
_devMenuConfiguration = devMenuConfiguration;
206208
}
207209
return self;
208210
}
@@ -248,7 +250,8 @@ - (void)start
248250
turboModuleManagerDelegate:_turboModuleManagerDelegate
249251
moduleRegistry:_moduleRegistry
250252
parentInspectorTarget:_inspectorTarget.get()
251-
launchOptions:_launchOptions];
253+
launchOptions:_launchOptions
254+
devMenuConfiguration:_devMenuConfiguration];
252255
[_hostDelegate hostDidStart:self];
253256
}
254257

@@ -451,7 +454,8 @@ - (void)_reloadWithShouldRestartSurfaces:(BOOL)shouldRestartSurfaces
451454
turboModuleManagerDelegate:_turboModuleManagerDelegate
452455
moduleRegistry:_moduleRegistry
453456
parentInspectorTarget:_inspectorTarget.get()
454-
launchOptions:_launchOptions];
457+
launchOptions:_launchOptions
458+
devMenuConfiguration:_devMenuConfiguration];
455459
[_hostDelegate hostDidStart:self];
456460

457461
for (RCTFabricSurface *surface in [self _getAttachedSurfaces]) {

packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#import <UIKit/UIKit.h>
99

1010
#import <React/RCTDefines.h>
11+
#import <React/RCTDevMenu.h>
1112
#import <React/RCTJavaScriptLoader.h>
1213
#import <jsinspector-modern/ReactCdp.h>
1314
#import <react/runtime/JSRuntimeFactory.h>
@@ -71,7 +72,8 @@ RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags);
7172
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
7273
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
7374
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
74-
launchOptions:(nullable NSDictionary *)launchOptions;
75+
launchOptions:(nullable NSDictionary *)launchOptions
76+
devMenuConfiguration:(RCTDevMenuConfiguration *__nullable)devMenuConfiguration;
7577

7678
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
7779
- (void)callFunctionOnBufferedRuntimeExecutor:(std::function<void(facebook::jsi::Runtime &runtime)> &&)executor;

packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ @implementation RCTInstance {
119119

120120
// APIs supporting interop with native modules and view managers
121121
RCTBridgeModuleDecorator *_bridgeModuleDecorator;
122+
RCTDevMenuConfigurationDecorator *_devMenuConfigurationDecorator;
122123

123124
jsinspector_modern::HostTarget *_parentInspectorTarget;
124125
}
@@ -132,6 +133,7 @@ - (instancetype)initWithDelegate:(id<RCTInstanceDelegate>)delegate
132133
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
133134
parentInspectorTarget:(jsinspector_modern::HostTarget *)parentInspectorTarget
134135
launchOptions:(nullable NSDictionary *)launchOptions
136+
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
135137
{
136138
if (self = [super init]) {
137139
_performanceLogger = [RCTPerformanceLogger new];
@@ -142,10 +144,14 @@ - (instancetype)initWithDelegate:(id<RCTInstanceDelegate>)delegate
142144
_jsRuntimeFactory = jsRuntimeFactory;
143145
_appTMMDelegate = tmmDelegate;
144146
_jsThreadManager = [RCTJSThreadManager new];
147+
145148
_bridgeModuleDecorator = [[RCTBridgeModuleDecorator alloc] initWithViewRegistry:[RCTViewRegistry new]
146149
moduleRegistry:moduleRegistry
147150
bundleManager:bundleManager
148151
callableJSModules:[RCTCallableJSModules new]];
152+
_devMenuConfigurationDecorator =
153+
[[RCTDevMenuConfigurationDecorator alloc] initWithDevMenuConfiguration:devMenuConfiguration];
154+
149155
_parentInspectorTarget = parentInspectorTarget;
150156
{
151157
__weak __typeof(self) weakSelf = self;
@@ -326,7 +332,8 @@ - (void)_start
326332
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridgeProxy:bridgeProxy
327333
bridgeModuleDecorator:_bridgeModuleDecorator
328334
delegate:self
329-
jsInvoker:jsCallInvoker];
335+
jsInvoker:jsCallInvoker
336+
devMenuConfigurationDecorator:_devMenuConfigurationDecorator];
330337

331338
#if RCT_DEV
332339
/**

0 commit comments

Comments
 (0)