Run CLANGFORMAT on plugins
Summary: This diff runs CLANGFORMAT lint on plugins. I have added CLANGFORMAT as the lint engined for objc files in xplat/sonar. Right now the iOS folder is not formatted according to CLANGFORMAT. Ran `arc lint -a --paths-cmd "find ./iOS/Plugins -type f" --verbose` Reviewed By: passy Differential Revision: D19942173 fbshipit-source-id: 8b975b0a344df073b02d69cd1f9ee5629af2799d
This commit is contained in:
committed by
Facebook Github Bot
parent
a19a430eee
commit
e8b20d5b15
@@ -11,20 +11,21 @@
|
||||
|
||||
#import <FlipperKit/FlipperPlugin.h>
|
||||
|
||||
#import "SKTapListener.h"
|
||||
#import "SKInvalidation.h"
|
||||
#import "SKDescriptorMapper.h"
|
||||
#import "SKInvalidation.h"
|
||||
#import "SKTapListener.h"
|
||||
|
||||
@interface FlipperKitLayoutPlugin : NSObject<FlipperPlugin, SKInvalidationDelegate>
|
||||
@interface FlipperKitLayoutPlugin
|
||||
: NSObject<FlipperPlugin, SKInvalidationDelegate>
|
||||
|
||||
- (instancetype)initWithRootNode:(id<NSObject>)rootNode
|
||||
withDescriptorMapper:(SKDescriptorMapper *)mapper;
|
||||
withDescriptorMapper:(SKDescriptorMapper*)mapper;
|
||||
|
||||
- (instancetype)initWithRootNode:(id<NSObject>)rootNode
|
||||
withTapListener:(id<SKTapListener>)tapListener
|
||||
withDescriptorMapper:(SKDescriptorMapper *)mapper;
|
||||
withDescriptorMapper:(SKDescriptorMapper*)mapper;
|
||||
|
||||
@property (nonatomic, readonly, strong) SKDescriptorMapper *descriptorMapper;
|
||||
@property(nonatomic, readonly, strong) SKDescriptorMapper* descriptorMapper;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -13,21 +13,19 @@
|
||||
#import <FlipperKit/FlipperConnection.h>
|
||||
#import <FlipperKit/FlipperResponder.h>
|
||||
#import <FlipperKit/SKMacros.h>
|
||||
#import <mutex>
|
||||
#import "SKDescriptorMapper.h"
|
||||
#import "SKNodeDescriptor.h"
|
||||
#import "SKSearchResultNode.h"
|
||||
#import "SKTapListener.h"
|
||||
#import "SKTapListenerImpl.h"
|
||||
#import "SKSearchResultNode.h"
|
||||
#import <mutex>
|
||||
|
||||
@implementation FlipperKitLayoutPlugin
|
||||
{
|
||||
|
||||
NSMapTable<NSString *, id> *_trackedObjects;
|
||||
NSString *_lastHighlightedNode;
|
||||
NSMutableSet *_invalidObjects;
|
||||
@implementation FlipperKitLayoutPlugin {
|
||||
NSMapTable<NSString*, id>* _trackedObjects;
|
||||
NSString* _lastHighlightedNode;
|
||||
NSMutableSet* _invalidObjects;
|
||||
Boolean _invalidateMessageQueued;
|
||||
NSDate *_lastInvalidateMessage;
|
||||
NSDate* _lastInvalidateMessage;
|
||||
std::mutex invalidObjectsMutex;
|
||||
|
||||
id<NSObject> _rootNode;
|
||||
@@ -35,19 +33,19 @@
|
||||
|
||||
id<FlipperConnection> _connection;
|
||||
|
||||
NSMutableSet *_registeredDelegates;
|
||||
NSMutableSet* _registeredDelegates;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRootNode:(id<NSObject>)rootNode
|
||||
withDescriptorMapper:(SKDescriptorMapper *)mapper{
|
||||
return [self initWithRootNode: rootNode
|
||||
withTapListener: [SKTapListenerImpl new]
|
||||
withDescriptorMapper: mapper];
|
||||
withDescriptorMapper:(SKDescriptorMapper*)mapper {
|
||||
return [self initWithRootNode:rootNode
|
||||
withTapListener:[SKTapListenerImpl new]
|
||||
withDescriptorMapper:mapper];
|
||||
}
|
||||
|
||||
- (instancetype)initWithRootNode:(id<NSObject>)rootNode
|
||||
withTapListener:(id<SKTapListener>)tapListener
|
||||
withDescriptorMapper:(SKDescriptorMapper *)mapper {
|
||||
withDescriptorMapper:(SKDescriptorMapper*)mapper {
|
||||
if (self = [super init]) {
|
||||
_descriptorMapper = mapper;
|
||||
_trackedObjects = [NSMapTable strongToWeakObjectsMapTable];
|
||||
@@ -65,203 +63,279 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)identifier
|
||||
{
|
||||
- (NSString*)identifier {
|
||||
return @"Inspector";
|
||||
}
|
||||
|
||||
- (void)didConnect:(id<FlipperConnection>)connection {
|
||||
_connection = connection;
|
||||
|
||||
|
||||
if (!_rootNode) {
|
||||
// TODO: T61384369 get rid off this if condition.
|
||||
_rootNode = [UIApplication sharedApplication];
|
||||
}
|
||||
|
||||
|
||||
[SKInvalidation enableInvalidations];
|
||||
|
||||
// Run setup logic for each descriptor
|
||||
for (SKNodeDescriptor *descriptor in _descriptorMapper.allDescriptors) {
|
||||
for (SKNodeDescriptor* descriptor in _descriptorMapper.allDescriptors) {
|
||||
[descriptor setUp];
|
||||
}
|
||||
|
||||
// In order to avoid a retain cycle (Connection -> Block -> FlipperKitLayoutPlugin -> Connection ...)
|
||||
__weak FlipperKitLayoutPlugin *weakSelf = self;
|
||||
// In order to avoid a retain cycle (Connection -> Block ->
|
||||
// FlipperKitLayoutPlugin -> Connection ...)
|
||||
__weak FlipperKitLayoutPlugin* weakSelf = self;
|
||||
|
||||
[connection receive:@"getRoot" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetRoot: responder]; }, responder);
|
||||
}];
|
||||
[connection receive:@"getRoot"
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(
|
||||
^{
|
||||
[weakSelf onCallGetRoot:responder];
|
||||
},
|
||||
responder);
|
||||
}];
|
||||
|
||||
[connection receive:@"getAllNodes" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetAllNodesWithResponder: responder]; }, responder);
|
||||
}];
|
||||
[connection receive:@"getAllNodes"
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(
|
||||
^{
|
||||
[weakSelf onCallGetAllNodesWithResponder:responder];
|
||||
},
|
||||
responder);
|
||||
}];
|
||||
|
||||
[connection receive:@"getNodes" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetNodes: params[@"ids"] withResponder: responder]; }, responder);
|
||||
}];
|
||||
[connection receive:@"getNodes"
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(
|
||||
^{
|
||||
[weakSelf onCallGetNodes:params[@"ids"]
|
||||
withResponder:responder];
|
||||
},
|
||||
responder);
|
||||
}];
|
||||
|
||||
[connection receive:@"setData" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(^{
|
||||
[weakSelf onCallSetData: params[@"id"]
|
||||
withPath: params[@"path"]
|
||||
toValue: params[@"value"]
|
||||
withConnection: connection];
|
||||
}, responder);
|
||||
}];
|
||||
[connection receive:@"setData"
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(
|
||||
^{
|
||||
[weakSelf onCallSetData:params[@"id"]
|
||||
withPath:params[@"path"]
|
||||
toValue:params[@"value"]
|
||||
withConnection:connection];
|
||||
},
|
||||
responder);
|
||||
}];
|
||||
|
||||
[connection receive:@"setHighlighted" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallSetHighlighted: params[@"id"] withResponder: responder]; }, responder);
|
||||
}];
|
||||
[connection receive:@"setHighlighted"
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(
|
||||
^{
|
||||
[weakSelf onCallSetHighlighted:params[@"id"]
|
||||
withResponder:responder];
|
||||
},
|
||||
responder);
|
||||
}];
|
||||
|
||||
[connection receive:@"setSearchActive" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallSetSearchActive: [params[@"active"] boolValue] withConnection: connection]; }, responder);
|
||||
}];
|
||||
[connection receive:@"setSearchActive"
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(
|
||||
^{
|
||||
[weakSelf
|
||||
onCallSetSearchActive:[params[@"active"] boolValue]
|
||||
withConnection:connection];
|
||||
},
|
||||
responder);
|
||||
}];
|
||||
|
||||
[connection receive:@"isSearchActive" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallIsSearchActiveWithConnection: responder]; }, responder);
|
||||
}];
|
||||
[connection receive:@"isSearchActive"
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(
|
||||
^{
|
||||
[weakSelf onCallIsSearchActiveWithConnection:responder];
|
||||
},
|
||||
responder);
|
||||
}];
|
||||
|
||||
[connection receive:@"isConsoleEnabled" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(^{ [responder success: @{@"isEnabled": @NO}];}, responder);
|
||||
}];
|
||||
[connection receive:@"isConsoleEnabled"
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(
|
||||
^{
|
||||
[responder success:@{@"isEnabled" : @NO}];
|
||||
},
|
||||
responder);
|
||||
}];
|
||||
|
||||
[connection receive:@"getSearchResults" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetSearchResults: params[@"query"] withResponder: responder]; }, responder);
|
||||
}];
|
||||
[connection receive:@"getSearchResults"
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
||||
FlipperPerformBlockOnMainThread(
|
||||
^{
|
||||
[weakSelf onCallGetSearchResults:params[@"query"]
|
||||
withResponder:responder];
|
||||
},
|
||||
responder);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)didDisconnect {
|
||||
// Clear the last highlight if there is any
|
||||
[self onCallSetHighlighted: nil withResponder: nil];
|
||||
[self onCallSetHighlighted:nil withResponder:nil];
|
||||
// Disable search if it is active
|
||||
[self onCallSetSearchActive: NO withConnection: nil];
|
||||
[self onCallSetSearchActive:NO withConnection:nil];
|
||||
}
|
||||
|
||||
- (void)onCallGetRoot:(id<FlipperResponder>)responder {
|
||||
const auto rootNode= [self getNode: [self trackObject: _rootNode]];
|
||||
const auto rootNode = [self getNode:[self trackObject:_rootNode]];
|
||||
|
||||
[responder success: rootNode];
|
||||
[responder success:rootNode];
|
||||
}
|
||||
|
||||
- (void)populateAllNodesFromNode:(nonnull NSString *)identifier inDictionary:(nonnull NSMutableDictionary<NSString*, NSDictionary*> *)mutableDict {
|
||||
NSDictionary *nodeDict = [self getNode:identifier];
|
||||
- (void)populateAllNodesFromNode:(nonnull NSString*)identifier
|
||||
inDictionary:
|
||||
(nonnull NSMutableDictionary<NSString*, NSDictionary*>*)
|
||||
mutableDict {
|
||||
NSDictionary* nodeDict = [self getNode:identifier];
|
||||
mutableDict[identifier] = nodeDict;
|
||||
NSArray *arr = nodeDict[@"children"];
|
||||
for (NSString *childIdentifier in arr) {
|
||||
NSArray* arr = nodeDict[@"children"];
|
||||
for (NSString* childIdentifier in arr) {
|
||||
[self populateAllNodesFromNode:childIdentifier inDictionary:mutableDict];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
- (void)populateAllNodesFromNode:(nonnull NSString *)identifier inArray:(nonnull NSMutableArray<NSDictionary *> *)mutableArray {
|
||||
NSDictionary *nodeDict = [self getNode:identifier];
|
||||
- (void)populateAllNodesFromNode:(nonnull NSString*)identifier
|
||||
inArray:(nonnull NSMutableArray<NSDictionary*>*)
|
||||
mutableArray {
|
||||
NSDictionary* nodeDict = [self getNode:identifier];
|
||||
if (nodeDict == nil) {
|
||||
return;
|
||||
}
|
||||
[mutableArray addObject:nodeDict];
|
||||
NSArray *children = nodeDict[@"children"];
|
||||
for (NSString *childIdentifier in children) {
|
||||
NSArray* children = nodeDict[@"children"];
|
||||
for (NSString* childIdentifier in children) {
|
||||
[self populateAllNodesFromNode:childIdentifier inArray:mutableArray];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onCallGetAllNodesWithResponder:(nonnull id<FlipperResponder>)responder {
|
||||
NSMutableArray<NSDictionary*> *allNodes = @[].mutableCopy;
|
||||
NSString *identifier = [self trackObject: _rootNode];
|
||||
NSDictionary *rootNode = [self getNode: identifier];
|
||||
NSMutableArray<NSDictionary*>* allNodes = @[].mutableCopy;
|
||||
NSString* identifier = [self trackObject:_rootNode];
|
||||
NSDictionary* rootNode = [self getNode:identifier];
|
||||
if (!rootNode) {
|
||||
return [responder error:@{@"error": [NSString stringWithFormat:@"getNode returned nil for the rootNode %@, while getting all the nodes", identifier]}];
|
||||
return [responder error:@{
|
||||
@"error" : [NSString
|
||||
stringWithFormat:
|
||||
@"getNode returned nil for the rootNode %@, while getting all the nodes",
|
||||
identifier]
|
||||
}];
|
||||
}
|
||||
[allNodes addObject:rootNode];
|
||||
NSMutableDictionary *allNodesDict = @{}.mutableCopy;
|
||||
NSMutableDictionary* allNodesDict = @{}.mutableCopy;
|
||||
[self populateAllNodesFromNode:identifier inDictionary:allNodesDict];
|
||||
[responder success:@{@"allNodes": @{@"rootElement": identifier, @"elements": allNodesDict}}];
|
||||
[responder success:@{
|
||||
@"allNodes" : @{@"rootElement" : identifier, @"elements" : allNodesDict}
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSMutableArray*)getChildrenForNode:(id)node withDescriptor:(SKNodeDescriptor*)descriptor {
|
||||
NSMutableArray *children = [NSMutableArray new];
|
||||
for (NSUInteger i = 0; i < [descriptor childCountForNode: node]; i++) {
|
||||
id childNode = [descriptor childForNode: node atIndex: i];
|
||||
- (NSMutableArray*)getChildrenForNode:(id)node
|
||||
withDescriptor:(SKNodeDescriptor*)descriptor {
|
||||
NSMutableArray* children = [NSMutableArray new];
|
||||
for (NSUInteger i = 0; i < [descriptor childCountForNode:node]; i++) {
|
||||
id childNode = [descriptor childForNode:node atIndex:i];
|
||||
|
||||
NSString *childIdentifier = [self trackObject: childNode];
|
||||
NSString* childIdentifier = [self trackObject:childNode];
|
||||
if (childIdentifier) {
|
||||
[children addObject: childIdentifier];
|
||||
[children addObject:childIdentifier];
|
||||
}
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
- (void)onCallGetNodes:(NSArray<NSDictionary *> *)nodeIds withResponder:(id<FlipperResponder>)responder {
|
||||
NSMutableArray<NSDictionary *> *elements = [NSMutableArray new];
|
||||
- (void)onCallGetNodes:(NSArray<NSDictionary*>*)nodeIds
|
||||
withResponder:(id<FlipperResponder>)responder {
|
||||
NSMutableArray<NSDictionary*>* elements = [NSMutableArray new];
|
||||
|
||||
for (id nodeId in nodeIds) {
|
||||
const auto node = [self getNode: nodeId];
|
||||
const auto node = [self getNode:nodeId];
|
||||
if (node == nil) {
|
||||
continue;
|
||||
}
|
||||
[elements addObject: node];
|
||||
[elements addObject:node];
|
||||
}
|
||||
|
||||
[responder success: @{ @"elements": elements }];
|
||||
[responder success:@{@"elements" : elements}];
|
||||
}
|
||||
|
||||
- (void)onCallSetData:(NSString *)objectId
|
||||
withPath:(NSArray<NSString *> *)path
|
||||
- (void)onCallSetData:(NSString*)objectId
|
||||
withPath:(NSArray<NSString*>*)path
|
||||
toValue:(id<NSObject>)value
|
||||
withConnection:(id<FlipperConnection>)connection {
|
||||
id node = [_trackedObjects objectForKey: objectId];
|
||||
id node = [_trackedObjects objectForKey:objectId];
|
||||
if (node == nil) {
|
||||
SKLog(@"node is nil, trying to setData: \
|
||||
objectId: %@ \
|
||||
path: %@ \
|
||||
value: %@",
|
||||
objectId, path, value);
|
||||
value: %@", objectId, path, value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sonar sends nil/NSNull on some values when the text-field
|
||||
// is empty, disregard these changes otherwise we'll crash.
|
||||
if (value == nil || [value isKindOfClass: [NSNull class]]) {
|
||||
if (value == nil || [value isKindOfClass:[NSNull class]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [node class]];
|
||||
SKNodeDescriptor* descriptor =
|
||||
[_descriptorMapper descriptorForClass:[node class]];
|
||||
|
||||
NSString *dotJoinedPath = [path componentsJoinedByString: @"."];
|
||||
SKNodeUpdateData updateDataForPath = [[descriptor dataMutationsForNode: node] objectForKey: dotJoinedPath];
|
||||
NSString* dotJoinedPath = [path componentsJoinedByString:@"."];
|
||||
SKNodeUpdateData updateDataForPath =
|
||||
[[descriptor dataMutationsForNode:node] objectForKey:dotJoinedPath];
|
||||
if (updateDataForPath != nil) {
|
||||
const auto identifierForInvalidation = [descriptor identifierForInvalidation:node];
|
||||
id nodeForInvalidation = [_trackedObjects objectForKey:identifierForInvalidation];
|
||||
SKNodeDescriptor *descriptorForInvalidation = [_descriptorMapper descriptorForClass:[nodeForInvalidation class]];
|
||||
const auto identifierForInvalidation =
|
||||
[descriptor identifierForInvalidation:node];
|
||||
id nodeForInvalidation =
|
||||
[_trackedObjects objectForKey:identifierForInvalidation];
|
||||
SKNodeDescriptor* descriptorForInvalidation =
|
||||
[_descriptorMapper descriptorForClass:[nodeForInvalidation class]];
|
||||
updateDataForPath(value);
|
||||
|
||||
NSMutableArray *nodesForInvalidation = [NSMutableArray new];
|
||||
[self populateAllNodesFromNode:[descriptorForInvalidation identifierForNode:nodeForInvalidation] inArray:nodesForInvalidation];
|
||||
[connection send: @"invalidateWithData" withParams: @{@"nodes": nodesForInvalidation}];
|
||||
|
||||
NSMutableArray* nodesForInvalidation = [NSMutableArray new];
|
||||
[self populateAllNodesFromNode:[descriptorForInvalidation
|
||||
identifierForNode:nodeForInvalidation]
|
||||
inArray:nodesForInvalidation];
|
||||
[connection send:@"invalidateWithData"
|
||||
withParams:@{@"nodes" : nodesForInvalidation}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onCallGetSearchResults:(NSString *)query withResponder:(id<FlipperResponder>)responder {
|
||||
const auto alreadyAddedElements = [NSMutableSet<NSString *> new];
|
||||
SKSearchResultNode *matchTree = [self searchForQuery:(NSString *)[query lowercaseString] fromNode:(id)_rootNode withElementsAlreadyAdded: alreadyAddedElements];
|
||||
- (void)onCallGetSearchResults:(NSString*)query
|
||||
withResponder:(id<FlipperResponder>)responder {
|
||||
const auto alreadyAddedElements = [NSMutableSet<NSString*> new];
|
||||
SKSearchResultNode* matchTree =
|
||||
[self searchForQuery:(NSString*)[query lowercaseString]
|
||||
fromNode:(id)_rootNode
|
||||
withElementsAlreadyAdded:alreadyAddedElements];
|
||||
|
||||
[responder success: @{
|
||||
@"results": [matchTree toNSDictionary] ?: [NSNull null],
|
||||
@"query": query
|
||||
}];
|
||||
[responder success:@{
|
||||
@"results" : [matchTree toNSDictionary] ?: [NSNull null],
|
||||
@"query" : query
|
||||
}];
|
||||
return;
|
||||
}
|
||||
|
||||
- (void)onCallSetHighlighted:(NSString *)objectId withResponder:(id<FlipperResponder>)responder {
|
||||
- (void)onCallSetHighlighted:(NSString*)objectId
|
||||
withResponder:(id<FlipperResponder>)responder {
|
||||
if (_lastHighlightedNode != nil) {
|
||||
id lastHighlightedObject = [_trackedObjects objectForKey: _lastHighlightedNode];
|
||||
id lastHighlightedObject =
|
||||
[_trackedObjects objectForKey:_lastHighlightedNode];
|
||||
if (lastHighlightedObject == nil) {
|
||||
[responder error: @{ @"error": @"unable to get last highlighted object" }];
|
||||
[responder error:@{@"error" : @"unable to get last highlighted object"}];
|
||||
return;
|
||||
}
|
||||
|
||||
SKNodeDescriptor *descriptor = [self->_descriptorMapper descriptorForClass: [lastHighlightedObject class]];
|
||||
[descriptor setHighlighted: NO forNode: lastHighlightedObject];
|
||||
SKNodeDescriptor* descriptor = [self->_descriptorMapper
|
||||
descriptorForClass:[lastHighlightedObject class]];
|
||||
[descriptor setHighlighted:NO forNode:lastHighlightedObject];
|
||||
|
||||
_lastHighlightedNode = nil;
|
||||
}
|
||||
@@ -270,35 +344,37 @@
|
||||
return;
|
||||
}
|
||||
|
||||
id object = [_trackedObjects objectForKey: objectId];
|
||||
id object = [_trackedObjects objectForKey:objectId];
|
||||
if (object == nil) {
|
||||
SKLog(@"tried to setHighlighted for untracked id, objectId: %@", objectId);
|
||||
return;
|
||||
}
|
||||
|
||||
SKNodeDescriptor *descriptor = [self->_descriptorMapper descriptorForClass: [object class]];
|
||||
[descriptor setHighlighted: YES forNode: object];
|
||||
SKNodeDescriptor* descriptor =
|
||||
[self->_descriptorMapper descriptorForClass:[object class]];
|
||||
[descriptor setHighlighted:YES forNode:object];
|
||||
|
||||
_lastHighlightedNode = objectId;
|
||||
}
|
||||
|
||||
- (void)onCallSetSearchActive:(BOOL)active withConnection:(id<FlipperConnection>)connection {
|
||||
- (void)onCallSetSearchActive:(BOOL)active
|
||||
withConnection:(id<FlipperConnection>)connection {
|
||||
if (active) {
|
||||
[_tapListener mountWithFrame: [[UIScreen mainScreen] bounds]];
|
||||
[_tapListener mountWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
__block id<NSObject> rootNode = _rootNode;
|
||||
|
||||
[_tapListener listenForTapWithBlock:^(CGPoint touchPoint) {
|
||||
SKTouch *touch =
|
||||
[[SKTouch alloc] initWithTouchPoint: touchPoint
|
||||
withRootNode: rootNode
|
||||
withDescriptorMapper: self->_descriptorMapper
|
||||
finishWithBlock:^(NSArray<NSString *> *path) {
|
||||
[connection send: @"select"
|
||||
withParams: @{ @"path": path }];
|
||||
}];
|
||||
SKTouch* touch = [[SKTouch alloc]
|
||||
initWithTouchPoint:touchPoint
|
||||
withRootNode:rootNode
|
||||
withDescriptorMapper:self->_descriptorMapper
|
||||
finishWithBlock:^(NSArray<NSString*>* path) {
|
||||
[connection send:@"select" withParams:@{@"path" : path}];
|
||||
}];
|
||||
|
||||
SKNodeDescriptor *descriptor = [self->_descriptorMapper descriptorForClass: [rootNode class]];
|
||||
[descriptor hitTest: touch forNode: rootNode];
|
||||
SKNodeDescriptor* descriptor =
|
||||
[self->_descriptorMapper descriptorForClass:[rootNode class]];
|
||||
[descriptor hitTest:touch forNode:rootNode];
|
||||
}];
|
||||
} else {
|
||||
[_tapListener unmount];
|
||||
@@ -306,20 +382,21 @@
|
||||
}
|
||||
|
||||
- (void)onCallIsSearchActiveWithConnection:(id<FlipperResponder>)responder {
|
||||
[responder success: @{ @"isSearchActive": @NO }];
|
||||
[responder success:@{@"isSearchActive" : @NO}];
|
||||
}
|
||||
|
||||
- (void)invalidateNode:(id<NSObject>)node {
|
||||
SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [node class]];
|
||||
SKNodeDescriptor* descriptor =
|
||||
[_descriptorMapper descriptorForClass:[node class]];
|
||||
if (descriptor == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *nodeId = [descriptor identifierForNode: node];
|
||||
if (![_trackedObjects objectForKey: nodeId]) {
|
||||
NSString* nodeId = [descriptor identifierForNode:node];
|
||||
if (![_trackedObjects objectForKey:nodeId]) {
|
||||
return;
|
||||
}
|
||||
[descriptor invalidateNode: node];
|
||||
[descriptor invalidateNode:node];
|
||||
|
||||
// Collect invalidate messages before sending in a batch
|
||||
std::lock_guard<std::mutex> lock(invalidObjectsMutex);
|
||||
@@ -330,19 +407,24 @@
|
||||
_invalidateMessageQueued = true;
|
||||
|
||||
if (_lastInvalidateMessage.timeIntervalSinceNow < -1) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 500 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
|
||||
[self reportInvalidatedObjects];
|
||||
});
|
||||
dispatch_after(
|
||||
dispatch_time(DISPATCH_TIME_NOW, 500 * NSEC_PER_MSEC),
|
||||
dispatch_get_main_queue(),
|
||||
^{
|
||||
[self reportInvalidatedObjects];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reportInvalidatedObjects {
|
||||
std::lock_guard<std::mutex> lock(invalidObjectsMutex);
|
||||
NSMutableArray *nodes = [NSMutableArray new];
|
||||
for (NSString *nodeId in self->_invalidObjects) {
|
||||
[nodes addObject: [NSDictionary dictionaryWithObject: nodeId forKey: @"id"]];
|
||||
NSMutableArray* nodes = [NSMutableArray new];
|
||||
for (NSString* nodeId in self->_invalidObjects) {
|
||||
[nodes addObject:[NSDictionary dictionaryWithObject:nodeId forKey:@"id"]];
|
||||
}
|
||||
[self->_connection send: @"invalidate" withParams: [NSDictionary dictionaryWithObject: nodes forKey: @"nodes"]];
|
||||
[self->_connection send:@"invalidate"
|
||||
withParams:[NSDictionary dictionaryWithObject:nodes
|
||||
forKey:@"nodes"]];
|
||||
self->_lastInvalidateMessage = [NSDate date];
|
||||
self->_invalidObjects = [NSMutableSet new];
|
||||
self->_invalidateMessageQueued = false;
|
||||
@@ -350,116 +432,125 @@
|
||||
}
|
||||
|
||||
- (void)updateNodeReference:(id<NSObject>)node {
|
||||
SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [node class]];
|
||||
SKNodeDescriptor* descriptor =
|
||||
[_descriptorMapper descriptorForClass:[node class]];
|
||||
if (descriptor == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *nodeId = [descriptor identifierForNode: node];
|
||||
NSString* nodeId = [descriptor identifierForNode:node];
|
||||
[_trackedObjects setObject:node forKey:nodeId];
|
||||
}
|
||||
|
||||
- (SKSearchResultNode *)searchForQuery:(NSString *)query fromNode:(id)node withElementsAlreadyAdded:(NSMutableSet<NSString *> *)alreadyAdded {
|
||||
SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [node class]];
|
||||
- (SKSearchResultNode*)searchForQuery:(NSString*)query
|
||||
fromNode:(id)node
|
||||
withElementsAlreadyAdded:(NSMutableSet<NSString*>*)alreadyAdded {
|
||||
SKNodeDescriptor* descriptor =
|
||||
[_descriptorMapper descriptorForClass:[node class]];
|
||||
if (node == nil || descriptor == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableArray<SKSearchResultNode *> *childTrees = nil;
|
||||
BOOL isMatch = [descriptor matchesQuery: query forNode: node];
|
||||
NSMutableArray<SKSearchResultNode*>* childTrees = nil;
|
||||
BOOL isMatch = [descriptor matchesQuery:query forNode:node];
|
||||
|
||||
NSString *nodeId = [self trackObject: node];
|
||||
NSString* nodeId = [self trackObject:node];
|
||||
|
||||
for (auto i = 0; i < [descriptor childCountForNode: node]; i++) {
|
||||
id child = [descriptor childForNode: node atIndex: i];
|
||||
for (auto i = 0; i < [descriptor childCountForNode:node]; i++) {
|
||||
id child = [descriptor childForNode:node atIndex:i];
|
||||
if (child) {
|
||||
SKSearchResultNode *childTree = [self searchForQuery: query fromNode: child withElementsAlreadyAdded:alreadyAdded];
|
||||
SKSearchResultNode* childTree = [self searchForQuery:query
|
||||
fromNode:child
|
||||
withElementsAlreadyAdded:alreadyAdded];
|
||||
if (childTree != nil) {
|
||||
if (childTrees == nil) {
|
||||
childTrees = [NSMutableArray new];
|
||||
}
|
||||
[childTrees addObject: childTree];
|
||||
[childTrees addObject:childTree];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isMatch || childTrees != nil) {
|
||||
|
||||
NSDictionary *element = [self getNode: nodeId];
|
||||
NSDictionary* element = [self getNode:nodeId];
|
||||
if (nodeId == nil || element == nil) {
|
||||
return nil;
|
||||
}
|
||||
NSMutableArray<NSString *> *descriptorChildElements = [element objectForKey: @"children"];
|
||||
NSMutableDictionary *newElement = [element mutableCopy];
|
||||
NSMutableArray<NSString*>* descriptorChildElements =
|
||||
[element objectForKey:@"children"];
|
||||
NSMutableDictionary* newElement = [element mutableCopy];
|
||||
|
||||
NSMutableArray<NSString *> *childElementsToReturn = [NSMutableArray new];
|
||||
for (NSString *child in descriptorChildElements) {
|
||||
if (![alreadyAdded containsObject: child]) {
|
||||
[alreadyAdded addObject: child]; //todo add all at end
|
||||
[childElementsToReturn addObject: child];
|
||||
NSMutableArray<NSString*>* childElementsToReturn = [NSMutableArray new];
|
||||
for (NSString* child in descriptorChildElements) {
|
||||
if (![alreadyAdded containsObject:child]) {
|
||||
[alreadyAdded addObject:child]; // todo add all at end
|
||||
[childElementsToReturn addObject:child];
|
||||
}
|
||||
}
|
||||
[newElement setObject: childElementsToReturn forKey: @"children"];
|
||||
return [[SKSearchResultNode alloc] initWithNode: nodeId
|
||||
asMatch: isMatch
|
||||
withElement: newElement
|
||||
andChildren: childTrees];
|
||||
[newElement setObject:childElementsToReturn forKey:@"children"];
|
||||
return [[SKSearchResultNode alloc] initWithNode:nodeId
|
||||
asMatch:isMatch
|
||||
withElement:newElement
|
||||
andChildren:childTrees];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSDictionary *)getNode:(NSString *)nodeId {
|
||||
id<NSObject> node = [_trackedObjects objectForKey: nodeId];
|
||||
- (NSDictionary*)getNode:(NSString*)nodeId {
|
||||
id<NSObject> node = [_trackedObjects objectForKey:nodeId];
|
||||
if (node == nil) {
|
||||
SKLog(@"node is nil, no tracked node found for nodeId: %@", nodeId);
|
||||
return nil;
|
||||
}
|
||||
|
||||
SKNodeDescriptor *nodeDescriptor = [_descriptorMapper descriptorForClass: [node class]];
|
||||
SKNodeDescriptor* nodeDescriptor =
|
||||
[_descriptorMapper descriptorForClass:[node class]];
|
||||
if (nodeDescriptor == nil) {
|
||||
SKLog(@"No registered descriptor for class: %@", [node class]);
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableArray *attributes = [NSMutableArray new];
|
||||
NSMutableDictionary *data = [NSMutableDictionary new];
|
||||
NSMutableArray* attributes = [NSMutableArray new];
|
||||
NSMutableDictionary* data = [NSMutableDictionary new];
|
||||
|
||||
const auto *nodeAttributes = [nodeDescriptor attributesForNode: node];
|
||||
for (const SKNamed<NSString *> *namedPair in nodeAttributes) {
|
||||
const auto* nodeAttributes = [nodeDescriptor attributesForNode:node];
|
||||
for (const SKNamed<NSString*>* namedPair in nodeAttributes) {
|
||||
const auto name = namedPair.name;
|
||||
if (name) {
|
||||
const NSDictionary *attribute = @{
|
||||
@"name": name,
|
||||
@"value": namedPair.value ?: [NSNull null],
|
||||
};
|
||||
[attributes addObject: attribute];
|
||||
const NSDictionary* attribute = @{
|
||||
@"name" : name,
|
||||
@"value" : namedPair.value ?: [NSNull null],
|
||||
};
|
||||
[attributes addObject:attribute];
|
||||
}
|
||||
}
|
||||
|
||||
const auto *nodeData = [nodeDescriptor dataForNode: node];
|
||||
for (const SKNamed<NSDictionary *> *namedPair in nodeData) {
|
||||
const auto* nodeData = [nodeDescriptor dataForNode:node];
|
||||
for (const SKNamed<NSDictionary*>* namedPair in nodeData) {
|
||||
data[namedPair.name] = namedPair.value;
|
||||
}
|
||||
|
||||
NSMutableArray *children = [self getChildrenForNode: node withDescriptor:nodeDescriptor];
|
||||
NSMutableArray* children = [self getChildrenForNode:node
|
||||
withDescriptor:nodeDescriptor];
|
||||
|
||||
NSDictionary *nodeDic =
|
||||
@{
|
||||
// We shouldn't get nil for id/name/decoration, but let's not crash if we do.
|
||||
@"id": [nodeDescriptor identifierForNode: node] ?: @"(unknown)",
|
||||
@"name": [nodeDescriptor nameForNode: node] ?: @"(unknown)",
|
||||
@"children": children,
|
||||
@"attributes": attributes,
|
||||
@"data": data,
|
||||
@"decoration": [nodeDescriptor decorationForNode: node] ?: @"(unknown)",
|
||||
};
|
||||
NSDictionary* nodeDic = @{
|
||||
// We shouldn't get nil for id/name/decoration, but let's not crash if we
|
||||
// do.
|
||||
@"id" : [nodeDescriptor identifierForNode:node] ?: @"(unknown)",
|
||||
@"name" : [nodeDescriptor nameForNode:node] ?: @"(unknown)",
|
||||
@"children" : children,
|
||||
@"attributes" : attributes,
|
||||
@"data" : data,
|
||||
@"decoration" : [nodeDescriptor decorationForNode:node] ?: @"(unknown)",
|
||||
};
|
||||
|
||||
return nodeDic;
|
||||
}
|
||||
|
||||
- (NSString *)trackObject:(id)object {
|
||||
const SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [object class]];
|
||||
NSString *objectIdentifier = [descriptor identifierForNode: object];
|
||||
- (NSString*)trackObject:(id)object {
|
||||
const SKNodeDescriptor* descriptor =
|
||||
[_descriptorMapper descriptorForClass:[object class]];
|
||||
NSString* objectIdentifier = [descriptor identifierForNode:object];
|
||||
|
||||
if (objectIdentifier == nil) {
|
||||
return nil;
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
- (instancetype)initWithDefaults;
|
||||
|
||||
- (SKNodeDescriptor *)descriptorForClass:(Class)cls;
|
||||
- (SKNodeDescriptor*)descriptorForClass:(Class)cls;
|
||||
|
||||
- (void)registerDescriptor:(SKNodeDescriptor *)descriptor forClass:(Class)cls;
|
||||
- (void)registerDescriptor:(SKNodeDescriptor*)descriptor forClass:(Class)cls;
|
||||
|
||||
- (NSArray<SKNodeDescriptor *> *)allDescriptors;
|
||||
- (NSArray<SKNodeDescriptor*>*)allDescriptors;
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,47 +15,51 @@
|
||||
#import "SKViewControllerDescriptor.h"
|
||||
#import "SKViewDescriptor.h"
|
||||
|
||||
@implementation SKDescriptorMapper
|
||||
{
|
||||
NSMutableDictionary<NSString *, SKNodeDescriptor *> *_descriptors;
|
||||
@implementation SKDescriptorMapper {
|
||||
NSMutableDictionary<NSString*, SKNodeDescriptor*>* _descriptors;
|
||||
}
|
||||
|
||||
- (instancetype)initWithDefaults {
|
||||
if (self = [super init]) {
|
||||
_descriptors = [NSMutableDictionary new];
|
||||
|
||||
[self registerDescriptor: [[SKApplicationDescriptor alloc] initWithDescriptorMapper: self]
|
||||
forClass: [UIApplication class]];
|
||||
[self registerDescriptor: [[SKViewControllerDescriptor alloc] initWithDescriptorMapper: self]
|
||||
forClass: [UIViewController class]];
|
||||
[self registerDescriptor: [[SKScrollViewDescriptor alloc] initWithDescriptorMapper: self]
|
||||
forClass: [UIScrollView class]];
|
||||
[self registerDescriptor: [[SKButtonDescriptor alloc] initWithDescriptorMapper: self]
|
||||
forClass: [UIButton class]];
|
||||
[self registerDescriptor: [[SKViewDescriptor alloc] initWithDescriptorMapper: self]
|
||||
forClass: [UIView class]];
|
||||
[self registerDescriptor:[[SKApplicationDescriptor alloc]
|
||||
initWithDescriptorMapper:self]
|
||||
forClass:[UIApplication class]];
|
||||
[self registerDescriptor:[[SKViewControllerDescriptor alloc]
|
||||
initWithDescriptorMapper:self]
|
||||
forClass:[UIViewController class]];
|
||||
[self registerDescriptor:[[SKScrollViewDescriptor alloc]
|
||||
initWithDescriptorMapper:self]
|
||||
forClass:[UIScrollView class]];
|
||||
[self registerDescriptor:[[SKButtonDescriptor alloc]
|
||||
initWithDescriptorMapper:self]
|
||||
forClass:[UIButton class]];
|
||||
[self registerDescriptor:[[SKViewDescriptor alloc]
|
||||
initWithDescriptorMapper:self]
|
||||
forClass:[UIView class]];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (SKNodeDescriptor *)descriptorForClass:(Class)cls {
|
||||
SKNodeDescriptor *classDescriptor = nil;
|
||||
- (SKNodeDescriptor*)descriptorForClass:(Class)cls {
|
||||
SKNodeDescriptor* classDescriptor = nil;
|
||||
|
||||
while (classDescriptor == nil && cls != nil) {
|
||||
classDescriptor = [_descriptors objectForKey: NSStringFromClass(cls)];
|
||||
classDescriptor = [_descriptors objectForKey:NSStringFromClass(cls)];
|
||||
cls = [cls superclass];
|
||||
}
|
||||
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
- (void)registerDescriptor:(SKNodeDescriptor *)descriptor forClass:(Class)cls {
|
||||
NSString *className = NSStringFromClass(cls);
|
||||
- (void)registerDescriptor:(SKNodeDescriptor*)descriptor forClass:(Class)cls {
|
||||
NSString* className = NSStringFromClass(cls);
|
||||
_descriptors[className] = descriptor;
|
||||
}
|
||||
|
||||
- (NSArray<SKNodeDescriptor *> *)allDescriptors {
|
||||
- (NSArray<SKNodeDescriptor*>*)allDescriptors {
|
||||
return [_descriptors allValues];
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,6 @@
|
||||
|
||||
+ (void)enableInvalidations;
|
||||
|
||||
@property (nonatomic, weak) id<SKInvalidationDelegate> delegate;
|
||||
@property(nonatomic, weak) id<SKInvalidationDelegate> delegate;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "SKInvalidation.h"
|
||||
#import "UIView+SKInvalidation.h"
|
||||
#import "UICollectionView+SKInvalidation.h"
|
||||
#import "UIView+SKInvalidation.h"
|
||||
|
||||
@implementation SKInvalidation
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static SKInvalidation *sInstance = nil;
|
||||
static SKInvalidation* sInstance = nil;
|
||||
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
@@ -32,24 +32,28 @@
|
||||
[UIView enableInvalidation];
|
||||
[UICollectionView enableInvalidations];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(windowDidBecomeVisible:)
|
||||
name:UIWindowDidBecomeVisibleNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(windowDidBecomeVisible:)
|
||||
name:UIWindowDidBecomeVisibleNotification
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(windowDidBecomeHidden:)
|
||||
name:UIWindowDidBecomeHiddenNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(windowDidBecomeHidden:)
|
||||
name:UIWindowDidBecomeHiddenNotification
|
||||
object:nil];
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)windowDidBecomeVisible:(NSNotification*)notification {
|
||||
[[SKInvalidation sharedInstance].delegate invalidateNode:[notification.object nextResponder]];
|
||||
[[SKInvalidation sharedInstance].delegate
|
||||
invalidateNode:[notification.object nextResponder]];
|
||||
}
|
||||
|
||||
+ (void)windowDidBecomeHidden:(NSNotification*)notification {
|
||||
[[SKInvalidation sharedInstance].delegate invalidateNode:[notification.object nextResponder]];
|
||||
[[SKInvalidation sharedInstance].delegate
|
||||
invalidateNode:[notification.object nextResponder]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
@interface SKNamed<__covariant T> : NSObject
|
||||
|
||||
+ (instancetype)newWithName:(NSString *)name withValue:(T)value;
|
||||
+ (instancetype)newWithName:(NSString*)name withValue:(T)value;
|
||||
|
||||
@property (nonatomic, readonly) NSString *name;
|
||||
@property (nonatomic, readonly) T value;
|
||||
@property(nonatomic, readonly) NSString* name;
|
||||
@property(nonatomic, readonly) T value;
|
||||
|
||||
@end
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
@implementation SKNamed
|
||||
|
||||
+ (instancetype)newWithName:(NSString *)name withValue:(id)value {
|
||||
return [[SKNamed alloc] initWithName: name withValue: value];
|
||||
+ (instancetype)newWithName:(NSString*)name withValue:(id)value {
|
||||
return [[SKNamed alloc] initWithName:name withValue:value];
|
||||
}
|
||||
|
||||
- (instancetype)initWithName:(NSString *)name withValue:(id)value {
|
||||
- (instancetype)initWithName:(NSString*)name withValue:(id)value {
|
||||
if (self = [super init]) {
|
||||
_name = name;
|
||||
_value = value;
|
||||
@@ -24,7 +24,7 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
- (NSString*)description {
|
||||
return [NSString stringWithFormat:@"%@: %@", _name, _value];
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ typedef void (^SKNodeUpdateData)(id value);
|
||||
|
||||
/**
|
||||
A SKNodeDescriptor is an object which know how to expose an Object of type T
|
||||
to SonarKitLayoutPlugin. This class is the extension point for SonarKitLayoutPlugin and
|
||||
is how custom objects or data can be exposed to Sonar.
|
||||
to SonarKitLayoutPlugin. This class is the extension point for
|
||||
SonarKitLayoutPlugin and is how custom objects or data can be exposed to Sonar.
|
||||
*/
|
||||
@interface SKNodeDescriptor<__covariant T> : NSObject
|
||||
|
||||
@@ -27,34 +27,35 @@ typedef void (^SKNodeUpdateData)(id value);
|
||||
- (void)setUp;
|
||||
|
||||
/**
|
||||
Initializes the node-descriptor with a SKDescriptorMapper which contains mappings
|
||||
between Class -> SKNodeDescriptor<Class>.
|
||||
Initializes the node-descriptor with a SKDescriptorMapper which contains
|
||||
mappings between Class -> SKNodeDescriptor<Class>.
|
||||
*/
|
||||
- (instancetype)initWithDescriptorMapper:(SKDescriptorMapper *)mapper;
|
||||
- (instancetype)initWithDescriptorMapper:(SKDescriptorMapper*)mapper;
|
||||
|
||||
/**
|
||||
Gets the node-descriptor registered for a specific class.
|
||||
*/
|
||||
- (SKNodeDescriptor *)descriptorForClass:(Class)cls;
|
||||
- (SKNodeDescriptor*)descriptorForClass:(Class)cls;
|
||||
|
||||
/**
|
||||
A globally unique ID used to identify a node in the hierarchy. This is used
|
||||
in the communication between SonarKitLayoutPlugin and the Sonar desktop application
|
||||
in order to identify nodes.
|
||||
in the communication between SonarKitLayoutPlugin and the Sonar desktop
|
||||
application in order to identify nodes.
|
||||
*/
|
||||
- (NSString *)identifierForNode:(T)node;
|
||||
- (NSString*)identifierForNode:(T)node;
|
||||
|
||||
/**
|
||||
An ID which is equal between reflowing components is needed to get the identifier of root
|
||||
node of a tree which need to be invalidated on FlipperKitLayoutPlugin side.
|
||||
An ID which is equal between reflowing components is needed to get the
|
||||
identifier of root node of a tree which need to be invalidated on
|
||||
FlipperKitLayoutPlugin side.
|
||||
*/
|
||||
- (NSString *)identifierForInvalidation:(T)node;
|
||||
- (NSString*)identifierForInvalidation:(T)node;
|
||||
|
||||
/**
|
||||
The name used to identify this node in the Sonar desktop application. This is what
|
||||
will be visible in the hierarchy.
|
||||
The name used to identify this node in the Sonar desktop application. This is
|
||||
what will be visible in the hierarchy.
|
||||
*/
|
||||
- (NSString *)nameForNode:(T)node;
|
||||
- (NSString*)nameForNode:(T)node;
|
||||
|
||||
/**
|
||||
The number of children this node exposes in the layout hierarchy.
|
||||
@@ -67,29 +68,30 @@ typedef void (^SKNodeUpdateData)(id value);
|
||||
- (id)childForNode:(T)node atIndex:(NSUInteger)index;
|
||||
|
||||
/**
|
||||
Get the data to show for this node in the sidebar of the Sonar application. The objects
|
||||
will be shown in order by SKNamed.name as their header.
|
||||
Get the data to show for this node in the sidebar of the Sonar application. The
|
||||
objects will be shown in order by SKNamed.name as their header.
|
||||
*/
|
||||
- (NSArray<SKNamed<NSDictionary *> *> *)dataForNode:(T)node;
|
||||
- (NSArray<SKNamed<NSDictionary*>*>*)dataForNode:(T)node;
|
||||
|
||||
/**
|
||||
Get the attributes for this node. Attributes will be showed in the Sonar application right
|
||||
next to the name of the node.
|
||||
Get the attributes for this node. Attributes will be showed in the Sonar
|
||||
application right next to the name of the node.
|
||||
*/
|
||||
- (NSArray<SKNamed<NSString *> *> *)attributesForNode:(T)node;
|
||||
- (NSArray<SKNamed<NSString*>*>*)attributesForNode:(T)node;
|
||||
|
||||
/**
|
||||
A mapping of the path for a specific value, and a block responsible for updating
|
||||
its corresponding value for a specific node.
|
||||
A mapping of the path for a specific value, and a block responsible for
|
||||
updating its corresponding value for a specific node.
|
||||
|
||||
The paths (string) is dependent on what `dataForNode` returns (e.g "SKNodeDescriptor.name").
|
||||
The paths (string) is dependent on what `dataForNode` returns (e.g
|
||||
"SKNodeDescriptor.name").
|
||||
*/
|
||||
- (NSDictionary<NSString *, SKNodeUpdateData> *)dataMutationsForNode:(T)node;
|
||||
- (NSDictionary<NSString*, SKNodeUpdateData>*)dataMutationsForNode:(T)node;
|
||||
|
||||
/**
|
||||
This is used in order to highlight any specific node which is currently
|
||||
selected in the Sonar application. The plugin automatically takes care of de-selecting
|
||||
the previously highlighted node.
|
||||
selected in the Sonar application. The plugin automatically takes care of
|
||||
de-selecting the previously highlighted node.
|
||||
*/
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(T)node;
|
||||
|
||||
@@ -98,7 +100,7 @@ typedef void (^SKNodeUpdateData)(id value);
|
||||
one of the children of the node, or finish the hit testing on this
|
||||
node.
|
||||
*/
|
||||
- (void)hitTest:(SKTouch *)point forNode:(T)node;
|
||||
- (void)hitTest:(SKTouch*)point forNode:(T)node;
|
||||
|
||||
/**
|
||||
Invalidate a specific node. This is called once a node is removed or added
|
||||
@@ -110,12 +112,12 @@ typedef void (^SKNodeUpdateData)(id value);
|
||||
The decoration for this node. Valid values are defined in the Sonar
|
||||
applictation.
|
||||
*/
|
||||
- (NSString *)decorationForNode:(T)node;
|
||||
- (NSString*)decorationForNode:(T)node;
|
||||
|
||||
/**
|
||||
Whether the node matches the given query.
|
||||
Used for layout search.
|
||||
*/
|
||||
- (BOOL)matchesQuery:(NSString *)query forNode:(T)node;
|
||||
- (BOOL)matchesQuery:(NSString*)query forNode:(T)node;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,87 +10,89 @@
|
||||
#import "SKNodeDescriptor.h"
|
||||
#import <FlipperKitLayoutTextSearchable/FKTextSearchable.h>
|
||||
|
||||
@implementation SKNodeDescriptor
|
||||
{
|
||||
SKDescriptorMapper *_mapper;
|
||||
@implementation SKNodeDescriptor {
|
||||
SKDescriptorMapper* _mapper;
|
||||
}
|
||||
|
||||
- (void)setUp {
|
||||
}
|
||||
|
||||
- (instancetype)initWithDescriptorMapper:(SKDescriptorMapper *)mapper {
|
||||
- (instancetype)initWithDescriptorMapper:(SKDescriptorMapper*)mapper {
|
||||
if (self = [super init]) {
|
||||
_mapper = mapper;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (SKNodeDescriptor *)descriptorForClass:(Class)cls {
|
||||
return [_mapper descriptorForClass: cls];
|
||||
- (SKNodeDescriptor*)descriptorForClass:(Class)cls {
|
||||
return [_mapper descriptorForClass:cls];
|
||||
}
|
||||
|
||||
- (NSString *)identifierForNode:(id)node {
|
||||
@throw [NSString stringWithFormat:@"need to implement %@", NSStringFromSelector(_cmd)];
|
||||
- (NSString*)identifierForNode:(id)node {
|
||||
@throw [NSString
|
||||
stringWithFormat:@"need to implement %@", NSStringFromSelector(_cmd)];
|
||||
}
|
||||
|
||||
- (NSString *)identifierForInvalidation:(id)node
|
||||
{
|
||||
- (NSString*)identifierForInvalidation:(id)node {
|
||||
return [self identifierForNode:node];
|
||||
}
|
||||
|
||||
- (NSString *)nameForNode:(id)node {
|
||||
- (NSString*)nameForNode:(id)node {
|
||||
return NSStringFromClass([node class]);
|
||||
}
|
||||
|
||||
- (NSUInteger)childCountForNode:(id)node {
|
||||
@throw [NSString stringWithFormat:@"need to implement %@", NSStringFromSelector(_cmd)];
|
||||
@throw [NSString
|
||||
stringWithFormat:@"need to implement %@", NSStringFromSelector(_cmd)];
|
||||
}
|
||||
|
||||
- (id)childForNode:(id)node atIndex:(NSUInteger)index {
|
||||
@throw [NSString stringWithFormat:@"need to implement %@", NSStringFromSelector(_cmd)];
|
||||
@throw [NSString
|
||||
stringWithFormat:@"need to implement %@", NSStringFromSelector(_cmd)];
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, SKNodeUpdateData> *)dataMutationsForNode:(id)node {
|
||||
- (NSDictionary<NSString*, SKNodeUpdateData>*)dataMutationsForNode:(id)node {
|
||||
return @{};
|
||||
}
|
||||
|
||||
- (NSArray<SKNamed<NSDictionary *> *> *)dataForNode:(id)node {
|
||||
- (NSArray<SKNamed<NSDictionary*>*>*)dataForNode:(id)node {
|
||||
return @[];
|
||||
}
|
||||
|
||||
- (NSArray<SKNamed<NSString *> *> *)attributesForNode:(id)node {
|
||||
- (NSArray<SKNamed<NSString*>*>*)attributesForNode:(id)node {
|
||||
return @[];
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(id)node {
|
||||
}
|
||||
|
||||
- (void)hitTest:(SKTouch *)point forNode:(id)node {
|
||||
- (void)hitTest:(SKTouch*)point forNode:(id)node {
|
||||
}
|
||||
|
||||
- (void)invalidateNode:(id)node {
|
||||
}
|
||||
|
||||
- (NSString *)decorationForNode:(id)node {
|
||||
- (NSString*)decorationForNode:(id)node {
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (BOOL)matchesQuery:(NSString *)query forNode:(id)node {
|
||||
NSString *name = [self nameForNode: node];
|
||||
NSString *text = nil;
|
||||
if ([node conformsToProtocol:@protocol(FKTextSearchable)]) {
|
||||
text = [node searchableText];
|
||||
}
|
||||
return [self string:name contains:query] ||
|
||||
[self string:[self identifierForNode: node] contains: query] ||
|
||||
[self string:text contains:query];
|
||||
- (BOOL)matchesQuery:(NSString*)query forNode:(id)node {
|
||||
NSString* name = [self nameForNode:node];
|
||||
NSString* text = nil;
|
||||
if ([node conformsToProtocol:@protocol(FKTextSearchable)]) {
|
||||
text = [node searchableText];
|
||||
}
|
||||
return [self string:name contains:query] ||
|
||||
[self string:[self identifierForNode:node] contains:query] ||
|
||||
[self string:text contains:query];
|
||||
}
|
||||
|
||||
- (BOOL)string:(NSString *)string contains:(NSString *)substring {
|
||||
return string != nil && substring != nil && [string rangeOfString: substring options: NSCaseInsensitiveSearch].location != NSNotFound;
|
||||
- (BOOL)string:(NSString*)string contains:(NSString*)substring {
|
||||
return string != nil && substring != nil &&
|
||||
[string rangeOfString:substring options:NSCaseInsensitiveSearch]
|
||||
.location != NSNotFound;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
|
||||
+ (instancetype)fromSonarValue:(id)sonarValue;
|
||||
|
||||
- (NSDictionary<NSString *, id<NSObject>> *)sonarValue;
|
||||
- (NSDictionary<NSString*, id<NSObject>>*)sonarValue;
|
||||
|
||||
@end
|
||||
|
||||
class SKObject {
|
||||
public:
|
||||
public:
|
||||
SKObject(CGRect rect);
|
||||
SKObject(CGSize size);
|
||||
SKObject(CGPoint point);
|
||||
@@ -25,28 +25,30 @@ public:
|
||||
SKObject(id<SKSonarValueCoder> value);
|
||||
SKObject(id value);
|
||||
|
||||
operator id<NSObject> () const noexcept {
|
||||
operator id<NSObject>() const noexcept {
|
||||
return _actual ?: [NSNull null];
|
||||
}
|
||||
protected:
|
||||
|
||||
protected:
|
||||
id<NSObject> _actual;
|
||||
};
|
||||
|
||||
class SKMutableObject : public SKObject {
|
||||
public:
|
||||
SKMutableObject(CGRect rect) : SKObject(rect) { }
|
||||
SKMutableObject(CGSize size) : SKObject(size) { };
|
||||
SKMutableObject(CGPoint point) : SKObject(point) { };
|
||||
SKMutableObject(UIEdgeInsets insets) : SKObject(insets) { };
|
||||
SKMutableObject(CGAffineTransform transform) : SKObject(transform) { };
|
||||
SKMutableObject(id<SKSonarValueCoder> value) : SKObject(value) { };
|
||||
SKMutableObject(id value) : SKObject(value) { };
|
||||
public:
|
||||
SKMutableObject(CGRect rect) : SKObject(rect) {}
|
||||
SKMutableObject(CGSize size) : SKObject(size){};
|
||||
SKMutableObject(CGPoint point) : SKObject(point){};
|
||||
SKMutableObject(UIEdgeInsets insets) : SKObject(insets){};
|
||||
SKMutableObject(CGAffineTransform transform) : SKObject(transform){};
|
||||
SKMutableObject(id<SKSonarValueCoder> value) : SKObject(value){};
|
||||
SKMutableObject(id value) : SKObject(value){};
|
||||
|
||||
operator id<NSObject> () {
|
||||
operator id<NSObject>() {
|
||||
convertToMutable();
|
||||
return _actual;
|
||||
}
|
||||
protected:
|
||||
|
||||
protected:
|
||||
BOOL _convertedToMutable = NO;
|
||||
void convertToMutable();
|
||||
};
|
||||
|
||||
@@ -10,86 +10,80 @@
|
||||
#import "SKObject.h"
|
||||
|
||||
SKObject::SKObject(CGRect rect) {
|
||||
_actual = @{
|
||||
@"origin": SKObject(rect.origin),
|
||||
@"size": SKObject(rect.size)
|
||||
};
|
||||
_actual = @{@"origin" : SKObject(rect.origin), @"size" : SKObject(rect.size)};
|
||||
}
|
||||
|
||||
SKObject::SKObject(CGSize size) {
|
||||
_actual = @{
|
||||
@"height": @(size.height),
|
||||
@"width": @(size.width)
|
||||
};
|
||||
_actual = @{@"height" : @(size.height), @"width" : @(size.width)};
|
||||
}
|
||||
|
||||
SKObject::SKObject(CGPoint point) {
|
||||
_actual = @{
|
||||
@"x": @(point.x),
|
||||
@"y": @(point.y)
|
||||
};
|
||||
_actual = @{@"x" : @(point.x), @"y" : @(point.y)};
|
||||
}
|
||||
|
||||
SKObject::SKObject(UIEdgeInsets insets) {
|
||||
_actual = @{
|
||||
@"top": @(insets.top),
|
||||
@"bottom": @(insets.bottom),
|
||||
@"left": @(insets.left),
|
||||
@"right": @(insets.right),
|
||||
};
|
||||
@"top" : @(insets.top),
|
||||
@"bottom" : @(insets.bottom),
|
||||
@"left" : @(insets.left),
|
||||
@"right" : @(insets.right),
|
||||
};
|
||||
}
|
||||
|
||||
SKObject::SKObject(CGAffineTransform transform) {
|
||||
_actual = @{
|
||||
@"a": @(transform.a),
|
||||
@"b": @(transform.b),
|
||||
@"c": @(transform.c),
|
||||
@"d": @(transform.d),
|
||||
@"tx": @(transform.tx),
|
||||
@"ty": @(transform.ty),
|
||||
};
|
||||
@"a" : @(transform.a),
|
||||
@"b" : @(transform.b),
|
||||
@"c" : @(transform.c),
|
||||
@"d" : @(transform.d),
|
||||
@"tx" : @(transform.tx),
|
||||
@"ty" : @(transform.ty),
|
||||
};
|
||||
}
|
||||
|
||||
SKObject::SKObject(id<SKSonarValueCoder> value) : _actual([value sonarValue]) { }
|
||||
SKObject::SKObject(id<SKSonarValueCoder> value) : _actual([value sonarValue]) {}
|
||||
|
||||
SKObject::SKObject(id value) : _actual(value) { }
|
||||
SKObject::SKObject(id value) : _actual(value) {}
|
||||
|
||||
static NSString *_objectType(id<NSObject> object) {
|
||||
if ([object isKindOfClass: [NSDictionary class]]) {
|
||||
return (NSString *)((NSDictionary *)object)[@"__type__"];
|
||||
static NSString* _objectType(id<NSObject> object) {
|
||||
if ([object isKindOfClass:[NSDictionary class]]) {
|
||||
return (NSString*)((NSDictionary*)object)[@"__type__"];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static id<NSObject> _objectValue(id<NSObject> object) {
|
||||
if ([object isKindOfClass: [NSDictionary class]]) {
|
||||
return ((NSDictionary *)object)[@"value"];
|
||||
if ([object isKindOfClass:[NSDictionary class]]) {
|
||||
return ((NSDictionary*)object)[@"value"];
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static NSDictionary<NSString *, id<NSObject>> *_SKValue(id<NSObject> object, BOOL isMutable) {
|
||||
NSString *type = _objectType(object);
|
||||
static NSDictionary<NSString*, id<NSObject>>* _SKValue(
|
||||
id<NSObject> object,
|
||||
BOOL isMutable) {
|
||||
NSString* type = _objectType(object);
|
||||
id<NSObject> value = _objectValue(object);
|
||||
|
||||
return @{
|
||||
@"__type__": (type != nil ? type : @"auto"),
|
||||
@"__mutable__": @(isMutable),
|
||||
@"value": (value != nil ? value : [NSNull null]),
|
||||
};
|
||||
@"__type__" : (type != nil ? type : @"auto"),
|
||||
@"__mutable__" : @(isMutable),
|
||||
@"value" : (value != nil ? value : [NSNull null]),
|
||||
};
|
||||
}
|
||||
|
||||
static NSDictionary *_SKMutable(const NSDictionary<NSString *, id<NSObject>> *skObject) {
|
||||
NSMutableDictionary *mutableObject = [NSMutableDictionary new];
|
||||
for (NSString *key: skObject) {
|
||||
static NSDictionary* _SKMutable(
|
||||
const NSDictionary<NSString*, id<NSObject>>* skObject) {
|
||||
NSMutableDictionary* mutableObject = [NSMutableDictionary new];
|
||||
for (NSString* key : skObject) {
|
||||
id<NSObject> value = skObject[key];
|
||||
|
||||
if (_objectType(value) != nil) {
|
||||
mutableObject[key] = _SKValue(value, YES);
|
||||
} else if ([value isKindOfClass: [NSDictionary class]]) {
|
||||
auto objectValue = (NSDictionary<NSString *, id<NSObject>>*) value;
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
auto objectValue = (NSDictionary<NSString*, id<NSObject>>*)value;
|
||||
mutableObject[key] = _SKMutable(objectValue);
|
||||
} else {
|
||||
mutableObject[key] = _SKValue(value, YES);
|
||||
@@ -104,8 +98,9 @@ void SKMutableObject::convertToMutable() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_objectType(_actual) == nil && [_actual isKindOfClass: [NSDictionary class]]) {
|
||||
auto object = (const NSDictionary<NSString *, id<NSObject>> *)_actual;
|
||||
if (_objectType(_actual) == nil &&
|
||||
[_actual isKindOfClass:[NSDictionary class]]) {
|
||||
auto object = (const NSDictionary<NSString*, id<NSObject>>*)_actual;
|
||||
_actual = _SKMutable(object);
|
||||
} else {
|
||||
_actual = _SKValue(_actual, YES);
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
|
||||
@interface SKSearchResultNode : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *nodeId;
|
||||
@property(nonatomic, copy, readonly) NSString* nodeId;
|
||||
|
||||
- (instancetype)initWithNode:(NSString *)nodeId
|
||||
- (instancetype)initWithNode:(NSString*)nodeId
|
||||
asMatch:(BOOL)isMatch
|
||||
withElement:(NSDictionary *)element
|
||||
andChildren:(NSArray<SKSearchResultNode *> *)children;
|
||||
withElement:(NSDictionary*)element
|
||||
andChildren:(NSArray<SKSearchResultNode*>*)children;
|
||||
|
||||
- (NSDictionary *)toNSDictionary;
|
||||
- (NSDictionary*)toNSDictionary;
|
||||
|
||||
@end
|
||||
#endif /* SKSearchResultNode_h */
|
||||
|
||||
@@ -8,48 +8,48 @@
|
||||
#import "SKSearchResultNode.h"
|
||||
|
||||
@implementation SKSearchResultNode {
|
||||
NSString *_nodeId;
|
||||
NSString* _nodeId;
|
||||
BOOL _isMatch;
|
||||
NSDictionary *_element;
|
||||
NSArray<SKSearchResultNode *> *_children;
|
||||
NSDictionary* _element;
|
||||
NSArray<SKSearchResultNode*>* _children;
|
||||
}
|
||||
|
||||
- (instancetype)initWithNode:(NSString *)nodeId
|
||||
- (instancetype)initWithNode:(NSString*)nodeId
|
||||
asMatch:(BOOL)isMatch
|
||||
withElement:(NSDictionary *)element
|
||||
andChildren:(NSArray<SKSearchResultNode *> *)children {
|
||||
withElement:(NSDictionary*)element
|
||||
andChildren:(NSArray<SKSearchResultNode*>*)children {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_nodeId = nodeId;
|
||||
_isMatch = isMatch;
|
||||
_element = element;
|
||||
_children = children;
|
||||
_nodeId = nodeId;
|
||||
_isMatch = isMatch;
|
||||
_element = element;
|
||||
_children = children;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *)toNSDictionary {
|
||||
- (NSDictionary*)toNSDictionary {
|
||||
if (_element == nil) {
|
||||
return nil;
|
||||
return nil;
|
||||
}
|
||||
NSMutableArray<NSDictionary *> *childArray;
|
||||
NSMutableArray<NSDictionary*>* childArray;
|
||||
if (_children) {
|
||||
childArray = [NSMutableArray new];
|
||||
for (SKSearchResultNode *child in _children) {
|
||||
NSDictionary *childDict = [child toNSDictionary];
|
||||
for (SKSearchResultNode* child in _children) {
|
||||
NSDictionary* childDict = [child toNSDictionary];
|
||||
if (childDict) {
|
||||
[childArray addObject:childDict];
|
||||
[childArray addObject:childDict];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
childArray = nil;
|
||||
}
|
||||
return @{
|
||||
@"id": _nodeId,
|
||||
@"isMatch": @(_isMatch),
|
||||
@"element": _element,
|
||||
@"children": childArray ?: [NSNull null]
|
||||
};
|
||||
@"id" : _nodeId,
|
||||
@"isMatch" : @(_isMatch),
|
||||
@"element" : _element,
|
||||
@"children" : childArray ?: [NSNull null]
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -11,7 +11,7 @@ typedef void (^SKTapReceiver)(CGPoint touchPoint);
|
||||
|
||||
@protocol SKTapListener
|
||||
|
||||
@property (nonatomic, readonly) BOOL isMounted;
|
||||
@property(nonatomic, readonly) BOOL isMounted;
|
||||
|
||||
- (void)mountWithFrame:(CGRect)frame;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#import "SKTapListener.h"
|
||||
|
||||
@interface SKTapListenerImpl : NSObject<SKTapListener, UIGestureRecognizerDelegate>
|
||||
@interface SKTapListenerImpl
|
||||
: NSObject<SKTapListener, UIGestureRecognizerDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@@ -13,12 +13,11 @@
|
||||
|
||||
#import <FlipperKitHighlightOverlay/SKHighlightOverlay.h>
|
||||
|
||||
@implementation SKTapListenerImpl
|
||||
{
|
||||
NSMutableArray<SKTapReceiver> *_receiversWaitingForInput;
|
||||
UITapGestureRecognizer *_gestureRecognizer;
|
||||
@implementation SKTapListenerImpl {
|
||||
NSMutableArray<SKTapReceiver>* _receiversWaitingForInput;
|
||||
UITapGestureRecognizer* _gestureRecognizer;
|
||||
|
||||
SKHiddenWindow *_overlayWindow;
|
||||
SKHiddenWindow* _overlayWindow;
|
||||
}
|
||||
|
||||
@synthesize isMounted = _isMounted;
|
||||
@@ -27,7 +26,8 @@
|
||||
if (self = [super init]) {
|
||||
_receiversWaitingForInput = [NSMutableArray new];
|
||||
|
||||
_gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: self action: nil];
|
||||
_gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
|
||||
action:nil];
|
||||
_gestureRecognizer.delegate = self;
|
||||
|
||||
_isMounted = NO;
|
||||
@@ -37,7 +37,7 @@
|
||||
_overlayWindow.windowLevel = UIWindowLevelAlert;
|
||||
_overlayWindow.backgroundColor = [SKHighlightOverlay overlayColor];
|
||||
|
||||
[_overlayWindow addGestureRecognizer: _gestureRecognizer];
|
||||
[_overlayWindow addGestureRecognizer:_gestureRecognizer];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -48,7 +48,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
[_overlayWindow setFrame: frame];
|
||||
[_overlayWindow setFrame:frame];
|
||||
[_overlayWindow makeKeyAndVisible];
|
||||
_overlayWindow.hidden = NO;
|
||||
|
||||
@@ -68,15 +68,16 @@
|
||||
}
|
||||
|
||||
- (void)listenForTapWithBlock:(SKTapReceiver)receiver {
|
||||
[_receiversWaitingForInput addObject: receiver];
|
||||
[_receiversWaitingForInput addObject:receiver];
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
|
||||
shouldReceiveTouch:(UITouch*)touch {
|
||||
if ([_receiversWaitingForInput count] == 0) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
CGPoint touchPoint = [touch locationInView: _overlayWindow];
|
||||
CGPoint touchPoint = [touch locationInView:_overlayWindow];
|
||||
|
||||
for (SKTapReceiver recv in _receiversWaitingForInput) {
|
||||
recv(touchPoint);
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
|
||||
#import "SKDescriptorMapper.h"
|
||||
|
||||
typedef void (^SKTouchFinishDelegate)(NSArray<NSString *> *path);
|
||||
typedef void (^SKTouchFinishDelegate)(NSArray<NSString*>* path);
|
||||
|
||||
@interface SKTouch : NSObject
|
||||
|
||||
- (instancetype)initWithTouchPoint:(CGPoint)touchPoint
|
||||
withRootNode:(id<NSObject>)node
|
||||
withDescriptorMapper:(SKDescriptorMapper *)mapper
|
||||
finishWithBlock:(SKTouchFinishDelegate)d;
|
||||
withRootNode:(id<NSObject>)node
|
||||
withDescriptorMapper:(SKDescriptorMapper*)mapper
|
||||
finishWithBlock:(SKTouchFinishDelegate)d;
|
||||
|
||||
- (void)continueWithChildIndex:(NSUInteger)childIndex
|
||||
withOffset:(CGPoint)offset;
|
||||
withOffset:(CGPoint)offset;
|
||||
|
||||
- (void)finish;
|
||||
|
||||
|
||||
@@ -10,21 +10,20 @@
|
||||
#import "SKTouch.h"
|
||||
#import "SKNodeDescriptor.h"
|
||||
|
||||
@implementation SKTouch
|
||||
{
|
||||
@implementation SKTouch {
|
||||
SKTouchFinishDelegate _onFinish;
|
||||
NSMutableArray<NSString *> *_path;
|
||||
NSMutableArray<NSString*>* _path;
|
||||
|
||||
CGPoint _currentTouchPoint;
|
||||
id<NSObject> _currentNode;
|
||||
|
||||
SKDescriptorMapper *_descriptorMapper;
|
||||
SKDescriptorMapper* _descriptorMapper;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTouchPoint:(CGPoint)touchPoint
|
||||
withRootNode:(id<NSObject>)node
|
||||
withDescriptorMapper:(SKDescriptorMapper *)mapper
|
||||
finishWithBlock:(SKTouchFinishDelegate)finishBlock {
|
||||
withRootNode:(id<NSObject>)node
|
||||
withDescriptorMapper:(SKDescriptorMapper*)mapper
|
||||
finishWithBlock:(SKTouchFinishDelegate)finishBlock {
|
||||
if (self = [super init]) {
|
||||
_onFinish = finishBlock;
|
||||
_currentTouchPoint = touchPoint;
|
||||
@@ -36,17 +35,19 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)continueWithChildIndex:(NSUInteger)childIndex withOffset:(CGPoint)offset {
|
||||
- (void)continueWithChildIndex:(NSUInteger)childIndex
|
||||
withOffset:(CGPoint)offset {
|
||||
_currentTouchPoint.x -= offset.x;
|
||||
_currentTouchPoint.y -= offset.y;
|
||||
|
||||
SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [_currentNode class]];
|
||||
_currentNode = [descriptor childForNode: _currentNode atIndex: childIndex];
|
||||
SKNodeDescriptor* descriptor =
|
||||
[_descriptorMapper descriptorForClass:[_currentNode class]];
|
||||
_currentNode = [descriptor childForNode:_currentNode atIndex:childIndex];
|
||||
|
||||
descriptor = [_descriptorMapper descriptorForClass: [_currentNode class]];
|
||||
[_path addObject: [descriptor identifierForNode: _currentNode]];
|
||||
descriptor = [_descriptorMapper descriptorForClass:[_currentNode class]];
|
||||
[_path addObject:[descriptor identifierForNode:_currentNode]];
|
||||
|
||||
[descriptor hitTest: self forNode: _currentNode];
|
||||
[descriptor hitTest:self forNode:_currentNode];
|
||||
}
|
||||
|
||||
- (void)finish {
|
||||
|
||||
@@ -18,16 +18,20 @@ FB_LINKABLE(UICollectionView_SKInvalidation)
|
||||
+ (void)enableInvalidations {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
swizzleMethods([self class], @selector(cellForItemAtIndexPath:), @selector(swizzle_cellForItemAtIndexPath:));
|
||||
swizzleMethods(
|
||||
[self class],
|
||||
@selector(cellForItemAtIndexPath:),
|
||||
@selector(swizzle_cellForItemAtIndexPath:));
|
||||
});
|
||||
}
|
||||
|
||||
- (UICollectionViewCell *)swizzle_cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
- (UICollectionViewCell*)swizzle_cellForItemAtIndexPath:
|
||||
(NSIndexPath*)indexPath {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[SKInvalidation sharedInstance].delegate invalidateNode: self];
|
||||
[[SKInvalidation sharedInstance].delegate invalidateNode:self];
|
||||
});
|
||||
|
||||
return [self swizzle_cellForItemAtIndexPath: indexPath];
|
||||
return [self swizzle_cellForItemAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
#import "SKObject.h"
|
||||
|
||||
FB_LINK_REQUIRE_CATEGORY(UIColor_SonarValueCoder)
|
||||
@interface UIColor (SonarValueCoder) <SKSonarValueCoder>
|
||||
@interface UIColor (SonarValueCoder)<SKSonarValueCoder>
|
||||
|
||||
@end
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
FB_LINKABLE(UIColor_SonarValueCoder)
|
||||
@implementation UIColor (SonarValueCoder)
|
||||
|
||||
+ (instancetype)fromSonarValue:(NSNumber *)sonarValue {
|
||||
+ (instancetype)fromSonarValue:(NSNumber*)sonarValue {
|
||||
NSUInteger intColor = [sonarValue integerValue];
|
||||
|
||||
CGFloat r, g, b, a;
|
||||
@@ -22,10 +22,10 @@ FB_LINKABLE(UIColor_SonarValueCoder)
|
||||
r = CGFloat((intColor >> 16) & 0xFF) / 255;
|
||||
a = CGFloat((intColor >> 24) & 0xFF) / 255;
|
||||
|
||||
return [[UIColor alloc] initWithRed: r green: g blue: b alpha: a];
|
||||
return [[UIColor alloc] initWithRed:r green:g blue:b alpha:a];
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, id<NSObject>> *)sonarValue {
|
||||
- (NSDictionary<NSString*, id<NSObject>>*)sonarValue {
|
||||
CGColorSpaceRef colorSpace = CGColorGetColorSpace([self CGColor]);
|
||||
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
|
||||
|
||||
@@ -35,7 +35,7 @@ FB_LINKABLE(UIColor_SonarValueCoder)
|
||||
case kCGColorSpaceModelUnknown:
|
||||
case kCGColorSpaceModelRGB: {
|
||||
CGFloat r, g, b, a;
|
||||
[self getRed: &r green: &g blue: &b alpha: &a];
|
||||
[self getRed:&r green:&g blue:&b alpha:&a];
|
||||
|
||||
red = (NSUInteger)(r * 255) & 0xFF;
|
||||
green = (NSUInteger)(g * 255) & 0xFF;
|
||||
@@ -45,7 +45,7 @@ FB_LINKABLE(UIColor_SonarValueCoder)
|
||||
|
||||
case kCGColorSpaceModelMonochrome: {
|
||||
CGFloat a, w;
|
||||
[self getWhite: &w alpha: &a];
|
||||
[self getWhite:&w alpha:&a];
|
||||
|
||||
red = green = blue = (NSUInteger)(w * 255) & 0xFF;
|
||||
alpha = (NSUInteger)(a * 255) & 0xFF;
|
||||
@@ -56,11 +56,8 @@ FB_LINKABLE(UIColor_SonarValueCoder)
|
||||
}
|
||||
|
||||
NSUInteger intColor = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
||||
return @{
|
||||
@"__type__": @"color",
|
||||
@"__mutable__": @NO,
|
||||
@"value": @(intColor)
|
||||
};
|
||||
return
|
||||
@{@"__type__" : @"color", @"__mutable__" : @NO, @"value" : @(intColor)};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,34 +20,42 @@ FB_LINKABLE(UIView_SKInvalidation)
|
||||
+ (void)enableInvalidation {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
swizzleMethods([self class], @selector(setHidden:), @selector(swizzle_setHidden:));
|
||||
swizzleMethods([self class], @selector(addSubview:), @selector(swizzle_addSubview:));
|
||||
swizzleMethods([self class], @selector(removeFromSuperview), @selector(swizzle_removeFromSuperview));
|
||||
swizzleMethods(
|
||||
[self class], @selector(setHidden:), @selector(swizzle_setHidden:));
|
||||
swizzleMethods(
|
||||
[self class], @selector(addSubview:), @selector(swizzle_addSubview:));
|
||||
swizzleMethods(
|
||||
[self class],
|
||||
@selector(removeFromSuperview),
|
||||
@selector(swizzle_removeFromSuperview));
|
||||
});
|
||||
}
|
||||
|
||||
- (void)swizzle_setHidden:(BOOL)hidden {
|
||||
[self swizzle_setHidden: hidden];
|
||||
[self swizzle_setHidden:hidden];
|
||||
|
||||
id<SKInvalidationDelegate> delegate = [SKInvalidation sharedInstance].delegate;
|
||||
id<SKInvalidationDelegate> delegate =
|
||||
[SKInvalidation sharedInstance].delegate;
|
||||
if (delegate != nil) {
|
||||
[delegate invalidateNode: self.superview];
|
||||
[delegate invalidateNode:self.superview];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)swizzle_addSubview:(UIView *)view {
|
||||
[self swizzle_addSubview: view];
|
||||
- (void)swizzle_addSubview:(UIView*)view {
|
||||
[self swizzle_addSubview:view];
|
||||
|
||||
id<SKInvalidationDelegate> delegate = [SKInvalidation sharedInstance].delegate;
|
||||
id<SKInvalidationDelegate> delegate =
|
||||
[SKInvalidation sharedInstance].delegate;
|
||||
if (delegate != nil) {
|
||||
[delegate invalidateNode: view];
|
||||
[delegate invalidateNode:view];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)swizzle_removeFromSuperview {
|
||||
id<SKInvalidationDelegate> delegate = [SKInvalidation sharedInstance].delegate;
|
||||
id<SKInvalidationDelegate> delegate =
|
||||
[SKInvalidation sharedInstance].delegate;
|
||||
if (delegate != nil && self.superview != nil) {
|
||||
[delegate invalidateNode: self.superview];
|
||||
[delegate invalidateNode:self.superview];
|
||||
}
|
||||
|
||||
[self swizzle_removeFromSuperview];
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
|
||||
#import "SKNodeDescriptor.h"
|
||||
|
||||
@interface SKApplicationDescriptor : SKNodeDescriptor<UIApplication *>
|
||||
@interface SKApplicationDescriptor : SKNodeDescriptor<UIApplication*>
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,38 +9,40 @@
|
||||
|
||||
#import "SKApplicationDescriptor.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#import "SKDescriptorMapper.h"
|
||||
#import "SKHiddenWindow.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation SKApplicationDescriptor
|
||||
|
||||
- (NSString *)identifierForNode:(UIApplication *)node {
|
||||
return [NSString stringWithFormat: @"%p", node];
|
||||
- (NSString*)identifierForNode:(UIApplication*)node {
|
||||
return [NSString stringWithFormat:@"%p", node];
|
||||
}
|
||||
|
||||
- (NSUInteger)childCountForNode:(UIApplication *)node {
|
||||
return [[self visibleChildrenForNode: node] count];
|
||||
- (NSUInteger)childCountForNode:(UIApplication*)node {
|
||||
return [[self visibleChildrenForNode:node] count];
|
||||
}
|
||||
|
||||
- (id)childForNode:(UIApplication *)node atIndex:(NSUInteger)index {
|
||||
return [self visibleChildrenForNode: node][index];
|
||||
- (id)childForNode:(UIApplication*)node atIndex:(NSUInteger)index {
|
||||
return [self visibleChildrenForNode:node][index];
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIApplication *)node {
|
||||
SKNodeDescriptor *windowDescriptor = [self descriptorForClass: [UIWindow class]];
|
||||
[windowDescriptor setHighlighted: highlighted forNode: [node keyWindow]];
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIApplication*)node {
|
||||
SKNodeDescriptor* windowDescriptor =
|
||||
[self descriptorForClass:[UIWindow class]];
|
||||
[windowDescriptor setHighlighted:highlighted forNode:[node keyWindow]];
|
||||
}
|
||||
|
||||
- (void)hitTest:(SKTouch *)touch forNode:(UIApplication *)node {
|
||||
for (NSInteger index = [self childCountForNode: node] - 1; index >= 0; index--) {
|
||||
UIWindow *child = [self childForNode: node atIndex: index];
|
||||
- (void)hitTest:(SKTouch*)touch forNode:(UIApplication*)node {
|
||||
for (NSInteger index = [self childCountForNode:node] - 1; index >= 0;
|
||||
index--) {
|
||||
UIWindow* child = [self childForNode:node atIndex:index];
|
||||
if (child.isHidden || child.alpha <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([touch containedIn: child.frame]) {
|
||||
[touch continueWithChildIndex: index withOffset: child.frame.origin];
|
||||
if ([touch containedIn:child.frame]) {
|
||||
[touch continueWithChildIndex:index withOffset:child.frame.origin];
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -48,16 +50,17 @@
|
||||
[touch finish];
|
||||
}
|
||||
|
||||
- (NSArray<UIWindow *> *)visibleChildrenForNode:(UIApplication *)node {
|
||||
NSMutableArray<UIWindow *> *children = [NSMutableArray new];
|
||||
for (UIWindow *window in node.windows) {
|
||||
if ([window isKindOfClass: [SKHiddenWindow class]]
|
||||
|| [window isKindOfClass:objc_lookUpClass("FBAccessibilityOverlayWindow")]
|
||||
|| [window isKindOfClass:objc_lookUpClass("UITextEffectsWindow")]
|
||||
|| [window isKindOfClass:objc_lookUpClass("FBStatusBarTrackingWindow")]) {
|
||||
- (NSArray<UIWindow*>*)visibleChildrenForNode:(UIApplication*)node {
|
||||
NSMutableArray<UIWindow*>* children = [NSMutableArray new];
|
||||
for (UIWindow* window in node.windows) {
|
||||
if ([window isKindOfClass:[SKHiddenWindow class]] ||
|
||||
[window
|
||||
isKindOfClass:objc_lookUpClass("FBAccessibilityOverlayWindow")] ||
|
||||
[window isKindOfClass:objc_lookUpClass("UITextEffectsWindow")] ||
|
||||
[window isKindOfClass:objc_lookUpClass("FBStatusBarTrackingWindow")]) {
|
||||
continue;
|
||||
}
|
||||
[children addObject: window];
|
||||
[children addObject:window];
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
|
||||
@class UIButton;
|
||||
|
||||
@interface SKButtonDescriptor : SKNodeDescriptor<UIButton *>
|
||||
@interface SKButtonDescriptor : SKNodeDescriptor<UIButton*>
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,44 +15,48 @@
|
||||
|
||||
@implementation SKButtonDescriptor
|
||||
|
||||
- (NSString *)identifierForNode:(UIButton *)node {
|
||||
return [NSString stringWithFormat: @"%p", node];
|
||||
- (NSString*)identifierForNode:(UIButton*)node {
|
||||
return [NSString stringWithFormat:@"%p", node];
|
||||
}
|
||||
|
||||
- (NSUInteger)childCountForNode:(UIButton *)node {
|
||||
- (NSUInteger)childCountForNode:(UIButton*)node {
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (id)childForNode:(UIButton *)node atIndex:(NSUInteger)index {
|
||||
- (id)childForNode:(UIButton*)node atIndex:(NSUInteger)index {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray<SKNamed<NSDictionary *> *> *)dataForNode:(UIButton *)node {
|
||||
SKNodeDescriptor *viewDescriptor = [self descriptorForClass: [UIView class]];
|
||||
auto *viewData = [viewDescriptor dataForNode: node];
|
||||
- (NSArray<SKNamed<NSDictionary*>*>*)dataForNode:(UIButton*)node {
|
||||
SKNodeDescriptor* viewDescriptor = [self descriptorForClass:[UIView class]];
|
||||
auto* viewData = [viewDescriptor dataForNode:node];
|
||||
|
||||
NSMutableArray *data = [NSMutableArray new];
|
||||
[data addObjectsFromArray: viewData];
|
||||
[data addObject:
|
||||
[SKNamed newWithName: @"UIButton"
|
||||
withValue: @{
|
||||
@"focused": @(node.focused),
|
||||
@"enabled": SKMutableObject(@(node.enabled)),
|
||||
@"highlighted": SKMutableObject(@(node.highlighted)),
|
||||
@"titleEdgeInsets": SKObject(node.titleEdgeInsets),
|
||||
@"titleLabel": SKMutableObject(node.titleLabel.attributedText.string.stringByStandardizingPath),
|
||||
@"currentTitleColor": SKMutableObject(node.currentTitleColor),
|
||||
}]
|
||||
];
|
||||
NSMutableArray* data = [NSMutableArray new];
|
||||
[data addObjectsFromArray:viewData];
|
||||
[data addObject:[SKNamed
|
||||
newWithName:@"UIButton"
|
||||
withValue:@{
|
||||
@"focused" : @(node.focused),
|
||||
@"enabled" : SKMutableObject(@(node.enabled)),
|
||||
@"highlighted" : SKMutableObject(@(node.highlighted)),
|
||||
@"titleEdgeInsets" : SKObject(node.titleEdgeInsets),
|
||||
@"titleLabel" : SKMutableObject(
|
||||
node.titleLabel.attributedText.string
|
||||
.stringByStandardizingPath),
|
||||
@"currentTitleColor" :
|
||||
SKMutableObject(node.currentTitleColor),
|
||||
}]];
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, SKNodeUpdateData> *)dataMutationsForNode:(UIButton *)node {
|
||||
NSDictionary *buttonMutations = @{
|
||||
@"UIButton.titleLabel": ^(NSString *newValue) {
|
||||
[node setTitle: newValue forState: node.state];
|
||||
},
|
||||
- (NSDictionary<NSString*, SKNodeUpdateData>*)dataMutationsForNode:
|
||||
(UIButton*)node {
|
||||
NSDictionary* buttonMutations =
|
||||
@{@"UIButton.titleLabel" : ^(NSString* newValue){
|
||||
[node setTitle:newValue forState:node.state];
|
||||
}
|
||||
,
|
||||
@"UIButton.currentTitleColor": ^(NSNumber *newValue) {
|
||||
[node setTitleColor: [UIColor fromSonarValue: newValue] forState: node.state];
|
||||
},
|
||||
@@ -62,29 +66,30 @@
|
||||
@"UIButton.enabled": ^(NSNumber *enabled) {
|
||||
[node setEnabled: [enabled boolValue]];
|
||||
}
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
SKNodeDescriptor *viewDescriptor = [self descriptorForClass: [UIView class]];
|
||||
NSDictionary *viewMutations = [viewDescriptor dataMutationsForNode: node];
|
||||
SKNodeDescriptor* viewDescriptor = [self descriptorForClass:[UIView class]];
|
||||
NSDictionary* viewMutations = [viewDescriptor dataMutationsForNode:node];
|
||||
|
||||
NSMutableDictionary *mutations = [NSMutableDictionary new];
|
||||
[mutations addEntriesFromDictionary: buttonMutations];
|
||||
[mutations addEntriesFromDictionary: viewMutations];
|
||||
NSMutableDictionary* mutations = [NSMutableDictionary new];
|
||||
[mutations addEntriesFromDictionary:buttonMutations];
|
||||
[mutations addEntriesFromDictionary:viewMutations];
|
||||
|
||||
return mutations;
|
||||
return mutations;
|
||||
}
|
||||
|
||||
- (NSArray<SKNamed<NSString *> *> *)attributesForNode:(UIScrollView *)node {
|
||||
SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]];
|
||||
return [descriptor attributesForNode: node];
|
||||
- (NSArray<SKNamed<NSString*>*>*)attributesForNode:(UIScrollView*)node {
|
||||
SKNodeDescriptor* descriptor = [self descriptorForClass:[UIView class]];
|
||||
return [descriptor attributesForNode:node];
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIButton *)node {
|
||||
SKNodeDescriptor *viewDescriptor = [self descriptorForClass: [UIView class]];
|
||||
[viewDescriptor setHighlighted: highlighted forNode: node];
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIButton*)node {
|
||||
SKNodeDescriptor* viewDescriptor = [self descriptorForClass:[UIView class]];
|
||||
[viewDescriptor setHighlighted:highlighted forNode:node];
|
||||
}
|
||||
|
||||
- (void)hitTest:(SKTouch *)touch forNode:(UIButton *)node {
|
||||
- (void)hitTest:(SKTouch*)touch forNode:(UIButton*)node {
|
||||
[touch finish];
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
|
||||
#import "SKNodeDescriptor.h"
|
||||
|
||||
@interface SKScrollViewDescriptor : SKNodeDescriptor<UIScrollView *>
|
||||
@interface SKScrollViewDescriptor : SKNodeDescriptor<UIScrollView*>
|
||||
|
||||
@end
|
||||
|
||||
@@ -13,55 +13,56 @@
|
||||
|
||||
@implementation SKScrollViewDescriptor
|
||||
|
||||
- (NSString *)identifierForNode:(UIScrollView *)node {
|
||||
SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]];
|
||||
return [descriptor identifierForNode: node];
|
||||
- (NSString*)identifierForNode:(UIScrollView*)node {
|
||||
SKNodeDescriptor* descriptor = [self descriptorForClass:[UIView class]];
|
||||
return [descriptor identifierForNode:node];
|
||||
}
|
||||
|
||||
- (NSUInteger)childCountForNode:(UIScrollView *)node {
|
||||
SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]];
|
||||
return [descriptor childCountForNode: node];
|
||||
- (NSUInteger)childCountForNode:(UIScrollView*)node {
|
||||
SKNodeDescriptor* descriptor = [self descriptorForClass:[UIView class]];
|
||||
return [descriptor childCountForNode:node];
|
||||
}
|
||||
|
||||
- (id)childForNode:(UIScrollView *)node atIndex:(NSUInteger)index {
|
||||
SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]];
|
||||
return [descriptor childForNode: node atIndex: index];
|
||||
- (id)childForNode:(UIScrollView*)node atIndex:(NSUInteger)index {
|
||||
SKNodeDescriptor* descriptor = [self descriptorForClass:[UIView class]];
|
||||
return [descriptor childForNode:node atIndex:index];
|
||||
}
|
||||
|
||||
- (id)dataForNode:(UIScrollView *)node {
|
||||
SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]];
|
||||
- (id)dataForNode:(UIScrollView*)node {
|
||||
SKNodeDescriptor* descriptor = [self descriptorForClass:[UIView class]];
|
||||
return [descriptor dataForNode:node];
|
||||
}
|
||||
|
||||
- (id)dataMutationsForNode:(UIScrollView *)node {
|
||||
SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]];
|
||||
- (id)dataMutationsForNode:(UIScrollView*)node {
|
||||
SKNodeDescriptor* descriptor = [self descriptorForClass:[UIView class]];
|
||||
return [descriptor dataMutationsForNode:node];
|
||||
}
|
||||
|
||||
- (NSArray<SKNamed<NSString *> *> *)attributesForNode:(UIScrollView *)node {
|
||||
SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]];
|
||||
return [descriptor attributesForNode: node];
|
||||
- (NSArray<SKNamed<NSString*>*>*)attributesForNode:(UIScrollView*)node {
|
||||
SKNodeDescriptor* descriptor = [self descriptorForClass:[UIView class]];
|
||||
return [descriptor attributesForNode:node];
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIScrollView *)node {
|
||||
SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]];
|
||||
[descriptor setHighlighted: highlighted forNode: node];
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIScrollView*)node {
|
||||
SKNodeDescriptor* descriptor = [self descriptorForClass:[UIView class]];
|
||||
[descriptor setHighlighted:highlighted forNode:node];
|
||||
}
|
||||
|
||||
- (void)hitTest:(SKTouch *)touch forNode:(UIScrollView *)node {
|
||||
for (NSInteger index = [self childCountForNode: node] - 1; index >= 0; index--) {
|
||||
id<NSObject> childNode = [self childForNode: node atIndex: index];
|
||||
- (void)hitTest:(SKTouch*)touch forNode:(UIScrollView*)node {
|
||||
for (NSInteger index = [self childCountForNode:node] - 1; index >= 0;
|
||||
index--) {
|
||||
id<NSObject> childNode = [self childForNode:node atIndex:index];
|
||||
CGRect frame;
|
||||
|
||||
if ([childNode isKindOfClass: [UIViewController class]]) {
|
||||
UIViewController *child = (UIViewController *)childNode;
|
||||
if ([childNode isKindOfClass:[UIViewController class]]) {
|
||||
UIViewController* child = (UIViewController*)childNode;
|
||||
if (child.view.isHidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
frame = child.view.frame;
|
||||
} else {
|
||||
UIView *child = (UIView *)childNode;
|
||||
UIView* child = (UIView*)childNode;
|
||||
if (child.isHidden) {
|
||||
continue;
|
||||
}
|
||||
@@ -72,8 +73,8 @@
|
||||
frame.origin.x -= node.contentOffset.x;
|
||||
frame.origin.y -= node.contentOffset.y;
|
||||
|
||||
if ([touch containedIn: frame]) {
|
||||
[touch continueWithChildIndex: index withOffset: frame.origin];
|
||||
if ([touch containedIn:frame]) {
|
||||
[touch continueWithChildIndex:index withOffset:frame.origin];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
|
||||
#import "SKNodeDescriptor.h"
|
||||
|
||||
@interface SKViewControllerDescriptor : SKNodeDescriptor<UIViewController *>
|
||||
@interface SKViewControllerDescriptor : SKNodeDescriptor<UIViewController*>
|
||||
|
||||
@end
|
||||
|
||||
@@ -13,38 +13,35 @@
|
||||
|
||||
@implementation SKViewControllerDescriptor
|
||||
|
||||
- (NSString *)identifierForNode:(UIViewController *)node {
|
||||
return [NSString stringWithFormat: @"%p", node];
|
||||
- (NSString*)identifierForNode:(UIViewController*)node {
|
||||
return [NSString stringWithFormat:@"%p", node];
|
||||
}
|
||||
|
||||
- (NSUInteger)childCountForNode:(UIViewController *)node {
|
||||
- (NSUInteger)childCountForNode:(UIViewController*)node {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (id)childForNode:(UIViewController *)node atIndex:(NSUInteger)index {
|
||||
- (id)childForNode:(UIViewController*)node atIndex:(NSUInteger)index {
|
||||
return node.view;
|
||||
}
|
||||
|
||||
- (void)setHighlightedForNode:(UIViewController *)node {
|
||||
- (void)setHighlightedForNode:(UIViewController*)node {
|
||||
}
|
||||
|
||||
- (NSArray<SKNamed<NSString *> *> *)attributesForNode:(UIViewController *)node {
|
||||
return @[
|
||||
[SKNamed newWithName: @"addr"
|
||||
withValue: [NSString stringWithFormat: @"%p", node]]
|
||||
];
|
||||
- (NSArray<SKNamed<NSString*>*>*)attributesForNode:(UIViewController*)node {
|
||||
return @[ [SKNamed newWithName:@"addr"
|
||||
withValue:[NSString stringWithFormat:@"%p", node]] ];
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIViewController *)node {
|
||||
SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]];
|
||||
[descriptor setHighlighted: highlighted forNode: node.view];
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIViewController*)node {
|
||||
SKNodeDescriptor* descriptor = [self descriptorForClass:[UIView class]];
|
||||
[descriptor setHighlighted:highlighted forNode:node.view];
|
||||
}
|
||||
|
||||
- (void)hitTest:(SKTouch *)touch forNode:(UIViewController *)node {
|
||||
[touch continueWithChildIndex: 0 withOffset: (CGPoint){ 0, 0}];
|
||||
- (void)hitTest:(SKTouch*)touch forNode:(UIViewController*)node {
|
||||
[touch continueWithChildIndex:0 withOffset:(CGPoint){0, 0}];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#import "SKNodeDescriptor.h"
|
||||
|
||||
@interface SKViewDescriptor : SKNodeDescriptor<UIView *>
|
||||
@interface SKViewDescriptor : SKNodeDescriptor<UIView*>
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -9,59 +9,61 @@
|
||||
|
||||
#import "SKViewDescriptor.h"
|
||||
|
||||
#import <FlipperKitHighlightOverlay/SKHighlightOverlay.h>
|
||||
#import <YogaKit/UIView+Yoga.h>
|
||||
#import "SKDescriptorMapper.h"
|
||||
#import "SKNamed.h"
|
||||
#import "SKObject.h"
|
||||
#import "SKYogaKitHelper.h"
|
||||
#import "UIColor+SKSonarValueCoder.h"
|
||||
#import <YogaKit/UIView+Yoga.h>
|
||||
#import <FlipperKitHighlightOverlay/SKHighlightOverlay.h>
|
||||
|
||||
@implementation SKViewDescriptor
|
||||
|
||||
static NSDictionary *YGDirectionEnumMap = nil;
|
||||
static NSDictionary *YGFlexDirectionEnumMap = nil;
|
||||
static NSDictionary *YGJustifyEnumMap = nil;
|
||||
static NSDictionary *YGAlignEnumMap = nil;
|
||||
static NSDictionary *YGPositionTypeEnumMap = nil;
|
||||
static NSDictionary *YGWrapEnumMap = nil;
|
||||
static NSDictionary *YGOverflowEnumMap = nil;
|
||||
static NSDictionary *YGDisplayEnumMap = nil;
|
||||
static NSDictionary *YGUnitEnumMap = nil;
|
||||
static NSDictionary* YGDirectionEnumMap = nil;
|
||||
static NSDictionary* YGFlexDirectionEnumMap = nil;
|
||||
static NSDictionary* YGJustifyEnumMap = nil;
|
||||
static NSDictionary* YGAlignEnumMap = nil;
|
||||
static NSDictionary* YGPositionTypeEnumMap = nil;
|
||||
static NSDictionary* YGWrapEnumMap = nil;
|
||||
static NSDictionary* YGOverflowEnumMap = nil;
|
||||
static NSDictionary* YGDisplayEnumMap = nil;
|
||||
static NSDictionary* YGUnitEnumMap = nil;
|
||||
|
||||
- (instancetype)initWithDescriptorMapper:(SKDescriptorMapper *)mapper {
|
||||
if (self = [super initWithDescriptorMapper: mapper]) {
|
||||
- (instancetype)initWithDescriptorMapper:(SKDescriptorMapper*)mapper {
|
||||
if (self = [super initWithDescriptorMapper:mapper]) {
|
||||
initEnumDictionaries();
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)identifierForNode:(UIView *)node {
|
||||
return [NSString stringWithFormat: @"%p", node];
|
||||
- (NSString*)identifierForNode:(UIView*)node {
|
||||
return [NSString stringWithFormat:@"%p", node];
|
||||
}
|
||||
|
||||
- (NSUInteger)childCountForNode:(UIView *)node {
|
||||
return [[self validChildrenForNode: node] count];
|
||||
- (NSUInteger)childCountForNode:(UIView*)node {
|
||||
return [[self validChildrenForNode:node] count];
|
||||
}
|
||||
|
||||
- (id)childForNode:(UIView *)node atIndex:(NSUInteger)index {
|
||||
return [[self validChildrenForNode:node] objectAtIndex: index];
|
||||
- (id)childForNode:(UIView*)node atIndex:(NSUInteger)index {
|
||||
return [[self validChildrenForNode:node] objectAtIndex:index];
|
||||
}
|
||||
|
||||
- (NSArray *)validChildrenForNode:(UIView *)node {
|
||||
NSMutableArray *validChildren = [NSMutableArray new];
|
||||
- (NSArray*)validChildrenForNode:(UIView*)node {
|
||||
NSMutableArray* validChildren = [NSMutableArray new];
|
||||
|
||||
// Use UIViewControllers for children which responds to a different
|
||||
// viewController than their parent
|
||||
for (UIView *child in node.subviews) {
|
||||
BOOL responderIsUIViewController = [child.nextResponder isKindOfClass: [UIViewController class]];
|
||||
for (UIView* child in node.subviews) {
|
||||
BOOL responderIsUIViewController =
|
||||
[child.nextResponder isKindOfClass:[UIViewController class]];
|
||||
|
||||
if (!child.isHidden) {
|
||||
if (responderIsUIViewController && child.nextResponder != node.nextResponder) {
|
||||
[validChildren addObject: child.nextResponder];
|
||||
if (responderIsUIViewController &&
|
||||
child.nextResponder != node.nextResponder) {
|
||||
[validChildren addObject:child.nextResponder];
|
||||
} else {
|
||||
[validChildren addObject: child];
|
||||
[validChildren addObject:child];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,121 +71,165 @@ static NSDictionary *YGUnitEnumMap = nil;
|
||||
return validChildren;
|
||||
}
|
||||
|
||||
- (NSArray<SKNamed<NSDictionary *> *> *)dataForNode:(UIView *)node {
|
||||
return [NSArray arrayWithObjects:
|
||||
[SKNamed newWithName: @"UIView"
|
||||
withValue: @{
|
||||
@"frame": SKMutableObject(node.frame),
|
||||
@"bounds": SKObject(node.bounds),
|
||||
@"center": SKObject(node.center),
|
||||
@"layoutMargins": SKObject(node.layoutMargins),
|
||||
@"clipsToBounds": @(node.clipsToBounds),
|
||||
@"alpha": SKMutableObject(@(node.alpha)),
|
||||
@"tag": @(node.tag),
|
||||
@"backgroundColor": SKMutableObject(node.backgroundColor)
|
||||
}],
|
||||
[SKNamed newWithName: @"CALayer"
|
||||
withValue: @{
|
||||
@"shadowColor": SKMutableObject([UIColor colorWithCGColor:node.layer.shadowColor]),
|
||||
@"shadowOpacity": SKMutableObject(@(node.layer.shadowOpacity)),
|
||||
@"shadowRadius": SKMutableObject(@(node.layer.shadowRadius)),
|
||||
@"shadowOffset": SKMutableObject(node.layer.shadowOffset),
|
||||
@"backgroundColor": SKMutableObject([UIColor colorWithCGColor:node.layer.backgroundColor]),
|
||||
@"borderColor": SKMutableObject([UIColor colorWithCGColor:node.layer.borderColor]),
|
||||
@"borderWidth": SKMutableObject(@(node.layer.borderWidth)),
|
||||
@"cornerRadius": SKMutableObject(@(node.layer.cornerRadius)),
|
||||
@"masksToBounds": SKMutableObject(@(node.layer.masksToBounds)),
|
||||
}],
|
||||
[SKNamed newWithName: @"Accessibility"
|
||||
withValue: @{
|
||||
@"isAccessibilityElement": SKMutableObject(@(node.isAccessibilityElement)),
|
||||
@"accessibilityLabel": SKMutableObject(node.accessibilityLabel ?: @""),
|
||||
@"accessibilityIdentifier": SKMutableObject(node.accessibilityIdentifier ?: @""),
|
||||
@"accessibilityValue": SKMutableObject(node.accessibilityValue ?: @""),
|
||||
@"accessibilityHint": SKMutableObject(node.accessibilityHint ?: @""),
|
||||
@"accessibilityTraits": AccessibilityTraitsDict(node.accessibilityTraits),
|
||||
@"accessibilityViewIsModal": SKMutableObject(@(node.accessibilityViewIsModal)),
|
||||
@"shouldGroupAccessibilityChildren": SKMutableObject(@(node.shouldGroupAccessibilityChildren)),
|
||||
}],
|
||||
!node.isYogaEnabled ? nil :
|
||||
[SKNamed newWithName: @"YGLayout"
|
||||
withValue: @{
|
||||
@"direction": SKMutableObject(YGDirectionEnumMap[@(node.yoga.direction)]),
|
||||
@"justifyContent": SKMutableObject(YGJustifyEnumMap[@(node.yoga.justifyContent)]),
|
||||
@"aligns": @{
|
||||
@"alignContent": SKMutableObject(YGAlignEnumMap[@(node.yoga.alignContent)]),
|
||||
@"alignItems": SKMutableObject(YGAlignEnumMap[@(node.yoga.alignItems)]),
|
||||
@"alignSelf": SKMutableObject(YGAlignEnumMap[@(node.yoga.alignSelf)]),
|
||||
},
|
||||
@"position": @{
|
||||
@"type": SKMutableObject(YGPositionTypeEnumMap[@(node.yoga.position)]),
|
||||
@"left": SKYGValueObject(node.yoga.left),
|
||||
@"top": SKYGValueObject(node.yoga.top),
|
||||
@"right": SKYGValueObject(node.yoga.right),
|
||||
@"bottom": SKYGValueObject(node.yoga.bottom),
|
||||
@"start": SKYGValueObject(node.yoga.start),
|
||||
@"end": SKYGValueObject(node.yoga.end),
|
||||
},
|
||||
@"overflow": SKMutableObject(YGOverflowEnumMap[@(node.yoga.overflow)]),
|
||||
@"display": SKMutableObject(YGDisplayEnumMap[@(node.yoga.display)]),
|
||||
@"flex": @{
|
||||
@"flexDirection": SKMutableObject(YGFlexDirectionEnumMap[@(node.yoga.flexDirection)]),
|
||||
@"flexWrap": SKMutableObject(YGWrapEnumMap[@(node.yoga.flexWrap)]),
|
||||
@"flexGrow": SKMutableObject(@(node.yoga.flexGrow)),
|
||||
@"flexShrink": SKMutableObject(@(node.yoga.flexShrink)),
|
||||
@"flexBasis": SKYGValueObject(node.yoga.flexBasis),
|
||||
},
|
||||
@"margin": @{
|
||||
@"left": SKYGValueObject(node.yoga.marginLeft),
|
||||
@"top": SKYGValueObject(node.yoga.marginTop),
|
||||
@"right": SKYGValueObject(node.yoga.marginRight),
|
||||
@"bottom": SKYGValueObject(node.yoga.marginBottom),
|
||||
@"start": SKYGValueObject(node.yoga.marginStart),
|
||||
@"end": SKYGValueObject(node.yoga.marginEnd),
|
||||
@"horizontal": SKYGValueObject(node.yoga.marginHorizontal),
|
||||
@"vertical": SKYGValueObject(node.yoga.marginVertical),
|
||||
@"all": SKYGValueObject(node.yoga.margin),
|
||||
},
|
||||
@"padding": @{
|
||||
@"left": SKYGValueObject(node.yoga.paddingLeft),
|
||||
@"top": SKYGValueObject(node.yoga.paddingTop),
|
||||
@"right": SKYGValueObject(node.yoga.paddingRight),
|
||||
@"bottom": SKYGValueObject(node.yoga.paddingBottom),
|
||||
@"start": SKYGValueObject(node.yoga.paddingStart),
|
||||
@"end": SKYGValueObject(node.yoga.paddingEnd),
|
||||
@"horizontal": SKYGValueObject(node.yoga.paddingHorizontal),
|
||||
@"vertical": SKYGValueObject(node.yoga.paddingVertical),
|
||||
@"all": SKYGValueObject(node.yoga.padding),
|
||||
},
|
||||
@"border": @{
|
||||
@"leftWidth": SKMutableObject(@(node.yoga.borderLeftWidth)),
|
||||
@"topWidth": SKMutableObject(@(node.yoga.borderTopWidth)),
|
||||
@"rightWidth": SKMutableObject(@(node.yoga.borderRightWidth)),
|
||||
@"bottomWidth": SKMutableObject(@(node.yoga.borderBottomWidth)),
|
||||
@"startWidth": SKMutableObject(@(node.yoga.borderStartWidth)),
|
||||
@"endWidth": SKMutableObject(@(node.yoga.borderEndWidth)),
|
||||
@"all": SKMutableObject(@(node.yoga.borderWidth)),
|
||||
},
|
||||
@"dimensions": @{
|
||||
@"width": SKYGValueObject(node.yoga.width),
|
||||
@"height": SKYGValueObject(node.yoga.height),
|
||||
@"minWidth": SKYGValueObject(node.yoga.minWidth),
|
||||
@"minHeight": SKYGValueObject(node.yoga.minHeight),
|
||||
@"maxWidth": SKYGValueObject(node.yoga.maxWidth),
|
||||
@"maxHeight": SKYGValueObject(node.yoga.maxHeight),
|
||||
},
|
||||
@"aspectRatio": SKMutableObject(@(node.yoga.aspectRatio)),
|
||||
@"resolvedDirection": SKObject(YGDirectionEnumMap[@(node.yoga.resolvedDirection)]),
|
||||
}],
|
||||
- (NSArray<SKNamed<NSDictionary*>*>*)dataForNode:(UIView*)node {
|
||||
return [NSArray
|
||||
arrayWithObjects:
|
||||
[SKNamed
|
||||
newWithName:@"UIView"
|
||||
withValue:@{
|
||||
@"frame" : SKMutableObject(node.frame),
|
||||
@"bounds" : SKObject(node.bounds),
|
||||
@"center" : SKObject(node.center),
|
||||
@"layoutMargins" : SKObject(node.layoutMargins),
|
||||
@"clipsToBounds" : @(node.clipsToBounds),
|
||||
@"alpha" : SKMutableObject(@(node.alpha)),
|
||||
@"tag" : @(node.tag),
|
||||
@"backgroundColor" : SKMutableObject(node.backgroundColor)
|
||||
}],
|
||||
[SKNamed
|
||||
newWithName:@"CALayer"
|
||||
withValue:@{
|
||||
@"shadowColor" : SKMutableObject(
|
||||
[UIColor colorWithCGColor:node.layer.shadowColor]),
|
||||
@"shadowOpacity" :
|
||||
SKMutableObject(@(node.layer.shadowOpacity)),
|
||||
@"shadowRadius" : SKMutableObject(@(node.layer.shadowRadius)),
|
||||
@"shadowOffset" : SKMutableObject(node.layer.shadowOffset),
|
||||
@"backgroundColor" : SKMutableObject(
|
||||
[UIColor colorWithCGColor:node.layer.backgroundColor]),
|
||||
@"borderColor" : SKMutableObject(
|
||||
[UIColor colorWithCGColor:node.layer.borderColor]),
|
||||
@"borderWidth" : SKMutableObject(@(node.layer.borderWidth)),
|
||||
@"cornerRadius" : SKMutableObject(@(node.layer.cornerRadius)),
|
||||
@"masksToBounds" :
|
||||
SKMutableObject(@(node.layer.masksToBounds)),
|
||||
}],
|
||||
[SKNamed newWithName:@"Accessibility"
|
||||
withValue:@{
|
||||
@"isAccessibilityElement" :
|
||||
SKMutableObject(@(node.isAccessibilityElement)),
|
||||
@"accessibilityLabel" :
|
||||
SKMutableObject(node.accessibilityLabel ?: @""),
|
||||
@"accessibilityIdentifier" :
|
||||
SKMutableObject(node.accessibilityIdentifier ?: @""),
|
||||
@"accessibilityValue" :
|
||||
SKMutableObject(node.accessibilityValue ?: @""),
|
||||
@"accessibilityHint" :
|
||||
SKMutableObject(node.accessibilityHint ?: @""),
|
||||
@"accessibilityTraits" :
|
||||
AccessibilityTraitsDict(node.accessibilityTraits),
|
||||
@"accessibilityViewIsModal" :
|
||||
SKMutableObject(@(node.accessibilityViewIsModal)),
|
||||
@"shouldGroupAccessibilityChildren" : SKMutableObject(
|
||||
@(node.shouldGroupAccessibilityChildren)),
|
||||
}],
|
||||
!node.isYogaEnabled
|
||||
? nil
|
||||
: [SKNamed
|
||||
newWithName:@"YGLayout"
|
||||
withValue:@{
|
||||
@"direction" : SKMutableObject(
|
||||
YGDirectionEnumMap[@(node.yoga.direction)]),
|
||||
@"justifyContent" : SKMutableObject(
|
||||
YGJustifyEnumMap[@(node.yoga.justifyContent)]),
|
||||
@"aligns" : @{
|
||||
@"alignContent" : SKMutableObject(
|
||||
YGAlignEnumMap[@(node.yoga.alignContent)]),
|
||||
@"alignItems" : SKMutableObject(
|
||||
YGAlignEnumMap[@(node.yoga.alignItems)]),
|
||||
@"alignSelf" : SKMutableObject(
|
||||
YGAlignEnumMap[@(node.yoga.alignSelf)]),
|
||||
},
|
||||
@"position" : @{
|
||||
@"type" : SKMutableObject(
|
||||
YGPositionTypeEnumMap[@(node.yoga.position)]),
|
||||
@"left" : SKYGValueObject(node.yoga.left),
|
||||
@"top" : SKYGValueObject(node.yoga.top),
|
||||
@"right" : SKYGValueObject(node.yoga.right),
|
||||
@"bottom" : SKYGValueObject(node.yoga.bottom),
|
||||
@"start" : SKYGValueObject(node.yoga.start),
|
||||
@"end" : SKYGValueObject(node.yoga.end),
|
||||
},
|
||||
@"overflow" : SKMutableObject(
|
||||
YGOverflowEnumMap[@(node.yoga.overflow)]),
|
||||
@"display" : SKMutableObject(
|
||||
YGDisplayEnumMap[@(node.yoga.display)]),
|
||||
@"flex" : @{
|
||||
@"flexDirection" :
|
||||
SKMutableObject(YGFlexDirectionEnumMap[
|
||||
@(node.yoga.flexDirection)]),
|
||||
@"flexWrap" : SKMutableObject(
|
||||
YGWrapEnumMap[@(node.yoga.flexWrap)]),
|
||||
@"flexGrow" : SKMutableObject(@(node.yoga.flexGrow)),
|
||||
@"flexShrink" :
|
||||
SKMutableObject(@(node.yoga.flexShrink)),
|
||||
@"flexBasis" : SKYGValueObject(node.yoga.flexBasis),
|
||||
},
|
||||
@"margin" : @{
|
||||
@"left" : SKYGValueObject(node.yoga.marginLeft),
|
||||
@"top" : SKYGValueObject(node.yoga.marginTop),
|
||||
@"right" : SKYGValueObject(node.yoga.marginRight),
|
||||
@"bottom" : SKYGValueObject(node.yoga.marginBottom),
|
||||
@"start" : SKYGValueObject(node.yoga.marginStart),
|
||||
@"end" : SKYGValueObject(node.yoga.marginEnd),
|
||||
@"horizontal" :
|
||||
SKYGValueObject(node.yoga.marginHorizontal),
|
||||
@"vertical" :
|
||||
SKYGValueObject(node.yoga.marginVertical),
|
||||
@"all" : SKYGValueObject(node.yoga.margin),
|
||||
},
|
||||
@"padding" : @{
|
||||
@"left" : SKYGValueObject(node.yoga.paddingLeft),
|
||||
@"top" : SKYGValueObject(node.yoga.paddingTop),
|
||||
@"right" : SKYGValueObject(node.yoga.paddingRight),
|
||||
@"bottom" : SKYGValueObject(node.yoga.paddingBottom),
|
||||
@"start" : SKYGValueObject(node.yoga.paddingStart),
|
||||
@"end" : SKYGValueObject(node.yoga.paddingEnd),
|
||||
@"horizontal" :
|
||||
SKYGValueObject(node.yoga.paddingHorizontal),
|
||||
@"vertical" :
|
||||
SKYGValueObject(node.yoga.paddingVertical),
|
||||
@"all" : SKYGValueObject(node.yoga.padding),
|
||||
},
|
||||
@"border" : @{
|
||||
@"leftWidth" :
|
||||
SKMutableObject(@(node.yoga.borderLeftWidth)),
|
||||
@"topWidth" :
|
||||
SKMutableObject(@(node.yoga.borderTopWidth)),
|
||||
@"rightWidth" :
|
||||
SKMutableObject(@(node.yoga.borderRightWidth)),
|
||||
@"bottomWidth" :
|
||||
SKMutableObject(@(node.yoga.borderBottomWidth)),
|
||||
@"startWidth" :
|
||||
SKMutableObject(@(node.yoga.borderStartWidth)),
|
||||
@"endWidth" :
|
||||
SKMutableObject(@(node.yoga.borderEndWidth)),
|
||||
@"all" : SKMutableObject(@(node.yoga.borderWidth)),
|
||||
},
|
||||
@"dimensions" : @{
|
||||
@"width" : SKYGValueObject(node.yoga.width),
|
||||
@"height" : SKYGValueObject(node.yoga.height),
|
||||
@"minWidth" : SKYGValueObject(node.yoga.minWidth),
|
||||
@"minHeight" : SKYGValueObject(node.yoga.minHeight),
|
||||
@"maxWidth" : SKYGValueObject(node.yoga.maxWidth),
|
||||
@"maxHeight" : SKYGValueObject(node.yoga.maxHeight),
|
||||
},
|
||||
@"aspectRatio" :
|
||||
SKMutableObject(@(node.yoga.aspectRatio)),
|
||||
@"resolvedDirection" : SKObject(
|
||||
YGDirectionEnumMap[@(node.yoga.resolvedDirection)]),
|
||||
}],
|
||||
nil];
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, SKNodeUpdateData> *)dataMutationsForNode:(UIView *)node {
|
||||
- (NSDictionary<NSString*, SKNodeUpdateData>*)dataMutationsForNode:
|
||||
(UIView*)node {
|
||||
return @{
|
||||
// UIView
|
||||
@"UIView.alpha": ^(NSNumber *value) {
|
||||
node.alpha = [value floatValue];
|
||||
},
|
||||
@"UIView.alpha" : ^(NSNumber* value){
|
||||
node.alpha = [value floatValue];
|
||||
}
|
||||
,
|
||||
@"UIView.backgroundColor": ^(NSNumber *value) {
|
||||
node.backgroundColor = [UIColor fromSonarValue: value];
|
||||
},
|
||||
@@ -415,43 +461,43 @@ static NSDictionary *YGUnitEnumMap = nil;
|
||||
@"Accessibility.shouldGroupAccessibilityChildren": ^(NSNumber *value) {
|
||||
node.shouldGroupAccessibilityChildren = [value boolValue];
|
||||
},
|
||||
};
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
- (NSArray<SKNamed<NSString *> *> *)attributesForNode:(UIView *)node {
|
||||
return @[
|
||||
[SKNamed newWithName: @"addr"
|
||||
withValue: [NSString stringWithFormat: @"%p", node]]
|
||||
];
|
||||
- (NSArray<SKNamed<NSString*>*>*)attributesForNode:(UIView*)node {
|
||||
return @[ [SKNamed newWithName:@"addr"
|
||||
withValue:[NSString stringWithFormat:@"%p", node]] ];
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIView *)node {
|
||||
SKHighlightOverlay *overlay = [SKHighlightOverlay sharedInstance];
|
||||
- (void)setHighlighted:(BOOL)highlighted forNode:(UIView*)node {
|
||||
SKHighlightOverlay* overlay = [SKHighlightOverlay sharedInstance];
|
||||
if (highlighted == YES) {
|
||||
[overlay mountInView: node withFrame: node.bounds];
|
||||
[overlay mountInView:node withFrame:node.bounds];
|
||||
} else {
|
||||
[overlay unmount];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)hitTest:(SKTouch *)touch forNode:(UIView *)node {
|
||||
for (NSInteger index = [self childCountForNode: node] - 1; index >= 0; index--) {
|
||||
id<NSObject> childNode = [self childForNode: node atIndex: index];
|
||||
UIView *viewForNode = nil;
|
||||
- (void)hitTest:(SKTouch*)touch forNode:(UIView*)node {
|
||||
for (NSInteger index = [self childCountForNode:node] - 1; index >= 0;
|
||||
index--) {
|
||||
id<NSObject> childNode = [self childForNode:node atIndex:index];
|
||||
UIView* viewForNode = nil;
|
||||
|
||||
if ([childNode isKindOfClass: [UIViewController class]]) {
|
||||
UIViewController *child = (UIViewController *)childNode;
|
||||
if ([childNode isKindOfClass:[UIViewController class]]) {
|
||||
UIViewController* child = (UIViewController*)childNode;
|
||||
viewForNode = child.view;
|
||||
} else {
|
||||
viewForNode = (UIView *)childNode;
|
||||
viewForNode = (UIView*)childNode;
|
||||
}
|
||||
|
||||
if (viewForNode.isHidden || viewForNode.alpha <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([touch containedIn: viewForNode.frame]) {
|
||||
[touch continueWithChildIndex: index withOffset: viewForNode.frame.origin ];
|
||||
if ([touch containedIn:viewForNode.frame]) {
|
||||
[touch continueWithChildIndex:index withOffset:viewForNode.frame.origin];
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -463,73 +509,73 @@ static void initEnumDictionaries() {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
YGDirectionEnumMap = @{
|
||||
@(YGDirectionInherit): @"inherit",
|
||||
@(YGDirectionLTR): @"LTR",
|
||||
@(YGDirectionRTL): @"RTL",
|
||||
};
|
||||
@(YGDirectionInherit) : @"inherit",
|
||||
@(YGDirectionLTR) : @"LTR",
|
||||
@(YGDirectionRTL) : @"RTL",
|
||||
};
|
||||
|
||||
YGFlexDirectionEnumMap = @{
|
||||
@(YGFlexDirectionColumn): @"column",
|
||||
@(YGFlexDirectionColumnReverse): @"column-reverse",
|
||||
@(YGFlexDirectionRow): @"row",
|
||||
@(YGFlexDirectionRowReverse): @"row-reverse",
|
||||
};
|
||||
@(YGFlexDirectionColumn) : @"column",
|
||||
@(YGFlexDirectionColumnReverse) : @"column-reverse",
|
||||
@(YGFlexDirectionRow) : @"row",
|
||||
@(YGFlexDirectionRowReverse) : @"row-reverse",
|
||||
};
|
||||
|
||||
YGJustifyEnumMap = @{
|
||||
@(YGJustifyFlexStart): @"flex-start",
|
||||
@(YGJustifyCenter): @"center",
|
||||
@(YGJustifyFlexEnd): @"flex-end",
|
||||
@(YGJustifySpaceBetween): @"space-between",
|
||||
@(YGJustifySpaceAround): @"space-around",
|
||||
};
|
||||
@(YGJustifyFlexStart) : @"flex-start",
|
||||
@(YGJustifyCenter) : @"center",
|
||||
@(YGJustifyFlexEnd) : @"flex-end",
|
||||
@(YGJustifySpaceBetween) : @"space-between",
|
||||
@(YGJustifySpaceAround) : @"space-around",
|
||||
};
|
||||
|
||||
YGAlignEnumMap = @{
|
||||
@(YGAlignAuto): @"auto",
|
||||
@(YGAlignFlexStart): @"flex-start",
|
||||
@(YGAlignCenter): @"end",
|
||||
@(YGAlignFlexEnd): @"flex-end",
|
||||
@(YGAlignStretch): @"stretch",
|
||||
@(YGAlignBaseline): @"baseline",
|
||||
@(YGAlignSpaceBetween): @"space-between",
|
||||
@(YGAlignSpaceAround): @"space-around",
|
||||
};
|
||||
@(YGAlignAuto) : @"auto",
|
||||
@(YGAlignFlexStart) : @"flex-start",
|
||||
@(YGAlignCenter) : @"end",
|
||||
@(YGAlignFlexEnd) : @"flex-end",
|
||||
@(YGAlignStretch) : @"stretch",
|
||||
@(YGAlignBaseline) : @"baseline",
|
||||
@(YGAlignSpaceBetween) : @"space-between",
|
||||
@(YGAlignSpaceAround) : @"space-around",
|
||||
};
|
||||
|
||||
YGPositionTypeEnumMap = @{
|
||||
@(YGPositionTypeRelative): @"relative",
|
||||
@(YGPositionTypeAbsolute): @"absolute",
|
||||
};
|
||||
@(YGPositionTypeRelative) : @"relative",
|
||||
@(YGPositionTypeAbsolute) : @"absolute",
|
||||
};
|
||||
|
||||
YGWrapEnumMap = @{
|
||||
@(YGWrapNoWrap): @"no-wrap",
|
||||
@(YGWrapWrap): @"wrap",
|
||||
@(YGWrapWrapReverse): @"wrap-reverse",
|
||||
};
|
||||
@(YGWrapNoWrap) : @"no-wrap",
|
||||
@(YGWrapWrap) : @"wrap",
|
||||
@(YGWrapWrapReverse) : @"wrap-reverse",
|
||||
};
|
||||
|
||||
YGOverflowEnumMap = @{
|
||||
@(YGOverflowVisible): @"visible",
|
||||
@(YGOverflowHidden): @"hidden",
|
||||
@(YGOverflowScroll): @"scroll",
|
||||
};
|
||||
@(YGOverflowVisible) : @"visible",
|
||||
@(YGOverflowHidden) : @"hidden",
|
||||
@(YGOverflowScroll) : @"scroll",
|
||||
};
|
||||
|
||||
YGDisplayEnumMap = @{
|
||||
@(YGDisplayFlex): @"flex",
|
||||
@(YGDisplayNone): @"none",
|
||||
};
|
||||
@(YGDisplayFlex) : @"flex",
|
||||
@(YGDisplayNone) : @"none",
|
||||
};
|
||||
|
||||
YGUnitEnumMap = @{
|
||||
@(YGUnitUndefined): @"undefined",
|
||||
@(YGUnitPoint): @"point",
|
||||
@(YGUnitPercent): @"percent",
|
||||
@(YGUnitAuto): @"auto",
|
||||
};
|
||||
@(YGUnitUndefined) : @"undefined",
|
||||
@(YGUnitPoint) : @"point",
|
||||
@(YGUnitPercent) : @"percent",
|
||||
@(YGUnitAuto) : @"auto",
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
static NSDictionary *SKYGValueObject(YGValue value) {
|
||||
static NSDictionary* SKYGValueObject(YGValue value) {
|
||||
return @{
|
||||
@"value": SKMutableObject(@(value.value)),
|
||||
@"unit": SKMutableObject(YGUnitEnumMap[@(value.unit)]),
|
||||
};
|
||||
@"value" : SKMutableObject(@(value.value)),
|
||||
@"unit" : SKMutableObject(YGUnitEnumMap[@(value.unit)]),
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -537,36 +583,60 @@ static NSDictionary *SKYGValueObject(YGValue value) {
|
||||
e.g. originalTraits = UIAccessibilityTraitButton | UIAccessibilityTraitSelected
|
||||
toggleTraits = UIAccessibilityTraitImage
|
||||
toggleValue = YES
|
||||
return value = UIAccessibilityTraitButton | UIAccessibilityTraitSelected | UIAccessibilityTraitImage
|
||||
return value = UIAccessibilityTraitButton | UIAccessibilityTraitSelected |
|
||||
UIAccessibilityTraitImage
|
||||
*/
|
||||
static UIAccessibilityTraits AccessibilityTraitsToggle(UIAccessibilityTraits originalTraits, UIAccessibilityTraits toggleTraits, BOOL toggleValue) {
|
||||
// NEGATE all bits of toggleTraits from originalTraits and OR it against either toggleTraits or 0 (UIAccessibilityTraitNone) based on toggleValue
|
||||
UIAccessibilityTraits bitsValue = toggleValue ? toggleTraits : UIAccessibilityTraitNone;
|
||||
static UIAccessibilityTraits AccessibilityTraitsToggle(
|
||||
UIAccessibilityTraits originalTraits,
|
||||
UIAccessibilityTraits toggleTraits,
|
||||
BOOL toggleValue) {
|
||||
// NEGATE all bits of toggleTraits from originalTraits and OR it against
|
||||
// either toggleTraits or 0 (UIAccessibilityTraitNone) based on toggleValue
|
||||
UIAccessibilityTraits bitsValue =
|
||||
toggleValue ? toggleTraits : UIAccessibilityTraitNone;
|
||||
return (originalTraits & ~(toggleTraits)) | bitsValue;
|
||||
}
|
||||
|
||||
static NSDictionary *AccessibilityTraitsDict(UIAccessibilityTraits accessibilityTraits) {
|
||||
NSMutableDictionary *traitsDict = [NSMutableDictionary new];
|
||||
static NSDictionary* AccessibilityTraitsDict(
|
||||
UIAccessibilityTraits accessibilityTraits) {
|
||||
NSMutableDictionary* traitsDict = [NSMutableDictionary new];
|
||||
[traitsDict addEntriesFromDictionary:@{
|
||||
@"UIAccessibilityTraitButton": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitButton))),
|
||||
@"UIAccessibilityTraitLink": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitLink))),
|
||||
@"UIAccessibilityTraitHeader": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitHeader))),
|
||||
@"UIAccessibilityTraitSearchField": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitSearchField))),
|
||||
@"UIAccessibilityTraitImage": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitImage))),
|
||||
@"UIAccessibilityTraitSelected": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitSelected))),
|
||||
@"UIAccessibilityTraitPlaysSound": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitPlaysSound))),
|
||||
@"UIAccessibilityTraitKeyboardKey": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitKeyboardKey))),
|
||||
@"UIAccessibilityTraitStaticText": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitStaticText))),
|
||||
@"UIAccessibilityTraitSummaryElement": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitSummaryElement))),
|
||||
@"UIAccessibilityTraitNotEnabled": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitNotEnabled))),
|
||||
@"UIAccessibilityTraitUpdatesFrequently": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitUpdatesFrequently))),
|
||||
@"UIAccessibilityTraitStartsMediaSession": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitStartsMediaSession))),
|
||||
@"UIAccessibilityTraitAdjustable": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitAdjustable))),
|
||||
@"UIAccessibilityTraitAllowsDirectInteraction": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitAllowsDirectInteraction))),
|
||||
@"UIAccessibilityTraitCausesPageTurn": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitCausesPageTurn))),
|
||||
}];
|
||||
@"UIAccessibilityTraitButton" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitButton))),
|
||||
@"UIAccessibilityTraitLink" :
|
||||
SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitLink))),
|
||||
@"UIAccessibilityTraitHeader" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitHeader))),
|
||||
@"UIAccessibilityTraitSearchField" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitSearchField))),
|
||||
@"UIAccessibilityTraitImage" :
|
||||
SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitImage))),
|
||||
@"UIAccessibilityTraitSelected" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitSelected))),
|
||||
@"UIAccessibilityTraitPlaysSound" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitPlaysSound))),
|
||||
@"UIAccessibilityTraitKeyboardKey" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitKeyboardKey))),
|
||||
@"UIAccessibilityTraitStaticText" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitStaticText))),
|
||||
@"UIAccessibilityTraitSummaryElement" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitSummaryElement))),
|
||||
@"UIAccessibilityTraitNotEnabled" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitNotEnabled))),
|
||||
@"UIAccessibilityTraitUpdatesFrequently" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitUpdatesFrequently))),
|
||||
@"UIAccessibilityTraitStartsMediaSession" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitStartsMediaSession))),
|
||||
@"UIAccessibilityTraitAdjustable" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitAdjustable))),
|
||||
@"UIAccessibilityTraitAllowsDirectInteraction" : SKMutableObject(@(
|
||||
!!(accessibilityTraits & UIAccessibilityTraitAllowsDirectInteraction))),
|
||||
@"UIAccessibilityTraitCausesPageTurn" : SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitCausesPageTurn))),
|
||||
}];
|
||||
if (@available(iOS 10.0, *)) {
|
||||
traitsDict[@"UIAccessibilityTraitTabBar"] = SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitTabBar)));
|
||||
traitsDict[@"UIAccessibilityTraitTabBar"] = SKMutableObject(
|
||||
@(!!(accessibilityTraits & UIAccessibilityTraitTabBar)));
|
||||
}
|
||||
return traitsDict;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
as keys in C++ STL
|
||||
*/
|
||||
class SKObjectHash {
|
||||
public:
|
||||
size_t operator()(const NSObject *x) const {
|
||||
public:
|
||||
size_t operator()(const NSObject* x) const {
|
||||
return (size_t)[x hash];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -16,14 +16,18 @@ void swizzleMethods(Class cls, SEL original, SEL swissled) {
|
||||
Method originalMethod = class_getInstanceMethod(cls, original);
|
||||
Method swissledMethod = class_getInstanceMethod(cls, swissled);
|
||||
|
||||
BOOL didAddMethod = class_addMethod(cls, original,
|
||||
method_getImplementation(swissledMethod),
|
||||
method_getTypeEncoding(swissledMethod));
|
||||
BOOL didAddMethod = class_addMethod(
|
||||
cls,
|
||||
original,
|
||||
method_getImplementation(swissledMethod),
|
||||
method_getTypeEncoding(swissledMethod));
|
||||
|
||||
if (didAddMethod) {
|
||||
class_replaceMethod(cls, swissled,
|
||||
method_getImplementation(originalMethod),
|
||||
method_getTypeEncoding(originalMethod));
|
||||
class_replaceMethod(
|
||||
cls,
|
||||
swissled,
|
||||
method_getImplementation(originalMethod),
|
||||
method_getTypeEncoding(originalMethod));
|
||||
} else {
|
||||
method_exchangeImplementations(originalMethod, swissledMethod);
|
||||
}
|
||||
|
||||
@@ -7,25 +7,31 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#define APPLY_ENUM_TO_YOGA_PROPERTY(varName, enumName) \
|
||||
^(NSString *newValue) { \
|
||||
NSNumber *varName = [[enumName##EnumMap allKeysForObject:newValue] lastObject]; \
|
||||
if (varName == nil) { return; } \
|
||||
node.yoga.varName = (enumName)[varName unsignedIntegerValue]; \
|
||||
}
|
||||
#define APPLY_ENUM_TO_YOGA_PROPERTY(varName, enumName) \
|
||||
^(NSString * newValue) { \
|
||||
NSNumber* varName = \
|
||||
[[enumName##EnumMap allKeysForObject:newValue] lastObject]; \
|
||||
if (varName == nil) { \
|
||||
return; \
|
||||
} \
|
||||
node.yoga.varName = (enumName)[varName unsignedIntegerValue]; \
|
||||
}
|
||||
|
||||
#define APPLY_VALUE_TO_YGVALUE(varName) \
|
||||
^(NSNumber *value) { \
|
||||
YGValue newValue = node.yoga.varName; \
|
||||
newValue.value = [value floatValue]; \
|
||||
node.yoga.varName = newValue; \
|
||||
}
|
||||
#define APPLY_VALUE_TO_YGVALUE(varName) \
|
||||
^(NSNumber * value) { \
|
||||
YGValue newValue = node.yoga.varName; \
|
||||
newValue.value = [value floatValue]; \
|
||||
node.yoga.varName = newValue; \
|
||||
}
|
||||
|
||||
#define APPLY_UNIT_TO_YGVALUE(varName, enumName) \
|
||||
^(NSString *value) { \
|
||||
NSNumber *varName = [[enumName##EnumMap allKeysForObject:value] lastObject]; \
|
||||
if (varName == nil) { return; } \
|
||||
YGValue newValue = node.yoga.varName; \
|
||||
newValue.unit = (enumName)[varName unsignedIntegerValue]; \
|
||||
node.yoga.varName = newValue; \
|
||||
}
|
||||
#define APPLY_UNIT_TO_YGVALUE(varName, enumName) \
|
||||
^(NSString * value) { \
|
||||
NSNumber* varName = \
|
||||
[[enumName##EnumMap allKeysForObject:value] lastObject]; \
|
||||
if (varName == nil) { \
|
||||
return; \
|
||||
} \
|
||||
YGValue newValue = node.yoga.varName; \
|
||||
newValue.unit = (enumName)[varName unsignedIntegerValue]; \
|
||||
node.yoga.varName = newValue; \
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user