Repository: incubator-weex Updated Branches: refs/heads/0.16-dev af2923026 -> 5b99cc6b0
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m new file mode 100644 index 0000000..49ed216 --- /dev/null +++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m @@ -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 "WXRecycleListDataManager.h" +#import "NSArray+Weex.h" +#import "WXLog.h" +#import "WXAssert.h" + +@implementation WXRecycleListDataManager +{ + NSArray *_data; +} + +- (instancetype)initWithData:(NSArray *)data +{ + if (self = [super init]) { + if (![data isKindOfClass:[NSArray class]]) { + WXLogError(@"list data must be an array!"); + } else { + _data = data; + } + } + + return self; +} + +- (void)updateData:(NSArray *)data +{ + WXAssertMainThread(); + + _data = data; +} + +- (NSDictionary *)dataAtIndex:(NSInteger)index +{ + WXAssertMainThread(); + + return [_data wx_safeObjectAtIndex:index]; +} + +- (NSInteger)numberOfItems +{ + WXAssertMainThread(); + + return [_data count]; +} + +@end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.h b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.h new file mode 100644 index 0000000..389dbb8 --- /dev/null +++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.h @@ -0,0 +1,33 @@ +/* + * 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> +#import "WXCellSlotComponent.h" + +@interface WXRecycleListTemplateManager : NSObject + +@property (nonatomic, weak) UICollectionView *collectionView; + +- (void)addTemplate:(WXCellSlotComponent *)component; + +- (WXCellSlotComponent *)dequeueCellSlotWithType:(NSString *)type forIndexPath:(NSIndexPath *)indexPath; + +- (WXCellSlotComponent *)templateWithType:(NSString *)type; + +@end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.m b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.m new file mode 100644 index 0000000..0ac528e --- /dev/null +++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.m @@ -0,0 +1,94 @@ +/* + * 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 "WXRecycleListTemplateManager.h" +#import "WXLog.h" +#import "WXAssert.h" + +@interface WXReusableCollectionViewCell : UICollectionViewCell + +@end + +@implementation WXReusableCollectionViewCell + +@end + +@implementation WXRecycleListTemplateManager +{ + NSMapTable<NSString *, WXCellSlotComponent *> *_templateTypeMap; +} + +- (instancetype)init +{ + if (self = [super init]) { + _templateTypeMap = [NSMapTable strongToWeakObjectsMapTable]; + } + + return self; +} + +- (void)setCollectionView:(UICollectionView *)collectionView +{ + WXAssertMainThread(); + + if (_collectionView == collectionView) { + return; + } + + _collectionView = collectionView; + + for (NSString *templateType in [_templateTypeMap.keyEnumerator.allObjects copy]) { + [self _registerCellClassForReuseID:templateType]; + } +} + +- (void)addTemplate:(WXCellSlotComponent *)component +{ + WXAssertMainThread(); + + NSString *templateType = component.templateType; + WXAssert(templateType != nil, @"cell-slot:%@ must have a template id!", component); + + [_templateTypeMap setObject:component forKey:templateType]; + if (_collectionView) { + [self _registerCellClassForReuseID:templateType]; + } +} + +- (WXCellSlotComponent *)dequeueCellSlotWithType:(NSString *)type forIndexPath:(NSIndexPath *)indexPath +{ + WXAssertMainThread(); + + WXCellSlotComponent *cellSlot = [_templateTypeMap objectForKey:type]; + return [cellSlot copy]; +} + +- (WXCellSlotComponent *)templateWithType:(NSString *)type +{ + return [_templateTypeMap objectForKey:type];; +} + +- (void)_registerCellClassForReuseID:(NSString *)templateID +{ + WXLogDebug(@"register cell class for template id:%@", templateID); + //TODO: register class updateTemplateId + [_collectionView registerClass:[WXReusableCollectionViewCell class] forCellWithReuseIdentifier:templateID]; +} + +@end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.h b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.h new file mode 100644 index 0000000..c96bbcd --- /dev/null +++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.h @@ -0,0 +1,28 @@ +/* + * 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> + +@interface WXRecycleListUpdateManager : NSObject + +@property (nonatomic, weak) UICollectionView *collectionView; + +- (void)reload; + +@end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.m b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.m new file mode 100644 index 0000000..1395607 --- /dev/null +++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.m @@ -0,0 +1,29 @@ +/* + * 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 "WXRecycleListUpdateManager.h" + +@implementation WXRecycleListUpdateManager + +- (void)reload +{ + [_collectionView reloadData]; +} + +@end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/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 e579139..0902eab 100644 --- a/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.m +++ b/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.m @@ -100,7 +100,7 @@ - (void)_moveToSupercomponent:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index { - if (self.delegate == newSupercomponent) { + if (self.delegate == (id<WXCellRenderDelegate>)newSupercomponent) { [self.delegate cell:self didMoveToIndex:index]; [super _removeFromSupercomponent]; [newSupercomponent _insertSubcomponent:self atIndex:index]; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/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 1452118..1b0f784 100644 --- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h +++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h @@ -25,6 +25,7 @@ @class WXTouchGestureRecognizer; @class WXThreadSafeCounter; +typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL *needUpdate); /** * The following variables and methods are used in Weex INTERNAL logic. @@ -131,6 +132,21 @@ BOOL _lazyCreateView; WXTransform *_transform; + + /** + * Data Binding + */ + BOOL _isTemplate; + WXComponent *_templateComponent; + WXDataBindingBlock _bindingMatch; + WXDataBindingBlock _bindingRepeat; + NSString *_repeatIndexIdentify; + NSString *_repeatLabelIdentify; + BOOL _isRepeating; + BOOL _isSkipUpdate; + + NSMutableDictionary<NSString *, NSArray<NSString *> *> *_bindingAttributes; + NSMutableDictionary<NSString *, NSArray<NSString *> *> *_bindingStyles; } ///-------------------------------------- @@ -226,6 +242,10 @@ - (void)setGradientLayer; +- (void)_storeBindingsWithStyles:(NSDictionary *)styles attributes:(NSDictionary *)attributes; + +- (void)_didInserted; + @end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m b/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m index c2db44a..ef1c73d 100644 --- a/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m +++ b/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m @@ -109,6 +109,10 @@ [self registerComponent:@"textarea" withClass:NSClassFromString(@"WXTextAreaComponent")]; [self registerComponent:@"canvas" withClass:NSClassFromString(@"WXCanvasComponent")]; [self registerComponent:@"slider-neighbor" withClass:NSClassFromString(@"WXSliderNeighborComponent")]; + + [self registerComponent:@"recycle-list" withClass:NSClassFromString(@"WXRecycleListComponent")]; + [self registerComponent:@"cell-slot" withClass:NSClassFromString(@"WXCellSlotComponent") withProperties: @{@"append":@"tree", @"isTemplate":@YES}]; + } + (void)registerComponent:(NSString *)name withClass:(Class)clazz http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.h b/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.h index f2d2f6a..73b08e1 100644 --- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.h +++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.h @@ -18,6 +18,16 @@ */ #import <Foundation/Foundation.h> +#import "WXInvocationConfig.h" + +@interface WXComponentConfig : WXInvocationConfig + +@property (nonatomic, strong) NSDictionary *properties; + +- (instancetype)initWithName:(NSString *)name class:(NSString *)clazz pros:(NSDictionary *)pros; + +@end + @interface WXComponentFactory : NSObject @@ -53,6 +63,8 @@ */ + (Class)classWithComponentName:(NSString *)name; ++ (WXComponentConfig *)configWithComponentName:(NSString *)name; + /** * @abstract Returns the registered components. */ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.m b/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.m index 6970376..0101d7a 100644 --- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.m +++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.m @@ -20,17 +20,9 @@ #import "WXComponentFactory.h" #import "WXAssert.h" #import "WXLog.h" -#import "WXInvocationConfig.h" #import <objc/runtime.h> -@interface WXComponentConfig : WXInvocationConfig -@property (nonatomic, strong) NSDictionary *properties; - -- (instancetype)initWithName:(NSString *)name class:(NSString *)clazz pros:(NSDictionary *)pros; - -@end - @implementation WXComponentConfig - (instancetype)initWithName:(NSString *)name class:(NSString *)clazz pros:(NSDictionary *)pros @@ -82,7 +74,17 @@ + (Class)classWithComponentName:(NSString *)name { - return [[self sharedInstance] classWithComponentName:name]; + WXComponentConfig *config = [self configWithComponentName:name]; + if(!config || !config.clazz) { + return nil; + } + + return NSClassFromString(config.clazz); +} + ++ (WXComponentConfig *)configWithComponentName:(NSString *)name +{ + return [[self sharedInstance] configWithComponentName:name]; } + (void)registerComponent:(NSString *)name withClass:(Class)clazz withPros:(NSDictionary *)pros @@ -195,9 +197,9 @@ return componentDic; } -- (Class)classWithComponentName:(NSString *)name +- (WXComponentConfig *)configWithComponentName:(NSString *)name { - WXAssert(name, @"Can not find class for a nil component name"); + WXAssert(name, @"Can not find config for a nil component name"); WXComponentConfig *config = nil; @@ -209,11 +211,7 @@ } [_configLock unlock]; - if(!config || !config.clazz) { - return nil; - } - - return NSClassFromString(config.clazz); + return config; } - (void)registerComponent:(NSString *)name withClass:(Class)clazz withPros:(NSDictionary *)pros http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h index 729e6d7..387e3d0 100644 --- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h +++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h @@ -24,8 +24,15 @@ @class WXSDKInstance; @class WXComponent; -extern void WXPerformBlockOnComponentThread(void (^block)()); - +#ifdef __cplusplus +extern "C" { +#endif + +void WXPerformBlockOnComponentThread(void (^block)()); + +#ifdef __cplusplus +} +#endif @interface WXComponentManager : NSObject @@ -91,6 +98,7 @@ extern void WXPerformBlockOnComponentThread(void (^block)()); */ - (NSUInteger)numberOfComponents; +- (void)addComponent:(WXComponent *)component toIndexDictForRef:(NSString *)ref; ///-------------------------------------- /// @name Updating http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m index 86ec447..bfd96eb 100644 --- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m +++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m @@ -20,6 +20,7 @@ #import "WXComponentManager.h" #import "WXComponent.h" #import "WXComponent_internal.h" +#import "WXComponent+DataBinding.h" #import "WXComponentFactory.h" #import "WXDefine.h" #import "NSArray+Weex.h" @@ -204,6 +205,15 @@ static NSThread *WXComponentThread; _rootComponent = [self _buildComponentForData:data supercomponent:nil]; [self _initRootCSSNode]; + + NSArray *subcomponentsData = [data valueForKey:@"children"]; + if (subcomponentsData) { + BOOL appendTree = [_rootComponent.attributes[@"append"] isEqualToString:@"tree"]; + for(NSDictionary *subcomponentData in subcomponentsData){ + [self _recursivelyAddComponent:subcomponentData toSupercomponent:_rootComponent atIndex:-1 appendingInTree:appendTree]; + } + } + __weak typeof(self) weakSelf = self; [self _addUITask:^{ [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:data[@"ref"] className:nil name:data[@"type"] phase:WXTracingBegin functionName:@"createBody" options:@{@"threadName":WXTUIThread}]; @@ -212,6 +222,8 @@ static NSThread *WXComponentThread; [strongSelf.weexInstance.rootView addSubview:strongSelf->_rootComponent.view]; [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:data[@"ref"] className:nil name:data[@"type"] phase:WXTracingEnd functionName:@"createBody" options:@{@"threadName":WXTUIThread}]; }]; + + } static bool rootNodeIsDirty(void *context) @@ -258,14 +270,16 @@ static css_node_t * rootNodeGetChild(void *context, int i) if(supercomponent && component && supercomponent->_lazyCreateView) { component->_lazyCreateView = YES; } - - __weak typeof(self) weakSelf = self; - [self _addUITask:^{ - [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:componentData[@"ref"] className:nil name:componentData[@"type"] phase:WXTracingBegin functionName:@"addElement" options:@{@"threadName":WXTUIThread}]; - [supercomponent insertSubview:component atIndex:index]; - [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:componentData[@"ref"] className:nil name:componentData[@"type"] phase:WXTracingEnd functionName:@"addElement" options:@{@"threadName":WXTUIThread}]; - }]; - + + if (!component->_isTemplate) { + __weak typeof(self) weakSelf = self; + [self _addUITask:^{ + [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:componentData[@"ref"] className:nil name:componentData[@"type"] phase:WXTracingBegin functionName:@"addElement" options:@{@"threadName":WXTUIThread}]; + [supercomponent insertSubview:component atIndex:index]; + [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:componentData[@"ref"] className:nil name:componentData[@"type"] phase:WXTracingEnd functionName:@"addElement" options:@{@"threadName":WXTUIThread}]; + }]; + } + NSArray *subcomponentsData = [componentData valueForKey:@"children"]; BOOL appendTree = !appendingInTree && [component.attributes[@"append"] isEqualToString:@"tree"]; @@ -273,6 +287,9 @@ static css_node_t * rootNodeGetChild(void *context, int i) for(NSDictionary *subcomponentData in subcomponentsData){ [self _recursivelyAddComponent:subcomponentData toSupercomponent:component atIndex:-1 appendingInTree:appendTree || appendingInTree]; } + + [component _didInserted]; + if (appendTree) { // If appending treeï¼force layout in case of too much tasks piling up in syncQueue [self _layoutAndSyncUI]; @@ -383,9 +400,26 @@ static css_node_t * rootNodeGetChild(void *context, int i) } } } - - Class clazz = [WXComponentFactory classWithComponentName:type]; + + WXComponentConfig *config = [WXComponentFactory configWithComponentName:type]; + BOOL isTemplate = [config.properties[@"isTemplate"] boolValue] || (supercomponent && supercomponent->_isTemplate); + NSDictionary *bindingStyles; + NSDictionary *bindingAttibutes; + NSDictionary *bindingEvents; + if (isTemplate) { + bindingStyles = [self _extractBindings:&styles]; + bindingAttibutes = [self _extractBindings:&attributes]; + bindingEvents = [self _extractBindingEvents:&events]; + } + + Class clazz = NSClassFromString(config.clazz);; WXComponent *component = [[clazz alloc] initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:self.weexInstance]; + + if (isTemplate) { + component->_isTemplate = YES; + [component _storeBindingsWithStyles:bindingStyles attributes:bindingAttibutes]; + } + WXAssert(component, @"Component build failed for data:%@", data); [_indexDict setObject:component forKey:component.ref]; @@ -393,6 +427,67 @@ static css_node_t * rootNodeGetChild(void *context, int i) return component; } +- (void)addComponent:(WXComponent *)component toIndexDictForRef:(NSString *)ref +{ + [_indexDict setObject:component forKey:ref]; +} + +- (NSDictionary *)_extractBindings:(NSDictionary **)attributesOrStylesPoint +{ + NSDictionary *attributesOrStyles = *attributesOrStylesPoint; + if (!attributesOrStyles) { + return nil; + } + + NSMutableDictionary *newAttributesOrStyles = [attributesOrStyles mutableCopy]; + NSMutableDictionary *bindingAttributesOrStyles = [NSMutableDictionary dictionary]; + + [attributesOrStyles enumerateKeysAndObjectsUsingBlock:^(id _Nonnull attributeOrStyleName, id _Nonnull attributeOrStyle, BOOL * _Nonnull stop) { + if ([WXBindingMatchIdentify isEqualToString:attributeOrStyleName] // match + || [WXBindingRepeatIdentify isEqualToString:attributeOrStyleName] // repeat + || ([attributeOrStyle isKindOfClass:[NSDictionary class]] && attributeOrStyle[WXBindingIdentify])) { // {"attributeOrStyleName": {"@binding":"bindingExpression"} + bindingAttributesOrStyles[attributeOrStyleName] = attributeOrStyle; + [newAttributesOrStyles removeObjectForKey:attributeOrStyleName]; + } else if ([attributeOrStyle isKindOfClass:[NSArray class]]) { + // {"attributeOrStyleName":[..., "string", {"@binding":"bindingExpression"}, "string", {"@binding":"bindingExpression"}, ...] + __block BOOL isBinding = NO; + [attributeOrStyle enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if ([obj isKindOfClass:[NSDictionary class]] && obj[WXBindingIdentify]) { + isBinding = YES; + *stop = YES; + } + }]; + + if (isBinding) { + bindingAttributesOrStyles[attributeOrStyleName] = attributeOrStyle; + [newAttributesOrStyles removeObjectForKey:attributeOrStyleName]; + } + } + }]; + + *attributesOrStylesPoint = newAttributesOrStyles; + + return bindingAttributesOrStyles; +} + +- (NSDictionary *)_extractBindingEvents:(NSArray **)eventsPoint +{ + NSArray *events = *eventsPoint; + NSMutableArray *newEvents = [events mutableCopy]; + NSMutableDictionary *bindingEvents = [NSMutableDictionary dictionary]; + [events enumerateObjectsUsingBlock:^(id _Nonnull event, NSUInteger idx, BOOL * _Nonnull stop) { + if ([event isKindOfClass:[NSDictionary class]] && event[@"type"] && event[@"params"]) { + NSString *eventName = event[@"type"]; + NSString *bindingParams = event[@"params"]; + bindingEvents[eventName] = bindingParams; + [newEvents removeObject:event]; + } + }]; + + *eventsPoint = newEvents; + return bindingEvents; +} + #pragma mark Reset -(BOOL)isShouldReset:(id )value { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Model/WXComponent.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.h b/ios/sdk/WeexSDK/Sources/Model/WXComponent.h index 39385ef..ac1b13a 100644 --- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.h +++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.h @@ -23,6 +23,11 @@ @class WXSDKInstance; +typedef enum : NSUInteger { + WXDisplayTypeNone, + WXDisplayTypeBlock +} WXDisplayType; + /** * @abstract the component callback , result can be string or dictionary. * @discussion callback data to js, the id of callback function will be removed to save memory. @@ -37,7 +42,7 @@ typedef void (^WXKeepAliveCallback)(_Nonnull id result, BOOL keepAlive); NS_ASSUME_NONNULL_BEGIN -@interface WXComponent : NSObject +@interface WXComponent : NSObject <NSCopying> ///-------------------------------------- /// @name Component Hierarchy Management @@ -346,6 +351,8 @@ NS_ASSUME_NONNULL_BEGIN /// @name Display ///-------------------------------------- +@property (nonatomic, assign) WXDisplayType displayType; + /** * @abstract Marks the view as needing display. The method should be called on the main thread. * @discussion You can use this method to notify the system that your component's contents need to be redrawn. This method makes a note of the request and returns immediately. The component is not actually redrawn until the next drawing cycle, at which point all invalidated components are updated. @@ -399,6 +406,16 @@ NS_ASSUME_NONNULL_BEGIN */ - (UIImage *)endDrawContext:(CGContextRef)context; +///-------------------------------------- +/// @name Data Binding +///-------------------------------------- + +/** + * @abstract Update binding data for the component + * @parameter binding data to update + */ +- (void)updateBindingData:(NSDictionary *)data; + @end @interface WXComponent (Deprecated) http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Model/WXComponent.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m index 81f8178..76fb446 100644 --- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m +++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m @@ -88,6 +88,7 @@ _absolutePosition = CGPointMake(NAN, NAN); + _displayType = WXDisplayTypeBlock; _isNeedJoinLayoutSystem = YES; _isLayoutDirty = YES; _isViewFrameSyncWithCalculated = YES; @@ -136,6 +137,41 @@ return self; } +- (id)copyWithZone:(NSZone *)zone +{ + NSInteger copyId = 0; + @synchronized(self){ + static NSInteger __copy = 0; + copyId = __copy % (1024*1024); + __copy++; + } + NSString *copyRef = [NSString stringWithFormat:@"%ldcopy_of%@", copyId, _isTemplate ? self.ref : self->_templateComponent.ref]; + WXComponent *component = [[[self class] allocWithZone:zone] initWithRef:copyRef type:self.type styles:self.styles attributes:self.attributes events:self.events weexInstance:self.weexInstance]; + if (_isTemplate) { + component->_templateComponent = self; + } else { + component->_templateComponent = self->_templateComponent; + } + memcpy(component->_cssNode, self.cssNode, sizeof(css_node_t)); + component->_cssNode->context = (__bridge void *)component; + component->_calculatedFrame = self.calculatedFrame; + + NSMutableArray *subcomponentsCopy = [NSMutableArray array]; + for (WXComponent *subcomponent in self.subcomponents) { + WXComponent *subcomponentCopy = [subcomponent copy]; + subcomponentCopy->_supercomponent = component; + [subcomponentsCopy addObject:subcomponentCopy]; + } + + component->_subcomponents = subcomponentsCopy; + + WXPerformBlockOnComponentThread(^{ + [self.weexInstance.componentManager addComponent:component toIndexDictForRef:copyRef]; + }); + + return component; +} + - (void)dealloc { free_css_node(_cssNode); @@ -195,6 +231,28 @@ return events; } +- (void)setDisplayType:(WXDisplayType)displayType +{ + if (_displayType != displayType) { + _displayType = displayType; + if (displayType == WXDisplayTypeNone) { + _isNeedJoinLayoutSystem = NO; + [self.supercomponent _recomputeCSSNodeChildren]; + WXPerformBlockOnMainThread(^{ + [self removeFromSuperview]; + }); + } else { + _isNeedJoinLayoutSystem = YES; + [self.supercomponent _recomputeCSSNodeChildren]; + WXPerformBlockOnMainThread(^{ + [self _buildViewHierarchyLazily]; + // TODO: insert into the correct index + [self.supercomponent insertSubview:self atIndex:0]; + }); + } + } +} + - (WXSDKInstance *)weexInstance { return _weexInstance; @@ -423,6 +481,11 @@ [newSupercomponent _insertSubcomponent:self atIndex:index]; } +- (void)_didInserted +{ + +} + - (id<WXScrollerProtocol>)ancestorScroller { if(!_ancestorScroller) { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Utility/WXDiffUtil.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXDiffUtil.m b/ios/sdk/WeexSDK/Sources/Utility/WXDiffUtil.m index 9396243..4b05df3 100644 --- a/ios/sdk/WeexSDK/Sources/Utility/WXDiffUtil.m +++ b/ios/sdk/WeexSDK/Sources/Utility/WXDiffUtil.m @@ -107,7 +107,9 @@ typedef enum : NSUInteger { } } +#if DEBUG [self _printMatrix:matrix rowSize:oldSize columnSize:newSize]; +#endif NSMutableArray *updates = [NSMutableArray array]; NSMutableIndexSet *inserts = [NSMutableIndexSet indexSet]; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h index 5d96757..538dc77 100644 --- a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h +++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h @@ -81,33 +81,41 @@ do {\ }\ }while(0) +#ifdef __cplusplus +extern "C" { +#endif + /** * @abstract execute asynchronous action block on the main thread. * */ -extern void WXPerformBlockOnMainThread( void (^ _Nonnull block)()); +void WXPerformBlockOnMainThread( void (^ _Nonnull block)()); /** * @abstract execute synchronous action block on the main thread. * */ -extern void WXPerformBlockSyncOnMainThread( void (^ _Nonnull block)()); +void WXPerformBlockSyncOnMainThread( void (^ _Nonnull block)()); /** * @abstract execute action block on the specific thread. * */ -extern void WXPerformBlockOnThread(void (^ _Nonnull block)(), NSThread *_Nonnull thread); +void WXPerformBlockOnThread(void (^ _Nonnull block)(), NSThread *_Nonnull thread); /** * @abstract swizzling methods. * */ -extern void WXSwizzleInstanceMethod(_Nonnull Class className, _Nonnull SEL original, _Nonnull SEL replaced); +void WXSwizzleInstanceMethod(_Nonnull Class className, _Nonnull SEL original, _Nonnull SEL replaced); -extern void WXSwizzleInstanceMethodWithBlock(_Nonnull Class className, _Nonnull SEL original, _Nonnull id block, _Nonnull SEL replaced); +void WXSwizzleInstanceMethodWithBlock(_Nonnull Class className, _Nonnull SEL original, _Nonnull id block, _Nonnull SEL replaced); -extern _Nonnull SEL WXSwizzledSelectorForSelector(_Nonnull SEL selector); +_Nonnull SEL WXSwizzledSelectorForSelector(_Nonnull SEL selector); + +#ifdef __cplusplus +} +#endif @interface WXUtility : NSObject http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/877487a6/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m index ef00f9a..be27ae7 100644 --- a/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m +++ b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m @@ -94,6 +94,10 @@ do {\ { WXAssertMainThread(); + if (subcomponent.displayType == WXDisplayTypeNone) { + return; + } + WX_CHECK_COMPONENT_TYPE(self.componentType) if (subcomponent->_positionType == WXPositionTypeFixed) { [self.weexInstance.rootView addSubview:subcomponent.view];