You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ji...@apache.org on 2017/02/20 06:41:02 UTC
[13/50] [abbrv] incubator-weex git commit: V0.10.0 stable gitlab
(#178)
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/JSValue+Weex.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/JSValue+Weex.h b/ios/sdk/WeexSDK/Sources/Bridge/JSValue+Weex.h
new file mode 100644
index 0000000..3270a95
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Bridge/JSValue+Weex.h
@@ -0,0 +1,15 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import <JavaScriptCore/JavaScriptCore.h>
+
+@interface JSValue (Weex)
+
++ (JSValue *)wx_valueWithReturnValueFromInvocation:(NSInvocation *)invocation inContext:(JSContext *)context;
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/JSValue+Weex.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/JSValue+Weex.m b/ios/sdk/WeexSDK/Sources/Bridge/JSValue+Weex.m
new file mode 100644
index 0000000..3bc3dda
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Bridge/JSValue+Weex.m
@@ -0,0 +1,90 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "JSValue+Weex.h"
+#import <objc/runtime.h>
+
+@implementation JSValue (Weex)
+
++ (JSValue *)wx_valueWithReturnValueFromInvocation:(NSInvocation *)invocation inContext:(JSContext *)context
+{
+ if (!invocation || !context) {
+ return nil;
+ }
+
+ const char * returnType = [invocation.methodSignature methodReturnType];
+
+ JSValue *returnValue;
+ switch (returnType[0] == _C_CONST ? returnType[1] : returnType[0]) {
+ case _C_VOID: {
+ // 1.void
+ returnValue = [JSValue valueWithUndefinedInContext:context];
+ break;
+ }
+
+ case _C_ID: {
+ // 2.id
+ void *value;
+ [invocation getReturnValue:&value];
+ id object = (__bridge id)value;
+
+ returnValue = [JSValue valueWithObject:[object copy] inContext:context];
+ break;
+ }
+
+#define WX_JS_VALUE_RET_CASE(typeString, type) \
+ case typeString: { \
+ type value; \
+ [invocation getReturnValue:&value]; \
+ returnValue = [JSValue valueWithObject:@(value) inContext:context]; \
+ break; \
+ }
+ // 3.number
+ WX_JS_VALUE_RET_CASE(_C_CHR, char)
+ WX_JS_VALUE_RET_CASE(_C_UCHR, unsigned char)
+ WX_JS_VALUE_RET_CASE(_C_SHT, short)
+ WX_JS_VALUE_RET_CASE(_C_USHT, unsigned short)
+ WX_JS_VALUE_RET_CASE(_C_INT, int)
+ WX_JS_VALUE_RET_CASE(_C_UINT, unsigned int)
+ WX_JS_VALUE_RET_CASE(_C_LNG, long)
+ WX_JS_VALUE_RET_CASE(_C_ULNG, unsigned long)
+ WX_JS_VALUE_RET_CASE(_C_LNG_LNG, long long)
+ WX_JS_VALUE_RET_CASE(_C_ULNG_LNG, unsigned long long)
+ WX_JS_VALUE_RET_CASE(_C_FLT, float)
+ WX_JS_VALUE_RET_CASE(_C_DBL, double)
+ WX_JS_VALUE_RET_CASE(_C_BOOL, BOOL)
+
+ case _C_STRUCT_B: {
+ NSString *typeString = [NSString stringWithUTF8String:returnType];
+
+#define WX_JS_VALUE_RET_STRUCT(_type, _methodName) \
+ if ([typeString rangeOfString:@#_type].location != NSNotFound) { \
+ _type value; \
+ [invocation getReturnValue:&value]; \
+ returnValue = [JSValue _methodName:value inContext:context]; \
+ break; \
+ }
+ // 4.struct
+ WX_JS_VALUE_RET_STRUCT(CGRect, valueWithRect)
+ WX_JS_VALUE_RET_STRUCT(CGPoint, valueWithPoint)
+ WX_JS_VALUE_RET_STRUCT(CGSize, valueWithSize)
+ WX_JS_VALUE_RET_STRUCT(NSRange, valueWithRange)
+
+ }
+ case _C_CHARPTR:
+ case _C_PTR:
+ case _C_CLASS: {
+ returnValue = [JSValue valueWithUndefinedInContext:context];
+ break;
+ }
+ }
+
+ return returnValue;
+}
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h
index 4388bdf..1f4ee27 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h
@@ -8,7 +8,7 @@
#import <Foundation/Foundation.h>
-@class WXBridgeMethod;
+@class WXCallJSMethod;
@class WXSDKInstance;
@interface WXBridgeContext : NSObject
@@ -62,7 +62,7 @@
* Execute JS Method
* @param method : object of bridge method
**/
-- (void)executeJsMethod:(WXBridgeMethod *)method;
+- (void)executeJsMethod:(WXCallJSMethod *)method;
/**
* Register Modules Method
* @param modules : module list
@@ -70,6 +70,13 @@
- (void)registerModules:(NSDictionary *)modules;
/**
+ * Execute JS Service
+ * @param method : JS services name
+ * @param method : JS services script
+ **/
+- (void)executeJsService:(NSString *)script withName: (NSString *)name;
+
+/**
* Register Components Method
* @param components: component list
**/
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
index 79e22f3..9eae7de 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
@@ -12,7 +12,6 @@
#import "WXDebugLoggerBridge.h"
#import "WXLog.h"
#import "WXUtility.h"
-#import "WXBridgeMethod.h"
#import "WXModuleFactory.h"
#import "WXModuleProtocol.h"
#import "WXUtility.h"
@@ -21,11 +20,14 @@
#import "WXAssert.h"
#import "WXSDKManager.h"
#import "WXDebugTool.h"
-#import "WXModuleManager.h"
#import "WXSDKInstance_private.h"
#import "WXThreadSafeMutableArray.h"
#import "WXAppConfiguration.h"
#import "WXInvocationConfig.h"
+#import "WXComponentMethod.h"
+#import "WXModuleMethod.h"
+#import "WXCallJSMethod.h"
+#import "WXSDKInstance_private.h"
#define SuppressPerformSelectorLeakWarning(Stuff) \
do { \
@@ -48,6 +50,8 @@ _Pragma("clang diagnostic pop") \
@property (nonatomic) BOOL frameworkLoadFinished;
//store some methods temporarily before JSFramework is loaded
@property (nonatomic, strong) NSMutableArray *methodQueue;
+// store template service
+@property (nonatomic, strong) NSMutableArray *jsServiceQueue;
@end
@@ -59,6 +63,7 @@ _Pragma("clang diagnostic pop") \
if (self) {
_methodQueue = [NSMutableArray new];
_frameworkLoadFinished = NO;
+ _jsServiceQueue = [NSMutableArray new];
}
return self;
}
@@ -80,12 +85,20 @@ _Pragma("clang diagnostic pop") \
}
_jsBridge = _debugJS ? [NSClassFromString(@"WXDebugger") alloc] : [[WXJSCoreBridge alloc] init];
- __weak typeof(self) weakSelf = self;
+
+ [self registerGlobalFuntions];
+
+ return _jsBridge;
+}
+
+- (void)registerGlobalFuntions
+{
+ __weak typeof(self) weakSelf = self;
[_jsBridge registerCallNative:^NSInteger(NSString *instance, NSArray *tasks, NSString *callback) {
return [weakSelf invokeNative:instance tasks:tasks callback:callback];
}];
[_jsBridge registerCallAddElement:^NSInteger(NSString *instanceId, NSString *parentRef, NSDictionary *elementData, NSInteger index) {
-
+
// Temporary here , in order to improve performance, will be refactored next version.
WXSDKInstance *instance = [WXSDKManager instanceForID:instanceId];
@@ -106,7 +119,24 @@ _Pragma("clang diagnostic pop") \
return 0;
}];
- return _jsBridge;
+ [_jsBridge registerCallNativeModule:^NSInvocation*(NSString *instanceId, NSString *moduleName, NSString *methodName, NSArray *arguments, NSDictionary *options) {
+
+ WXSDKInstance *instance = [WXSDKManager instanceForID:instanceId];
+
+ if (!instance) {
+ WXLogInfo(@"instance not found for callNativeModule:%@.%@, maybe already destroyed", moduleName, methodName);
+ return nil;
+ }
+
+ WXModuleMethod *method = [[WXModuleMethod alloc] initWithModuleName:moduleName methodName:methodName arguments:arguments instance:instance];
+ return [method invoke];
+ }];
+
+ [_jsBridge registerCallNativeComponent:^void(NSString *instanceId, NSString *componentRef, NSString *methodName, NSArray *args, NSDictionary *options) {
+ WXSDKInstance *instance = [WXSDKManager instanceForID:instanceId];
+ WXComponentMethod *method = [[WXComponentMethod alloc] initWithComponentRef:componentRef methodName:methodName arguments:args instance:instance];
+ [method invoke];
+ }];
}
- (NSMutableArray *)insStack
@@ -141,24 +171,33 @@ _Pragma("clang diagnostic pop") \
#pragma mark JS Bridge Management
-- (NSInteger)invokeNative:(NSString *)instance tasks:(NSArray *)tasks callback:(NSString __unused*)callback
+- (NSInteger)invokeNative:(NSString *)instanceId tasks:(NSArray *)tasks callback:(NSString __unused*)callback
{
WXAssertBridgeThread();
- if (!instance || !tasks) {
+ if (!instanceId || !tasks) {
WX_MONITOR_FAIL(WXMTNativeRender, WX_ERR_JSFUNC_PARAM, @"JS call Native params error!");
return 0;
}
- if (![WXSDKManager instanceForID:instance]) {
- WXLogInfo(@"instance already destroyed");
+ WXSDKInstance *instance = [WXSDKManager instanceForID:instanceId];
+ if (!instance) {
+ WXLogInfo(@"instance already destroyed, task ignored");
return -1;
}
for (NSDictionary *task in tasks) {
- WXBridgeMethod *method = [[WXBridgeMethod alloc] initWihData:task];
- method.instance = instance;
- [[WXInvocationConfig sharedInstance] dispatchMethod:method];
+ NSString *methodName = task[@"method"];
+ NSArray *arguments = task[@"args"];
+ if (task[@"component"]) {
+ NSString *ref = task[@"ref"];
+ WXComponentMethod *method = [[WXComponentMethod alloc] initWithComponentRef:ref methodName:methodName arguments:arguments instance:instance];
+ [method invoke];
+ } else {
+ NSString *moduleName = task[@"module"];
+ WXModuleMethod *method = [[WXModuleMethod alloc] initWithModuleName:moduleName methodName:methodName arguments:arguments instance:instance];
+ [method invoke];
+ }
}
[self performSelector:@selector(_sendQueueLoop) withObject:nil];
@@ -255,6 +294,8 @@ _Pragma("clang diagnostic pop") \
//the JSFramework has been load successfully.
self.frameworkLoadFinished = YES;
+ [self executeAllJsService];
+
JSValue *frameworkVersion = [self.jsBridge callJSMethod:@"getJSFMVersion" args:nil];
if (frameworkVersion && [frameworkVersion isString]) {
[WXAppConfiguration setJSFrameworkVersion:[frameworkVersion toString]];
@@ -271,7 +312,7 @@ _Pragma("clang diagnostic pop") \
};
}
-- (void)executeJsMethod:(WXBridgeMethod *)method
+- (void)executeJsMethod:(WXCallJSMethod *)method
{
WXAssertBridgeThread();
@@ -280,9 +321,9 @@ _Pragma("clang diagnostic pop") \
return;
}
- NSMutableArray *sendQueue = self.sendQueue[method.instance];
+ NSMutableArray *sendQueue = self.sendQueue[method.instance.instanceId];
if (!sendQueue) {
- WXLogInfo(@"No send queue for instance:%@, may it has been destroyed so method:%@ is ignored", method.instance, method.method);
+ WXLogInfo(@"No send queue for instance:%@, may it has been destroyed so method:%@ is ignored", method.instance, method.methodName);
return;
}
@@ -290,6 +331,37 @@ _Pragma("clang diagnostic pop") \
[self performSelector:@selector(_sendQueueLoop) withObject:nil];
}
+- (void)executeAllJsService
+{
+ for(NSDictionary *service in _jsServiceQueue) {
+ NSString *script = [service valueForKey:@"script"];
+ NSString *name = [service valueForKey:@"name"];
+ [self executeJsService:script withName:name];
+ }
+
+ [_jsServiceQueue removeAllObjects];
+}
+
+- (void)executeJsService:(NSString *)script withName:(NSString *)name
+{
+ if(self.frameworkLoadFinished) {
+ WXAssert(script, @"param script required!");
+ [self.jsBridge executeJavascript:script];
+
+ if ([self.jsBridge exception]) {
+ NSString *message = [NSString stringWithFormat:@"JSService executes error: %@", [self.jsBridge exception]];
+ WX_MONITOR_FAIL(WXMTJSService, WX_ERR_JSFRAMEWORK_EXECUTE, message);
+ } else {
+ // success
+ }
+ }else {
+ [_jsServiceQueue addObject:@{
+ @"name": name,
+ @"script": script
+ }];
+ }
+}
+
- (void)registerModules:(NSDictionary *)modules
{
WXAssertBridgeThread();
@@ -312,8 +384,7 @@ _Pragma("clang diagnostic pop") \
{
if (self.frameworkLoadFinished) {
[self.jsBridge callJSMethod:method args:args];
- }
- else {
+ } else {
[_methodQueue addObject:@{@"method":method, @"args":args}];
}
}
@@ -349,40 +420,30 @@ _Pragma("clang diagnostic pop") \
#pragma mark Private Mehtods
-- (WXBridgeMethod *)_methodWithCallback:(NSString *)callback
-{
- WXAssertBridgeThread();
-
- if (!callback) return nil;
-
- NSDictionary *method = @{@"module":@"jsBridge", @"method":@"callback", @"args":@[callback]};
-
- return [[WXBridgeMethod alloc] initWihData:method];
-}
-
- (void)_sendQueueLoop
{
WXAssertBridgeThread();
BOOL hasTask = NO;
- NSMutableArray *methods = [NSMutableArray array];
+ NSMutableArray *tasks = [NSMutableArray array];
NSString *execIns = nil;
for (NSString *instance in self.insStack) {
NSMutableArray *sendQueue = self.sendQueue[instance];
if(sendQueue.count > 0){
hasTask = YES;
- for(WXBridgeMethod *method in sendQueue){
- [methods addObject:[method dataDesc]];
+ for(WXCallJSMethod *method in sendQueue){
+ [tasks addObject:[method callJSTask]];
}
+
[sendQueue removeAllObjects];
execIns = instance;
break;
}
}
- if ([methods count] > 0 && execIns) {
- [self callJSMethod:@"callJS" args:@[execIns, methods]];
+ if ([tasks count] > 0 && execIns) {
+ [self callJSMethod:@"callJS" args:@[execIns, tasks]];
}
if (hasTask) {
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXCallJSMethod.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCallJSMethod.h b/ios/sdk/WeexSDK/Sources/Bridge/WXCallJSMethod.h
new file mode 100644
index 0000000..50cdc20
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCallJSMethod.h
@@ -0,0 +1,20 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXBridgeMethod.h"
+
+@interface WXCallJSMethod : WXBridgeMethod
+
+- (instancetype)initWithModuleName:(NSString *)moduleName
+ methodName:(NSString *)methodName
+ arguments:(NSArray *)arguments
+ instance:(WXSDKInstance *)instance;
+
+- (NSDictionary *)callJSTask;
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXCallJSMethod.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCallJSMethod.m b/ios/sdk/WeexSDK/Sources/Bridge/WXCallJSMethod.m
new file mode 100644
index 0000000..ea98885
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCallJSMethod.m
@@ -0,0 +1,35 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXCallJSMethod.h"
+
+@implementation WXCallJSMethod
+{
+ NSString *_moduleName;
+}
+
+- (instancetype)initWithModuleName:(NSString *)moduleName
+ methodName:(NSString *)methodName
+ arguments:(NSArray *)arguments
+ instance:(WXSDKInstance *)instance
+{
+ if (self = [super initWithMethodName:methodName arguments:arguments instance:instance]) {
+ _moduleName = moduleName;
+ }
+
+ return self;
+}
+
+- (NSDictionary *)callJSTask
+{
+ return @{@"module":_moduleName ?: @"",
+ @"method":self.methodName ?: @"",
+ @"args":self.arguments ?: @[]};
+}
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXComponentMethod.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXComponentMethod.h b/ios/sdk/WeexSDK/Sources/Bridge/WXComponentMethod.h
new file mode 100644
index 0000000..5906e09
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXComponentMethod.h
@@ -0,0 +1,21 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXBridgeMethod.h"
+@class WXComponent;
+
+@interface WXComponentMethod : WXBridgeMethod
+
+- (instancetype)initWithComponentRef:(NSString *)ref
+ methodName:(NSString *)methodName
+ arguments:(NSArray *)arguments
+ instance:(WXSDKInstance *)instance;
+
+- (void)invoke;
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXComponentMethod.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXComponentMethod.m b/ios/sdk/WeexSDK/Sources/Bridge/WXComponentMethod.m
new file mode 100644
index 0000000..e8c5225
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXComponentMethod.m
@@ -0,0 +1,51 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXComponentMethod.h"
+#import "WXComponentFactory.h"
+#import "WXComponentManager.h"
+#import "WXSDKInstance.h"
+#import "WXLog.h"
+#import "WXUtility.h"
+
+@implementation WXComponentMethod
+{
+ NSString *_componentName;
+ NSString *_componentRef;
+}
+
+- (instancetype)initWithComponentRef:(NSString *)ref
+ methodName:(NSString *)methodName
+ arguments:(NSArray *)arguments
+ instance:(WXSDKInstance *)instance
+{
+ if (self = [super initWithMethodName:methodName arguments:arguments instance:instance]) {
+ _componentRef = ref;
+ }
+
+ return self;
+}
+
+- (void)invoke
+{
+ WXPerformBlockOnComponentThread(^{
+ WXComponent *component = [self.instance componentForRef:_componentRef];
+ if (!component) {
+ WXLogError(@"component not found for ref:%@, type:%@", _componentRef, _componentName);
+ }
+ SEL selector = [WXComponentFactory methodWithComponentName:component.type withMethod:self.methodName];
+ NSInvocation * invocation = [self invocationWithTarget:component selector:selector];
+ WXPerformBlockOnMainThread(^{
+ [invocation invoke];
+ });
+ });
+
+
+}
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.m b/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.m
index 9a966cd..f9c8702 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.m
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.m
@@ -108,6 +108,11 @@
#pragma mark - WXBridgeProtocol
+- (void)executeJavascript:(NSString *)script
+{
+ [self callJSMethod:@"evalFramework" args:@[script]];
+}
+
- (void)executeJSFramework:(NSString *)frameworkScript
{
[self callJSMethod:@"evalFramework" args:@[frameworkScript]];
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m b/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m
index d1c6551..cc43945 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m
@@ -20,6 +20,7 @@
#import <sys/utsname.h>
#import <JavaScriptCore/JavaScriptCore.h>
#import "WXPolyfillSet.h"
+#import "JSValue+Weex.h"
#import <dlfcn.h>
@@ -139,11 +140,16 @@
_jsContext[@"callNative"] = callNativeBlock;
}
+- (void)executeJavascript:(NSString *)script
+{
+ WXAssertParam(script);
+ [_jsContext evaluateScript:script];
+}
+
- (void)registerCallAddElement:(WXJSCallAddElement)callAddElement
{
id callAddElementBlock = ^(JSValue *instanceId, JSValue *ref, JSValue *element, JSValue *index, JSValue *ifCallback) {
- // Temporary here , in order to improve performance, will be refactored next version.
NSString *instanceIdString = [instanceId toString];
NSDictionary *componentData = [element toDictionary];
NSString *parentRef = [ref toString];
@@ -157,6 +163,38 @@
_jsContext[@"callAddElement"] = callAddElementBlock;
}
+- (void)registerCallNativeModule:(WXJSCallNativeModule)callNativeModuleBlock
+{
+ _jsContext[@"callNativeModule"] = ^JSValue *(JSValue *instanceId, JSValue *moduleName, JSValue *methodName, JSValue *args, JSValue *options) {
+ NSString *instanceIdString = [instanceId toString];
+ NSString *moduleNameString = [moduleName toString];
+ NSString *methodNameString = [methodName toString];
+ NSArray *argsArray = [args toArray];
+ NSDictionary *optionsDic = [options toDictionary];
+
+ WXLogDebug(@"callNativeModule...%@,%@,%@,%@", instanceIdString, moduleNameString, methodNameString, argsArray);
+
+ NSInvocation *invocation = callNativeModuleBlock(instanceIdString, moduleNameString, methodNameString, argsArray, optionsDic);
+ JSValue *returnValue = [JSValue wx_valueWithReturnValueFromInvocation:invocation inContext:[JSContext currentContext]];
+ return returnValue;
+ };
+}
+
+- (void)registerCallNativeComponent:(WXJSCallNativeComponent)callNativeComponentBlock
+{
+ _jsContext[@"callNativeComponent"] = ^void(JSValue *instanceId, JSValue *componentName, JSValue *methodName, JSValue *args, JSValue *options) {
+ NSString *instanceIdString = [instanceId toString];
+ NSString *componentNameString = [componentName toString];
+ NSString *methodNameString = [methodName toString];
+ NSArray *argsArray = [args toArray];
+ NSDictionary *optionsDic = [options toDictionary];
+
+ WXLogDebug(@"callNativeModule...%@,%@,%@,%@", instanceIdString, componentNameString, methodNameString, argsArray);
+
+ callNativeComponentBlock(instanceIdString, componentNameString, methodNameString, argsArray, optionsDic);
+ };
+}
+
- (JSValue*)exception
{
return _jsContext.exception;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXModuleMethod.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXModuleMethod.h b/ios/sdk/WeexSDK/Sources/Bridge/WXModuleMethod.h
new file mode 100644
index 0000000..1a4107d
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXModuleMethod.h
@@ -0,0 +1,28 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXBridgeMethod.h"
+
+typedef enum : NSUInteger {
+ WXModuleMethodTypeSync,
+ WXModuleMethodTypeAsync,
+} WXModuleMethodType;
+
+@interface WXModuleMethod : WXBridgeMethod
+
+@property (nonatomic, assign) WXModuleMethodType methodType;
+@property (nonatomic, strong, readonly) NSString *moduleName;
+
+- (instancetype)initWithModuleName:(NSString *)moduleName
+ methodName:(NSString *)methodName
+ arguments:(NSArray *)arguments
+ instance:(WXSDKInstance *)instance;
+
+- (NSInvocation *)invoke;
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Bridge/WXModuleMethod.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXModuleMethod.m b/ios/sdk/WeexSDK/Sources/Bridge/WXModuleMethod.m
new file mode 100644
index 0000000..de07eca
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXModuleMethod.m
@@ -0,0 +1,99 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXModuleMethod.h"
+#import "WXModuleFactory.h"
+#import "WXMonitor.h"
+#import "WXModuleProtocol.h"
+#import "WXAssert.h"
+#import "WXUtility.h"
+#import "WXSDKInstance_private.h"
+
+@implementation WXModuleMethod
+
+- (instancetype)initWithModuleName:(NSString *)moduleName
+ methodName:(NSString *)methodName
+ arguments:(NSArray *)arguments
+ instance:(WXSDKInstance *)instance
+{
+ if (self = [super initWithMethodName:methodName arguments:arguments instance:instance]) {
+ _moduleName = moduleName;
+ }
+
+ return self;
+}
+
+- (NSInvocation *)invoke
+{
+ Class moduleClass = [WXModuleFactory classWithModuleName:_moduleName];
+ if (!moduleClass) {
+ NSString *errorMessage = [NSString stringWithFormat:@"Module\uff1a%@ doesn't exist, maybe it has not been registered", _moduleName];
+ WX_MONITOR_FAIL(WXMTJSBridge, WX_ERR_INVOKE_NATIVE, errorMessage);
+ return nil;
+ }
+
+ id<WXModuleProtocol> moduleInstance = [self.instance moduleForClass:moduleClass];
+ WXAssert(moduleInstance, @"No instance found for module name:%@, class:%@", _moduleName, moduleClass);
+ BOOL isSync = NO;
+ SEL selector = [WXModuleFactory selectorWithModuleName:self.moduleName methodName:self.methodName isSync:&isSync];
+ if (!selector) {
+ NSString *errorMessage = [NSString stringWithFormat:@"method\uff1a%@ for module:%@ doesn't exist, maybe it has not been registered", self.methodName, _moduleName];
+ WX_MONITOR_FAIL(WXMTJSBridge, WX_ERR_INVOKE_NATIVE, errorMessage);
+ return nil;;
+ }
+ if (![moduleInstance respondsToSelector:selector]) {
+ // if not implement the selector, then dispatch default module method
+ if ([self.methodName isEqualToString:@"addEventListener"]) {
+ [self.instance _addModuleEventObserversWithModuleMethod:self];
+ }
+ if ([self.methodName isEqualToString:@"removeAllEventListeners"]) {
+ [self.instance _removeModuleEventObserverWithModuleMethod:self];
+ }
+ return nil;
+ }
+
+ NSInvocation *invocation = [self invocationWithTarget:moduleInstance selector:selector];
+
+ if (isSync) {
+ [invocation invoke];
+ return invocation;
+ } else {
+ [self _dispatchInvovation:invocation moduleInstance:moduleInstance];
+ return nil;
+ }
+}
+
+- (void)_dispatchInvovation:(NSInvocation *)invocation moduleInstance:(id<WXModuleProtocol>)moduleInstance
+{
+ // dispatch to user specified queue or thread, default is main thread
+ dispatch_block_t dipatchBlock = ^ (){
+ [invocation invoke];
+ };
+
+ NSThread *targetThread = nil;
+ dispatch_queue_t targetQueue = nil;
+ if([moduleInstance respondsToSelector:@selector(targetExecuteQueue)]){
+ targetQueue = [moduleInstance targetExecuteQueue] ?: dispatch_get_main_queue();
+ } else if([moduleInstance respondsToSelector:@selector(targetExecuteThread)]){
+ targetThread = [moduleInstance targetExecuteThread] ?: [NSThread mainThread];
+ } else {
+ targetThread = [NSThread mainThread];
+ }
+
+ WXAssert(targetQueue || targetThread, @"No queue or thread found for module:%@", moduleInstance);
+
+ if (targetQueue) {
+ dispatch_async(targetQueue, dipatchBlock);
+ } else {
+ WXPerformBlockOnThread(^{
+ dipatchBlock();
+ }, targetThread);
+ }
+}
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXCanvasComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXCanvasComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXCanvasComponent.m
index f83f1c9..8dbba33 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXCanvasComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXCanvasComponent.m
@@ -165,7 +165,7 @@
// OpenGL ES methods map
-#define WX_CANVAS_PIXEL(name, index) WXPixelType name = [WXConvert WXPixelType:params[index]];
+#define WX_CANVAS_PIXEL(name, index) WXPixelType name = [WXConvert WXPixelType:params[index] scaleFactor:self.weexInstance.pixelScaleFactor];
#define WX_CANVAS_CGFLOAT(name, index) CGFloat name = [WXConvert CGFloat:params[index]];
#define WX_CANVAS_PARAMS_CHECK(num) if ([params count] < num) return;
@@ -196,10 +196,10 @@
CGFloat sy = [WXConvert CGFloat:curParams[1]];
CGFloat sw = [WXConvert CGFloat:curParams[2]];
CGFloat sh = [WXConvert CGFloat:curParams[3]];
- CGFloat dx = [WXConvert WXPixelType:curParams[4]];
- CGFloat dy = [WXConvert WXPixelType:curParams[5]];
- CGFloat dw = [WXConvert WXPixelType:curParams[6]];
- CGFloat dh = [WXConvert WXPixelType:curParams[7]];
+ CGFloat dx = [WXConvert WXPixelType:curParams[4] scaleFactor:self.weexInstance.pixelScaleFactor];
+ CGFloat dy = [WXConvert WXPixelType:curParams[5] scaleFactor:self.weexInstance.pixelScaleFactor];
+ CGFloat dw = [WXConvert WXPixelType:curParams[6] scaleFactor:self.weexInstance.pixelScaleFactor];
+ CGFloat dh = [WXConvert WXPixelType:curParams[7] scaleFactor:self.weexInstance.pixelScaleFactor];
geometrys[i * 4] = GLKVector3Make(dx, dh + dy, 1);
geometrys[i * 4 + 1] = GLKVector3Make(dw + dx, dh + dy, 1);
@@ -221,7 +221,7 @@
[WXConvert CGFloat:curParams[16]]
);
// Because the params are base on 750, so we should make scale for the transform matrix
- matrix = GLKMatrix3Scale(matrix, 1, 1, WXScreenResizeRadio());
+ matrix = GLKMatrix3Scale(matrix, 1, 1, self.weexInstance.pixelScaleFactor);
geometrys[i * 4] = GLKMatrix3MultiplyVector3(matrix, geometrys[i * 4]);
geometrys[i * 4 + 1] = GLKMatrix3MultiplyVector3(matrix, geometrys[i * 4 + 1]);
geometrys[i * 4 + 2] = GLKMatrix3MultiplyVector3(matrix, geometrys[i * 4 + 2]);
@@ -311,7 +311,7 @@
- (void) setLineWidth:(NSArray *)params
{
WX_CANVAS_PARAMS_CHECK(1);
- _curLineWidth = [WXConvert WXPixelType:params[0]];
+ _curLineWidth = [WXConvert WXPixelType:params[0] scaleFactor:self.weexInstance.pixelScaleFactor];
}
// ["M", 0, 0, "L", 100, 100, "L", 0, 100, "L", 0, 0] it made a triangle
@@ -327,7 +327,7 @@
for (GLint i = 0; i < params.count; i += 3) {
NSString *type = [WXConvert NSString:params[i]];
- points[pointIndex] = GLKVector2Make([WXConvert WXPixelType:params[i + 1]], [WXConvert WXPixelType:params[i + 2]]);
+ points[pointIndex] = GLKVector2Make([WXConvert WXPixelType:params[i + 1] scaleFactor:self.weexInstance.pixelScaleFactor], [WXConvert WXPixelType:params[i + 2] scaleFactor:self.weexInstance.pixelScaleFactor]);
if ([type isEqualToString:@"L"]) {
if (isLastMove) {
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.h b/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.h
index a0656dd..544fbfe 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.h
@@ -12,6 +12,8 @@
@interface WXCellComponent : WXComponent
@property (nonatomic, strong) NSString *scope;
+@property (nonatomic, assign) UITableViewRowAnimation insertAnimation;
+@property (nonatomic, assign) UITableViewRowAnimation deleteAnimation;
@property (nonatomic, weak) WXListComponent *list;
-@end
\ No newline at end of file
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.m
index 5a11065..0483ec0 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.m
@@ -23,6 +23,8 @@
if (self) {
_async = attributes[@"async"] ? [WXConvert BOOL:attributes[@"async"]] : YES;
+ _insertAnimation = [WXConvert UITableViewRowAnimation:attributes[@"insertAnimation"]];
+ _deleteAnimation = [WXConvert UITableViewRowAnimation:attributes[@"deleteAnimation"]];
_lazyCreateView = YES;
_isNeedJoinLayoutSystem = NO;
}
@@ -60,6 +62,14 @@
if (attributes[@"async"]) {
_async = [WXConvert BOOL:attributes[@"async"]];
}
+
+ if (attributes[@"insertAnimation"]) {
+ _insertAnimation = [WXConvert UITableViewRowAnimation:attributes[@"insertAnimation"]];
+ }
+
+ if (attributes[@"deleteAnimation"]) {
+ _deleteAnimation = [WXConvert UITableViewRowAnimation:attributes[@"deleteAnimation"]];
+ }
}
- (void)_moveToSupercomponent:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXComponent+GradientColor.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent+GradientColor.h b/ios/sdk/WeexSDK/Sources/Component/WXComponent+GradientColor.h
new file mode 100644
index 0000000..0706eed
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent+GradientColor.h
@@ -0,0 +1,20 @@
+//
+// WXComponent+GradientColor.h
+// Pods
+//
+// Created by bobning on 16/12/23.
+//
+//
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import "WXComponent.h"
+#import "WXType.h"
+
+@interface WXComponent (GradientColor)
+
+- (void)setGradientLayer;
+
+- (UIImage *)gradientColorImageFromColors:(NSArray*)colors gradientType:(WXGradientType)gradientType imgSize:(CGSize)imgSize;
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXComponent+GradientColor.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent+GradientColor.m b/ios/sdk/WeexSDK/Sources/Component/WXComponent+GradientColor.m
new file mode 100644
index 0000000..e710ed0
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent+GradientColor.m
@@ -0,0 +1,116 @@
+//
+// WXComponent+GradientColor.m
+// Pods
+//
+// Created by bobning on 16/12/23.
+//
+//
+
+#import "WXComponent+GradientColor.h"
+#import "WXComponent_internal.h"
+#import "WXConvert.h"
+
+@implementation WXComponent (GradientColor)
+
+- (void)setGradientLayer {
+ //parse gradient-color, linear-gradient(to right, #a80077,rgba(200, 54, 54, 0.5))
+ if ([_backgroundImage hasPrefix:@"linear-gradient"] && [_backgroundImage hasSuffix:@")"] ) {
+ NSRange range = NSMakeRange(16, _backgroundImage.length - 17);
+ NSString *str = [_backgroundImage substringWithRange:range];
+ NSArray *array = [str componentsSeparatedByString:@","];
+ WXGradientType gradientType;
+ UIColor *startColor, *endColor;
+
+ if ([array count] == 3) {
+ gradientType = [WXConvert gradientType:array[0]];
+ startColor = [WXConvert UIColor:array[1]];
+ endColor = [WXConvert UIColor:array[2]];
+ }
+ else if ([array count] > 3){
+ NSString *gradientTypeStr = array[0];
+ NSString *subStr = [str substringFromIndex:gradientTypeStr.length + 1];
+
+ if ([subStr hasPrefix:@"rgb"]) {
+ gradientType = [WXConvert gradientType:gradientTypeStr];
+
+ range = [subStr rangeOfString:@")"];
+ NSString *startColorStr = [subStr substringToIndex:range.location + 1];
+ NSString *endColorStr = [subStr substringFromIndex:range.location + 2];
+ startColor = [WXConvert UIColor:startColorStr];
+ endColor = [WXConvert UIColor:endColorStr];
+ }
+ else {
+ gradientType = [WXConvert gradientType:gradientTypeStr];
+
+ startColor = [WXConvert UIColor:array[1]];
+
+ NSString *startColorStr = array[1];
+ NSString *endColorStr = [subStr substringFromIndex:startColorStr.length + 1];
+ endColor = [WXConvert UIColor:endColorStr];
+ }
+ }
+ else {
+ return;
+ }
+
+ __weak typeof(self) weakSelf = self;
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ UIImage *bgImg = [weakSelf gradientColorImageFromColors:@[startColor, endColor] gradientType:gradientType imgSize:weakSelf.view.frame.size];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ weakSelf.view.backgroundColor = [UIColor colorWithPatternImage:bgImg];
+ });
+ });
+ }
+}
+
+- (UIImage *)gradientColorImageFromColors:(NSArray*)colors gradientType:(WXGradientType)gradientType imgSize:(CGSize)imgSize;{
+ NSMutableArray *array = [NSMutableArray array];
+ for(UIColor *color in colors) {
+ [array addObject:(id)color.CGColor];
+ }
+
+ UIGraphicsBeginImageContextWithOptions(imgSize, YES, 1);
+ CGContextRef context = UIGraphicsGetCurrentContext();
+ CGContextSaveGState(context);
+ CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
+ CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)array, NULL);
+ CGPoint start;
+ CGPoint end;
+ switch (gradientType) {
+ case WXGradientTypeToTop:
+ start = CGPointMake(0.0, imgSize.height);
+ end = CGPointMake(0.0, 0.0);
+ break;
+ case WXGradientTypeToBottom:
+ start = CGPointMake(0.0, 0.0);
+ end = CGPointMake(0.0, imgSize.height);
+ break;
+ case WXGradientTypeToLeft:
+ start = CGPointMake(imgSize.width, 0.0);
+ end = CGPointMake(0.0, 0.0);
+ break;
+ case WXGradientTypeToRight:
+ start = CGPointMake(0.0, 0.0);
+ end = CGPointMake(imgSize.width, 0.0);
+ break;
+ case WXGradientTypeToTopleft:
+ start = CGPointMake(imgSize.width, imgSize.height);
+ end = CGPointMake(0.0, 0.0f);
+ break;
+ case WXGradientTypeToBottomright:
+ start = CGPointMake(0.0, 0.0);
+ end = CGPointMake(imgSize.width, imgSize.height);
+ break;
+ default:
+ break;
+ }
+ CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
+ UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
+ CGGradientRelease(gradient);
+ CGContextRestoreGState(context);
+ CGColorSpaceRelease(colorSpace);
+ UIGraphicsEndImageContext();
+ return image;
+}
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
index d09ce42..04f5440 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
@@ -34,12 +34,20 @@
* View
*/
UIColor *_backgroundColor;
+ NSString *_backgroundImage;
WXClipType _clipToBounds;
UIView *_view;
CGFloat _opacity;
WXVisibility _visibility;
/**
+ * PseudoClass
+ */
+ NSMutableDictionary *_pseudoClassStyles;
+ NSMutableDictionary *_updatedPseudoClassStyles;
+ BOOL _isListenPseudoTouch;
+
+ /**
* Events
*/
BOOL _appearEvent;
@@ -48,9 +56,14 @@
NSMutableArray *_swipeGestures;
UILongPressGestureRecognizer *_longPressGesture;
UIPanGestureRecognizer *_panGesture;
+
BOOL _listenPanStart;
BOOL _listenPanMove;
BOOL _listenPanEnd;
+
+ BOOL _listenHorizontalPan;
+ BOOL _listenVerticalPan;
+
WXTouchGestureRecognizer* _touchGesture;
/**
@@ -110,7 +123,7 @@
- (void)_removeFromSupercomponent;
- (void)_moveToSupercomponent:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index;
-- (void)_updateStylesOnComponentThread:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles;
+- (void)_updateStylesOnComponentThread:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles isUpdateStyles:(BOOL)isUpdateStyles;
- (void)_updateAttributesOnComponentThread:(NSDictionary *)attributes;
- (void)_updateStylesOnMainThread:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles;
- (void)_updateAttributesOnMainThread:(NSDictionary *)attributes;
@@ -156,6 +169,8 @@
- (void)_initEvents:(NSArray *)events;
+- (void)_initPseudoEvents:(BOOL)isListenPseudoTouch;
+
- (void)_removeAllEvents;
- (void)_setupNavBarWithStyles:(NSMutableDictionary *)styles attributes:(NSMutableDictionary *)attributes;
@@ -166,4 +181,7 @@
- (void)_resetNativeBorderRadius;
+- (void)_updatePseudoClassStyles:(NSString *)key;
+
+- (void)_restoreViewStyles;
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXEmbedComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXEmbedComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXEmbedComponent.m
index 1d47b4d..3b1df98 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXEmbedComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXEmbedComponent.m
@@ -151,16 +151,18 @@
};
_embedInstance.onFailed = ^(NSError *error) {
- if (weakSelf.errorView) {
- return ;
- }
-
- WXErrorView *errorView = [[WXErrorView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 135.0f, 130.0f)];
- errorView.center = CGPointMake(weakSelf.view.bounds.size.width / 2.0f, weakSelf.view.bounds.size.height / 2.0f);
- errorView.delegate = weakSelf;
- [weakSelf.view addSubview:errorView];
-
- weakSelf.errorView = errorView;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (weakSelf.errorView) {
+ return ;
+ }
+
+ WXErrorView *errorView = [[WXErrorView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 135.0f, 130.0f)];
+ errorView.center = CGPointMake(weakSelf.view.bounds.size.width / 2.0f, weakSelf.view.bounds.size.height / 2.0f);
+ errorView.delegate = weakSelf;
+ [weakSelf.view addSubview:errorView];
+
+ weakSelf.errorView = errorView;
+ });
};
_embedInstance.renderFinish = ^(UIView *view) {
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m
index 6baac1d..20b80aa 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m
@@ -34,6 +34,7 @@ static dispatch_queue_t WXImageUpdateQueue;
@property (nonatomic, strong) NSString *imageSrc;
@property (nonatomic, strong) NSString *placeholdSrc;
+@property (nonatomic, assign) CGFloat blurRadius;
@property (nonatomic, assign) UIViewContentMode resizeMode;
@property (nonatomic, assign) WXImageQuality imageQuality;
@property (nonatomic, assign) WXImageSharp imageSharp;
@@ -41,6 +42,7 @@ static dispatch_queue_t WXImageUpdateQueue;
@property (nonatomic, strong) id<WXImageOperationProtocol> imageOperation;
@property (nonatomic, strong) id<WXImageOperationProtocol> placeholderOperation;
@property (nonatomic) BOOL imageLoadEvent;
+@property (nonatomic) BOOL imageDownloadFinish;
@end
@@ -60,9 +62,11 @@ static dispatch_queue_t WXImageUpdateQueue;
}
[self configPlaceHolder:attributes];
_resizeMode = [WXConvert UIViewContentMode:attributes[@"resize"]];
+ [self configFilter:styles];
_imageQuality = [WXConvert WXImageQuality:styles[@"quality"]];
_imageSharp = [WXConvert WXImageSharp:styles[@"sharpen"]];
_imageLoadEvent = NO;
+ _imageDownloadFinish = NO;
}
return self;
@@ -74,6 +78,27 @@ static dispatch_queue_t WXImageUpdateQueue;
}
}
+- (void)configFilter:(NSDictionary *)styles {
+ if (styles[@"filter"]) {
+ NSString *filter = styles[@"filter"];
+
+ NSString *pattern = @"blur\\((\\d+)(px)?\\)";
+ NSError *error = nil;
+ NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
+ options:NSRegularExpressionCaseInsensitive
+ error:&error];
+ NSArray *matches = [regex matchesInString:filter options:0 range:NSMakeRange(0, filter.length)];
+ if (matches && matches.count > 0) {
+ NSTextCheckingResult *match = matches[matches.count - 1];
+ NSRange matchRange = [match rangeAtIndex:1];
+ NSString *matchString = [filter substringWithRange:matchRange];
+ if (matchString && matchString.length > 0) {
+ _blurRadius = [matchString doubleValue];
+ }
+ }
+ }
+}
+
- (UIView *)loadView
{
return [[WXImageView alloc] init];
@@ -102,6 +127,7 @@ static dispatch_queue_t WXImageUpdateQueue;
_imageSharp = [WXConvert WXImageSharp:styles[@"sharpen"]];
[self updateImage];
}
+ [self configFilter:styles];
}
- (void)updateAttributes:(NSDictionary *)attributes
@@ -176,6 +202,7 @@ static dispatch_queue_t WXImageUpdateQueue;
{
if (![src isEqualToString:_imageSrc]) {
_imageSrc = src;
+ _imageDownloadFinish = NO;
[self updateImage];
}
}
@@ -187,6 +214,7 @@ static dispatch_queue_t WXImageUpdateQueue;
[self cancelImage];
void(^downloadFailed)(NSString *, NSError *) = ^void(NSString *url, NSError *error){
+ weakSelf.imageDownloadFinish = YES;
WXLogError(@"Error downloading image:%@, detail:%@", url, [error localizedDescription]);
};
@@ -196,6 +224,8 @@ static dispatch_queue_t WXImageUpdateQueue;
if (!weakSelf.imageSrc && !weakSelf.placeholdSrc) {
dispatch_async(dispatch_get_main_queue(), ^{
self.layer.contents = nil;
+ weakSelf.imageDownloadFinish = YES;
+ [weakSelf readyToRender];
});
}
});
@@ -208,7 +238,7 @@ static dispatch_queue_t WXImageUpdateQueue;
if (placeholderSrc) {
WXLogDebug(@"Updating image, component:%@, placeholder:%@ ", self.ref, placeholderSrc);
NSMutableString *newURL = [_placeholdSrc mutableCopy];
- WX_REWRITE_URL(_placeholdSrc, WXResourceTypeLink, self.weexInstance, &newURL)
+ WX_REWRITE_URL(_placeholdSrc, WXResourceTypeImage, self.weexInstance, &newURL)
__weak typeof(self) weakSelf = self;
self.placeholderOperation = [[self imageLoader] downloadImageWithURL:newURL imageFrame:self.calculatedFrame userInfo:nil completed:^(UIImage *image, NSError *error, BOOL finished) {
@@ -219,6 +249,7 @@ static dispatch_queue_t WXImageUpdateQueue;
downloadFailedBlock(placeholderSrc,error);
if ([strongSelf isViewLoaded] && !viewImage) {
((UIImageView *)(strongSelf.view)).image = nil;
+ [self readyToRender];
}
return;
}
@@ -228,6 +259,8 @@ static dispatch_queue_t WXImageUpdateQueue;
if ([strongSelf isViewLoaded] && !viewImage) {
((UIImageView *)strongSelf.view).image = image;
+ weakSelf.imageDownloadFinish = YES;
+ [self readyToRender];
}
});
}];
@@ -236,13 +269,12 @@ static dispatch_queue_t WXImageUpdateQueue;
- (void)updateContentImageWithFailedBlock:(void(^)(NSString *, NSError *))downloadFailedBlock
{
-
NSString *imageSrc = self.imageSrc;
if (imageSrc) {
WXLogDebug(@"Updating image:%@, component:%@", self.imageSrc, self.ref);
- NSDictionary *userInfo = @{@"imageQuality":@(self.imageQuality), @"imageSharp":@(self.imageSharp)};
+ NSDictionary *userInfo = @{@"imageQuality":@(self.imageQuality), @"imageSharp":@(self.imageSharp), @"blurRadius":@(self.blurRadius)};
NSMutableString * newURL = [imageSrc mutableCopy];
- WX_REWRITE_URL(imageSrc, WXResourceTypeLink, self.weexInstance, &newURL)
+ WX_REWRITE_URL(imageSrc, WXResourceTypeImage, self.weexInstance, &newURL)
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.imageOperation = [[weakSelf imageLoader] downloadImageWithURL:newURL imageFrame:weakSelf.calculatedFrame userInfo:userInfo completed:^(UIImage *image, NSError *error, BOOL finished) {
@@ -250,10 +282,14 @@ static dispatch_queue_t WXImageUpdateQueue;
__strong typeof(self) strongSelf = weakSelf;
if (weakSelf.imageLoadEvent) {
- [strongSelf fireEvent:@"load" params:@{ @"success": error? @"false" : @"true"}];
+ NSMutableDictionary *sizeDict = [NSMutableDictionary new];
+ sizeDict[@"naturalWidth"] = @(image.size.width * image.scale);
+ sizeDict[@"naturalHeight"] = @(image.size.height * image.scale);
+ [strongSelf fireEvent:@"load" params:@{ @"success": error? @false : @true,@"size":sizeDict}];
}
if (error) {
downloadFailedBlock(imageSrc, error);
+ [strongSelf readyToRender];
return ;
}
@@ -262,7 +298,9 @@ static dispatch_queue_t WXImageUpdateQueue;
}
if ([strongSelf isViewLoaded]) {
+ strongSelf.imageDownloadFinish = YES;
((UIImageView *)strongSelf.view).image = image;
+ [strongSelf readyToRender];
}
});
}];
@@ -270,6 +308,14 @@ static dispatch_queue_t WXImageUpdateQueue;
}
}
+- (void)readyToRender
+{
+ // when image download completely (success or failed)
+ if (self.weexInstance.trackComponent && _imageDownloadFinish) {
+ [super readyToRender];
+ }
+}
+
- (void)cancelImage
{
[_imageOperation cancel];
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXIndicatorComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXIndicatorComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXIndicatorComponent.m
index 00fc7e1..5b2b858 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXIndicatorComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXIndicatorComponent.m
@@ -10,6 +10,7 @@
#import "WXSliderComponent.h"
#import "WXConvert.h"
#import "WXSliderNeighborComponent.h"
+#import "WXSDKInstance.h"
@implementation WXIndicatorView
@@ -136,7 +137,7 @@
if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
_itemColor = styles[@"itemColor"] ? [WXConvert UIColor:styles[@"itemColor"]]:[UIColor colorWithRed:0xff/255.0f green:0xff/255.0f blue:0xff/255.0f alpha:0.5f];
_itemSelectedColor = styles[@"itemSelectedColor"] ? [WXConvert UIColor:styles[@"itemSelectedColor"]]:[UIColor colorWithRed:0xff/255.0f green:0xd5/255.0f blue:0x45/255.0f alpha:1.0f];
- _itemSize = styles[@"itemSize"] ? [WXConvert WXPixelType:styles[@"itemSize"]] : 5.0f;
+ _itemSize = styles[@"itemSize"] ? [WXConvert WXPixelType:styles[@"itemSize"] scaleFactor:self.weexInstance.pixelScaleFactor] : 5.0f;
}
return self;
}
@@ -185,7 +186,7 @@
if (styles[@"itemSize"]) {
styleChange = YES;
- _itemSize = [WXConvert WXPixelType:styles[@"itemSize"]];
+ _itemSize = [WXConvert WXPixelType:styles[@"itemSize"] scaleFactor:self.weexInstance.pixelScaleFactor];
[_indicatorView setPointSize:_itemSize];
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m
index 8e6a611..bea72d0 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m
@@ -36,6 +36,20 @@
[self.wx_component layoutDidFinish];
}
+- (void)setContentOffset:(CGPoint)contentOffset
+{
+ // FIXME: side effect caused by hooking _adjustContentOffsetIfNecessary.
+ // When UITableView is pulled down and finger releases\uff0ccontentOffset will be set from -xxxx to about -0.5(greater than -0.5), then contentOffset will be reset to zero by calling _adjustContentOffsetIfNecessary.
+ // So hooking _adjustContentOffsetIfNecessary will always cause remaining 1px space between list's top and navigator.
+ // Demo: http://dotwe.org/895630945793a9a044e49abe39cbb77f
+ // Have to reset contentOffset to zero manually here.
+ if (fabs(contentOffset.y) < 0.5) {
+ contentOffset.y = 0;
+ }
+
+ [super setContentOffset:contentOffset];
+}
+
@end
@interface WXHeaderComponent : WXComponent
@@ -209,7 +223,7 @@
NSIndexPath *toIndexPath = [self indexPathForCell:(WXCellComponent*)cellComponent sections:_completedSections];
CGRect cellRect = [_tableView rectForRowAtIndexPath:toIndexPath];
contentOffsetY += cellRect.origin.y;
- contentOffsetY += offset * WXScreenResizeRadio();
+ contentOffsetY += offset * self.weexInstance.pixelScaleFactor;
if (contentOffsetY > _tableView.contentSize.height - _tableView.frame.size.height) {
contentOffset.y = _tableView.contentSize.height - _tableView.frame.size.height;
@@ -297,9 +311,15 @@
[self removeCellForIndexPath:indexPath withSections:_completedSections];
WXLogDebug(@"Delete cell:%@ at indexPath:%@", cell.ref, indexPath);
- [UIView performWithoutAnimation:^{
- [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
- }];
+ if (cell.deleteAnimation == UITableViewRowAnimationNone) {
+ [UIView performWithoutAnimation:^{
+ [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
+ [self handleAppear];
+ }];
+ } else {
+ [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:cell.deleteAnimation];
+ [self handleAppear];
+ }
}];
}
@@ -327,13 +347,20 @@
if (!isReload) {
WXLogDebug(@"Insert cell:%@ at indexPath:%@", cell.ref, indexPath);
_completedSections = completedSections;
- [UIView performWithoutAnimation:^{
- [_tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
- }];
+ if (cell.insertAnimation == UITableViewRowAnimationNone) {
+ [UIView performWithoutAnimation:^{
+ [_tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
+ [self handleAppear];
+ }];
+ } else {
+ [_tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:cell.insertAnimation];
+ [self handleAppear];
+ }
} else {
WXLogInfo(@"Reload cell:%@ at indexPath:%@", cell.ref, indexPath);
[UIView performWithoutAnimation:^{
[_tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
+ [self handleAppear];
}];
}
}];
@@ -381,6 +408,7 @@
[self insertCell:cell forIndexPath:toIndexPath withSections:_completedSections];
[UIView performWithoutAnimation:^{
[_tableView moveRowAtIndexPath:fromIndexPath toIndexPath:toIndexPath];
+ [self handleAppear];
}];
}];
}
@@ -603,7 +631,11 @@
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
- //(\u0e07 \u2022\u0300_\u2022\u0301)\u0e07\u253b\u2501\u253b Stupid scoll view, always reset content offset to zero after insert cells, any other more elegant way?
+ // FIXME:(\u0e07 \u2022\u0300_\u2022\u0301)\u0e07\u253b\u2501\u253b Stupid scoll view, always reset content offset to zero by calling _adjustContentOffsetIfNecessary after insert cells.
+ // So if you pull down list while list is rendering, the list will be flickering.
+ // Demo:
+ // Have to hook _adjustContentOffsetIfNecessary here.
+ // Any other more elegant way?
NSString *a = @"ntOffsetIfNe";
NSString *b = @"adjustConte";
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.h b/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.h
index d256567..248d03a 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.h
@@ -21,5 +21,7 @@
- (NSUInteger)childrenCountForScrollerLayout;
+- (void)handleAppear;
+
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.m
index 7a72883..fa91d3e 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.m
@@ -44,6 +44,7 @@
CGFloat _loadMoreOffset;
CGFloat _previousLoadMoreContentHeight;
CGPoint _lastContentOffset;
+ BOOL _scrollable;
// vertical & horizontal
WXScrollDirection _scrollDirection;
@@ -91,6 +92,7 @@ WX_EXPORT_METHOD(@selector(resetLoadmore))
_loadMoreOffset = attributes[@"loadmoreoffset"] ? [WXConvert CGFloat:attributes[@"loadmoreoffset"]] : 0;
_loadmoreretry = attributes[@"loadmoreretry"] ? [WXConvert NSUInteger:attributes[@"loadmoreretry"]] : 0;
_listenLoadMore = [events containsObject:@"loadmore"];
+ _scrollable = attributes[@"scrollable"] ? [WXConvert BOOL:attributes[@"scrollable"]] : YES;
_scrollerCSSNode = new_css_node();
@@ -123,6 +125,7 @@ WX_EXPORT_METHOD(@selector(resetLoadmore))
scrollView.clipsToBounds = YES;
scrollView.showsVerticalScrollIndicator = _showScrollBar;
scrollView.showsHorizontalScrollIndicator = _showScrollBar;
+ scrollView.scrollEnabled = _scrollable;
if (self.ancestorScroller) {
scrollView.scrollsToTop = NO;
@@ -174,6 +177,10 @@ WX_EXPORT_METHOD(@selector(resetLoadmore))
}
self.loadmoreretry = loadmoreretry;
}
+ if (attributes[@"scrollable"]) {
+ _scrollable = attributes[@"scrollable"] ? [WXConvert BOOL:attributes[@"scrollable"]] : YES;
+ ((UIScrollView *)self.view).scrollEnabled = _scrollable;
+ }
}
- (void)addEvent:(NSString *)eventName
@@ -215,7 +222,7 @@ WX_EXPORT_METHOD(@selector(resetLoadmore))
}
CGFloat scrollOffsetY = ((UIScrollView *)self.view).contentOffset.y;
for(WXComponent *component in self.stickyArray) {
- if (CGPointEqualToPoint(component->_absolutePosition, CGPointZero)) {
+ if (isnan(component->_absolutePosition.x) && isnan(component->_absolutePosition.y)) {
component->_absolutePosition = [component.supercomponent.view convertPoint:component.view.frame.origin toView:self.view];
}
CGPoint relativePosition = component->_absolutePosition;
@@ -299,10 +306,11 @@ WX_EXPORT_METHOD(@selector(resetLoadmore))
{
UIScrollView *scrollView = (UIScrollView *)self.view;
CGPoint contentOffset = scrollView.contentOffset;
+ CGFloat scaleFactor = self.weexInstance.pixelScaleFactor;
if (_scrollDirection == WXScrollDirectionHorizontal) {
CGFloat contentOffetX = [component.supercomponent.view convertPoint:component.view.frame.origin toView:self.view].x;
- contentOffetX += offset * WXScreenResizeRadio();
+ contentOffetX += offset * scaleFactor;
if (contentOffetX > scrollView.contentSize.width - scrollView.frame.size.width) {
contentOffset.x = scrollView.contentSize.width - scrollView.frame.size.width;
@@ -311,7 +319,7 @@ WX_EXPORT_METHOD(@selector(resetLoadmore))
}
} else {
CGFloat contentOffetY = [component.supercomponent.view convertPoint:component.view.frame.origin toView:self.view].y;
- contentOffetY += offset * WXScreenResizeRadio();
+ contentOffetY += offset * scaleFactor;
if (contentOffetY > scrollView.contentSize.height - scrollView.frame.size.height) {
contentOffset.y = scrollView.contentSize.height - scrollView.frame.size.height;
@@ -325,7 +333,7 @@ WX_EXPORT_METHOD(@selector(resetLoadmore))
- (BOOL)isNeedLoadMore
{
- if (_loadMoreOffset >= 0.0) {
+ if (_loadMoreOffset >= 0.0 && ((UIScrollView *)self.view).contentOffset.y >= 0) {
return _previousLoadMoreContentHeight != ((UIScrollView *)self.view).contentSize.height && ((UIScrollView *)self.view).contentSize.height - ((UIScrollView *)self.view).contentOffset.y - self.view.frame.size.height <= _loadMoreOffset;
}
@@ -461,8 +469,6 @@ WX_EXPORT_METHOD(@selector(resetLoadmore))
}
}
-#pragma mark Private Methods
-
- (void)handleAppear
{
if (![self isViewLoaded]) {
@@ -481,6 +487,8 @@ WX_EXPORT_METHOD(@selector(resetLoadmore))
}
}
+#pragma mark Private Methods
+
- (void)scrollToTarget:(WXScrollToTarget *)target scrollRect:(CGRect)rect
{
WXComponent *component = target.target;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXSliderComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXSliderComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXSliderComponent.m
index 99a4c6f..6ad82ff 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXSliderComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXSliderComponent.m
@@ -18,6 +18,7 @@
@protocol WXSliderViewDelegate <UIScrollViewDelegate>
+- (void)sliderView:(WXSliderView *)sliderView sliderViewDidScroll:(UIScrollView *)scrollView;
- (void)sliderView:(WXSliderView *)sliderView didScrollToItemAtIndex:(NSInteger)index;
@end
@@ -284,6 +285,9 @@
if (itemView) {
self.currentIndex = itemView.tag;
}
+ if (self.delegate && [self.delegate respondsToSelector:@selector(sliderView:sliderViewDidScroll:)]) {
+ [self.delegate sliderView:self sliderViewDidScroll:self.scrollView];
+ }
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
@@ -310,8 +314,12 @@
@property (nonatomic, assign) BOOL autoPlay;
@property (nonatomic, assign) NSUInteger interval;
@property (nonatomic, assign) NSInteger index;
+@property (nonatomic, assign) CGFloat lastOffsetXRatio;
+@property (nonatomic, assign) CGFloat offsetXAccuracy;
@property (nonatomic, assign) BOOL sliderChangeEvent;
+@property (nonatomic, assign) BOOL sliderScrollEvent;
@property (nonatomic, strong) NSMutableArray *childrenView;
+@property (nonatomic, assign) BOOL scrollable;
@end
@@ -326,8 +334,10 @@
{
if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
_sliderChangeEvent = NO;
+ _sliderScrollEvent = NO;
_interval = 3000;
_childrenView = [NSMutableArray new];
+ _lastOffsetXRatio = 0;
if (attributes[@"autoPlay"]) {
_autoPlay = [attributes[@"autoPlay"] boolValue];
@@ -341,6 +351,12 @@
_index = [attributes[@"index"] integerValue];
}
+ _scrollable = attributes[@"scrollable"] ? [WXConvert BOOL:attributes[@"scrollable"]] : YES;
+
+ if (attributes[@"offsetXAccuracy"]) {
+ _offsetXAccuracy = [WXConvert CGFloat:attributes[@"offsetXAccuracy"]];
+ }
+
self.cssNode->style.flex_direction = CSS_FLEX_DIRECTION_ROW;
}
return self;
@@ -359,6 +375,7 @@
_sliderView.delegate = self;
_sliderView.scrollView.pagingEnabled = YES;
_sliderView.exclusiveTouch = YES;
+ _sliderView.scrollView.scrollEnabled = _scrollable;
if (_autoPlay) {
[self _startAutoPlayTimer];
@@ -465,6 +482,15 @@
self.currentIndex = _index;
[_sliderView scroll2ItemView:self.currentIndex animated:YES];
}
+
+ if (attributes[@"scrollable"]) {
+ _scrollable = attributes[@"scrollable"] ? [WXConvert BOOL:attributes[@"scrollable"]] : YES;
+ ((WXSliderView *)self.view).scrollView.scrollEnabled = _scrollable;
+ }
+
+ if (attributes[@"offsetXAccuracy"]) {
+ _offsetXAccuracy = [WXConvert CGFloat:attributes[@"offsetXAccuracy"]];
+ }
}
- (void)addEvent:(NSString *)eventName
@@ -472,6 +498,9 @@
if ([eventName isEqualToString:@"change"]) {
_sliderChangeEvent = YES;
}
+ if ([eventName isEqualToString:@"scroll"]) {
+ _sliderScrollEvent = YES;
+ }
}
- (void)removeEvent:(NSString *)eventName
@@ -479,6 +508,9 @@
if ([eventName isEqualToString:@"change"]) {
_sliderChangeEvent = NO;
}
+ if ([eventName isEqualToString:@"scroll"]) {
+ _sliderScrollEvent = NO;
+ }
}
#pragma mark Public Methods
@@ -530,10 +562,24 @@
}
}
+#pragma mark ScrollView Delegate
+
+- (void)sliderView:(WXSliderView *)sliderView sliderViewDidScroll:(UIScrollView *)scrollView
+{
+ if (_sliderScrollEvent) {
+ CGFloat width = scrollView.frame.size.width;
+ CGFloat XDeviation = scrollView.frame.origin.x - (scrollView.contentOffset.x - width);
+ CGFloat offsetXRatio = (XDeviation / width);
+ if (ABS(offsetXRatio - _lastOffsetXRatio) >= _offsetXAccuracy) {
+ _lastOffsetXRatio = offsetXRatio;
+ [self fireEvent:@"scroll" params:@{@"offsetXRatio":[NSNumber numberWithFloat:offsetXRatio]} domChanges:nil];
+ }
+ }
+}
+
- (void)sliderView:(WXSliderView *)sliderView didScrollToItemAtIndex:(NSInteger)index
{
self.currentIndex = index;
-
if (_sliderChangeEvent) {
[self fireEvent:@"change" params:@{@"index":@(index)} domChanges:@{@"attrs": @{@"index": @(index)}}];
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b5123119/ios/sdk/WeexSDK/Sources/Component/WXSliderNeighborComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXSliderNeighborComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXSliderNeighborComponent.m
index b3ec0de..d7b3203 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXSliderNeighborComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXSliderNeighborComponent.m
@@ -114,7 +114,7 @@
self.isAccessibilityElement = YES;
[self addSubview:_contentView];
-
+
if (_dataSource) {
[self reloadData];
}
@@ -514,6 +514,23 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
return YES;
}
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
+ //if the view which the otherGestureRecognizer works on is a scrollview and also it is scrollEnabled vertically ,at this time,we should not block the guesture from being recognized by the otherGestureRecognize
+ if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
+ if ([otherGestureRecognizer.view isKindOfClass:[UIScrollView class]]) {
+ UIScrollView* scrollview = (UIScrollView *)otherGestureRecognizer.view;
+ if (scrollview.scrollEnabled) {
+ UIPanGestureRecognizer* panRcgn= (UIPanGestureRecognizer *)gestureRecognizer;
+ //check offset for confirming vertival movement
+ if (fabs([panRcgn translationInView:panRcgn.view].y) > fabs([panRcgn translationInView:panRcgn.view].x)*16) {
+ return YES;
+ }
+ }
+ }
+ }
+ return NO;
+}
+
- (void)didPan:(UIPanGestureRecognizer *)panGesture
{
@@ -1364,7 +1381,9 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
WXPixelType neighborSpace;
CGFloat neighborAlpha;
CGFloat neighborScale;
+ CGFloat currentItemScale;
}
+
@property (nonatomic, strong) WXSliderNeighborView *sliderView;
@property (nonatomic, assign) BOOL autoPlay;
@property (nonatomic, assign) NSUInteger interval;
@@ -1374,43 +1393,33 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
@property (nonatomic, assign) BOOL sliderChangeEvent;
@property (nonatomic, assign) NSInteger currentIndex;
@property (nonatomic) CGRect itemRect;
+@property (nonatomic, assign) BOOL scrollable;
+
@end
+#define DEFAULT_NEIGHBOR_ITEM_SCALE 0.8
+#define DEFAULT_CURRENT_ITEM_SCALE 0.9
+#define DEFAULT_NEIGHBOR_ALPHA 0.6
+#define DEFAULT_ANIMATION_DURATION 0.3
+#define DEFAULT_NEIGHBOR_SPACE 25
+
+
@implementation WXSliderNeighborComponent
- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance {
if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
_sliderChangeEvent = NO;
- _sliderView = [[WXSliderNeighborView alloc] init];
- _sliderView.delegate = self;
- _sliderView.dataSource = self;
_interval = 3000;
- [self setNeighborSpace:attributes];
- [self setNeighborAlpha:attributes];
- [self setNeighborScale:attributes];
_items = [NSMutableArray array];
_itemRect = CGRectNull;
-
- if (attributes[@"autoPlay"]) {
- _autoPlay = [attributes[@"autoPlay"] boolValue];
- }
-
- if (attributes[@"interval"]) {
- _interval = [attributes[@"interval"] integerValue];
- }
-
- if (attributes[@"index"]) {
- _index = [attributes[@"index"] integerValue];
- _currentIndex = _index;
- }
- if (attributes[@"autoPlay"]) {
- _autoPlay = [attributes[@"autoPlay"] boolValue];
- }
-
- if (attributes[@"interval"]) {
- _interval = [attributes[@"interval"] integerValue];
- }
+ self->neighborAlpha = DEFAULT_NEIGHBOR_ALPHA;
+ self->neighborScale = DEFAULT_NEIGHBOR_ITEM_SCALE;
+ self->currentItemScale = DEFAULT_CURRENT_ITEM_SCALE;
+ self->neighborSpace = [WXConvert WXPixelType:@(DEFAULT_NEIGHBOR_SPACE) scaleFactor:self.weexInstance.pixelScaleFactor];
+ _scrollable = YES;
+ [self setAttributes:attributes];
+ _scrollable = attributes[@"scrollable"] ? [WXConvert BOOL:attributes[@"scrollable"]] : YES;
}
self.cssNode->style.flex_direction = CSS_FLEX_DIRECTION_ROW;
@@ -1422,15 +1431,33 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
- (UIView *)loadView
{
+ _sliderView = [[WXSliderNeighborView alloc] init];
return _sliderView;
}
+- (void)dealloc
+{
+ _sliderView.delegate = nil;
+ _sliderView.dataSource = nil;
+ if (_autoPlay) {
+ [self _stopAutoPlayTimer];
+ }
+ _sliderView = nil;
+ [self.items removeAllObjects];
+}
+
+- (void)viewDidUnload
+{
+ [self.items removeAllObjects];
+}
+
- (void)viewDidLoad
{
_sliderView = (WXSliderNeighborView *)self.view;
_sliderView.delegate = self;
_sliderView.dataSource = self;
_sliderView.contentView.clipsToBounds = YES;
+ _sliderView.scrollEnabled = _scrollable;
if (_autoPlay) {
[self _startAutoPlayTimer];
} else {
@@ -1491,7 +1518,7 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
}
#pragma mark attributes update
-- (void)updateAttributes:(NSDictionary *)attributes
+- (void)setAttributes:(NSDictionary *)attributes
{
if (attributes[@"index"]) {
_index = [attributes[@"index"] integerValue];
@@ -1505,7 +1532,6 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
[self _stopAutoPlayTimer];
}
}
-
if (attributes[@"interval"]) {
_interval = [attributes[@"interval"] integerValue];
@@ -1518,14 +1544,24 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
if (attributes[@"neighborScale"]) {
[self setNeighborScale:attributes];
}
+ if (attributes[@"currentItemScale"]) {
+ [self setCurrentItemScale:attributes];
+ }
if (attributes[@"neighborAlpha"]) {
[self setNeighborAlpha:attributes];
}
-
if (attributes[@"neighborSpace"]) {
[self setNeighborSpace:attributes];
}
-
+ if (attributes[@"scrollable"]) {
+ _scrollable = attributes[@"scrollable"] ? [WXConvert BOOL:attributes[@"scrollable"]] : YES;
+ ((WXSliderNeighborView *)self.view).scrollEnabled = _scrollable;
+ }
+}
+
+- (void)updateAttributes:(NSDictionary *)attributes
+{
+ [self setAttributes:attributes];
[self.sliderView setCurrentItemIndex:_index];
[self updateSliderPage:YES];
}
@@ -1558,9 +1594,7 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
- (void)setNeighborSpace:(NSDictionary *)attributes{
if(attributes[@"neighborSpace"]) {
- self->neighborSpace = [WXConvert WXPixelType:attributes[@"neighborSpace"]];
- } else {
- self->neighborSpace = [WXConvert WXPixelType:@(25)];
+ self->neighborSpace = [WXConvert WXPixelType:attributes[@"neighborSpace"] scaleFactor:self.weexInstance.pixelScaleFactor];
}
}
@@ -1569,8 +1603,14 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
self->neighborAlpha = [WXConvert CGFloat:attributes[@"neighborAlpha"]];
self->neighborAlpha = self->neighborAlpha >= 0 ? self->neighborAlpha : 0;
self->neighborAlpha = self->neighborAlpha <= 1 ? self->neighborAlpha: 1;
- } else {
- self->neighborAlpha = 0.6;
+ }
+}
+
+- (void)setCurrentItemScale:(NSDictionary *)attributes {
+ if (attributes[@"currentItemScale"]) {
+ self->currentItemScale = [WXConvert CGFloat:attributes[@"currentItemScale"]];
+ self->currentItemScale = self->currentItemScale >= 0 ? self->currentItemScale : 0;
+ self->currentItemScale = self->currentItemScale <= 1 ? self->currentItemScale: 1;
}
}
@@ -1580,9 +1620,6 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
self->neighborScale = [WXConvert CGFloat:attributes[@"neighborScale"]];
self->neighborScale = self->neighborScale >= 0? self->neighborScale : 0;
self->neighborScale = self->neighborScale <= 1? self->neighborScale :1;
-
- } else {
- self->neighborScale = 0.8;
}
}
@@ -1639,7 +1676,11 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
- (UIView *)sliderNeighbor:(WXSliderNeighborView *)sliderNeighbor viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view {
if (!view) {
- view = self.items[index];
+ if (index < [self.items count]) {
+ view = self.items[index];
+ }else {
+ return nil;
+ }
} else {
view.tag = 1;
}
@@ -1700,7 +1741,7 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
float duration = 0;
__weak typeof(self) weakSelf = self;
if (animate) {
- duration = 0.3;
+ duration = DEFAULT_ANIMATION_DURATION;
}
[UIView animateWithDuration:duration animations:^{
@@ -1708,14 +1749,13 @@ NSComparisonResult sliderNeighorCompareViewDepth(UIView *view1, UIView *view2, W
if (strongSelf) {
currentView.alpha = 1.0;
- if (fabs(strongSelf->neighborScale - 0) > CGFLOAT_MIN) {
- transfrom = CGAffineTransformConcat(transfrom,CGAffineTransformMakeScale(0.9, 0.9));
+ if (fabs(strongSelf->currentItemScale) > CGFLOAT_MIN) {
+ transfrom = CGAffineTransformConcat(transfrom,CGAffineTransformMakeScale(strongSelf->currentItemScale, strongSelf->currentItemScale));
}
currentView.transform = transfrom;
transfrom = CGAffineTransformIdentity;
-
- if (fabs(strongSelf->neighborScale - 0) <= CGFLOAT_MIN) {
- strongSelf->neighborScale = 0.8;
+ if (fabs(strongSelf->neighborScale) <= CGFLOAT_MIN) {
+ strongSelf->neighborScale = DEFAULT_NEIGHBOR_ITEM_SCALE;
}
CGFloat tx = 0.5*_itemRect.size.width*((1-self->neighborScale)+(1-0.9))-self->neighborSpace;