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:
Pritesh Nandgaonkar
2020-02-17 10:46:43 -08:00
committed by Facebook Github Bot
parent a19a430eee
commit e8b20d5b15
101 changed files with 3918 additions and 2867 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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];
}

View File

@@ -21,6 +21,6 @@
+ (void)enableInvalidations;
@property (nonatomic, weak) id<SKInvalidationDelegate> delegate;
@property(nonatomic, weak) id<SKInvalidationDelegate> delegate;
@end

View File

@@ -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

View File

@@ -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

View File

@@ -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];
}

View File

@@ -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

View File

@@ -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

View File

@@ -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();
};

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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

View File

@@ -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;

View File

@@ -7,6 +7,7 @@
#import "SKTapListener.h"
@interface SKTapListenerImpl : NSObject<SKTapListener, UIGestureRecognizerDelegate>
@interface SKTapListenerImpl
: NSObject<SKTapListener, UIGestureRecognizerDelegate>
@end

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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

View File

@@ -12,6 +12,6 @@
#import "SKObject.h"
FB_LINK_REQUIRE_CATEGORY(UIColor_SonarValueCoder)
@interface UIColor (SonarValueCoder) <SKSonarValueCoder>
@interface UIColor (SonarValueCoder)<SKSonarValueCoder>
@end

View File

@@ -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

View File

@@ -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];

View File

@@ -9,6 +9,6 @@
#import "SKNodeDescriptor.h"
@interface SKApplicationDescriptor : SKNodeDescriptor<UIApplication *>
@interface SKApplicationDescriptor : SKNodeDescriptor<UIApplication*>
@end

View File

@@ -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;
}

View File

@@ -11,6 +11,6 @@
@class UIButton;
@interface SKButtonDescriptor : SKNodeDescriptor<UIButton *>
@interface SKButtonDescriptor : SKNodeDescriptor<UIButton*>
@end

View File

@@ -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];
}

View File

@@ -9,6 +9,6 @@
#import "SKNodeDescriptor.h"
@interface SKScrollViewDescriptor : SKNodeDescriptor<UIScrollView *>
@interface SKScrollViewDescriptor : SKNodeDescriptor<UIScrollView*>
@end

View File

@@ -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;
}
}

View File

@@ -9,6 +9,6 @@
#import "SKNodeDescriptor.h"
@interface SKViewControllerDescriptor : SKNodeDescriptor<UIViewController *>
@interface SKViewControllerDescriptor : SKNodeDescriptor<UIViewController*>
@end

View File

@@ -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

View File

@@ -11,7 +11,7 @@
#import "SKNodeDescriptor.h"
@interface SKViewDescriptor : SKNodeDescriptor<UIView *>
@interface SKViewDescriptor : SKNodeDescriptor<UIView*>
@end

View File

@@ -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;
}

View File

@@ -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];
}
};

View File

@@ -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);
}

View File

@@ -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; \
}