Implement Android's dispatchViewManagerCommand interface on iOS
Summary: public Android implement ViewManager methods via a dispatch method on UIManager, whereas iOS implements them by exposing the methods on the view manager modules directly. This diff polyfills Android's implementation on top of the iOS implementation, allowing the same JS API to be used for both. Reviewed By: javache Differential Revision: D2803020 fb-gh-sync-id: 0da0544e593dc936467d16ce957a77f7ca41355b
This commit is contained in:
parent
28c0240361
commit
17df595e32
|
@ -56,8 +56,8 @@ Object.keys(RemoteModules).forEach((moduleName) => {
|
|||
});
|
||||
|
||||
/**
|
||||
* Copies the ViewManager constants into UIManager. This is only
|
||||
* needed for iOS, which puts the constants in the ViewManager
|
||||
* Copies the ViewManager constants and commands into UIManager. This is
|
||||
* only needed for iOS, which puts the constants in the ViewManager
|
||||
* namespace instead of UIManager, unlike Android.
|
||||
*
|
||||
* We'll eventually move this logic to UIManager.js, once all
|
||||
|
@ -67,12 +67,16 @@ Object.keys(RemoteModules).forEach((moduleName) => {
|
|||
const UIManager = NativeModules.UIManager;
|
||||
UIManager && Object.keys(UIManager).forEach(viewName => {
|
||||
const viewConfig = UIManager[viewName];
|
||||
const constants = {};
|
||||
if (viewConfig.Manager) {
|
||||
let constants;
|
||||
/* $FlowFixMe - nice try. Flow doesn't like getters */
|
||||
Object.defineProperty(viewConfig, 'Constants', {
|
||||
enumerable: true,
|
||||
get: () => {
|
||||
if (constants) {
|
||||
return constants;
|
||||
}
|
||||
constants = {};
|
||||
const viewManager = NativeModules[normalizePrefix(viewConfig.Manager)];
|
||||
viewManager && Object.keys(viewManager).forEach(key => {
|
||||
const value = viewManager[key];
|
||||
|
@ -83,6 +87,25 @@ UIManager && Object.keys(UIManager).forEach(viewName => {
|
|||
return constants;
|
||||
},
|
||||
});
|
||||
let commands;
|
||||
/* $FlowFixMe - nice try. Flow doesn't like getters */
|
||||
Object.defineProperty(viewConfig, 'Commands', {
|
||||
enumerable: true,
|
||||
get: () => {
|
||||
if (commands) {
|
||||
return commands;
|
||||
}
|
||||
commands = {};
|
||||
const viewManager = NativeModules[normalizePrefix(viewConfig.Manager)];
|
||||
viewManager && Object.keys(viewManager).forEach((key, index) => {
|
||||
const value = viewManager[key];
|
||||
if (typeof value === 'function') {
|
||||
commands[key] = index;
|
||||
}
|
||||
});
|
||||
return commands;
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ var EdgeInsetsPropType = require('EdgeInsetsPropType');
|
|||
var React = require('React');
|
||||
var StyleSheet = require('StyleSheet');
|
||||
var Text = require('Text');
|
||||
var UIManager = require('UIManager');
|
||||
var View = require('View');
|
||||
|
||||
var invariant = require('invariant');
|
||||
|
@ -240,15 +241,27 @@ var WebView = React.createClass({
|
|||
},
|
||||
|
||||
goForward: function() {
|
||||
RCTWebViewManager.goForward(this.getWebViewHandle());
|
||||
UIManager.dispatchViewManagerCommand(
|
||||
this.getWebViewHandle(),
|
||||
UIManager.RCTWebView.Commands.goForward,
|
||||
null
|
||||
);
|
||||
},
|
||||
|
||||
goBack: function() {
|
||||
RCTWebViewManager.goBack(this.getWebViewHandle());
|
||||
UIManager.dispatchViewManagerCommand(
|
||||
this.getWebViewHandle(),
|
||||
UIManager.RCTWebView.Commands.goBack,
|
||||
null
|
||||
);
|
||||
},
|
||||
|
||||
reload: function() {
|
||||
RCTWebViewManager.reload(this.getWebViewHandle());
|
||||
UIManager.dispatchViewManagerCommand(
|
||||
this.getWebViewHandle(),
|
||||
UIManager.RCTWebView.Commands.reload,
|
||||
null
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -222,6 +222,14 @@ RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
|
|||
return _moduleClassesByID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by RCTUIManager
|
||||
*/
|
||||
- (RCTModuleData *)moduleDataForName:(NSString *)moduleName
|
||||
{
|
||||
return _moduleDataByName[moduleName];
|
||||
}
|
||||
|
||||
- (id)moduleForName:(NSString *)moduleName
|
||||
{
|
||||
RCTModuleData *moduleData = _moduleDataByName[moduleName];
|
||||
|
|
|
@ -63,6 +63,12 @@
|
|||
*/
|
||||
- (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue;
|
||||
|
||||
/**
|
||||
* Get the module data for a given module name. Used by UIManager to implement
|
||||
* the `dispatchViewManagerCommand` method.
|
||||
*/
|
||||
- (RCTModuleData *)moduleDataForName:(NSString *)moduleName;
|
||||
|
||||
/**
|
||||
* Systrace profiler toggling methods exposed for the RCTDevMenu
|
||||
*/
|
||||
|
|
|
@ -31,8 +31,4 @@
|
|||
JSMethodName:(NSString *)JSMethodName
|
||||
moduleClass:(Class)moduleClass NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (void)invokeWithBridge:(RCTBridge *)bridge
|
||||
module:(id)module
|
||||
arguments:(NSArray *)arguments;
|
||||
|
||||
@end
|
||||
|
|
|
@ -16,12 +16,15 @@
|
|||
#import "RCTAnimationType.h"
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
#import "RCTComponent.h"
|
||||
#import "RCTComponentData.h"
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTDefines.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTModuleData.h"
|
||||
#import "RCTModuleMethod.h"
|
||||
#import "RCTProfile.h"
|
||||
#import "RCTRootView.h"
|
||||
#import "RCTRootViewInternal.h"
|
||||
|
@ -907,6 +910,20 @@ RCT_EXPORT_METHOD(findSubviewIn:(nonnull NSNumber *)reactTag atPoint:(CGPoint)po
|
|||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(dispatchViewManagerCommand:(nonnull NSNumber *)reactTag
|
||||
commandID:(NSInteger)commandID
|
||||
commandArgs:(NSArray<id> *)commandArgs)
|
||||
{
|
||||
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
||||
RCTComponentData *componentData = _componentDataByName[shadowView.viewName];
|
||||
Class managerClass = componentData.managerClass;
|
||||
RCTModuleData *moduleData = [_bridge moduleDataForName:RCTBridgeModuleNameForClass(managerClass)];
|
||||
id<RCTBridgeMethod> method = moduleData.methods[commandID];
|
||||
|
||||
NSArray *args = [@[reactTag] arrayByAddingObjectsFromArray:commandArgs];
|
||||
[method invokeWithBridge:_bridge module:componentData.manager arguments:args];
|
||||
}
|
||||
|
||||
- (void)partialBatchDidFlush
|
||||
{
|
||||
if (self.unsafeFlushUIChangesBeforeBatchEnds) {
|
||||
|
|
Loading…
Reference in New Issue