This is an automated email from the ASF dual-hosted git repository.

moshen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-weex.git


The following commit(s) were added to refs/heads/master by this push:
     new c3dda86  [iOS] support reactor protocol to render
     new 18328bc  Merge pull request #3225 from jianhan-he/master
c3dda86 is described below

commit c3dda86b2b5d916f53db066b83a10a386d483218
Author: linghe.lh <linghe...@alibaba-inc.com>
AuthorDate: Thu Jun 11 10:09:33 2020 +0800

    [iOS] support reactor protocol to render
---
 WeexSDK.podspec                                    |   3 +-
 ios/sdk/WeexSDK.xcodeproj/project.pbxproj          |  23 +++-
 ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm     |  10 +-
 .../Sources/Component/RecycleList/WXJSASTParser.mm |   2 +-
 .../WeexSDK/Sources/Events/WXComponent+Events.m    |   3 +
 ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h  |   2 +
 ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m  |  21 +++-
 ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h      |  10 ++
 ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m      |  45 +++++++-
 .../WeexSDK/Sources/Model/WXSDKInstance_private.h  |   2 +
 .../WeexSDK/Sources/Protocol/WXReactorProtocol.h   |  64 +++++++++++
 ios/sdk/WeexSDK/Sources/WeexSDK.h                  |   2 +
 weex_core/Source/core/render/page/reactor_page.cpp | 127 +++++++++++++++++++++
 weex_core/Source/core/render/page/reactor_page.h   |  79 +++++++++++++
 weex_core/Source/core/render/page/render_page.cpp  |   4 -
 15 files changed, 380 insertions(+), 17 deletions(-)

diff --git a/WeexSDK.podspec b/WeexSDK.podspec
index 37fbc1b..8689ebb 100644
--- a/WeexSDK.podspec
+++ b/WeexSDK.podspec
@@ -107,7 +107,8 @@ Pod::Spec.new do |s|
                           'weex_core/Source/core/layout/flex_enum.h',
                           'weex_core/Source/core/layout/layout.h',
                           'weex_core/Source/core/layout/style.h',
-                          'weex_core/Source/core/bridge/eagle_bridge.h'
+                          'weex_core/Source/core/bridge/eagle_bridge.h',
+                          'weex_core/Source/core/render/page/reactor_page.h'
 
   s.module_map = 'WeexSDK.modulemap'
 
diff --git a/ios/sdk/WeexSDK.xcodeproj/project.pbxproj 
b/ios/sdk/WeexSDK.xcodeproj/project.pbxproj
index 470c4ad..d14d0a7 100644
--- a/ios/sdk/WeexSDK.xcodeproj/project.pbxproj
+++ b/ios/sdk/WeexSDK.xcodeproj/project.pbxproj
@@ -575,6 +575,14 @@
                BD88C14C22F02128004467AA /* 
render_action_update_richtext_child_style.cpp in Sources */ = {isa = 
PBXBuildFile; fileRef = BD88C14822F02128004467AA /* 
render_action_update_richtext_child_style.cpp */; };
                BD9205FB223651D900EDF93D /* eagle_bridge.h in Headers */ = {isa 
= PBXBuildFile; fileRef = BD9205F9223651D800EDF93D /* eagle_bridge.h */; 
settings = {ATTRIBUTES = (Public, ); }; };
                BD9205FC223651D900EDF93D /* eagle_bridge.cpp in Sources */ = 
{isa = PBXBuildFile; fileRef = BD9205FA223651D800EDF93D /* eagle_bridge.cpp */; 
};
+               BDB112982459D6C2008492F9 /* WXReactorProtocol.h in Headers */ = 
{isa = PBXBuildFile; fileRef = BDB112972459D6C2008492F9 /* WXReactorProtocol.h 
*/; settings = {ATTRIBUTES = (Public, ); }; };
+               BDB1129B2459D71E008492F9 /* reactor_page.cpp in Sources */ = 
{isa = PBXBuildFile; fileRef = BDB112992459D71E008492F9 /* reactor_page.cpp */; 
};
+               BDB1129C2459D71E008492F9 /* reactor_page.h in Headers */ = {isa 
= PBXBuildFile; fileRef = BDB1129A2459D71E008492F9 /* reactor_page.h */; 
settings = {ATTRIBUTES = (Public, ); }; };
+               BDB1129D2459D802008492F9 /* WXReactorProtocol.h in Headers */ = 
{isa = PBXBuildFile; fileRef = BDB112972459D6C2008492F9 /* WXReactorProtocol.h 
*/; settings = {ATTRIBUTES = (Public, ); }; };
+               BDB1129E2459D8D3008492F9 /* reactor_page.cpp in Headers */ = 
{isa = PBXBuildFile; fileRef = BDB112992459D71E008492F9 /* reactor_page.cpp */; 
};
+               BDB1129F2459D8FC008492F9 /* reactor_page.cpp in Sources */ = 
{isa = PBXBuildFile; fileRef = BDB112992459D71E008492F9 /* reactor_page.cpp */; 
};
+               BDB112A02459D90F008492F9 /* reactor_page.h in Headers */ = {isa 
= PBXBuildFile; fileRef = BDB1129A2459D71E008492F9 /* reactor_page.h */; 
settings = {ATTRIBUTES = (Public, ); }; };
+               BDBA319B248D0A5200C6EDD0 /* reactor_page.cpp in Headers */ = 
{isa = PBXBuildFile; fileRef = BDB112992459D71E008492F9 /* reactor_page.cpp */; 
};
                BDEEADBA22F2902E0099F1D7 /* time_calculator.cpp in Sources */ = 
{isa = PBXBuildFile; fileRef = BDEEADB822F2902D0099F1D7 /* time_calculator.cpp 
*/; };
                BDEEADBB22F2902E0099F1D7 /* time_calculator.cpp in Sources */ = 
{isa = PBXBuildFile; fileRef = BDEEADB822F2902D0099F1D7 /* time_calculator.cpp 
*/; };
                BDEEADBC22F2902E0099F1D7 /* time_calculator.h in Headers */ = 
{isa = PBXBuildFile; fileRef = BDEEADB922F2902E0099F1D7 /* time_calculator.h 
*/; };
@@ -1331,6 +1339,9 @@
                BD88C14822F02128004467AA /* 
render_action_update_richtext_child_style.cpp */ = {isa = PBXFileReference; 
fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 
render_action_update_richtext_child_style.cpp; sourceTree = "<group>"; };
                BD9205F9223651D800EDF93D /* eagle_bridge.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
eagle_bridge.h; sourceTree = "<group>"; };
                BD9205FA223651D800EDF93D /* eagle_bridge.cpp */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; 
path = eagle_bridge.cpp; sourceTree = "<group>"; };
+               BDB112972459D6C2008492F9 /* WXReactorProtocol.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
WXReactorProtocol.h; sourceTree = "<group>"; };
+               BDB112992459D71E008492F9 /* reactor_page.cpp */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; 
path = reactor_page.cpp; sourceTree = "<group>"; };
+               BDB1129A2459D71E008492F9 /* reactor_page.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
reactor_page.h; sourceTree = "<group>"; };
                BDEEADB822F2902D0099F1D7 /* time_calculator.cpp */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; 
path = time_calculator.cpp; sourceTree = "<group>"; };
                BDEEADB922F2902E0099F1D7 /* time_calculator.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
time_calculator.h; sourceTree = "<group>"; };
                C401945D1E344E8300D19C31 /* WXFloatCompareTests.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= WXFloatCompareTests.m; sourceTree = "<group>"; };
@@ -1887,6 +1898,7 @@
                77D1611C1C02DD3C0010B15B /* Protocol */ = {
                        isa = PBXGroup;
                        children = (
+                               BDB112972459D6C2008492F9 /* WXReactorProtocol.h 
*/,
                                D7D6B6E1238E1B1D00BE56DD /* 
WXDarkSchemeProtocol.h */,
                                33CE19122153444900CF9670 /* 
WXJSFrameworkLoadProtocol.h */,
                                17036A5220FDE7490029AE3D /* WXApmProtocol.h */,
@@ -2226,6 +2238,8 @@
                B8D66B372125572F003960BD /* page */ = {
                        isa = PBXGroup;
                        children = (
+                               BDB112992459D71E008492F9 /* reactor_page.cpp */,
+                               BDB1129A2459D71E008492F9 /* reactor_page.h */,
                                77788B6E2229252C000D5102 /* 
render_page_base.cpp */,
                                77788B702229252C000D5102 /* render_page_base.h 
*/,
                                77788B6F2229252C000D5102 /* 
render_page_custom.cpp */,
@@ -2448,6 +2462,8 @@
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               BDB112982459D6C2008492F9 /* WXReactorProtocol.h 
in Headers */,
+                               BDB1129C2459D71E008492F9 /* reactor_page.h in 
Headers */,
                                77E659F11C0C3612008B8775 /* WXModuleFactory.h 
in Headers */,
                                F75C591C2313C1FC002FFF94 /* WXStreamModule.h in 
Headers */,
                                986CEAA723B230C2004166E0 /* WXEaglePlugin.h in 
Headers */,
@@ -2461,7 +2477,6 @@
                                45E0B4C121CB7B82005D1B3B /* WXConvertUtility.h 
in Headers */,
                                BD88C13F22F02111004467AA /* 
render_action_remove_child_from_richtext.h in Headers */,
                                BD9205FB223651D900EDF93D /* eagle_bridge.h in 
Headers */,
-                               BD9205F82236518700EDF93D /* 
WXDataRenderHandler.h in Headers */,
                                D7D6B6E2238E1B1D00BE56DD /* 
WXDarkSchemeProtocol.h in Headers */,
                                7715EB6221A69DD9001F1108 /* WXRichText.h in 
Headers */,
                                B8D66C1B21255730003960BD /* style.h in Headers 
*/,
@@ -2523,6 +2538,7 @@
                                B8D66C6B21255730003960BD /* render_scroller.h 
in Headers */,
                                B8D66C6921255730003960BD /* render_mask.h in 
Headers */,
                                C4C30DE91E1B833D00786B6C /* 
WXComponent+PseudoClassManagement.h in Headers */,
+                               BDB1129E2459D8D3008492F9 /* reactor_page.cpp in 
Headers */,
                                591DD3321D23AD5800BE8709 /* WXErrorView.h in 
Headers */,
                                B8D66C8D21255730003960BD /* render_creator.h in 
Headers */,
                                17C74F0B2072145100AB4CAB /* 
WXAnalyzerCenter+Transfer.h in Headers */,
@@ -2700,6 +2716,8 @@
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               BDB1129D2459D802008492F9 /* WXReactorProtocol.h 
in Headers */,
+                               BDB112A02459D90F008492F9 /* reactor_page.h in 
Headers */,
                                DCA4461D1EFA5AAA00D0CFA8 /* WXHandlerFactory.h 
in Headers */,
                                DCA446101EFA5A8500D0CFA8 /* WXBridgeMethod.h in 
Headers */,
                                DCA4461A1EFA5AA000D0CFA8 /* 
WXInvocationConfig.h in Headers */,
@@ -2769,6 +2787,7 @@
                                DCA4459F1EFA56EC00D0CFA8 /* 
WXURLRewriteProtocol.h in Headers */,
                                DCA445A21EFA570100D0CFA8 /* 
WXScrollerComponent.h in Headers */,
                                B8D66C7621255730003960BD /* render_object.h in 
Headers */,
+                               BDBA319B248D0A5200C6EDD0 /* reactor_page.cpp in 
Headers */,
                                DCA445B71EFA579200D0CFA8 /* 
WXImgLoaderProtocol.h in Headers */,
                                1746EA7420E9D253007E55BD /* 
WXComponent_performance.h in Headers */,
                                B8D66CEB21255B2A003960BD /* WXWebSocketLoader.h 
in Headers */,
@@ -3208,6 +3227,7 @@
                                744D61111E49979000B624B3 /* WXFooterComponent.m 
in Sources */,
                                B8D66C0721255730003960BD /* 
core_environment.cpp in Sources */,
                                745B2D6F1E5A8E1E0092D38A /* 
WXRecyclerUpdateController.m in Sources */,
+                               BDB1129B2459D71E008492F9 /* reactor_page.cpp in 
Sources */,
                                745B2D6B1E5A8E1E0092D38A /* 
WXRecyclerComponent.mm in Sources */,
                                B8D66C0D21255730003960BD /* 
core_side_in_platform.cpp in Sources */,
                                B8D66C5D21255730003960BD /* 
render_action_appendtree_createfinish.cpp in Sources */,
@@ -3387,6 +3407,7 @@
                        buildActionMask = 2147483647;
                        files = (
                                D77286FF22C9B22C00E1DA7D /* eagle_bridge.cpp in 
Sources */,
+                               BDB1129F2459D8FC008492F9 /* reactor_page.cpp in 
Sources */,
                                453F376F219A78D700A03F1D /* WXConvertUtility.mm 
in Sources */,
                                453F376E219A789A00A03F1D /* 
default_request_handler.mm in Sources */,
                                453F376A219A784F00A03F1D /* http_module.cc in 
Sources */,
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm 
b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
index f232ada..07db550 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
@@ -1821,9 +1821,9 @@ static WeexCore::ScriptBridge* jsBridge = nullptr;
     return nullptr;
 }
 
-+ (std::vector<std::pair<std::string, 
std::string>>*)_parseMapValuePairs:(NSDictionary *)data
++ (std::unique_ptr<std::vector<std::pair<std::string, 
std::string>>>)_parseMapValuePairs:(NSDictionary *)data
 {
-    std::vector<std::pair<std::string, std::string>>* result = new 
std::vector<std::pair<std::string, std::string>>();
+    __block std::unique_ptr<std::vector<std::pair<std::string, std::string>>> 
result = std::make_unique<std::vector<std::pair<std::string, std::string>>>();
     [data enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull 
obj, BOOL * _Nonnull stop) {
         ConvertToCString(obj, ^(const char * value) {
             if (value != nullptr) {
@@ -1831,7 +1831,7 @@ static WeexCore::ScriptBridge* jsBridge = nullptr;
             }
         });
     }];
-    return result;
+    return std::move(result);
 }
 
 + (void)callAddElement:(NSString*)pageId parentRef:(NSString*)parentRef 
data:(NSDictionary*)data index:(int)index
@@ -1877,13 +1877,13 @@ static WeexCore::ScriptBridge* jsBridge = nullptr;
 + (void)callUpdateAttrs:(NSString*)pageId ref:(NSString*)ref 
data:(NSDictionary*)data
 {
     SetConvertCurrentPage(pageId);
-    WeexCore::RenderManager::GetInstance()->UpdateAttr([pageId UTF8String] ?: 
"", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
+    WeexCore::RenderManager::GetInstance()->UpdateAttr([pageId UTF8String] ?: 
"", [ref UTF8String] ?: "", [self _parseMapValuePairs:data].get());
 }
 
 + (void)callUpdateStyle:(NSString*)pageId ref:(NSString*)ref 
data:(NSDictionary*)data
 {
     SetConvertCurrentPage(pageId);
-    WeexCore::RenderManager::GetInstance()->UpdateStyle([pageId UTF8String] ?: 
"", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
+    WeexCore::RenderManager::GetInstance()->UpdateStyle([pageId UTF8String] ?: 
"", [ref UTF8String] ?: "", [self _parseMapValuePairs:data].get());
 }
 
 + (void)callAddEvent:(NSString*)pageId ref:(NSString*)ref 
event:(NSString*)event
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm 
b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm
index 2d26ff0..c6a69ef 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm
@@ -427,7 +427,7 @@ static int binaryPrecedence(WXJSToken *token)
                             
                             // 3 digits are only allowed when string starts
                             // with 0, 1, 2, 3
-                            if (std::string(1, '0123').find(ch) != 
std::string::npos &&
+                            if (std::string("0123").find(ch) != 
std::string::npos &&
                                 _index < _length &&
                                 isOctalDigit(_source[_index])) {
                                 code = code * 8 + _source[_index++] - '0';
diff --git a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m 
b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
index 6e7e6db..34f0c69 100644
--- a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
+++ b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
@@ -416,11 +416,14 @@ if ([removeEventName 
isEqualToString:@#eventName1]||[removeEventName isEqualToSt
         return;
     }
     if (!CGRectEqualToRect(self.view.frame, CGRectZero)) {
+        CGPoint pageLocation = [recognizer 
locationInView:self.weexInstance.rootView];
         CGRect frame = [self.view.superview convertRect:self.view.frame 
toView:self.view.window];
         position[@"x"] = @(frame.origin.x/scaleFactor);
         position[@"y"] = @(frame.origin.y/scaleFactor);
         position[@"width"] = @(frame.size.width/scaleFactor);
         position[@"height"] = @(frame.size.height/scaleFactor);
+        position[@"pageX"] = @(pageLocation.x/scaleFactor);
+        position[@"pageY"] = @(pageLocation.y/scaleFactor);
     }
     [self fireEvent:@"click" params:@{@"position":position}];
 }
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h 
b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
index 5fc9c54..e5fefd3 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
@@ -252,6 +252,8 @@ extern "C" {
 
 - (void)checkJSThread;
 
++ (NSThread *)jsThread;
+
 @end
 
 NS_ASSUME_NONNULL_END
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m 
b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
index c5106a2..5c1f455 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
@@ -39,6 +39,7 @@
 #import "WXExceptionUtils.h"
 #import "WXSDKEngine.h"
 #import "WXConfigCenterProtocol.h"
+#import "WXReactorProtocol.h"
 
 @interface WXBridgeManager ()
 
@@ -642,7 +643,16 @@ void WXPerformBlockSyncOnBridgeThreadForInstance(void 
(^block) (void), NSString*
         WXLogError(@"Event type and component ref should not be nil");
         return;
     }
-    
+    if (instance.useReactor) {
+        id<WXReactorProtocol> reactorHandler = [WXHandlerFactory 
handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")];
+        if (reactorHandler) {
+            [reactorHandler fireEvent:instanceId ref:ref event:type 
args:params?:@{} domChanges:domChanges?:@{}];
+        } else {
+            WXLogError(@"There is no reactor handler");
+        }
+        return;
+    }
+
     NSArray *args = @[ref, type, params?:@{}, domChanges?:@{}];
     if (handlerArguments) {
         NSMutableArray *newArgs = [args mutableCopy];
@@ -706,7 +716,14 @@ void WXPerformBlockSyncOnBridgeThreadForInstance(void 
(^block) (void), NSString*
             [instance.renderPlugin invokeCallBack:instanceId function:funcId 
args:strongArgs keepAlive:keepAlive];
         });
     }
-    else {
+    else if (instance.useReactor) {
+        id<WXReactorProtocol> reactorHandler = [WXHandlerFactory 
handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")];
+        if (reactorHandler) {
+            [reactorHandler invokeCallBack:instanceId function:funcId 
args:args];
+        } else {
+            WXLogError(@"There is no reactor handler");
+        }
+    } else {
         WXCallJSMethod *method = [[WXCallJSMethod alloc] 
initWithModuleName:@"jsBridge" methodName:@"callback" arguments:args 
instance:instance];
         [self callJsMethod:method];
     }
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h 
b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
index fec4ac6..484172b 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
@@ -121,6 +121,11 @@ typedef BOOL (^WXModuleInterceptCallback)(NSString 
*moduleName, NSString *method
 @property (nonatomic, strong) NSDictionary* containerInfo;
 
 /**
+* Params for Canal
+**/
+@property (nonatomic, strong) NSMutableDictionary* canalParams;
+
+/**
  * Whether this instance is rendered or not. Please MUST not render an 
instance twice even if you have called destroyInstance.
  **/
 @property (nonatomic, assign, readonly) BOOL isRendered;
@@ -388,6 +393,11 @@ typedef enum : NSUInteger {
 - (NSURL *)completeURL:(NSString *)url;
 
 /**
+* register jscontext for reactor
+*/
+- (void)registerReactorContext:(JSContext*)context;
+
+/**
  * jsbundle str ,may be nil (weak)
  */
 - (NSString* _Nullable) bundleTemplate;
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m 
b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
index 4879a57..31a51c8 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
@@ -54,6 +54,7 @@
 #import "WXDarkSchemeProtocol.h"
 #import "WXDarkSchemeModule.h"
 #import <WeexSDK/WXEaglePluginManager.h>
+#import "WXReactorProtocol.h"
 
 #define WEEX_RENDER_TYPE_PLATFORM       @"platform"
 
@@ -164,6 +165,8 @@ typedef enum : NSUInteger {
         _apmInstance = [[WXApmForInstance alloc] init];
                 
         _useBackupJsThread = NO;
+        _useReactor = NO;
+        _canalParams = [NSMutableDictionary dictionary];
 
         [self addObservers];
     }
@@ -339,7 +342,7 @@ typedef enum : NSUInteger {
         return;
     }
     WXLogInfo(@"pageid: %@ renderWithURL: %@", _instanceId, 
url.absoluteString);
-    
+
     _renderPlugin = [WXEaglePluginManager renderWithURL:&url];
     if (!_renderPlugin) {
         _renderPlugin = [WXEaglePluginManager renderWithOption:options];
@@ -402,6 +405,21 @@ typedef enum : NSUInteger {
     }
 }
 
+- (void)registerReactorContext:(JSContext*)context {
+    if (!context) {
+        return;
+    }
+    [WXCoreBridge install];
+    [self.canalParams setObject:context forKey:@"mainJSContext"];
+
+    id<WXReactorProtocol> reactorHandler = [WXHandlerFactory 
handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")];
+    if (reactorHandler) {
+        [reactorHandler registerJSContext:self.instanceId];
+    } else {
+        WXLogError(@"There is no reactor handler");
+    }
+}
+
 - (NSString *) bundleTemplate
 {
     return self.mainBundleString;
@@ -597,7 +615,20 @@ typedef enum : NSUInteger {
         return;
     }
     
-    [[WXSDKManager bridgeMgr] createInstance:self.instanceId 
template:mainBundleString options:dictionary data:_jsData];
+    if ([dictionary[@"USE_REACTOR"] boolValue]) {
+        id<WXReactorProtocol> reactorHandler = [WXHandlerFactory 
handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")];
+        if (reactorHandler) {
+            _useReactor = YES;
+            if (![self.canalParams objectForKey:@"mainJSContext"]) {
+                [reactorHandler registerJSContext:self.instanceId];
+            }
+            [reactorHandler render:self.instanceId source:mainBundleString 
data:_jsData];
+        } else {
+            WXLogError(@"There is no reactor handler");
+        }
+    } else {
+        [[WXSDKManager bridgeMgr] createInstance:self.instanceId 
template:mainBundleString options:dictionary data:_jsData];
+    }
     
     WX_MONITOR_PERF_SET(WXPTBundleSize, [mainBundleString 
lengthOfBytesUsingEncoding:NSUTF8StringEncoding], self);
     
@@ -830,7 +861,15 @@ typedef enum : NSUInteger {
 
     [WXPrerenderManager removePrerenderTaskforUrl:[self.scriptURL 
absoluteString]];
     [WXPrerenderManager destroyTask:self.instanceId];
-    if (!self.renderPlugin) {
+
+    if (_useReactor) {
+        id<WXReactorProtocol> reactorHandler = [WXHandlerFactory 
handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")];
+        if (reactorHandler) {
+            [reactorHandler unregisterJSContext:self.instanceId];
+        } else {
+            WXLogError(@"There is no reactor handler");
+        }
+    } else if (!self.renderPlugin) {
         [[WXSDKManager bridgeMgr] destroyInstance:self.instanceId];
     }
     
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h 
b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h
index 38e5bb2..6ea7e4d 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h
@@ -36,6 +36,8 @@
 @property (nonatomic, strong) NSString *mainBundleString;
 @property (nonatomic, weak) id <WXEaglePlugin> renderPlugin;
 
+@property (nonatomic, assign) BOOL useReactor;
+
 // add monitor information
 @property (nonatomic, strong) NSString *callCreateInstanceContext;
 @property (nonatomic, strong) NSString *createInstanceContextResult;
diff --git a/ios/sdk/WeexSDK/Sources/Protocol/WXReactorProtocol.h 
b/ios/sdk/WeexSDK/Sources/Protocol/WXReactorProtocol.h
new file mode 100644
index 0000000..4ac03f6
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Protocol/WXReactorProtocol.h
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JSContext;
+
+@protocol WXReactorProtocol <NSObject>
+
+@required
+
+/**
+Weex should register a JSContext to reactor
+*/
+- (void)registerJSContext:(NSString *)instanceId;
+
+/**
+ Reactor execute js source
+*/
+- (void)render:(NSString *)instanceId source:(NSString*)source 
data:(NSDictionary* _Nullable)data;
+
+- (void)unregisterJSContext:(NSString *)instanceId;
+
+/**
+ When js call Weex NativeModule, invoke callback function
+ 
+ @param instanceId : weex instance id
+ @param callbackId : callback function id
+ @param args       : args
+*/
+- (void)invokeCallBack:(NSString *)instanceId function:(NSString *)callbackId 
args:(NSArray * _Nullable)args;
+
+/**
+Native event to js
+ 
+@param instanceId :   instance id
+@param ref        :   node reference
+@param event      :   event type
+@param args       :   parameters in event object
+@param domChanges :  dom value changes, used for two-way data binding
+*/
+- (void)fireEvent:(NSString *)instanceId ref:(NSString *)ref event:(NSString 
*)event args:(NSDictionary * _Nullable)args domChanges:(NSDictionary * 
_Nullable)domChanges;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/sdk/WeexSDK/Sources/WeexSDK.h 
b/ios/sdk/WeexSDK/Sources/WeexSDK.h
index 331ac78..372078a 100644
--- a/ios/sdk/WeexSDK/Sources/WeexSDK.h
+++ b/ios/sdk/WeexSDK/Sources/WeexSDK.h
@@ -24,6 +24,7 @@ FOUNDATION_EXPORT double WeexSDKVersionNumber;
 FOUNDATION_EXPORT const unsigned char WeexSDKVersionString[];
 
 #import <WeexSDK/style.h>
+#import <WeexSDK/reactor_page.h>
 #import <WeexSDK/layout.h>
 #import <WeexSDK/flex_enum.h>
 #import <WeexSDK/eagle_bridge.h>
@@ -49,6 +50,7 @@ FOUNDATION_EXPORT const unsigned char WeexSDKVersionString[];
 #import <WeexSDK/WXResourceLoader.h>
 #import <WeexSDK/WXRefreshComponent.h>
 #import <WeexSDK/WXRecyclerComponent.h>
+#import <WeexSDK/WXReactorProtocol.h>
 #import <WeexSDK/WXPrerenderManager.h>
 #import <WeexSDK/WXPageEventNotifyEvent.h>
 #import <WeexSDK/WXNetworkProtocol.h>
diff --git a/weex_core/Source/core/render/page/reactor_page.cpp 
b/weex_core/Source/core/render/page/reactor_page.cpp
new file mode 100644
index 0000000..f151dae
--- /dev/null
+++ b/weex_core/Source/core/render/page/reactor_page.cpp
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "core/render/page/reactor_page.h"
+
+#include "core/render/manager/render_manager.h"
+#include "core/render/page/render_page.h"
+#include "core/render/node/factory/render_creator.h"
+#include "core/manager/weex_core_manager.h"
+
+namespace WeexCore {
+
+void PostTaskOnComponentThread(const std::function<void()>& callback) {
+#if OS_IOS
+     
WeexCoreManager::Instance()->getPlatformBridge()->platform_side()->PostTaskOnComponentThread(callback);
+#else
+    callback();
+#endif
+}
+
+void ReactorPage::CreateBody(const std::string& ref,
+                             const std::string& type,
+                             const std::map<std::string, std::string>& styles,
+                             const std::map<std::string, std::string>& attrs,
+                             const std::vector<std::string>& events) {
+    RenderManager::GetInstance()->CreatePage(page_id_, [&] (RenderPage* 
page_instance) -> RenderObject* {
+#if OS_IOS
+        page_instance->set_before_layout_needed(false); // do not need before 
and after layout on ios platform
+        page_instance->set_after_layout_needed(false);
+        page_instance->set_platform_layout_needed(true);
+#endif
+        return CreateRenderObject(ref, type, 0, styles, attrs, events, 
page_instance->reserve_css_styles(), nullptr);
+    });
+    
+}
+
+void ReactorPage::AddElement(const std::string& ref,
+                             const std::string& type,
+                             const std::map<std::string, std::string>& styles,
+                             const std::map<std::string, std::string>& attrs,
+                             const std::vector<std::string>& events,
+                             const std::string parent_ref, int index) {
+    RenderManager::GetInstance()->AddRenderObject(page_id_, parent_ref, index, 
[&] (RenderPage* page_instance) -> RenderObject* {
+        return CreateRenderObject(ref, type, 0, styles, attrs, events, 
page_instance->reserve_css_styles(), nullptr);
+     });
+}
+
+void ReactorPage::UpdateStyles(const std::string& ref, 
std::vector<std::pair<std::string, std::string>> styles) {
+     WeexCore::RenderManager::GetInstance()->UpdateStyle(page_id_, ref, 
&styles);
+}
+
+void ReactorPage::UpdateAttrs(const std::string& ref, 
std::vector<std::pair<std::string, std::string>> attrs) {
+     WeexCore::RenderManager::GetInstance()->UpdateAttr(page_id_, ref, &attrs);
+}
+
+void ReactorPage::CreateFinish() {
+    
WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->CreateFinish(page_id_.c_str());
+}
+
+void ReactorPage::RemoveElement(const std::string& ref) {
+    
WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->RemoveElement(page_id_.c_str(),
 ref.c_str());
+}
+
+void ReactorPage::CallNativeModule(const std::string& module,
+                                   const std::string& method,
+                                   const std::string& arguments,
+                                   size_t arguments_length,
+                                   const std::string& options,
+                                   int options_length) {
+  std::unique_ptr<ValueWithType> ptr = WeexCoreManager::Instance()
+      ->getPlatformBridge()
+      ->platform_side()
+      ->CallNativeModule(page_id_.c_str(), module.c_str(), method.c_str(), 
arguments.c_str(), static_cast<int>(arguments_length), options.c_str(), 
options_length);
+}
+
+RenderObject* ReactorPage::CreateRenderObject(const std::string& ref,
+                                              const std::string& type,
+                                              unsigned index,
+                                              const std::map<std::string, 
std::string>& styles,
+                                              const std::map<std::string, 
std::string>& attrs,
+                                              const std::vector<std::string>& 
events,
+                                              bool reserve_styles,
+                                              WeexCore::RenderObject* parent) {
+    if (ref.empty() || type.empty()) {
+        return nullptr;
+    }
+
+    RenderObject* render_object = (RenderObject 
*)RenderCreator::GetInstance()->CreateRender(type, ref);
+    render_object->set_page_id(page_id_);
+    if (parent) {
+        parent->AddRenderObject(index, render_object);
+    }
+
+    //fill attributes, styles and events
+    for (const auto& attr : attrs) {
+        render_object->AddAttr(attr.first, attr.second);
+    }
+    for (const auto& style : styles) {
+        render_object->AddStyle(style.first, style.second, reserve_styles);
+    }
+    for (const auto& event : events) {
+        render_object->AddEvent(event);
+    }
+
+    render_object->ApplyDefaultStyle(reserve_styles);
+    render_object->ApplyDefaultAttr();
+    return render_object;
+}
+
+}  // namespace WeexCore
+
diff --git a/weex_core/Source/core/render/page/reactor_page.h 
b/weex_core/Source/core/render/page/reactor_page.h
new file mode 100644
index 0000000..577f7e0
--- /dev/null
+++ b/weex_core/Source/core/render/page/reactor_page.h
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef CORE_RENDER_PAGE_REACTOR_PAGE_H_
+#define CORE_RENDER_PAGE_REACTOR_PAGE_H_
+
+#if defined __cplusplus
+
+#include <string>
+#include <map>
+#include <functional>
+
+namespace WeexCore {
+
+void PostTaskOnComponentThread(const std::function<void()>& callback);
+
+class RenderObject;
+
+class ReactorPage {
+public:
+    explicit ReactorPage(const std::string& page_id)
+    : page_id_(page_id) {}
+
+    void CreateBody(const std::string& ref,
+                    const std::string& type,
+                    const std::map<std::string, std::string>& styles,
+                    const std::map<std::string, std::string>& attrs,
+                    const std::vector<std::string>& events);
+
+    void AddElement(const std::string& ref,
+                    const std::string& type,
+                    const std::map<std::string, std::string>& styles,
+                    const std::map<std::string, std::string>& attrs,
+                    const std::vector<std::string>& events,
+                    const std::string parent_ref, int index=-1);
+
+    void UpdateStyles(const std::string& ref, 
std::vector<std::pair<std::string, std::string>> styles);
+
+    void UpdateAttrs(const std::string& ref, 
std::vector<std::pair<std::string, std::string>> attrs);
+
+    void RemoveElement(const std::string& ref);
+
+    void CreateFinish();
+
+    const std::string& page_id() const {return page_id_;}
+
+    void CallNativeModule(const std::string& module,
+                          const std::string& method,
+                          const std::string& arguments,
+                          size_t arguments_length,
+                          const std::string& options,
+                          int options_length);
+
+private:
+    RenderObject* CreateRenderObject(const std::string& ref, const 
std::string& type, unsigned index, const std::map<std::string, std::string>& 
styles, const std::map<std::string, std::string>& attrs, const 
std::vector<std::string>& events, bool reserve_styles, WeexCore::RenderObject* 
parent);
+
+    const std::string page_id_;
+};
+
+}  // namespace WeexCore
+
+#endif
+
+#endif  // CORE_RENDER_PAGE_REACTOR_PAGE_H_
diff --git a/weex_core/Source/core/render/page/render_page.cpp 
b/weex_core/Source/core/render/page/render_page.cpp
index 79a3644..cb29d5c 100755
--- a/weex_core/Source/core/render/page/render_page.cpp
+++ b/weex_core/Source/core/render/page/render_page.cpp
@@ -338,8 +338,6 @@ bool RenderPage::UpdateStyle(
   if (src != nullptr) {
     src->clear();
     src->shrink_to_fit();
-    delete src;
-    src = nullptr;
   }
 
   if (style != nullptr) {
@@ -395,8 +393,6 @@ bool RenderPage::UpdateAttr(
   if (attrs != nullptr) {
     attrs->clear();
     attrs->shrink_to_fit();
-    delete attrs;
-    attrs = nullptr;
   }
 
   return true;

Reply via email to