blob: fd93fb95e8317ea835e390e794ea0cd3eb8952c0 [file] [log] [blame]
/**
* 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 "WXCSSDomainController.h"
#import "WXDOMDomainController.h"
#import "WXCSSTypes.h"
#import <WeexSDK/WeexSDK.h>
@implementation WXCSSDomainController
@dynamic domain;
+ (WXCSSDomainController *)defaultInstance {
static WXCSSDomainController *defaultInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
defaultInstance = [[WXCSSDomainController alloc] init];
});
return defaultInstance;
}
+ (Class)domainClass {
return [WXCSSDomain class];
}
#pragma mark - private method
- (WXDOMNode *)p_getNodeFromNodeId:(NSNumber *)nodeId rootNode:(WXDOMNode *)rootNode{
if (!rootNode) {
return nil;
}
if ([nodeId longValue] == [rootNode.nodeId longValue]) {
return rootNode;
}
if (rootNode.children.count > 0) {
for (WXDOMNode *node in rootNode.children) {
if ([node.nodeId longValue] == [nodeId longValue]) {
return node;
}else {
WXDOMNode *returnNode = [self p_getNodeFromNodeId:nodeId rootNode:node];
if (returnNode) {
return returnNode;
}
}
}
}
return nil;
}
- (NSArray *)p_formateFrame:(NSString *)frameStr {
NSCharacterSet *characterSet1 = [NSCharacterSet characterSetWithCharactersInString:@"{},"];
NSArray *array = [frameStr componentsSeparatedByCharactersInSet:characterSet1];
NSMutableArray *position = [NSMutableArray array];
for(NSString *string in array)
{
NSString *removeFrame = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([removeFrame length] > 0) {
[position addObject:removeFrame];
}
}
return position;
}
#pragma mark - WXCSSCommandDelegate
- (void)domain:(WXCSSDomain *)domain getMatchedStylesForNodeWithNodeId:(NSNumber *)nodeId includePseudo:(NSNumber *)includePseudo includeInherited:(NSNumber *)includeInherited callback:(void (^)(NSArray *matchedCSSRules, NSArray *pseudoElements, NSArray *inherited, id error))callback {
NSArray *inherited = @[];
NSArray *pseudoElements = @[];
if ([WXDebugger isVDom]) {
NSInteger transformNodeId = nodeId.integerValue;
if (transformNodeId > 2) {
transformNodeId -= 2;
}
NSString *nodeKey = [NSString stringWithFormat:@"%ld",(long)transformNodeId];
NSString *nodeName = nil;
/********actual********/
UIView *selectedView = [[[WXDOMDomainController defaultInstance] getObjectsForComponentRefs] objectForKey:[NSString stringWithFormat:@"%ld",(long)nodeId.integerValue]];
NSArray *actualAttrs = [[WXDOMDomainController defaultInstance] attributesArrayForObject:selectedView];
WXCSSSelectorListData *selectorData = [[WXCSSSelectorListData alloc] init];
//assembling object of cssStyle
WXCSSCSSStyle *style = [[WXCSSCSSStyle alloc] init];
NSMutableArray *cssProperties = [NSMutableArray array];
NSMutableString *cssText = [[NSMutableString alloc] init];
for (int i = 0; i < actualAttrs.count; i++) {
if (i & 1) {
if (![actualAttrs[i-1] isEqualToString:@"frame"]) {
WXCSSCSSProperty *cssProperty = [[WXCSSCSSProperty alloc] init];
[cssText appendFormat:@"%@;",actualAttrs[i]];
cssProperty.name = actualAttrs[i-1];
cssProperty.value = actualAttrs[i];
[cssProperties addObject:[cssProperty WX_JSONObject]];
}else {
NSArray *names = @[@"width",@"height",@"top",@"left"];
NSArray *position = [self p_formateFrame:actualAttrs[i]];
if (position.count == 4) {
NSDictionary *property = @{@"left":position[0],
@"top":position[1],
@"width":position[2],
@"height":position[3]};
for (int i = 0; i < property.count; i++) {
WXCSSCSSProperty *cssProperty = [[WXCSSCSSProperty alloc] init];
cssProperty.name = names[i];
cssProperty.value = [NSString stringWithFormat:@"%@px",[self _toPixelFromPoint:property[names[i]]]];
[cssText appendString:[NSString stringWithFormat:@"%@:%@;",cssProperty.name,cssProperty.value]];
[cssProperties addObject:[cssProperty WX_JSONObject]];
}
}
}
}else {
if (![actualAttrs[i] isEqualToString:@"frame"]) {
[cssText appendFormat:@"%@:",actualAttrs[i]];
if ([actualAttrs[i] isEqualToString:@"class"]) {
nodeName = actualAttrs[i+1];
}
}
}
}
selectorData.text = nodeName ? : @"";
selectorData.selectors = @[@{@"text":nodeName ? : @""},@{@"text":@"actual value"}];
style.shorthandEntries = @[];
style.cssText = cssText;
style.cssProperties = [NSArray arrayWithArray:cssProperties];
WXCSSCSSRule *rule = [[WXCSSCSSRule alloc] init];
rule.media = @[];
rule.origin = @"inspector";
rule.selectorList = selectorData;
rule.style = style;
/********vdom********/
WXCSSSelectorListData *vdomSelectorData = [[WXCSSSelectorListData alloc] init];
vdomSelectorData.text = nodeName ? : @"";
vdomSelectorData.selectors = @[@{@"text":nodeName ? : @""},@{@"text":@"vdom value"}];
//assembling object of cssStyle
WXCSSCSSStyle *vdomStyle = [[WXCSSCSSStyle alloc] init];
NSMutableArray *vdomCssProperties = [NSMutableArray array];
NSMutableString *vdomCssText = [[NSMutableString alloc] init];
WXPerformBlockOnComponentThread(^{
__block WXComponent *component = [[WXDOMDomainController defaultInstance] _getComponentFromRef:nodeKey];
WXPerformBlockOnMainThread(^{
if (component) {
NSDictionary *vdomStyles = component.styles;
if (vdomStyles.allKeys > 0) {
for (NSString *key in vdomStyles.allKeys) {
WXCSSCSSProperty *cssProperty = [[WXCSSCSSProperty alloc] init];
cssProperty.name = key;
if ([[vdomStyles objectForKey:key] isKindOfClass:[NSString class]]) {
cssProperty.value = [vdomStyles objectForKey:key];
}else {
cssProperty.value = [NSString stringWithFormat:@"%@",[vdomStyles objectForKey:key]];
}
[vdomCssText appendString:[NSString stringWithFormat:@"%@:%@;",cssProperty.name,cssProperty.value]];
[vdomCssProperties addObject:[cssProperty WX_JSONObject]];
}
}
}
vdomStyle.shorthandEntries = @[];
vdomStyle.cssText = vdomCssText;
vdomStyle.cssProperties = [NSArray arrayWithArray:vdomCssProperties];
WXCSSCSSRule *vdomRule = [[WXCSSCSSRule alloc] init];
vdomRule.media = @[];
vdomRule.origin = @"inspector";
vdomRule.selectorList = vdomSelectorData;
vdomRule.style = vdomStyle;
if ([rule WX_JSONObject] && [vdomRule WX_JSONObject]) {
NSDictionary *ruleMatch = @{@"matchingSelectors":@[[NSNumber numberWithInteger:0]],@"rule":[rule WX_JSONObject]};
NSDictionary *vdomRuleMatch = @{@"matchingSelectors":@[[NSNumber numberWithInteger:0]],@"rule":[vdomRule WX_JSONObject]};
NSArray *matchCSSRules = @[ruleMatch, vdomRuleMatch];
callback(matchCSSRules,pseudoElements,inherited,nil);
}else {
callback(nil,pseudoElements,inherited,nil);
}
});
});
} else {
//assembling object of rule
WXDOMNode *rootDomNode = [WXDOMDomainController defaultInstance].rootDomNode;
WXDOMNode *node = [self p_getNodeFromNodeId:nodeId rootNode:rootDomNode];
if (!node) {
rootDomNode = [WXDOMDomainController defaultInstance].rootNode;
node = [self p_getNodeFromNodeId:nodeId rootNode:rootDomNode];
if (!node) {
callback(nil,pseudoElements,inherited,nil);
return;
}
}
WXCSSSelectorListData *selectorData = [[WXCSSSelectorListData alloc] init];
selectorData.text = node.nodeName;
selectorData.selectors = @[@{@"text":node.nodeName}];
//assembling object of cssStyle
WXCSSCSSStyle *style = [[WXCSSCSSStyle alloc] init];
NSMutableArray *cssProperties = [NSMutableArray array];
NSMutableString *cssText = [[NSMutableString alloc] init];
for (int i = 0; i < node.attributes.count; i++) {
if (i & 1) {
if (![node.attributes[i-1] isEqualToString:@"frame"]) {
WXCSSCSSProperty *cssProperty = [[WXCSSCSSProperty alloc] init];
[cssText appendFormat:@"%@;",node.attributes[i]];
cssProperty.name = node.attributes[i-1];
cssProperty.value = node.attributes[i];
[cssProperties addObject:[cssProperty WX_JSONObject]];
}else {
NSArray *names = @[@"width",@"height",@"top",@"left"];
NSArray *position = [self p_formateFrame:node.attributes[i]];
if (position.count == 4) {
NSDictionary *property = @{@"left":position[0],
@"top":position[1],
@"width":position[2],
@"height":position[3]};
for (int i = 0; i < property.count; i++) {
WXCSSCSSProperty *cssProperty = [[WXCSSCSSProperty alloc] init];
cssProperty.name = names[i];
cssProperty.value = property[names[i]];
[cssText appendString:[NSString stringWithFormat:@"%@:%@;",cssProperty.name,cssProperty.value]];
[cssProperties addObject:[cssProperty WX_JSONObject]];
}
}
}
}else {
if (![node.attributes[i] isEqualToString:@"frame"]) {
[cssText appendFormat:@"%@:",node.attributes[i]];
}
}
}
style.shorthandEntries = @[];
style.cssText = cssText;
style.cssProperties = [NSArray arrayWithArray:cssProperties];
WXCSSCSSRule *rule = [[WXCSSCSSRule alloc] init];
rule.media = @[];
rule.origin = @"inspector";
rule.selectorList = selectorData;
rule.style = style;
if ([rule WX_JSONObject]) {
NSDictionary *ruleMatch = @{@"matchingSelectors":@[[NSNumber numberWithInteger:0]],@"rule":[rule WX_JSONObject]};
NSArray *matchCSSRules = @[ruleMatch];
callback(matchCSSRules,pseudoElements,inherited,nil);
}else {
callback(nil,pseudoElements,inherited,nil);
}
}
}
- (void)domain:(WXCSSDomain *)domain getInlineStylesForNodeWithNodeId:(NSNumber *)nodeId callback:(void (^)(WXCSSCSSStyle *inlineStyle, WXCSSCSSStyle *attributesStyle, id error))callback {
WXCSSCSSStyle *inlineStyle = [[WXCSSCSSStyle alloc] init];
inlineStyle.styleSheetId = @"22222.2";
inlineStyle.cssProperties = @[];
inlineStyle.cssText = @"";
inlineStyle.shorthandEntries = @[];
WXCSSSourceRange *range = [[WXCSSSourceRange alloc] init];
range.startLine = [NSNumber numberWithInt:0];
range.endLine = [NSNumber numberWithInt:0];
range.startColumn = [NSNumber numberWithInt:0];
range.endColumn = [NSNumber numberWithInt:0];
inlineStyle.range = range;
callback(inlineStyle,nil,nil);
}
- (void)domain:(WXCSSDomain *)domain getComputedStyleForNodeWithNodeId:(NSNumber *)nodeId callback:(void (^)(NSArray *computedStyle, id error))callback {
/*
WXDOMNode *rootDomNode = [WXDOMDomainController defaultInstance].rootDomNode;
WXDOMNode *node = [self p_getNodeFromNodeId:nodeId rootNode:rootDomNode];
__block NSArray *position;
[node.attributes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isEqualToString:@"frame"]) {
*stop = YES;
position = [self p_formateFrame:node.attributes[idx + 1]];
}
}];
*/
if ([WXDebugger isVDom]) {
UIView *selectedView = [[[WXDOMDomainController defaultInstance] getObjectsForComponentRefs] objectForKey:[NSString stringWithFormat:@"%ld",(long)nodeId.integerValue]];
NSArray *actualAttrs = [[WXDOMDomainController defaultInstance] attributesArrayForObject:selectedView];
__block NSArray *position;
[actualAttrs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isEqualToString:@"frame"]) {
*stop = YES;
position = [self p_formateFrame:actualAttrs[idx + 1]];
}
}];
NSString *width = @"";
NSString *height = @"";
NSString *top = @"";
NSString *left = @"";
if (position.count == 4) {
left = [self _toPixelFromPoint:position[0]];
top = [self _toPixelFromPoint:position[1]];
width = [self _toPixelFromPoint:position[2]];
height = [self _toPixelFromPoint:position[3]];
}
NSMutableArray *computedStyles = [[NSMutableArray alloc] init];
NSArray *layout = @[@{@"name":@"width",@"value":width},
@{@"name":@"height",@"value":height},
@{@"name":@"padding-top",@"value":@"0px"},
@{@"name":@"padding-left",@"value":@"0px"},
@{@"name":@"padding-right",@"value":@"0px"},
@{@"name":@"padding-bottom",@"value":@""},
@{@"name":@"border-top-width",@"value":@""},
@{@"name":@"border-left-width",@"value":@""},
@{@"name":@"border-right-width",@"value":@""},
@{@"name":@"border-bottom-width",@"value":@""},
@{@"name":@"margin-bottom",@"value":@"0px"},
@{@"name":@"margin-left",@"value":@"0px"},
@{@"name":@"margin-right",@"value":@"0px"},
@{@"name":@"margin-top",@"value":@"0px"},
@{@"name":@"top",@"value":top},
@{@"name":@"right",@"value":@"0px"},
@{@"name":@"left",@"value":left},
@{@"name":@"bottom",@"value":@"0px"}];
for (int i = 0; i < layout.count; i++) {
WXCSSCSSComputedStyleProperty *computedStyleProperty = [[WXCSSCSSComputedStyleProperty alloc] init];
computedStyleProperty.name = layout[i][@"name"];
computedStyleProperty.value = layout[i][@"value"];
[computedStyles addObject:[computedStyleProperty WX_JSONObject]];
}
callback(computedStyles,nil);
} else {
WXDOMNode *rootDomNode = [WXDOMDomainController defaultInstance].rootDomNode;
WXDOMNode *node = [self p_getNodeFromNodeId:nodeId rootNode:rootDomNode];
__block NSArray *position;
[node.attributes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isEqualToString:@"frame"]) {
*stop = YES;
position = [self p_formateFrame:node.attributes[idx + 1]];
}
}];
NSString *width = @"";
NSString *height = @"";
NSString *top = @"";
NSString *left = @"";
if (position.count == 4) {
width = position[2];
height = position[3];
top = position[1];
left = position[0];
}
NSMutableArray *computedStyles = [[NSMutableArray alloc] init];
NSArray *layout = @[@{@"name":@"width",@"value":width},
@{@"name":@"height",@"value":height},
@{@"name":@"padding-top",@"value":@"0px"},
@{@"name":@"padding-left",@"value":@"0px"},
@{@"name":@"padding-right",@"value":@"0px"},
@{@"name":@"padding-bottom",@"value":@""},
@{@"name":@"border-top-width",@"value":@""},
@{@"name":@"border-left-width",@"value":@""},
@{@"name":@"border-right-width",@"value":@""},
@{@"name":@"border-bottom-width",@"value":@""},
@{@"name":@"margin-bottom",@"value":@"0px"},
@{@"name":@"margin-left",@"value":@"0px"},
@{@"name":@"margin-right",@"value":@"0px"},
@{@"name":@"margin-top",@"value":@"0px"},
@{@"name":@"top",@"value":top},
@{@"name":@"right",@"value":@"0px"},
@{@"name":@"left",@"value":left},
@{@"name":@"bottom",@"value":@"0px"}];
for (int i = 0; i < layout.count; i++) {
WXCSSCSSComputedStyleProperty *computedStyleProperty = [[WXCSSCSSComputedStyleProperty alloc] init];
computedStyleProperty.name = layout[i][@"name"];
computedStyleProperty.value = layout[i][@"value"];
[computedStyles addObject:[computedStyleProperty WX_JSONObject]];
}
callback(computedStyles,nil);
}
}
- (void)domain:(WXCSSDomain *)domain getSupportedCSSPropertiesWithCallback:(void (^)(NSArray *cssProperties, id error))callback {
WXCSSCSSPropertyInfo *cssPropertyInfo = [[WXCSSCSSPropertyInfo alloc] init];
cssPropertyInfo.name = @"width";
cssPropertyInfo.longhands = @[];
NSArray *cssProperties = @[cssPropertyInfo];
callback(cssProperties,nil);
}
#pragma mark - utility
- (NSString *)_toPixelFromPoint:(NSString *)point
{
return [NSString stringWithFormat:@"%ld",(long)([point floatValue] * 2)];
}
@end