From d488b308dec70c491f8689b2f3d89384066f04f0 Mon Sep 17 00:00:00 2001 From: Paco Estevez Garcia Date: Thu, 27 Aug 2020 05:32:38 -0700 Subject: [PATCH] Add support for tagged messages on the Layout Inspector Summary: Related diff [Litho]: D23243009 This diff adds support for a protocol for layout messages where the type is recursively encoded as: ``` { kind: "type", data: ??? } ``` We check if the message adheres to the new encoding, otherwise we fall back to the old behavior. If it's the new encoding, the message is traversed recursively flattening the types to EditorValue using the type hints provided. Reviewed By: Andrey-Mishanin Differential Revision: D23319619 fbshipit-source-id: 79e8886f8f5a0aea4ec32938f1d5cd2fd645a297 --- .../FlipperKitLayoutPlugin.mm | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm index 1badbc419..f7c7e1adf 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm @@ -20,6 +20,9 @@ #import "SKTapListener.h" #import "SKTapListenerImpl.h" +NSObject* parseLayoutEditorMessage(NSObject* message); +NSObject* flattenLayoutEditorMessage(NSObject* field); + @implementation FlipperKitLayoutPlugin { NSMapTable* _trackedObjects; NSString* _lastHighlightedNode; @@ -246,6 +249,8 @@ return; } + value = parseLayoutEditorMessage(value); + SKNodeDescriptor* descriptor = [_descriptorMapper descriptorForClass:[node class]]; @@ -270,6 +275,45 @@ } } +/** + Layout editor messages are tagged with the types they contain, allowing for + heterogeneous NSArray and NSDictionary supported by Android and iOS. The method + parseLayoutEditorMessage traverses the message and flattens the messages to + their original types. + */ +NSObject* parseLayoutEditorMessage(NSObject* message) { + if ([message isKindOfClass:[NSDictionary class]]) { + NSDictionary* wrapper = (NSDictionary*)message; + if (wrapper[@"kind"]) { + NSObject* newData = wrapper[@"data"]; + return flattenLayoutEditorMessage(newData); + } + } + return message; +} + +NSObject* flattenLayoutEditorMessage(NSObject* field) { + if ([field isKindOfClass:[NSDictionary class]]) { + NSDictionary* wrapper = (NSDictionary*)field; + NSMutableDictionary* dictionary = + [[NSMutableDictionary alloc] initWithCapacity:[wrapper count]]; + for (NSString* key in wrapper) { + NSObject* value = wrapper[key]; + dictionary[key] = parseLayoutEditorMessage(value); + } + return dictionary; + } else if ([field isKindOfClass:[NSArray class]]) { + NSArray* wrapper = (NSArray*)field; + NSMutableArray* array = + [[NSMutableArray alloc] initWithCapacity:[wrapper count]]; + for (NSObject* value in wrapper) { + [array addObject:parseLayoutEditorMessage(value)]; + } + return array; + } + return field; +} + - (void)onCallGetSearchResults:(NSString*)query withResponder:(id)responder { const auto alreadyAddedElements = [NSMutableSet new];