From 4596a0f58c761ac0d38e3b3496355221655c3b53 Mon Sep 17 00:00:00 2001 From: Andrew Yates Date: Sat, 28 Dec 2019 07:56:45 +0000 Subject: [PATCH 01/56] Bump up IGListKit version (#1749) --- Texture.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Texture.podspec b/Texture.podspec index 8f4de9277..1dab227f6 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -45,7 +45,7 @@ Pod::Spec.new do |spec| end spec.subspec 'IGListKit' do |igl| - igl.dependency 'IGListKit', '~> 3.0' + igl.dependency 'IGListKit', '~> 4.0' igl.dependency 'Texture/Core' end From 6a2fdb2606e15feec17953208f9463bf191a9089 Mon Sep 17 00:00:00 2001 From: Hanton Yang Date: Sat, 28 Dec 2019 00:02:26 -0800 Subject: [PATCH 02/56] Use `queue` in `ASMainSerialQueue` (#1738) For removing the first element, time complexity of `NSMutableArray` is O(n) while `queue` is O(1), which is more efficient. --- Source/Details/ASMainSerialQueue.mm | 35 +++++++++++++---------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/Source/Details/ASMainSerialQueue.mm b/Source/Details/ASMainSerialQueue.mm index 8b77c654b..472214390 100644 --- a/Source/Details/ASMainSerialQueue.mm +++ b/Source/Details/ASMainSerialQueue.mm @@ -11,38 +11,29 @@ #import #import +#import @interface ASMainSerialQueue () { AS::Mutex _serialQueueLock; - NSMutableArray *_blocks; + std::queue _blocks; } @end @implementation ASMainSerialQueue -- (instancetype)init -{ - if (!(self = [super init])) { - return nil; - } - - _blocks = [[NSMutableArray alloc] init]; - return self; -} - - (NSUInteger)numberOfScheduledBlocks { AS::MutexLocker l(_serialQueueLock); - return _blocks.count; + return _blocks.size(); } - (void)performBlockOnMainThread:(dispatch_block_t)block { { AS::MutexLocker l(_serialQueueLock); - [_blocks addObject:block]; + _blocks.push(block); } [self runBlocks]; @@ -53,13 +44,11 @@ - (void)runBlocks dispatch_block_t mainThread = ^{ AS::UniqueLock l(self->_serialQueueLock); do { - dispatch_block_t block; - if (self->_blocks.count > 0) { - block = _blocks[0]; - [self->_blocks removeObjectAtIndex:0]; - } else { + if (_blocks.empty()) { break; } + dispatch_block_t block = _blocks.front(); + _blocks.pop(); { l.unlock(); block(); @@ -73,7 +62,15 @@ - (void)runBlocks - (NSString *)description { - return [[super description] stringByAppendingFormat:@" Blocks: %@", _blocks]; + NSString *desc = [super description]; + std::queue blocks = _blocks; + [desc stringByAppendingString:@" Blocks: "]; + while (!blocks.empty()) { + dispatch_block_t block = blocks.front(); + [desc stringByAppendingFormat:@"%@", block]; + blocks.pop(); + } + return desc; } @end From 005e2d5aa9b760c123240b85c86425c029319cc6 Mon Sep 17 00:00:00 2001 From: Andrew Yates Date: Thu, 2 Jan 2020 18:37:42 +0000 Subject: [PATCH 03/56] First pass at supporting new traits (#1568) --- Source/Details/ASTraitCollection.h | 8 ++++ Source/Details/ASTraitCollection.mm | 69 +++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/Source/Details/ASTraitCollection.h b/Source/Details/ASTraitCollection.h index 6378361dc..b896ca51c 100644 --- a/Source/Details/ASTraitCollection.h +++ b/Source/Details/ASTraitCollection.h @@ -47,6 +47,10 @@ typedef struct { unowned UIContentSizeCategory preferredContentSizeCategory API_AVAILABLE(ios(10.0)); CGSize containerSize; + + UIUserInterfaceLevel userInterfaceLevel API_AVAILABLE(ios(13.0)); + UIAccessibilityContrast accessibilityContrast API_AVAILABLE(ios(13.0)); + UILegibilityWeight legibilityWeight API_AVAILABLE(ios(13.0)); } ASPrimitiveTraitCollection; #pragma clang diagnostic pop @@ -148,6 +152,10 @@ AS_SUBCLASSING_RESTRICTED @property (readonly) CGSize containerSize; +@property (readonly) UIUserInterfaceLevel userInterfaceLevel API_AVAILABLE(ios(13.0)); +@property (readonly) UIAccessibilityContrast accessibilityContrast API_AVAILABLE(ios(13.0)); +@property (readonly) UILegibilityWeight legibilityWeight API_AVAILABLE(ios(13.0)); + - (BOOL)isEqualToTraitCollection:(ASTraitCollection *)traitCollection; @end diff --git a/Source/Details/ASTraitCollection.mm b/Source/Details/ASTraitCollection.mm index db37434bb..e07184f40 100644 --- a/Source/Details/ASTraitCollection.mm +++ b/Source/Details/ASTraitCollection.mm @@ -41,6 +41,11 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() { if (AS_AVAILABLE_IOS_TVOS(12, 10)) { tc.userInterfaceStyle = UIUserInterfaceStyleUnspecified; } + if(AS_AVAILABLE_IOS(13)){ + tc.userInterfaceLevel = UIUserInterfaceLevelUnspecified; + tc.accessibilityContrast = UIAccessibilityContrastUnspecified; + tc.legibilityWeight = UILegibilityWeightUnspecified; + } return tc; } @@ -61,6 +66,11 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra if (AS_AVAILABLE_IOS_TVOS(12, 10)) { environmentTraitCollection.userInterfaceStyle = traitCollection.userInterfaceStyle; } + if(AS_AVAILABLE_IOS(13)){ + environmentTraitCollection.userInterfaceLevel = traitCollection.userInterfaceLevel; + environmentTraitCollection.accessibilityContrast = traitCollection.accessibilityContrast; + environmentTraitCollection.legibilityWeight = traitCollection.legibilityWeight; + } return environmentTraitCollection; } @@ -169,6 +179,47 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr } } +// Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline +API_AVAILABLE(ios(13)) +ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentUserInterfaceLevel(UIUserInterfaceLevel userInterfaceLevel) { + switch (userInterfaceLevel) { + case UIUserInterfaceLevelBase: + return @"Base"; + case UIUserInterfaceLevelElevated: + return @"Elevated"; + default: + return @"Unspecified"; + } +} + +// Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline +API_AVAILABLE(ios(13)) +ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentAccessibilityContrast(UIAccessibilityContrast accessibilityContrast) { + switch (accessibilityContrast) { + case UIAccessibilityContrastNormal: + return @"Normal"; + case UIAccessibilityContrastHigh: + return @"High"; + default: + return @"Unspecified"; + } +} + +// Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline +API_AVAILABLE(ios(13)) +ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentLegibilityWeight(UILegibilityWeight legibilityWeight) { + switch (legibilityWeight) { + case UILegibilityWeightRegular: + return @"Regular"; + case UILegibilityWeightBold: + return @"Bold"; + default: + return @"Unspecified"; + } +} + + + NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection traits) { NSMutableArray *props = [NSMutableArray array]; [props addObject:@{ @"verticalSizeClass": AS_NSStringFromUIUserInterfaceSizeClass(traits.verticalSizeClass) }]; @@ -184,6 +235,11 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr [props addObject:@{ @"preferredContentSizeCategory": traits.preferredContentSizeCategory }]; [props addObject:@{ @"displayGamut": AS_NSStringFromUIDisplayGamut(traits.displayGamut) }]; } + if (AS_AVAILABLE_IOS(13)){ + [props addObject:@{ @"userInterfaceLevel": AS_NSStringFromUITraitEnvironmentUserInterfaceLevel(traits.userInterfaceLevel) }]; + [props addObject:@{ @"accessibilityContrast": AS_NSStringFromUITraitEnvironmentAccessibilityContrast(traits.accessibilityContrast) }]; + [props addObject:@{ @"legibilityWeight": AS_NSStringFromUITraitEnvironmentLegibilityWeight(traits.legibilityWeight) }]; + } [props addObject:@{ @"containerSize": NSStringFromCGSize(traits.containerSize) }]; return ASObjectDescriptionMakeWithoutObject(props); } @@ -244,6 +300,19 @@ - (UIContentSizeCategory)preferredContentSizeCategory { return _prim.preferredContentSizeCategory; } +- (UIUserInterfaceLevel)userInterfaceLevel +{ + return _prim.userInterfaceLevel; +} +- (UIAccessibilityContrast)accessibilityContrast +{ + return _prim.accessibilityContrast; +} +- (UILegibilityWeight)legibilityWeight +{ + return _prim.legibilityWeight; +} + - (NSUInteger)hash { return ASHashBytes(&_prim, sizeof(ASPrimitiveTraitCollection)); } From 69ae7ddf79fd6ddcf22f45f14fe9cb8a66049482 Mon Sep 17 00:00:00 2001 From: Hanton Yang Date: Thu, 2 Jan 2020 11:45:34 -0800 Subject: [PATCH 04/56] Simplify push_back `GroupNotify` (#1736) --- Source/Details/Transactions/_ASAsyncTransaction.mm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Source/Details/Transactions/_ASAsyncTransaction.mm b/Source/Details/Transactions/_ASAsyncTransaction.mm index cffe96d11..c23cad341 100644 --- a/Source/Details/Transactions/_ASAsyncTransaction.mm +++ b/Source/Details/Transactions/_ASAsyncTransaction.mm @@ -268,10 +268,7 @@ - (NSString *)description if (_pendingOperations == 0) { dispatch_async(queue, block); } else { - GroupNotify notify; - notify._block = block; - notify._queue = queue; - _notifyList.push_back(notify); + _notifyList.push_back({block, queue}); } } From 361aa5b5adf97c6c50fe5e5d3a9d113296cfab12 Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Thu, 2 Jan 2020 15:31:47 -0800 Subject: [PATCH 05/56] Remove references to xcpretty-travis-formatter (#1755) We now run our CI on GitHub Actions so this is no longer used. --- build.sh | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/build.sh b/build.sh index eeba23b06..620c9f62b 100755 --- a/build.sh +++ b/build.sh @@ -35,7 +35,7 @@ function build_example { -sdk "$SDK" \ -destination "$PLATFORM" \ -derivedDataPath "$DERIVED_DATA_PATH" \ - build | xcpretty $FORMATTER + build | xcpretty -s elif [ -f "${example}/Cartfile" ]; then echo "Using Carthage" local_repo=`pwd` @@ -50,7 +50,7 @@ function build_example { -scheme Sample \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build | xcpretty $FORMATTER + build | xcpretty -s cd ../.. fi @@ -66,12 +66,6 @@ MODE="$1" cleanup -if type xcpretty-travis-formatter &> /dev/null; then - FORMATTER="-f $(xcpretty-travis-formatter)" - else - FORMATTER="-s" -fi - case "$MODE" in tests|all) echo "Building & testing AsyncDisplayKit." @@ -81,7 +75,7 @@ tests|all) -scheme AsyncDisplayKit \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build-for-testing test | xcpretty $FORMATTER + build-for-testing test | xcpretty -s success="1" ;; @@ -100,7 +94,7 @@ tests_listkit) -scheme ASDKListKitTests \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build-for-testing test | xcpretty $FORMATTER + build-for-testing test | xcpretty -s success="1" ;; @@ -199,7 +193,7 @@ life-without-cocoapods|all) -scheme "Life Without CocoaPods" \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build | xcpretty $FORMATTER + build | xcpretty -s success="1" ;; @@ -211,7 +205,7 @@ framework|all) -scheme Sample \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build | xcpretty $FORMATTER + build | xcpretty -s success="1" ;; From 80ffcdfa09770e1ef7087871ea2b62ec064316f1 Mon Sep 17 00:00:00 2001 From: Christian Selig Date: Fri, 3 Jan 2020 13:20:31 -0400 Subject: [PATCH 06/56] Add empty ASViewController initializer to facilitate subclassing (#1754) --- Source/ASViewController.h | 9 +++++++++ Source/ASViewController.mm | 11 +++++++++++ .../Sample/ViewController.swift | 2 +- .../Sample/OverviewViewController.swift | 2 +- examples/Swift/Sample/ViewController.swift | 2 +- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Source/ASViewController.h b/Source/ASViewController.h index 94863298d..89c02d6f9 100644 --- a/Source/ASViewController.h +++ b/Source/ASViewController.h @@ -38,6 +38,15 @@ typedef ASTraitCollection * _Nonnull (^ASDisplayTraitsForTraitWindowSizeBlock)(C */ - (instancetype)initWithNode:(DisplayNodeType)node NS_DESIGNATED_INITIALIZER; +/** +* ASViewController initializer. Useful for interoperability with normal UIViewControllers. +* +* @return An ASViewController instance with a nil node whose root view will be backed by a standard UIView as with a normal UIViewController. +* +* @see ASVisibilityDepth +*/ +- (instancetype)init NS_DESIGNATED_INITIALIZER; + NS_ASSUME_NONNULL_END /** diff --git a/Source/ASViewController.mm b/Source/ASViewController.mm index a15a2144c..6bc855666 100644 --- a/Source/ASViewController.mm +++ b/Source/ASViewController.mm @@ -64,6 +64,17 @@ - (instancetype)initWithNode:(ASDisplayNode *)node return self; } +- (instancetype)init +{ + if (!(self = [super initWithNibName:nil bundle:nil])) { + return nil; + } + + [self _initializeInstance]; + + return self; +} + - (void)_initializeInstance { if (_node == nil) { diff --git a/examples/CustomCollectionView-Swift/Sample/ViewController.swift b/examples/CustomCollectionView-Swift/Sample/ViewController.swift index 3af629079..1e33a06f3 100644 --- a/examples/CustomCollectionView-Swift/Sample/ViewController.swift +++ b/examples/CustomCollectionView-Swift/Sample/ViewController.swift @@ -17,7 +17,7 @@ class ViewController: ASViewController, MosaicCollectionViewLa let _layoutInspector = MosaicCollectionViewLayoutInspector() let kNumberOfImages: UInt = 14 - init() { + override init() { let layout = MosaicCollectionViewLayout() layout.numberOfColumns = 3; layout.headerHeight = 44; diff --git a/examples/LayoutSpecExamples-Swift/Sample/OverviewViewController.swift b/examples/LayoutSpecExamples-Swift/Sample/OverviewViewController.swift index f306a12f2..0c9110a3b 100644 --- a/examples/LayoutSpecExamples-Swift/Sample/OverviewViewController.swift +++ b/examples/LayoutSpecExamples-Swift/Sample/OverviewViewController.swift @@ -13,7 +13,7 @@ class OverviewViewController: ASViewController { let tableNode = ASTableNode() let layoutExamples: [LayoutExampleNode.Type] - init() { + override init() { layoutExamples = [ HeaderWithRightAndLeftItems.self, PhotoWithInsetTextOverlay.self, diff --git a/examples/Swift/Sample/ViewController.swift b/examples/Swift/Sample/ViewController.swift index 0c94d86ac..8384906cb 100644 --- a/examples/Swift/Sample/ViewController.swift +++ b/examples/Swift/Sample/ViewController.swift @@ -29,7 +29,7 @@ final class ViewController: ASViewController, ASTableDataSource, fileprivate(set) var state: State = .empty - init() { + override init() { super.init(node: ASTableNode()) tableNode.delegate = self tableNode.dataSource = self From 8becd09b4ebc2b222c454213150f3657d60589d2 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Fri, 3 Jan 2020 10:06:37 -0800 Subject: [PATCH 07/56] Omit UIUserInterfaceLevel from tvOS build (#1757) - UIUserInterfaceLevel was added to ASTraitCollection in #1568. However, it's unavailable on tvOS and thus broke our podspec linting CI job. Fix by only include it if the build target is iOS. --- Source/Details/ASTraitCollection.h | 11 ++++++++--- Source/Details/ASTraitCollection.mm | 25 ++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Source/Details/ASTraitCollection.h b/Source/Details/ASTraitCollection.h index b896ca51c..f6ca95416 100644 --- a/Source/Details/ASTraitCollection.h +++ b/Source/Details/ASTraitCollection.h @@ -47,8 +47,10 @@ typedef struct { unowned UIContentSizeCategory preferredContentSizeCategory API_AVAILABLE(ios(10.0)); CGSize containerSize; - - UIUserInterfaceLevel userInterfaceLevel API_AVAILABLE(ios(13.0)); + +#if TARGET_OS_IOS + UIUserInterfaceLevel userInterfaceLevel API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos); +#endif UIAccessibilityContrast accessibilityContrast API_AVAILABLE(ios(13.0)); UILegibilityWeight legibilityWeight API_AVAILABLE(ios(13.0)); } ASPrimitiveTraitCollection; @@ -152,7 +154,10 @@ AS_SUBCLASSING_RESTRICTED @property (readonly) CGSize containerSize; -@property (readonly) UIUserInterfaceLevel userInterfaceLevel API_AVAILABLE(ios(13.0)); +#if TARGET_OS_IOS +@property (readonly) UIUserInterfaceLevel userInterfaceLevel API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos); +#endif + @property (readonly) UIAccessibilityContrast accessibilityContrast API_AVAILABLE(ios(13.0)); @property (readonly) UILegibilityWeight legibilityWeight API_AVAILABLE(ios(13.0)); diff --git a/Source/Details/ASTraitCollection.mm b/Source/Details/ASTraitCollection.mm index e07184f40..ded4a228f 100644 --- a/Source/Details/ASTraitCollection.mm +++ b/Source/Details/ASTraitCollection.mm @@ -41,8 +41,14 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() { if (AS_AVAILABLE_IOS_TVOS(12, 10)) { tc.userInterfaceStyle = UIUserInterfaceStyleUnspecified; } + +#if TARGET_OS_IOS if(AS_AVAILABLE_IOS(13)){ tc.userInterfaceLevel = UIUserInterfaceLevelUnspecified; + } +#endif + + if (AS_AVAILABLE_IOS(13)) { tc.accessibilityContrast = UIAccessibilityContrastUnspecified; tc.legibilityWeight = UILegibilityWeightUnspecified; } @@ -66,8 +72,14 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra if (AS_AVAILABLE_IOS_TVOS(12, 10)) { environmentTraitCollection.userInterfaceStyle = traitCollection.userInterfaceStyle; } + +#if TARGET_OS_IOS if(AS_AVAILABLE_IOS(13)){ environmentTraitCollection.userInterfaceLevel = traitCollection.userInterfaceLevel; + } +#endif + + if (AS_AVAILABLE_IOS(13)) { environmentTraitCollection.accessibilityContrast = traitCollection.accessibilityContrast; environmentTraitCollection.legibilityWeight = traitCollection.legibilityWeight; } @@ -180,7 +192,7 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr } // Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline -API_AVAILABLE(ios(13)) +API_AVAILABLE(ios(13)) API_UNAVAILABLE(tvos) ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentUserInterfaceLevel(UIUserInterfaceLevel userInterfaceLevel) { switch (userInterfaceLevel) { case UIUserInterfaceLevelBase: @@ -235,8 +247,14 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr [props addObject:@{ @"preferredContentSizeCategory": traits.preferredContentSizeCategory }]; [props addObject:@{ @"displayGamut": AS_NSStringFromUIDisplayGamut(traits.displayGamut) }]; } + +#if TARGET_OS_IOS if (AS_AVAILABLE_IOS(13)){ [props addObject:@{ @"userInterfaceLevel": AS_NSStringFromUITraitEnvironmentUserInterfaceLevel(traits.userInterfaceLevel) }]; + } +#endif + + if (AS_AVAILABLE_IOS(13)) { [props addObject:@{ @"accessibilityContrast": AS_NSStringFromUITraitEnvironmentAccessibilityContrast(traits.accessibilityContrast) }]; [props addObject:@{ @"legibilityWeight": AS_NSStringFromUITraitEnvironmentLegibilityWeight(traits.legibilityWeight) }]; } @@ -300,14 +318,19 @@ - (UIContentSizeCategory)preferredContentSizeCategory { return _prim.preferredContentSizeCategory; } + +#if TARGET_OS_IOS - (UIUserInterfaceLevel)userInterfaceLevel { return _prim.userInterfaceLevel; } +#endif + - (UIAccessibilityContrast)accessibilityContrast { return _prim.accessibilityContrast; } + - (UILegibilityWeight)legibilityWeight { return _prim.legibilityWeight; From cfaa55cdb48d5297c680020923216c397bcaa9d3 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Fri, 3 Jan 2020 11:55:11 -0800 Subject: [PATCH 08/56] Link to IGListDiffKit in our IGListKit subspec (#1756) - In IGListDiff is no longer part of IGListKit as of 4.0. It has its own podspec now. After bumping our IGListKit dependency of our subspec, we got an "Undefined symbol: _IGListDiff" error which breaks podspec linting CI job (as well as some of our clients as reported in #1749). - To fix it, we can either remove the IGListDiff dependency since it's used once in the entire project, or link to IGListDiffKit. I opt for the latter because I imagine many IGListKit users would have IGListDiffKit anyway so we can still take advantage of it (it's faster than our built in diffing algorithm). Plus, it's not a big dependency. --- AsyncDisplayKit.xcodeproj/project.pbxproj | 18 +++++++++--------- Source/AsyncDisplayKit.h | 2 +- Source/Base/ASAvailability.h | 1 + ...ut+IGListKit.h => ASLayout+IGListDiffKit.h} | 12 ++++++------ ...+IGListKit.mm => ASLayout+IGListDiffKit.mm} | 10 +++++----- Source/Private/ASLayoutTransition.mm | 7 +++---- Texture.podspec | 1 + 7 files changed, 26 insertions(+), 25 deletions(-) rename Source/Layout/{ASLayout+IGListKit.h => ASLayout+IGListDiffKit.h} (52%) rename Source/Layout/{ASLayout+IGListKit.mm => ASLayout+IGListDiffKit.mm} (73%) diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index ef8c5d9c3..7cb9587b1 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -30,8 +30,6 @@ 058D0A40195D057000B7D73C /* ASTextNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A36195D057000B7D73C /* ASTextNodeTests.mm */; }; 058D0A41195D057000B7D73C /* ASTextNodeWordKernerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A37195D057000B7D73C /* ASTextNodeWordKernerTests.mm */; }; 05EA6FE71AC0966E00E35788 /* ASSnapshotTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.mm */; }; - 0FAFDF7520EC1C90003A51C0 /* ASLayout+IGListKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAFDF7320EC1C8F003A51C0 /* ASLayout+IGListKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0FAFDF7620EC1C90003A51C0 /* ASLayout+IGListKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0FAFDF7420EC1C90003A51C0 /* ASLayout+IGListKit.mm */; }; 18C2ED7F1B9B7DE800F627B3 /* ASCollectionNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 18C2ED7C1B9B7DE800F627B3 /* ASCollectionNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18C2ED831B9B7DE800F627B3 /* ASCollectionNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18C2ED7D1B9B7DE800F627B3 /* ASCollectionNode.mm */; }; 1A6C000D1FAB4E2100D05926 /* ASCornerLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A6C000B1FAB4E2000D05926 /* ASCornerLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -100,8 +98,8 @@ 3917EBD41E9C2FC400D04A01 /* _ASCollectionReusableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 3917EBD21E9C2FC400D04A01 /* _ASCollectionReusableView.h */; settings = {ATTRIBUTES = (Private, ); }; }; 3917EBD51E9C2FC400D04A01 /* _ASCollectionReusableView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.mm */; }; 3C9C128519E616EF00E942A0 /* ASTableViewTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C9C128419E616EF00E942A0 /* ASTableViewTests.mm */; }; - 4080D66C2350384400CDC199 /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 407B8BAE2310E2ED00CB979E /* ASLayoutSpecUtilitiesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 407B8BAD2310E2ED00CB979E /* ASLayoutSpecUtilitiesTests.mm */; }; + 4080D66C2350384400CDC199 /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 471D04B1224CB98600649215 /* ASImageNodeBackingSizeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 471D04B0224CB98600649215 /* ASImageNodeBackingSizeTests.mm */; }; 4E9127691F64157600499623 /* ASRunLoopQueueTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4E9127681F64157600499623 /* ASRunLoopQueueTests.mm */; }; 509E68601B3AED8E009B9150 /* ASScrollDirection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E111B371BD7007741D0 /* ASScrollDirection.mm */; }; @@ -475,6 +473,8 @@ DECBD6E81BE56E1900CF4905 /* ASButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; }; DEFAD8131CC48914000527C4 /* ASVideoNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E01C20C2DD00EC1693 /* ASVideoNode.mm */; }; + E517F9C823BF14BC006E40E0 /* ASLayout+IGListDiffKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = E517F9C623BF14BC006E40E0 /* ASLayout+IGListDiffKit.mm */; }; + E517F9C923BF14BC006E40E0 /* ASLayout+IGListDiffKit.h in Headers */ = {isa = PBXBuildFile; fileRef = E517F9C723BF14BC006E40E0 /* ASLayout+IGListDiffKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.mm */; }; E54E00721F1D3828000B30D7 /* ASPagerNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = E54E00711F1D3828000B30D7 /* ASPagerNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; E54E81FC1EB357BD00FFE8E1 /* ASPageTable.h in Headers */ = {isa = PBXBuildFile; fileRef = E54E81FA1EB357BD00FFE8E1 /* ASPageTable.h */; }; @@ -623,8 +623,6 @@ 058D0A44195D058D00B7D73C /* ASBaseDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBaseDefines.h; sourceTree = ""; }; 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASSnapshotTestCase.mm; sourceTree = ""; }; 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageProtocols.h; sourceTree = ""; }; - 0FAFDF7320EC1C8F003A51C0 /* ASLayout+IGListKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASLayout+IGListKit.h"; sourceTree = ""; }; - 0FAFDF7420EC1C90003A51C0 /* ASLayout+IGListKit.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASLayout+IGListKit.mm"; sourceTree = ""; }; 18C2ED7C1B9B7DE800F627B3 /* ASCollectionNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionNode.h; sourceTree = ""; }; 18C2ED7D1B9B7DE800F627B3 /* ASCollectionNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionNode.mm; sourceTree = ""; }; 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEqualityHelpers.h; sourceTree = ""; }; @@ -1015,6 +1013,8 @@ DEC146B41C37A16A004A0EE7 /* ASCollectionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASCollectionInternal.h; path = Details/ASCollectionInternal.h; sourceTree = ""; }; DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASButtonNode.h; sourceTree = ""; }; DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASButtonNode.mm; sourceTree = ""; }; + E517F9C623BF14BC006E40E0 /* ASLayout+IGListDiffKit.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASLayout+IGListDiffKit.mm"; sourceTree = ""; }; + E517F9C723BF14BC006E40E0 /* ASLayout+IGListDiffKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASLayout+IGListDiffKit.h"; sourceTree = ""; }; E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutFlatteningTests.mm; sourceTree = ""; }; E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutTransition.mm; sourceTree = ""; }; E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutTransition.h; sourceTree = ""; }; @@ -1700,8 +1700,8 @@ ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutSpec.mm */, ACF6ED0B1B17843500DA7C62 /* ASLayout.h */, ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */, - 0FAFDF7320EC1C8F003A51C0 /* ASLayout+IGListKit.h */, - 0FAFDF7420EC1C90003A51C0 /* ASLayout+IGListKit.mm */, + E517F9C723BF14BC006E40E0 /* ASLayout+IGListDiffKit.h */, + E517F9C623BF14BC006E40E0 /* ASLayout+IGListDiffKit.mm */, ACF6ED111B17843500DA7C62 /* ASLayoutElement.h */, E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */, 698C8B601CAB49FC0052DC3F /* ASLayoutElementExtensibility.h */, @@ -1896,6 +1896,7 @@ files = ( 1A6C000D1FAB4E2100D05926 /* ASCornerLayoutSpec.h in Headers */, E54E00721F1D3828000B30D7 /* ASPagerNode+Beta.h in Headers */, + E517F9C923BF14BC006E40E0 /* ASLayout+IGListDiffKit.h in Headers */, E5B225281F1790D6001E1431 /* ASHashing.h in Headers */, CC034A131E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.h in Headers */, 693A1DCA1ECC944E00D0C9D2 /* IGListAdapter+AsyncDisplayKit.h in Headers */, @@ -1917,7 +1918,6 @@ 69E0E8A71D356C9400627613 /* ASEqualityHelpers.h in Headers */, 698C8B621CAB49FC0052DC3F /* ASLayoutElementExtensibility.h in Headers */, 69F10C871C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */, - 0FAFDF7520EC1C90003A51C0 /* ASLayout+IGListKit.h in Headers */, B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */, 68355B411CB57A6C001D4E68 /* ASImageContainerProtocolCategories.h in Headers */, 7630FFA81C9E267E007A7C0E /* ASVideoNode.h in Headers */, @@ -2417,7 +2417,6 @@ E5B078001E69F4EB00C24B5B /* ASElementMap.mm in Sources */, 9C8898BC1C738BA800D6B02E /* ASTextKitFontSizeAdjuster.mm in Sources */, 690ED59B1E36D118000627C0 /* ASImageNode+tvOS.mm in Sources */, - 0FAFDF7620EC1C90003A51C0 /* ASLayout+IGListKit.mm in Sources */, CCDC9B4E200991D10063C1F8 /* ASGraphicsContext.mm in Sources */, CCCCCCD81EC3EF060087FE10 /* ASTextInput.mm in Sources */, 34EFC7621B701CA400AD841F /* ASBackgroundLayoutSpec.mm in Sources */, @@ -2511,6 +2510,7 @@ 90FC784F1E4BFE1B00383C5A /* ASDisplayNode+Yoga.mm in Sources */, CCA282C91E9EB64B0037E8B7 /* ASDisplayNodeTipState.mm in Sources */, 509E68601B3AED8E009B9150 /* ASScrollDirection.mm in Sources */, + E517F9C823BF14BC006E40E0 /* ASLayout+IGListDiffKit.mm in Sources */, B35062091B010EFD0018CF92 /* ASScrollNode.mm in Sources */, 69BCE3D91EC6513B007DCCAD /* ASDisplayNode+Layout.mm in Sources */, 8BDA5FC81CDBDF95007D13B2 /* ASVideoPlayerNode.mm in Sources */, diff --git a/Source/AsyncDisplayKit.h b/Source/AsyncDisplayKit.h index 19d823abf..59e9aeeca 100644 --- a/Source/AsyncDisplayKit.h +++ b/Source/AsyncDisplayKit.h @@ -129,5 +129,5 @@ #import #import -#import +#import #import diff --git a/Source/Base/ASAvailability.h b/Source/Base/ASAvailability.h index c6e0fcf86..b210397fc 100644 --- a/Source/Base/ASAvailability.h +++ b/Source/Base/ASAvailability.h @@ -86,6 +86,7 @@ #define AS_PIN_REMOTE_IMAGE __has_include() #define AS_IG_LIST_KIT __has_include() +#define AS_IG_LIST_DIFF_KIT __has_include() /** * For IGListKit versions < 3.0, you have to use IGListCollectionView. diff --git a/Source/Layout/ASLayout+IGListKit.h b/Source/Layout/ASLayout+IGListDiffKit.h similarity index 52% rename from Source/Layout/ASLayout+IGListKit.h rename to Source/Layout/ASLayout+IGListDiffKit.h index 6f6753da2..34636efa2 100644 --- a/Source/Layout/ASLayout+IGListKit.h +++ b/Source/Layout/ASLayout+IGListDiffKit.h @@ -1,15 +1,15 @@ // -// ASLayout+IGListKit.h +// ASLayout+IGListDiffKit.h // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#if AS_IG_LIST_KIT +#if AS_IG_LIST_DIFF_KIT #import -#import -@interface ASLayout(IGListKit) -@end +#import -#endif // AS_IG_LIST_KIT +@interface ASLayout(IGListDiffKit) +@end +#endif // AS_IG_LIST_DIFF_KIT diff --git a/Source/Layout/ASLayout+IGListKit.mm b/Source/Layout/ASLayout+IGListDiffKit.mm similarity index 73% rename from Source/Layout/ASLayout+IGListKit.mm rename to Source/Layout/ASLayout+IGListDiffKit.mm index f9cc139e9..d6e57b215 100644 --- a/Source/Layout/ASLayout+IGListKit.mm +++ b/Source/Layout/ASLayout+IGListDiffKit.mm @@ -1,13 +1,13 @@ // -// ASLayout+IGListKit.mm +// ASLayout+IGListDiffKit.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // #import -#if AS_IG_LIST_KIT -#import "ASLayout+IGListKit.h" +#if AS_IG_LIST_DIFF_KIT +#import "ASLayout+IGListDiffKit.h" @interface ASLayout() { @public @@ -15,7 +15,7 @@ @interface ASLayout() { } @end -@implementation ASLayout(IGListKit) +@implementation ASLayout(IGListDiffKit) - (id )diffIdentifier { @@ -27,4 +27,4 @@ - (BOOL)isEqualToDiffableObject:(id )other return [self isEqual:other]; } @end -#endif // AS_IG_LIST_KIT +#endif // AS_IG_LIST_DIFF_KIT diff --git a/Source/Private/ASLayoutTransition.mm b/Source/Private/ASLayoutTransition.mm index 1830b60e8..588b27565 100644 --- a/Source/Private/ASLayoutTransition.mm +++ b/Source/Private/ASLayoutTransition.mm @@ -16,9 +16,8 @@ #import -#if AS_IG_LIST_KIT -#import -#import +#if AS_IG_LIST_DIFF_KIT +#import #endif using AS::MutexLocker; @@ -160,7 +159,7 @@ - (void)calculateSubnodeOperationsIfNeeded ASLayout *pendingLayout = _pendingLayout.layout; if (previousLayout) { -#if AS_IG_LIST_KIT +#if AS_IG_LIST_DIFF_KIT // IGListDiff completes in linear time O(m+n), so use it if we have it: IGListIndexSetResult *result = IGListDiff(previousLayout.sublayouts, pendingLayout.sublayouts, IGListDiffEquality); _insertedSubnodePositions = findNodesInLayoutAtIndexes(pendingLayout, result.inserts, &_insertedSubnodes); diff --git a/Texture.podspec b/Texture.podspec index 1dab227f6..0f426c5bb 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -46,6 +46,7 @@ Pod::Spec.new do |spec| spec.subspec 'IGListKit' do |igl| igl.dependency 'IGListKit', '~> 4.0' + igl.dependency 'IGListDiffKit', '~> 4.0' igl.dependency 'Texture/Core' end From ea8172e5181f0ae4ae0d256e5e0c3addce8081b2 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Fri, 3 Jan 2020 12:48:35 -0800 Subject: [PATCH 09/56] Lint podspec on all pull requests (#1758) - We recently let a couple of issues slip through code review becase we don't lint our podspec on pull requests since the task takes too long (about half an hour). To prevent this from happening again, this PR adds 2 new CI jobs that lint default and other subspecs on all PRs. By splitting into 2 tasks, the impact on total CI time should be mitigated somewhat. There is still a master-only task that lint all subspecs as the last line of defense in case the 2 new tasks miss any. --- .github/workflows/ci-pull-requests-only.yml | 26 ++++++++++++++++++++ .github/workflows/ci.yml | 2 +- build.sh | 27 +++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci-pull-requests-only.yml diff --git a/.github/workflows/ci-pull-requests-only.yml b/.github/workflows/ci-pull-requests-only.yml new file mode 100644 index 000000000..0aee87211 --- /dev/null +++ b/.github/workflows/ci-pull-requests-only.yml @@ -0,0 +1,26 @@ +name: CI (pull-requests-only jobs) + +on: + pull_request: + branches: + - master + +jobs: + buildsh: + env: + DEVELOPER_DIR: /Applications/Xcode_11.app/Contents/Developer + strategy: + matrix: + mode: [cocoapods-lint-default-subspecs, cocoapods-lint-other-subspecs] + include: + - mode: cocoapods-lint-default-subspecs + name: Verify that default subspecs lint + - mode: cocoapods-lint-other-subspecs + name: Verify that other subspecs lint + name: ${{ matrix.name }} + runs-on: macOS-latest + steps: + - name: Checkout the Git repository + uses: actions/checkout@v1 + - name: Run build script + run: ./build.sh ${{ matrix.mode }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99e2d69ef..b4b26d585 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,4 +32,4 @@ jobs: - name: Checkout the Git repository uses: actions/checkout@v1 - name: Run build script - run: ./build.sh ${{ matrix.mode }} \ No newline at end of file + run: ./build.sh ${{ matrix.mode }} diff --git a/build.sh b/build.sh index 620c9f62b..9701dfb9c 100755 --- a/build.sh +++ b/build.sh @@ -56,6 +56,11 @@ function build_example { fi } +# Lint subspec +function lint_subspec { + set -o pipefail && pod env && pod lib lint --allow-warnings --subspec="$1" +} + function cleanup { # remove all Pods directories find . -name Pods -type d -exec rm -rf {} + @@ -216,6 +221,28 @@ cocoapods-lint|all) success="1" ;; +cocoapods-lint-default-subspecs) + echo "Verifying that default subspecs lint." + + for subspec in 'Core' 'PINRemoteImage' 'Video' 'MapKit' 'AssetsLibrary' 'Photos'; do + echo "Verifying that $subspec subspec lints." + + lint_subspec $subspec + done + success="1" + ;; + +cocoapods-lint-other-subspecs) + echo "Verifying that other subspecs lint." + + for subspec in 'IGListKit' 'Yoga' 'TextNode2'; do + echo "Verifying that $subspec subspec lints." + + lint_subspec $subspec + done + success="1" + ;; + carthage|all) echo "Verifying carthage works." From 01b613e97b46224573b62f1a892a75ff490d9766 Mon Sep 17 00:00:00 2001 From: Suyeol Jeon Date: Tue, 7 Jan 2020 06:27:56 +0900 Subject: [PATCH 10/56] Fix typo in examples/README.md (#1759) --- examples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/README.md b/examples/README.md index 76c71a75d..39fac1c1c 100644 --- a/examples/README.md +++ b/examples/README.md @@ -83,7 +83,7 @@ Featuring: ### CustomCollectionView [ObjC+Swift] -![CustomCollectionView Example App gif](https://github.com/AsyncDisplayKit/Documentation/raw/master/docs/static/images/example-app-screenshots/CustomCollectionView.git) +![CustomCollectionView Example App gif](https://github.com/AsyncDisplayKit/Documentation/raw/master/docs/static/images/example-app-screenshots/CustomCollectionView.gif) Featuring: - custom collection view layout From 70613a655a0a3ac38b8d1f77d22b4ef8b5308afa Mon Sep 17 00:00:00 2001 From: trufflin Date: Tue, 28 Jan 2020 14:37:55 -0800 Subject: [PATCH 11/56] Pruning ASExperimentalRemoveTextKitInitialisingLock code. (#1766) * Remove code for unused ASExperimentalRemoveTextKitInitialisingLock experiment. * Prune some additional unnecessary references. Co-authored-by: rgupta-pinterest <59977334+rgupta-pinterest@users.noreply.github.com> --- Schemas/configuration.json | 1 - Source/ASExperimentalFeatures.h | 7 +++---- Source/ASExperimentalFeatures.mm | 1 - Source/TextKit/ASTextKitContext.mm | 2 -- Tests/ASConfigurationTests.mm | 2 -- 5 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Schemas/configuration.json b/Schemas/configuration.json index bffa63b7a..e18d4380b 100644 --- a/Schemas/configuration.json +++ b/Schemas/configuration.json @@ -24,7 +24,6 @@ "exp_did_enter_preload_skip_asm_layout", "exp_dispatch_apply", "exp_oom_bg_dealloc_disable", - "exp_remove_textkit_initialising_lock" ] } } diff --git a/Source/ASExperimentalFeatures.h b/Source/ASExperimentalFeatures.h index 7c2e84873..bec8614bb 100644 --- a/Source/ASExperimentalFeatures.h +++ b/Source/ASExperimentalFeatures.h @@ -28,10 +28,9 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { ASExperimentalDidEnterPreloadSkipASMLayout = 1 << 7, // exp_did_enter_preload_skip_asm_layout ASExperimentalDispatchApply = 1 << 8, // exp_dispatch_apply ASExperimentalOOMBackgroundDeallocDisable = 1 << 9, // exp_oom_bg_dealloc_disable - ASExperimentalRemoveTextKitInitialisingLock = 1 << 10, // exp_remove_textkit_initialising_lock - ASExperimentalDrawingGlobal = 1 << 11, // exp_drawing_global - ASExperimentalOptimizeDataControllerPipeline = 1 << 12, // exp_optimize_data_controller_pipeline - ASExperimentalTraitCollectionDidChangeWithPreviousCollection = 1 << 13, // exp_trait_collection_did_change_with_previous_collection + ASExperimentalDrawingGlobal = 1 << 10, // exp_drawing_global + ASExperimentalOptimizeDataControllerPipeline = 1 << 11, // exp_optimize_data_controller_pipeline + ASExperimentalTraitCollectionDidChangeWithPreviousCollection = 1 << 12, // exp_trait_collection_did_change_with_previous_collection ASExperimentalFeatureAll = 0xFFFFFFFF }; diff --git a/Source/ASExperimentalFeatures.mm b/Source/ASExperimentalFeatures.mm index 7637481bc..eb9848292 100644 --- a/Source/ASExperimentalFeatures.mm +++ b/Source/ASExperimentalFeatures.mm @@ -22,7 +22,6 @@ @"exp_did_enter_preload_skip_asm_layout", @"exp_dispatch_apply", @"exp_oom_bg_dealloc_disable", - @"exp_remove_textkit_initialising_lock", @"exp_drawing_global", @"exp_optimize_data_controller_pipeline", @"exp_trait_collection_did_change_with_previous_collection"])); diff --git a/Source/TextKit/ASTextKitContext.mm b/Source/TextKit/ASTextKitContext.mm index e5b16a696..8c24644d4 100644 --- a/Source/TextKit/ASTextKitContext.mm +++ b/Source/TextKit/ASTextKitContext.mm @@ -37,9 +37,7 @@ - (instancetype)initWithAttributedString:(NSAttributedString *)attributedString static dispatch_once_t onceToken; // Concurrently initialising TextKit components crashes (rdar://18448377) so we use a global lock. dispatch_once(&onceToken, ^{ - if (!ASActivateExperimentalFeature(ASExperimentalRemoveTextKitInitialisingLock)) { mutex = new AS::Mutex(); - } }); if (mutex != NULL) { mutex->lock(); diff --git a/Tests/ASConfigurationTests.mm b/Tests/ASConfigurationTests.mm index c5e533e22..a0eefcaa2 100644 --- a/Tests/ASConfigurationTests.mm +++ b/Tests/ASConfigurationTests.mm @@ -28,7 +28,6 @@ ASExperimentalDidEnterPreloadSkipASMLayout, ASExperimentalDispatchApply, ASExperimentalOOMBackgroundDeallocDisable, - ASExperimentalRemoveTextKitInitialisingLock, ASExperimentalDrawingGlobal, ASExperimentalOptimizeDataControllerPipeline }; @@ -53,7 +52,6 @@ + (NSArray *)names { @"exp_did_enter_preload_skip_asm_layout", @"exp_dispatch_apply", @"exp_oom_bg_dealloc_disable", - @"exp_remove_textkit_initialising_lock", @"exp_drawing_global", @"exp_optimize_data_controller_pipeline" ]; From 36744028597fef3f560726d81c23a2e3573e76fb Mon Sep 17 00:00:00 2001 From: vovasty Date: Mon, 10 Feb 2020 16:13:37 -0800 Subject: [PATCH 12/56] Fix calling CALayer out of the main thread (#1762) --- Source/ASDisplayNode.mm | 61 +++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index ccad49b33..afa39b224 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -438,36 +438,43 @@ - (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body - (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTraitCollection)previousTraitCollection { if (@available(iOS 13.0, *)) { + // When changing between light and dark mode, often the entire node needs to re-render. + // This change doesn't happen frequently so it's fairly safe to render nodes again __instanceLock__.lock(); - if (self.primitiveTraitCollection.userInterfaceStyle != previousTraitCollection.userInterfaceStyle) { - // When changing between light and dark mode, often the entire node needs to re-render. - // This change doesn't happen frequently so it's fairly safe to render nodes again - BOOL needsClippingCornerUpdate = NO; - CGFloat cornerRadius = _cornerRadius; - ASCornerRoundingType cornerRoundingType = _cornerRoundingType; - UIColor *backgroundColor = _backgroundColor; - if (_loaded(self)) { - CGColorRef cgBackgroundColor = backgroundColor.CGColor; - if (!CGColorEqualToColor(_layer.backgroundColor, cgBackgroundColor)) { - // Background colors do not dynamically update for layer backed nodes since they utilize CGColorRef - // instead of UIColor. Non layer backed node also receive color to the layer (see [_ASPendingState -applyToView:withSpecialPropertiesHandling:]). - // We utilize the _backgroundColor instance variable to track the full dynamic color - // and apply any changes here when trait collection updates occur. - _layer.backgroundColor = cgBackgroundColor; - } - // If we have clipping corners, re-render the clipping corner layer upon user interface style change - if (cornerRoundingType == ASCornerRoundingTypeClipping && cornerRadius > 0.0f) { - needsClippingCornerUpdate = YES; - } - } - __instanceLock__.unlock(); - if (needsClippingCornerUpdate) { - [self _updateClipCornerLayerContentsWithRadius:cornerRadius backgroundColor:backgroundColor]; + BOOL loaded = _loaded(self); + ASPrimitiveTraitCollection primitiveTraitCollection = _primitiveTraitCollection; + __instanceLock__.unlock(); + if (primitiveTraitCollection.userInterfaceStyle != previousTraitCollection.userInterfaceStyle) { + if (loaded) { + // we need to run that on main thread, cause accessing CALayer properties. + // It seems than in iOS 13 sometimes it causes deadlock. + ASPerformBlockOnMainThread(^{ + __instanceLock__.lock(); + CGFloat cornerRadius = _cornerRadius; + ASCornerRoundingType cornerRoundingType = _cornerRoundingType; + UIColor *backgroundColor = _backgroundColor; + ASPrimitiveTraitCollection primitiveTraitCollection = _primitiveTraitCollection; + __instanceLock__.unlock(); + UITraitCollection *traitCollection = ASPrimitiveTraitCollectionToUITraitCollection(primitiveTraitCollection); + UIColor *resolvedBackgroundColor = [backgroundColor resolvedColorWithTraitCollection:traitCollection]; + CGColorRef cgBackgroundColor = resolvedBackgroundColor.CGColor; + if (!CGColorEqualToColor(_layer.backgroundColor, cgBackgroundColor)) { + // Background colors do not dynamically update for layer backed nodes since they utilize CGColorRef + // instead of UIColor. Non layer backed node also receive color to the layer (see [_ASPendingState -applyToView:withSpecialPropertiesHandling:]). + // We utilize the _backgroundColor instance variable to track the full dynamic color + // and apply any changes here when trait collection updates occur. + _layer.backgroundColor = cgBackgroundColor; + } + + // If we have clipping corners, re-render the clipping corner layer upon user interface style change + if (cornerRoundingType == ASCornerRoundingTypeClipping && cornerRadius > 0.0f) { + [self _updateClipCornerLayerContentsWithRadius:cornerRadius backgroundColor:backgroundColor]; + } + + [self setNeedsDisplay]; + }); } - [self setNeedsDisplay]; - return; } - __instanceLock__.unlock(); } } From 7798440bcf818d62446b53fd81596c987cfad45e Mon Sep 17 00:00:00 2001 From: Oliver Fox Date: Tue, 11 Feb 2020 00:30:27 +0000 Subject: [PATCH 13/56] Prevent crashing during non critical logging at rotation (#1770) --- Source/Details/ASTraitCollection.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Details/ASTraitCollection.mm b/Source/Details/ASTraitCollection.mm index ded4a228f..39c1615d5 100644 --- a/Source/Details/ASTraitCollection.mm +++ b/Source/Details/ASTraitCollection.mm @@ -244,7 +244,9 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr } if (AS_AVAILABLE_IOS(10)) { [props addObject:@{ @"layoutDirection": AS_NSStringFromUITraitEnvironmentLayoutDirection(traits.layoutDirection) }]; - [props addObject:@{ @"preferredContentSizeCategory": traits.preferredContentSizeCategory }]; + if (traits.preferredContentSizeCategory != nil) { + [props addObject:@{ @"preferredContentSizeCategory": traits.preferredContentSizeCategory }]; + } [props addObject:@{ @"displayGamut": AS_NSStringFromUIDisplayGamut(traits.displayGamut) }]; } From 70f61e9d01eff930f3f8e2bf4146a1841821c79a Mon Sep 17 00:00:00 2001 From: vovasty Date: Thu, 20 Feb 2020 16:04:39 -0800 Subject: [PATCH 14/56] [ASDisplayNode] Resolve background color using system trait collection (#1777) --- Source/ASDisplayNode.mm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index afa39b224..c9495389f 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -453,11 +453,10 @@ - (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTra CGFloat cornerRadius = _cornerRadius; ASCornerRoundingType cornerRoundingType = _cornerRoundingType; UIColor *backgroundColor = _backgroundColor; - ASPrimitiveTraitCollection primitiveTraitCollection = _primitiveTraitCollection; __instanceLock__.unlock(); - UITraitCollection *traitCollection = ASPrimitiveTraitCollectionToUITraitCollection(primitiveTraitCollection); - UIColor *resolvedBackgroundColor = [backgroundColor resolvedColorWithTraitCollection:traitCollection]; - CGColorRef cgBackgroundColor = resolvedBackgroundColor.CGColor; + // TODO: we should resolve color using node's trait collection + // but Texture changes it from many places, so we may receive the wrong one. + CGColorRef cgBackgroundColor = backgroundColor.CGColor; if (!CGColorEqualToColor(_layer.backgroundColor, cgBackgroundColor)) { // Background colors do not dynamically update for layer backed nodes since they utilize CGColorRef // instead of UIColor. Non layer backed node also receive color to the layer (see [_ASPendingState -applyToView:withSpecialPropertiesHandling:]). From 9d7510489fa6d7c78b9504b3fc207cc14c97a1a9 Mon Sep 17 00:00:00 2001 From: Aleksandr Zolotarev Date: Mon, 30 Mar 2020 20:28:06 +0300 Subject: [PATCH 15/56] Adds new delegate methods to ASCommonTableViewDelegate for swipe (#1694) - I added new delegate methods to ASCommonTableViewDelegate: - tableView(_:leadingSwipeActionsConfigurationForRowAt:) - tableView(_:trailingSwipeActionsConfigurationForRowAt:) - And marked old method as deprecated since iOS 13. --- Source/ASTableViewProtocols.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/ASTableViewProtocols.h b/Source/ASTableViewProtocols.h index 969a5c61c..499ebe2b3 100644 --- a/Source/ASTableViewProtocols.h +++ b/Source/ASTableViewProtocols.h @@ -75,7 +75,9 @@ NS_ASSUME_NONNULL_BEGIN - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath; - (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath; #if TARGET_OS_IOS -- (nullable NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath; +- (nullable NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath API_DEPRECATED_WITH_REPLACEMENT("tableView:trailingSwipeActionsConfigurationForRowAtIndexPath:", ios(8.0, 13.0)); +- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)); +- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)); #endif - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath; From ce0aebff75f378919e6762cec4b74004bd33295a Mon Sep 17 00:00:00 2001 From: Anton Kuzmin Date: Wed, 1 Apr 2020 19:58:33 +0300 Subject: [PATCH 16/56] Context menu iOS 13 API (#1795) --- Source/ASTableViewProtocols.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/ASTableViewProtocols.h b/Source/ASTableViewProtocols.h index 499ebe2b3..77402e11c 100644 --- a/Source/ASTableViewProtocols.h +++ b/Source/ASTableViewProtocols.h @@ -78,6 +78,11 @@ NS_ASSUME_NONNULL_BEGIN - (nullable NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath API_DEPRECATED_WITH_REPLACEMENT("tableView:trailingSwipeActionsConfigurationForRowAtIndexPath:", ios(8.0, 13.0)); - (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)); - (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)); +- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)); +- (UITargetedPreview *)tableView:(UITableView *)tableView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)); +- (UITargetedPreview *)tableView:(UITableView *)tableView previewForHighlightingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)); +- (void)tableView:(UITableView *)tableView willPerformPreviewActionForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration animator:(id)animator API_AVAILABLE(ios(13.0)); + #endif - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath; From 65a65a6daf6ce5734be5a5f8cff04dd0ed82db08 Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Thu, 2 Apr 2020 10:21:44 -0700 Subject: [PATCH 17/56] Add `nullable` to new ASCommonTableViewDelegate methods (#1796) These were recently introduced in #1795 but were missing `nullable` annotations on their return types. Also, reorder the declarations to match `UITableView.h`. --- Source/ASTableViewProtocols.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/ASTableViewProtocols.h b/Source/ASTableViewProtocols.h index 77402e11c..ea392e2f4 100644 --- a/Source/ASTableViewProtocols.h +++ b/Source/ASTableViewProtocols.h @@ -78,11 +78,10 @@ NS_ASSUME_NONNULL_BEGIN - (nullable NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath API_DEPRECATED_WITH_REPLACEMENT("tableView:trailingSwipeActionsConfigurationForRowAtIndexPath:", ios(8.0, 13.0)); - (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)); - (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)); -- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)); -- (UITargetedPreview *)tableView:(UITableView *)tableView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)); -- (UITargetedPreview *)tableView:(UITableView *)tableView previewForHighlightingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)); +- (nullable UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)); +- (nullable UITargetedPreview *)tableView:(UITableView *)tableView previewForHighlightingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)); +- (nullable UITargetedPreview *)tableView:(UITableView *)tableView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)); - (void)tableView:(UITableView *)tableView willPerformPreviewActionForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration animator:(id)animator API_AVAILABLE(ios(13.0)); - #endif - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath; From 508bd2b49a0ed89fa362ec526c15aa4d8186d235 Mon Sep 17 00:00:00 2001 From: ricky Date: Fri, 24 Apr 2020 12:35:13 -0700 Subject: [PATCH 18/56] [ASDisplayNode] Allow explicit setting of accessibilityElements (#1807) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ASDisplayNode] Allow explicit setting of accessibilityElements Since `NSObject` conforms to the informal accessibility protocol, `ASDisplayNode` has an inherited property for `accessibilityElements`. However, setting this property has no effect since `ASDisplayNode` overrides the `accessibilityElements` getter. Added a small change to the getter to check if the `accessibilityElements` property on `ASDisplayNode` has been explicitly set, and if so return that. I also added a comment around `_ASDisplayView`’s `setAccessibilityElements:` method to clear up some (of my own) confusion. * comment tweak * Fix flakey test --- Source/Details/_ASDisplayViewAccessiblity.mm | 12 ++++ Tests/ASDisplayViewAccessibilityTests.mm | 58 ++++++++++++++++++++ Tests/ASViewControllerTests.mm | 3 +- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index 858fd5ddc..fa90666dd 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -259,6 +259,10 @@ @implementation _ASDisplayView (UIAccessibilityContainer) - (void)setAccessibilityElements:(NSArray *)accessibilityElements { ASDisplayNodeAssertMainThread(); + // While it looks very strange to ignore the accessibilyElements param and set _accessibilityElements to nil, it is actually on purpose. + // _ASDisplayView's accessibilityElements method will always defer to the node for accessibilityElements when _accessibilityElements is + // nil. Calling setAccessibilityElements on _ASDisplayView is basically clearing the cache and forcing _ASDisplayView to ask the node + // for its accessibilityElements the next time they are requested. _accessibilityElements = nil; } @@ -283,6 +287,14 @@ @implementation ASDisplayNode (AccessibilityInternal) - (NSArray *)accessibilityElements { + // NSObject implements the informal accessibility protocol. This means that all ASDisplayNodes already have an accessibilityElements + // property. If an ASDisplayNode subclass has explicitly set the property, let's use that instead of traversing the node tree to try + // to create the elements automatically + NSArray *elements = [super accessibilityElements]; + if (elements.count) { + return elements; + } + if (!self.isNodeLoaded) { ASDisplayNodeFailAssert(@"Cannot access accessibilityElements since node is not loaded"); return @[]; diff --git a/Tests/ASDisplayViewAccessibilityTests.mm b/Tests/ASDisplayViewAccessibilityTests.mm index 15d14c29a..f2476a00d 100644 --- a/Tests/ASDisplayViewAccessibilityTests.mm +++ b/Tests/ASDisplayViewAccessibilityTests.mm @@ -12,6 +12,8 @@ #import +#import +#import #import #import #import @@ -193,4 +195,60 @@ - (void)testActionForwarding { OCMVerifyAll(mockNode); } +#pragma mark - +#pragma mark AccessibilityElements + +// dummy action for a button +- (void)fakeSelector:(id)sender { } + +- (void)testThatAccessibilityElementsWorks { + ASDisplayNode *containerNode = [[ASDisplayNode alloc] init]; + containerNode.frame = CGRectMake(0, 0, 100, 200); + + ASTextNode *label = [[ASTextNode alloc] init]; + label.attributedText = [[NSAttributedString alloc] initWithString:@"test label"]; + label.frame = CGRectMake(0, 0, 100, 20); + + ASButtonNode *button = [[ASButtonNode alloc] init]; + [button setTitle:@"tap me" withFont:[UIFont systemFontOfSize:17] withColor:nil forState:UIControlStateNormal]; + [button addTarget:self action:@selector(fakeSelector:) forControlEvents:ASControlNodeEventTouchUpInside]; + button.frame = CGRectMake(0, 25, 100, 20); + + [containerNode addSubnode:label]; + [containerNode addSubnode:button]; + + // force load + __unused UIView *view = containerNode.view; + + NSArray *elements = [containerNode accessibilityElements]; + XCTAssertTrue(elements.count == 2); + XCTAssertEqual([elements.firstObject asyncdisplaykit_node], label); + XCTAssertEqual([elements.lastObject asyncdisplaykit_node], button); +} + +- (void)testThatAccessibilityElementsOverrideWorks { + ASDisplayNode *containerNode = [[ASDisplayNode alloc] init]; + containerNode.frame = CGRectMake(0, 0, 100, 200); + + ASTextNode *label = [[ASTextNode alloc] init]; + label.attributedText = [[NSAttributedString alloc] initWithString:@"test label"]; + label.frame = CGRectMake(0, 0, 100, 20); + + ASButtonNode *button = [[ASButtonNode alloc] init]; + [button setTitle:@"tap me" withFont:[UIFont systemFontOfSize:17] withColor:nil forState:UIControlStateNormal]; + [button addTarget:self action:@selector(fakeSelector:) forControlEvents:ASControlNodeEventTouchUpInside]; + button.frame = CGRectMake(0, 25, 100, 20); + + [containerNode addSubnode:label]; + [containerNode addSubnode:button]; + containerNode.accessibilityElements = @[ label ]; + + // force load + __unused UIView *view = containerNode.view; + + NSArray *elements = [containerNode accessibilityElements]; + XCTAssertTrue(elements.count == 1); + XCTAssertEqual(elements.firstObject, label); +} + @end diff --git a/Tests/ASViewControllerTests.mm b/Tests/ASViewControllerTests.mm index ede0ab144..929ee67b3 100644 --- a/Tests/ASViewControllerTests.mm +++ b/Tests/ASViewControllerTests.mm @@ -77,8 +77,9 @@ - (void)testThatViewControllerFrameIsRightAfterCustomTransitionWithNonextendedEd nav.delegate = navDelegate; window.rootViewController = nav; [window makeKeyAndVisible]; - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]]; + [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]]; [nav pushViewController:vc animated:YES]; + [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]]; [self waitForExpectationsWithTimeout:2 handler:nil]; From d085cd63494488c5921e20842a585470aa6ab1d9 Mon Sep 17 00:00:00 2001 From: ricky Date: Wed, 6 May 2020 11:10:35 -0700 Subject: [PATCH 19/56] [ASDisplayViewAccessibility] A few accessibility improvements (#1812) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ASDisplayViewAccessibility] A few accessibility improvements This diff includes a few improvements for accessibility in Texture. * When determining a node’s accessibility elements, ignore any elements that are hidden, transparent, or out of the window. This matches UIKit’s behavior. * When sorting the accessible elements and their origins are equal, give precedence to elements with shorter accessibility frames, followed by elements with narrower widths. * Allow the ability to customize the comparator block that sorts the accessibility elements * Create an experiment to stop caching accessibilityElements in `_ASDisplayView`. If we cache elements, we will require users to clear the cache (by calling `setAccessibilityElements` to get the side effect of clearing the cache) when nodes change their hidden state or opacity. This seems like a lot to request of the user. We will put this in an experiment so we can see the perf implication is both when using voice over and when not using voice over. A few other notes: * I got rid of the `ASAccessibilityElementPositioning` protocol in favor of passing `NSObjects` to the sort comparator. `NSObject` implements the informal `UIAccessibilityProtocol` and therefore has an `accessibilityFrame` property. * I removed `static` from the `SortAccessibilityElements()` method definition. This allows me to declare it as `extern` in test it via unit tests. --- Podfile.lock | 28 +-- Schemas/configuration.json | 1 + Source/ASExperimentalFeatures.h | 1 + Source/ASExperimentalFeatures.mm | 3 +- Source/Details/_ASDisplayViewAccessiblity.h | 14 ++ Source/Details/_ASDisplayViewAccessiblity.mm | 76 +++++--- Tests/ASConfigurationTests.mm | 8 +- Tests/ASDisplayViewAccessibilityTests.mm | 183 +++++++++++++++++++ Tests/ASScrollNodeTests.mm | 4 + 9 files changed, 267 insertions(+), 51 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index df3c6fcb8..ce77f9d72 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -2,35 +2,16 @@ PODS: - FBSnapshotTestCase/Core (2.1.4) - JGMethodSwizzler (2.0.1) - OCMock (3.4.1) - - PINCache (3.0.1-beta.7): - - PINCache/Arc-exception-safe (= 3.0.1-beta.7) - - PINCache/Core (= 3.0.1-beta.7) - - PINCache/Arc-exception-safe (3.0.1-beta.7): - - PINCache/Core - - PINCache/Core (3.0.1-beta.7): - - PINOperation (~> 1.1.1) - - PINOperation (1.1.1) - - PINRemoteImage (3.0.0-beta.14): - - PINRemoteImage/PINCache (= 3.0.0-beta.14) - - PINRemoteImage/Core (3.0.0-beta.14): - - PINOperation - - PINRemoteImage/PINCache (3.0.0-beta.14): - - PINCache (= 3.0.1-beta.7) - - PINRemoteImage/Core DEPENDENCIES: - FBSnapshotTestCase/Core (~> 2.1) - JGMethodSwizzler (from `https://github.com/JonasGessner/JGMethodSwizzler`, branch `master`) - OCMock (= 3.4.1) - - PINRemoteImage (= 3.0.0-beta.14) SPEC REPOS: - https://github.com/cocoapods/specs.git: + https://github.com/CocoaPods/Specs.git: - FBSnapshotTestCase - OCMock - - PINCache - - PINOperation - - PINRemoteImage EXTERNAL SOURCES: JGMethodSwizzler: @@ -46,10 +27,7 @@ SPEC CHECKSUMS: FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a JGMethodSwizzler: 7328146117fffa8a4038c42eb7cd3d4c75006f97 OCMock: 2cd0716969bab32a2283ff3a46fd26a8c8b4c5e3 - PINCache: 7cb9ae068c8f655717f7c644ef1dff9fd573e979 - PINOperation: a6219e6fc9db9c269eb7a7b871ac193bcf400aac - PINRemoteImage: 81bbff853acc71c6de9e106e9e489a791b8bbb08 -PODFILE CHECKSUM: 445046ac151568c694ff286684322273f0b597d6 +PODFILE CHECKSUM: 345a6700f5fdec438ef5553e1eebf62653862733 -COCOAPODS: 1.6.0 +COCOAPODS: 1.9.1 diff --git a/Schemas/configuration.json b/Schemas/configuration.json index e18d4380b..d2d041851 100644 --- a/Schemas/configuration.json +++ b/Schemas/configuration.json @@ -24,6 +24,7 @@ "exp_did_enter_preload_skip_asm_layout", "exp_dispatch_apply", "exp_oom_bg_dealloc_disable", + "exp_do_not_cache_accessibility_elements", ] } } diff --git a/Source/ASExperimentalFeatures.h b/Source/ASExperimentalFeatures.h index bec8614bb..82995b214 100644 --- a/Source/ASExperimentalFeatures.h +++ b/Source/ASExperimentalFeatures.h @@ -31,6 +31,7 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { ASExperimentalDrawingGlobal = 1 << 10, // exp_drawing_global ASExperimentalOptimizeDataControllerPipeline = 1 << 11, // exp_optimize_data_controller_pipeline ASExperimentalTraitCollectionDidChangeWithPreviousCollection = 1 << 12, // exp_trait_collection_did_change_with_previous_collection + ASExperimentalDoNotCacheAccessibilityElements = 1 << 13, // exp_do_not_cache_accessibility_elements ASExperimentalFeatureAll = 0xFFFFFFFF }; diff --git a/Source/ASExperimentalFeatures.mm b/Source/ASExperimentalFeatures.mm index eb9848292..f936525bc 100644 --- a/Source/ASExperimentalFeatures.mm +++ b/Source/ASExperimentalFeatures.mm @@ -24,7 +24,8 @@ @"exp_oom_bg_dealloc_disable", @"exp_drawing_global", @"exp_optimize_data_controller_pipeline", - @"exp_trait_collection_did_change_with_previous_collection"])); + @"exp_trait_collection_did_change_with_previous_collection", + @"exp_do_not_cache_accessibility_elements"])); if (flags == ASExperimentalFeatureAll) { return allNames; } diff --git a/Source/Details/_ASDisplayViewAccessiblity.h b/Source/Details/_ASDisplayViewAccessiblity.h index 192b24d2c..7f159d1d0 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.h +++ b/Source/Details/_ASDisplayViewAccessiblity.h @@ -14,3 +14,17 @@ // should still work as long as accessibility is enabled, this framework provides no guarantees on // their correctness. For details, see // https://developer.apple.com/documentation/objectivec/nsobject/1615147-accessibilityelements + +// After recusively collecting all of the accessibility elements of a node, they get sorted. This sort determines +// the order that a screen reader will traverse the elements. By default, we sort these elements based on their +// origin: lower y origin comes first, then lower x origin. If 2 nodes have an equal origin, the node with the smaller +// height is placed before the node with the smaller width. If two nodes have the exact same rect, we throw up our hands +// and return NSOrderedSame. +// +// In general this seems to work fairly well. However, if you want to provide a custom sort you can do so via +// setUserDefinedAccessibilitySortComparator(). The two elements you are comparing are NSObjects, which conforms to the +// informal UIAccessibility protocol, so you can safely compare properties like accessibilityFrame. +typedef NSComparisonResult (^ASSortAccessibilityElementsComparator)(NSObject *, NSObject *); + +// Use this method to supply your own custom sort comparator used to determine the order of the accessibility elements +void setUserDefinedAccessibilitySortComparator(ASSortAccessibilityElementsComparator userDefinedComparator); diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index fa90666dd..8115eea53 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -10,6 +10,7 @@ #ifndef ASDK_ACCESSIBILITY_DISABLE #import +#import #import #import #import @@ -21,35 +22,47 @@ #pragma mark - UIAccessibilityElement -@protocol ASAccessibilityElementPositioning +static ASSortAccessibilityElementsComparator currentAccessibilityComparator = nil; +static ASSortAccessibilityElementsComparator defaultAccessibilityComparator = nil; -@property (nonatomic, readonly) CGRect accessibilityFrame; - -@end - -typedef NSComparisonResult (^SortAccessibilityElementsComparator)(id, id); +void setUserDefinedAccessibilitySortComparator(ASSortAccessibilityElementsComparator userDefinedComparator) { + currentAccessibilityComparator = userDefinedComparator ?: defaultAccessibilityComparator; +} /// Sort accessiblity elements first by y and than by x origin. -static void SortAccessibilityElements(NSMutableArray *elements) +void SortAccessibilityElements(NSMutableArray *elements) { ASDisplayNodeCAssertNotNil(elements, @"Should pass in a NSMutableArray"); - - static SortAccessibilityElementsComparator comparator = nil; + static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - comparator = ^NSComparisonResult(id a, id b) { - CGPoint originA = a.accessibilityFrame.origin; - CGPoint originB = b.accessibilityFrame.origin; - if (originA.y == originB.y) { - if (originA.x == originB.x) { - return NSOrderedSame; + defaultAccessibilityComparator = ^NSComparisonResult(NSObject *a, NSObject *b) { + CGPoint originA = a.accessibilityFrame.origin; + CGPoint originB = b.accessibilityFrame.origin; + if (originA.y == originB.y) { + if (originA.x == originB.x) { + // if we have the same origin, favor shorter items. If heights are the same, favor thinner items. If size is the same ¯\_(ツ)_/¯ + CGSize sizeA = a.accessibilityFrame.size; + CGSize sizeB = b.accessibilityFrame.size; + if (sizeA.height == sizeB.height) { + if (sizeA.width == sizeB.width) { + return NSOrderedSame; + } + return (sizeA.width < sizeB.width) ? NSOrderedAscending : NSOrderedDescending; } - return (originA.x < originB.x) ? NSOrderedAscending : NSOrderedDescending; + return (sizeA.height < sizeB.height) ? NSOrderedAscending : NSOrderedDescending; } - return (originA.y < originB.y) ? NSOrderedAscending : NSOrderedDescending; - }; + return (originA.x < originB.x) ? NSOrderedAscending : NSOrderedDescending; + } + return (originA.y < originB.y) ? NSOrderedAscending : NSOrderedDescending; + }; + + if (!currentAccessibilityComparator) { + currentAccessibilityComparator = defaultAccessibilityComparator; + } }); - [elements sortUsingComparator:comparator]; + + [elements sortUsingComparator:currentAccessibilityComparator]; } static CGRect ASAccessibilityFrameForNode(ASDisplayNode *node) { @@ -57,7 +70,7 @@ static CGRect ASAccessibilityFrameForNode(ASDisplayNode *node) { return [layer convertRect:node.bounds toLayer:ASFindWindowOfLayer(layer).layer]; } -@interface ASAccessibilityElement : UIAccessibilityElement +@interface ASAccessibilityElement : UIAccessibilityElement @property (nonatomic) ASDisplayNode *node; @@ -93,7 +106,7 @@ - (CGRect)accessibilityFrame #pragma mark - _ASDisplayView / UIAccessibilityContainer -@interface ASAccessibilityCustomAction : UIAccessibilityCustomAction +@interface ASAccessibilityCustomAction : UIAccessibilityCustomAction @property (nonatomic) ASDisplayNode *node; @@ -214,6 +227,11 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el UIView *view = node.view; + // If we don't have a window, let's just bail out + if (!view.window) { + return; + } + if (node.isAccessibilityContainer && !anySubNodeIsCollection) { CollectAccessibilityElementsForContainer(node, view, elements); return; @@ -224,8 +242,18 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el CollectUIAccessibilityElementsForNode(node, node, view, elements); return; } - + for (ASDisplayNode *subnode in node.subnodes) { + // If a node is hidden or has an alpha of 0.0 we should not include it + if (subnode.hidden || subnode.alpha == 0.0) { + continue; + } + // If a subnode is outside of the view's window, exclude it + CGRect nodeInWindowCoords = [node convertRect:subnode.frame toNode:nil]; + if (!CGRectIntersectsRect(view.window.frame, nodeInWindowCoords)) { + continue; + } + if (subnode.isAccessibilityElement) { // An accessiblityElement can either be a UIView or a UIAccessibilityElement if (subnode.isLayerBacked) { @@ -275,7 +303,9 @@ - (NSArray *)accessibilityElements return @[]; } - if (_accessibilityElements == nil) { + // when items become hidden/visible we have to manually clear the _accessibilityElements in order to get an updated version + // Instead, let's try computing the elements every time and see how badly it affects performance. + if (_accessibilityElements == nil || ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements)) { _accessibilityElements = [viewNode accessibilityElements]; } return _accessibilityElements; diff --git a/Tests/ASConfigurationTests.mm b/Tests/ASConfigurationTests.mm index a0eefcaa2..67a0b0090 100644 --- a/Tests/ASConfigurationTests.mm +++ b/Tests/ASConfigurationTests.mm @@ -29,7 +29,9 @@ ASExperimentalDispatchApply, ASExperimentalOOMBackgroundDeallocDisable, ASExperimentalDrawingGlobal, - ASExperimentalOptimizeDataControllerPipeline + ASExperimentalOptimizeDataControllerPipeline, + ASExperimentalTraitCollectionDidChangeWithPreviousCollection, + ASExperimentalDoNotCacheAccessibilityElements, }; @interface ASConfigurationTests : ASTestCase @@ -53,7 +55,9 @@ + (NSArray *)names { @"exp_dispatch_apply", @"exp_oom_bg_dealloc_disable", @"exp_drawing_global", - @"exp_optimize_data_controller_pipeline" + @"exp_optimize_data_controller_pipeline", + @"exp_trait_collection_did_change_with_previous_collection", + @"exp_do_not_cache_accessibility_elements", ]; } diff --git a/Tests/ASDisplayViewAccessibilityTests.mm b/Tests/ASDisplayViewAccessibilityTests.mm index f2476a00d..d52151cd6 100644 --- a/Tests/ASDisplayViewAccessibilityTests.mm +++ b/Tests/ASDisplayViewAccessibilityTests.mm @@ -13,15 +13,19 @@ #import #import +#import #import #import #import #import #import #import +#import #import #import "ASDisplayNodeTestsHelper.h" +extern void SortAccessibilityElements(NSMutableArray *elements); + @interface ASDisplayViewAccessibilityTests : XCTestCase @end @@ -34,6 +38,11 @@ - (void)testAccessibilityElementsAccessors ASDisplayNode *subnode = nil; node = [[ASDisplayNode alloc] init]; subnode = [[ASDisplayNode alloc] init]; + + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 560)]; + [window addSubnode:node]; + [window makeKeyAndVisible]; + NSString *label = @"foo"; subnode.isAccessibilityElement = YES; subnode.accessibilityLabel = label; @@ -56,6 +65,10 @@ - (void)testThatSubnodeAccessibilityLabelAggregationWorks innerNode1 = [[ASDisplayNode alloc] init]; innerNode2 = [[ASDisplayNode alloc] init]; + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 560)]; + [window addSubnode:node]; + [window makeKeyAndVisible]; + // Initialize nodes with relevant accessibility data node.isAccessibilityContainer = YES; innerNode1.accessibilityLabel = @"hello"; @@ -78,6 +91,10 @@ - (void)testThatContainerAccessibilityLabelOverrideStopsAggregation node = [[ASDisplayNode alloc] init]; innerNode = [[ASDisplayNode alloc] init]; + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 560)]; + [window addSubnode:node]; + [window makeKeyAndVisible]; + // Initialize nodes with relevant accessibility data node.isAccessibilityContainer = YES; node.accessibilityLabel = @"hello"; @@ -94,6 +111,10 @@ - (void)testThatContainerAccessibilityLabelOverrideStopsAggregation - (void)testAccessibilityLayerBackedContainerWithinAccessibilityContainer { ASDisplayNode *container = [[ASDisplayNode alloc] init]; + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 560)]; + [window addSubnode:container]; + [window makeKeyAndVisible]; + container.frame = CGRectMake(50, 50, 200, 600); container.isAccessibilityContainer = YES; @@ -202,7 +223,12 @@ - (void)testActionForwarding { - (void)fakeSelector:(id)sender { } - (void)testThatAccessibilityElementsWorks { + ASDisplayNode *containerNode = [[ASDisplayNode alloc] init]; + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 560)]; + [window addSubnode:containerNode]; + [window makeKeyAndVisible]; + containerNode.frame = CGRectMake(0, 0, 100, 200); ASTextNode *label = [[ASTextNode alloc] init]; @@ -251,4 +277,161 @@ - (void)testThatAccessibilityElementsOverrideWorks { XCTAssertEqual(elements.firstObject, label); } +- (void)testHiddenAccessibilityElements { + ASDisplayNode *containerNode = [[ASDisplayNode alloc] init]; + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 560)]; + [window addSubnode:containerNode]; + [window makeKeyAndVisible]; + + containerNode.frame = CGRectMake(0, 0, 100, 200); + + ASTextNode *label = [[ASTextNode alloc] init]; + label.attributedText = [[NSAttributedString alloc] initWithString:@"test label"]; + label.frame = CGRectMake(0, 0, 100, 20); + + ASTextNode *hiddenLabel = [[ASTextNode alloc] init]; + hiddenLabel.attributedText = [[NSAttributedString alloc] initWithString:@"hidden label"]; + hiddenLabel.frame = CGRectMake(0, 24, 100, 20); + hiddenLabel.hidden = YES; + + [containerNode addSubnode:label]; + [containerNode addSubnode:hiddenLabel]; + + // force load + __unused UIView *view = containerNode.view; + + NSArray *elements = [containerNode accessibilityElements]; + XCTAssertTrue(elements.count == 1); + XCTAssertEqual(elements.firstObject, label.view); +} + +- (void)testTransparentAccessibilityElements { + ASDisplayNode *containerNode = [[ASDisplayNode alloc] init]; + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 560)]; + [window addSubnode:containerNode]; + [window makeKeyAndVisible]; + containerNode.frame = CGRectMake(0, 0, 100, 200); + + ASTextNode *label = [[ASTextNode alloc] init]; + label.attributedText = [[NSAttributedString alloc] initWithString:@"test label"]; + label.frame = CGRectMake(0, 0, 100, 20); + + ASTextNode *hiddenLabel = [[ASTextNode alloc] init]; + hiddenLabel.attributedText = [[NSAttributedString alloc] initWithString:@"hidden label"]; + hiddenLabel.frame = CGRectMake(0, 24, 100, 20); + hiddenLabel.alpha = 0.0; + + [containerNode addSubnode:label]; + [containerNode addSubnode:hiddenLabel]; + + // force load + __unused UIView *view = containerNode.view; + + NSArray *elements = [containerNode accessibilityElements]; + XCTAssertTrue(elements.count == 1); + XCTAssertEqual(elements.firstObject, label.view); +} + +- (void)testAccessibilityElementsNotInAppWindow { + + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 568)]; + ASDisplayNode *node = [[ASDisplayNode alloc] init]; + node.automaticallyManagesSubnodes = YES; + + ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + window.rootViewController = vc; + [window makeKeyAndVisible]; + [window layoutIfNeeded]; + + CGSize windowSize = window.frame.size; + ASTextNode *label = [[ASTextNode alloc] init]; + label.attributedText = [[NSAttributedString alloc] initWithString:@"on screen"]; + label.frame = CGRectMake(0, 0, 100, 20); + + ASTextNode *partiallyOnScreenNodeY = [[ASTextNode alloc] init]; + partiallyOnScreenNodeY.attributedText = [[NSAttributedString alloc] initWithString:@"partially on screen y"]; + partiallyOnScreenNodeY.frame = CGRectMake(0, windowSize.height - 10, 100, 20); + + ASTextNode *partiallyOnScreenNodeX = [[ASTextNode alloc] init]; + partiallyOnScreenNodeX.attributedText = [[NSAttributedString alloc] initWithString:@"partially on screen x"]; + partiallyOnScreenNodeX.frame = CGRectMake(windowSize.width - 10, 100, 100, 20); + + ASTextNode *offScreenNodeY = [[ASTextNode alloc] init]; + offScreenNodeY.attributedText = [[NSAttributedString alloc] initWithString:@"off screen y"]; + offScreenNodeY.frame = CGRectMake(0, windowSize.height + 10, 100, 20); + + ASTextNode *offScreenNodeX = [[ASTextNode alloc] init]; + offScreenNodeX.attributedText = [[NSAttributedString alloc] initWithString:@"off screen x"]; + offScreenNodeX.frame = CGRectMake(windowSize.width + 1, 200, 100, 20); + + ASTextNode *offScreenNode = [[ASTextNode alloc] init]; + offScreenNode.attributedText = [[NSAttributedString alloc] initWithString:@"off screen"]; + offScreenNode.frame = CGRectMake(windowSize.width + 1, windowSize.height + 1, 100, 20); + + [node addSubnode:label]; + [node addSubnode:partiallyOnScreenNodeY]; + [node addSubnode:partiallyOnScreenNodeX]; + [node addSubnode:offScreenNodeY]; + [node addSubnode:offScreenNodeX]; + [node addSubnode:offScreenNode]; + + NSArray *elements = [node accessibilityElements]; + XCTAssertTrue(elements.count == 3); + XCTAssertTrue([elements containsObject:label.view]); + XCTAssertTrue([elements containsObject:partiallyOnScreenNodeX.view]); + XCTAssertTrue([elements containsObject:partiallyOnScreenNodeY.view]); +} + +- (void)testAccessibilitySort { + ASDisplayNode *node1 = [[ASDisplayNode alloc] init]; + node1.accessibilityFrame = CGRectMake(0, 0, 50, 200); + + ASDisplayNode *node2 = [[ASDisplayNode alloc] init]; + node2.accessibilityFrame = CGRectMake(0, 0, 100, 200); + + ASDisplayNode *node3 = [[ASDisplayNode alloc] init]; + node3.accessibilityFrame = CGRectMake(0, 1, 100, 200); + + ASDisplayNode *node4 = [[ASDisplayNode alloc] init]; + node4.accessibilityFrame = CGRectMake(1, 1, 100, 200); + + NSMutableArray *elements = [@[node2, node4, node3, node1] mutableCopy]; + SortAccessibilityElements(elements); + XCTAssertEqual(elements[0], node1); + XCTAssertEqual(elements[1], node2); + XCTAssertEqual(elements[2], node3); + XCTAssertEqual(elements[3], node4); +} + +- (void)testCustomAccessibilitySort { + + // silly custom sorter that puts items with the largest height first. + setUserDefinedAccessibilitySortComparator(^NSComparisonResult(NSObject *a, NSObject *b) { + if (a.accessibilityFrame.size.height == b.accessibilityFrame.size.height) { + return NSOrderedSame; + } + return a.accessibilityFrame.size.height > b.accessibilityFrame.size.height ? NSOrderedAscending : NSOrderedDescending; + }); + + ASDisplayNode *node1 = [[ASDisplayNode alloc] init]; + node1.accessibilityFrame = CGRectMake(0, 0, 50, 300); + + ASDisplayNode *node2 = [[ASDisplayNode alloc] init]; + node2.accessibilityFrame = CGRectMake(0, 0, 100, 250); + + ASDisplayNode *node3 = [[ASDisplayNode alloc] init]; + node3.accessibilityFrame = CGRectMake(0, 0, 100, 200); + + ASDisplayNode *node4 = [[ASDisplayNode alloc] init]; + node4.accessibilityFrame = CGRectMake(0, 0, 100, 150); + + NSMutableArray *elements = [@[node2, node4, node3, node1] mutableCopy]; + SortAccessibilityElements(elements); + XCTAssertEqual(elements[0], node1); + XCTAssertEqual(elements[1], node2); + XCTAssertEqual(elements[2], node3); + XCTAssertEqual(elements[3], node4); +} + + @end diff --git a/Tests/ASScrollNodeTests.mm b/Tests/ASScrollNodeTests.mm index f9dbd5152..1f7e8c176 100644 --- a/Tests/ASScrollNodeTests.mm +++ b/Tests/ASScrollNodeTests.mm @@ -170,6 +170,10 @@ - (void)testAutomaticallyManagesContentSizeWithInvalidCalculatedSizeForLayout - (void)testASScrollNodeAccessibility { ASDisplayNode *scrollNode = [[ASDisplayNode alloc] init]; + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 560)]; + [window addSubnode:scrollNode]; + [window makeKeyAndVisible]; + ASDisplayNode *node = [[ASDisplayNode alloc] init]; node.isAccessibilityContainer = YES; node.accessibilityLabel = @"node"; From ca217e1275fddace026ef90ba5a9950bae4720c7 Mon Sep 17 00:00:00 2001 From: dmaclach Date: Wed, 20 May 2020 08:39:14 -0700 Subject: [PATCH 20/56] Removes unnecessary `-tearDown` code. (#1822) --- Tests/ASCollectionViewTests.mm | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Tests/ASCollectionViewTests.mm b/Tests/ASCollectionViewTests.mm index 6660c2bbb..2c748d1f8 100644 --- a/Tests/ASCollectionViewTests.mm +++ b/Tests/ASCollectionViewTests.mm @@ -182,18 +182,6 @@ - (void)setUp [ASConfigurationManager test_resetWithConfiguration:config]; } -- (void)tearDown -{ - // We can't prevent the system from retaining windows, but we can at least clear them out to avoid - // pollution between test cases. - for (UIWindow *window in [UIApplication sharedApplication].windows) { - for (UIView *subview in window.subviews) { - [subview removeFromSuperview]; - } - } - [super tearDown]; -} - - (void)testDataSourceImplementsNecessaryMethods { UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; From 6b16bf10beafc5c306c57cefc9618dd3ea6c5660 Mon Sep 17 00:00:00 2001 From: Jeffrey Macko Date: Wed, 20 May 2020 19:41:27 +0200 Subject: [PATCH 21/56] Update Texture.podspec (#1773) 3.0.0 --- Texture.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Texture.podspec b/Texture.podspec index 0f426c5bb..0ce226aff 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -39,7 +39,7 @@ Pod::Spec.new do |spec| end spec.subspec 'PINRemoteImage' do |pin| - pin.dependency 'PINRemoteImage/iOS', '= 3.0.0-beta.14' + pin.dependency 'PINRemoteImage/iOS', '~> 3.0.0' pin.dependency 'PINRemoteImage/PINCache' pin.dependency 'Texture/Core' end From 416568584da480392f2564e85f88d771adddbf97 Mon Sep 17 00:00:00 2001 From: vovasty Date: Wed, 20 May 2020 10:48:01 -0700 Subject: [PATCH 22/56] support cancelation in ASGraphicsCreateImage (#1814) * support cancelation in ASGraphicsCreateImage * updated comment --- Source/Details/ASGraphicsContext.h | 17 ++++++++++++ Source/Details/ASGraphicsContext.mm | 42 ++++++++++++++++++++++------- Tests/ASGraphicsContextTests.mm | 42 +++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 12 deletions(-) diff --git a/Source/Details/ASGraphicsContext.h b/Source/Details/ASGraphicsContext.h index ea39bf3b5..65781efa0 100644 --- a/Source/Details/ASGraphicsContext.h +++ b/Source/Details/ASGraphicsContext.h @@ -30,6 +30,23 @@ NS_ASSUME_NONNULL_BEGIN */ AS_EXTERN UIImage *ASGraphicsCreateImageWithOptions(CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t NS_NOESCAPE _Nullable isCancelled, void (NS_NOESCAPE ^work)(void)) ASDISPLAYNODE_DEPRECATED_MSG("Use ASGraphicsCreateImageWithTraitCollectionAndOptions instead"); +/** +* A wrapper for the UIKit drawing APIs. If you are in ASExperimentalDrawingGlobal, and you have iOS >= 10, we will create +* a UIGraphicsRenderer with an appropriate format. Otherwise, we will use UIGraphicsBeginImageContext et al. +* +* @param traitCollection Trait collection. The `work` block will be executed with this trait collection, so it will affect dynamic colors, etc. +* @param size The size of the context. +* @param opaque Whether the context should be opaque or not. +* @param scale The scale of the context. 0 uses main screen scale. +* @param sourceImage If you are planning to render a UIImage into this context, provide it here and we will use its +* preferred renderer format if we are using UIGraphicsImageRenderer. +* @param isCancelled An optional block for canceling the drawing before forming the image. +* @param work A block, wherein the current UIGraphics context is set based on the arguments. +* +* @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext. +*/ +AS_EXTERN UIImage *ASGraphicsCreateImage(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t _Nullable NS_NOESCAPE isCancelled, void (NS_NOESCAPE ^work)(void)); + /** * A wrapper for the UIKit drawing APIs. * diff --git a/Source/Details/ASGraphicsContext.mm b/Source/Details/ASGraphicsContext.mm index 15fcee0bc..fbd23ddc3 100644 --- a/Source/Details/ASGraphicsContext.mm +++ b/Source/Details/ASGraphicsContext.mm @@ -14,7 +14,7 @@ #if AS_AT_LEAST_IOS13 -#define PERFORM_WORK_WITH_TRAIT_COLLECTION(work, traitCollection) \ +#define ASPerformBlockWithTraitCollection(work, traitCollection) \ if (@available(iOS 13.0, *)) { \ UITraitCollection *uiTraitCollection = ASPrimitiveTraitCollectionToUITraitCollection(traitCollection); \ [uiTraitCollection performAsCurrentTraitCollection:^{ \ @@ -24,7 +24,7 @@ work(); \ } #else -#define PERFORM_WORK_WITH_TRAIT_COLLECTION(work, traitCollection) work(); +#define ASPerformBlockWithTraitCollection(work, traitCollection) work(); #endif @@ -43,10 +43,10 @@ NS_INLINE void ASConfigureExtendedRange(UIGraphicsImageRendererFormat *format) asdisplaynode_iscancelled_block_t NS_NOESCAPE isCancelled, void (^NS_NOESCAPE work)()) { - return ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollectionMakeDefault(), size, opaque, scale, sourceImage, work); + return ASGraphicsCreateImage(ASPrimitiveTraitCollectionMakeDefault(), size, opaque, scale, sourceImage, isCancelled, work); } -UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * sourceImage, void (NS_NOESCAPE ^work)()) { +UIImage *ASGraphicsCreateImage(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * sourceImage, asdisplaynode_iscancelled_block_t NS_NOESCAPE isCancelled, void (NS_NOESCAPE ^work)()) { if (AS_AVAILABLE_IOS_TVOS(10, 10)) { if (ASActivateExperimentalFeature(ASExperimentalDrawingGlobal)) { // If they used default scale, reuse one of two preferred formats. @@ -98,17 +98,39 @@ NS_INLINE void ASConfigureExtendedRange(UIGraphicsImageRendererFormat *format) ASConfigureExtendedRange(format); } - return [[[UIGraphicsImageRenderer alloc] initWithSize:size format:format] imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) { - ASDisplayNodeCAssert(UIGraphicsGetCurrentContext(), @"Should have a context!"); - PERFORM_WORK_WITH_TRAIT_COLLECTION(work, traitCollection) - }]; + // Avoid using the imageWithActions: method because it does not support cancellation at the + // last moment i.e. before actually creating the resulting image. + __block UIImage *image; + NSError *error; + [[[UIGraphicsImageRenderer alloc] initWithSize:size format:format] + runDrawingActions:^(UIGraphicsImageRendererContext *rendererContext) { + ASDisplayNodeCAssert(UIGraphicsGetCurrentContext(), @"Should have a context!"); + ASPerformBlockWithTraitCollection(work, traitCollection); + } + completionActions:^(UIGraphicsImageRendererContext *rendererContext) { + if (isCancelled == nil || !isCancelled()) { + image = rendererContext.currentImage; + } + } + error:&error]; + if (error) { + NSCAssert(NO, @"Error drawing: %@", error); + } + return image; } } // Bad OS or experiment flag. Use UIGraphics* API. UIGraphicsBeginImageContextWithOptions(size, opaque, scale); - PERFORM_WORK_WITH_TRAIT_COLLECTION(work, traitCollection) - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + ASPerformBlockWithTraitCollection(work, traitCollection) + UIImage *image = nil; + if (isCancelled == nil || !isCancelled()) { + image = UIGraphicsGetImageFromCurrentImageContext(); + } UIGraphicsEndImageContext(); return image; } + +UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * sourceImage, void (NS_NOESCAPE ^work)()) { + return ASGraphicsCreateImage(traitCollection, size, opaque, scale, sourceImage, nil, work); +} diff --git a/Tests/ASGraphicsContextTests.mm b/Tests/ASGraphicsContextTests.mm index 35c24b42a..1a9373418 100644 --- a/Tests/ASGraphicsContextTests.mm +++ b/Tests/ASGraphicsContextTests.mm @@ -28,6 +28,44 @@ - (void)setUp #if AS_AT_LEAST_IOS13 +- (void)testCanceled +{ + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { + CGSize size = CGSize{.width=100, .height=100}; + + XCTestExpectation *expectationCancelled = [self expectationWithDescription:@"canceled"]; + + asdisplaynode_iscancelled_block_t isCancelledBlock =^BOOL{ + [expectationCancelled fulfill]; + return true; + }; + + ASPrimitiveTraitCollection traitCollection = ASPrimitiveTraitCollectionMakeDefault(); + UIImage *canceledImage = ASGraphicsCreateImage(traitCollection, size, false, 0, nil, isCancelledBlock, ^{}); + + XCTAssertNil(canceledImage); + + [self waitForExpectations:@[expectationCancelled] timeout:1]; + } +} + +- (void)testCanceledNil +{ + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { + CGSize size = CGSize{.width=100, .height=100}; + ASPrimitiveTraitCollection traitCollection = ASPrimitiveTraitCollectionMakeDefault(); + + XCTestExpectation *expectation = [self expectationWithDescription:@"normal"]; + UIImage *image = ASGraphicsCreateImage(traitCollection, size, false, 0, nil, nil, ^{ + [expectation fulfill]; + }); + + XCTAssert(image); + + [self waitForExpectations:@[expectation] timeout:1]; + } +} + - (void)testTraitCollectionPassedToWork { if (AS_AVAILABLE_IOS_TVOS(13, 13)) { @@ -36,7 +74,7 @@ - (void)testTraitCollectionPassedToWork XCTestExpectation *expectationDark = [self expectationWithDescription:@"trait collection dark"]; ASPrimitiveTraitCollection traitCollectionDark = ASPrimitiveTraitCollectionMakeDefault(); traitCollectionDark.userInterfaceStyle = UIUserInterfaceStyleDark; - ASGraphicsCreateImageWithTraitCollectionAndOptions(traitCollectionDark, size, false, 0, nil, ^{ + ASGraphicsCreateImage(traitCollectionDark, size, false, 0, nil, nil, ^{ UITraitCollection *currentTraitCollection = [UITraitCollection currentTraitCollection]; XCTAssertEqual(currentTraitCollection.userInterfaceStyle, UIUserInterfaceStyleDark); [expectationDark fulfill]; @@ -45,7 +83,7 @@ - (void)testTraitCollectionPassedToWork XCTestExpectation *expectationLight = [self expectationWithDescription:@"trait collection light"]; ASPrimitiveTraitCollection traitCollectionLight = ASPrimitiveTraitCollectionMakeDefault(); traitCollectionLight.userInterfaceStyle = UIUserInterfaceStyleLight; - ASGraphicsCreateImageWithTraitCollectionAndOptions(traitCollectionLight, size, false, 0, nil, ^{ + ASGraphicsCreateImage(traitCollectionLight, size, false, 0, nil, nil, ^{ UITraitCollection *currentTraitCollection = [UITraitCollection currentTraitCollection]; XCTAssertEqual(currentTraitCollection.userInterfaceStyle, UIUserInterfaceStyleLight); [expectationLight fulfill]; From aa91df76345bd765c47cd569794615d561699552 Mon Sep 17 00:00:00 2001 From: Heberti Almeida Date: Thu, 21 May 2020 13:18:48 -0400 Subject: [PATCH 23/56] [IGListKit] Extended IGListKit support for displaying delegates (#1011) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Extended IGListKit support for node deselect, highlight and unhighlight * Proposal of renaming willDisplayItemWithNode and didEndDisplayingItemWithNode to be similiar to UICollectionView * Extended support for IGListDisplayDelegate * Updated changelog with displaying delegates change * Removed extra deprecation supression flag * Reverted ASCollectionNode changes and implemented displaing delegate with indexPathForNode: * Sending a real UICollectionViewCell to the delegate if not nil * Added safety check for nil indexPaths * Discard any CHANGELOG changes for fix Danger error * Add an experimental flag to use native dispatch_apply (#1345) * Add an experimental flag to use native dispatch_apply instead of our core count * 2 approach. This has shown performance wins in some profiling. * Add in other places * Don't return non-animated GIFs for animation (update to latest PINRemoteImage beta) (#940) * Don't return non-animated GIFs for animation * Update to latest PINRemoteImage beta * Fix typos (#1348) * Update containers-overview.md * Update subclassing.md * Update node-overview.md ASImageNode, ASNetworkImageNode and ASMultiplexImageNode are in place of UIImageView, not UIImage. * Revert "Have node and controller share lock (#1227)" (#1347) This reverts commit 2baa9438d798b9cf5689b46038383d0a9b7d007c. * Don't compile out ASExperimentalTextNode if ASTextNode is compiled out (#1353) * Lock up to yogaRoot during layout to avoid deadlocks. (#1356) * Lock up to yogaRoot during layout to avoid dead lock. 1) lock to root for tree 2) lock self to change parent (& consequently root) 3) Implement ASLocking (tryLock) on ASNodeController 4) add lockPair to try-lock node & controller together 5) lock controllers if they exist in lockToRoot... Disable some asserts due to lock to root. :( LL# No commands remaining. * Add macro so non-Yoga still builds :) * wut * Update layout-transition-api.md (#1357) * Optimize ASTwoDimensionalArrayUtils (#1351) * Optimize ASTwoDimensionalArrayUtils These methods are called on the main thread during range controller updates (i.e. every frame) and so they should be as fast as possible. * Rename * Use vector instead of stack array to handle really big cases (e.g. photos) * If we check for batching before content size is available we'll always fetch (#1355) * Do not lock the nodeController if we are not locking to root. (#1360) Doing so leaves it locked when we elsewhere explicitly unlock the node to ascend. * Resolve root constrained size before informing delegate to resolve infinite layout loop. (#1359) * Add `setNeedsLayout` to yoga tree changes. (#1361) * Make ASCollectionElement Public (#1303) * Update AsyncDisplayKit.h * Update project.pbxproj * Optimize _assertSubnodeState (#1352) * Optimize _assertSubnodeState This method is actually pretty painful in today's world. In one iPad mini trace, the first page of nodes spent 6.6ms in this call, just in time profiler. * Clean it up, check count * Check the right value * _ASCollectionViewCell - The point isn't converted before to send to node, impossible to touch button into the node hierarchy (#1362) * Revert node call, useless, the node has a ASDisplayView, and this view forward on the node in first. * Use convertPoint to convert the given point in hittest & pointInside methods. Keep the standard usage if the node didn't rasterized a view. * Removed isNodeLoaded, finally it's useless in this case In these methods, we are on the mainThread, we can create the view if the view is not created. * Optimize ASCATransactionQueue (#1350) * Optimize ASCATransactionQueue. This queue is very busy, and it runs on the main thread so it's important for it to be fast. Avoid waking up the run loop for every single node. Avoid a ton of NSPointerArray overhead that we don't need. Avoid retain/release traffic on the singleton by using an inline function. I confirmed that in release mode, the static __strong is correctly inlined and no ARC traffic is incurred. * Comment * Unlock right * Remove magic number * Cleanup Yoga Categories (#1364) * Add forwarding of UIAccessibilityAction methods (#1344) * Add forwarding of UIAccessibilityAction methods * Use OCMock for testing UIAccessibilityAction method forwarding * Don't add extraneous truncation token during kCTLineTruncationMiddle. (#1297) * Don't add extraneous truncation token during kCTLineTruncationMiddle * Expand these comments a little. * Update the FAQ to throw less shade. (#1379) * Update the FAQ to throw less shade. Both of these technologies have their place, no point in being assholes. * Update faq.md * [Updated Snapshots] Don't add extraneous truncation token during kCTLineTruncationMiddle (#1375) * Don't add extraneous truncation token during kCTLineTruncationMiddle * Expand these comments a little. * Update snapshot tests with beautiful correct behavior * Launches switching ASNetworkImageNode callbacks to global queue. (#1369) * Launches switching ASNetworkImageNode callbacks to global queue. * Good catch configuration tests! * Make ASTextNode2 more forgiving when searching for links (#1374) * Make ASTextNode2 more forgiving when searching for links by searching a 44x44 square around the touch * Trailing whitespace * Safely handle end-of-line * Experiment with different strategies for image downloader priority (#1349) Right now when an image node enters preload state, we kick off an image request with the default priority. Then when it enters display state, we change the priority to "imminent" which is mapped to the default priority as well. This means that requests from preload and display nodes have the same priority and are put to the same pool. The right behavior would be that preload requests should have a lower priority from the beginning. Another problem is that, due to the execution order of -didEnter(Preload|Display|Visible)State calls, a node may kick off a low priority request when it enters preload state even though it knows that it's also visible. By the time -didEnterVisibleState is called, the low priority request may have already been consumed and the download/data task won't pick up the new higher priority, or some work needs to be done to move it to another queue. A better behavior would be to always use the current interface state to determine the priority. This means that visible nodes will kick off high priority requests as soon as -didEnterPreloadState is called. The last (and smaller) issue is that a node marks its request as preload/low priority as soon as it exits visible state. I'd argue that this is too agressive. It may be reasonble for nodes in the trailing direction. Even so, we already handle this case by (almost always) have smaller trailing buffers. So this diff makes sure that nodes that exited visible state will have imminent/default priority if they remain in the display range. All of these new behaviors are wrapped in an experiment and will be tested carefully before being rolled out. * Add imports * Fix build failure * Encapsulate common logics into methods * Address comments * Whoops, someone forgot an else! (#1385) Luckily it seems this didn't cause huge memory bloat because there's a check below that keeps the display flag from being set in low memory conditions when the node is off the screen. * Catch invalid sizes during yoga layout (#1376) * Correct View vs. Layer here (tho it doesn't make any difference) (#1378) Older FBSnapshot versions, however, don't use VerifyViewOrLayer * Expose initial constrained size before layout in case anyone is interested later during the layout on the same thread. (#1377) Optionally, clients are expected to clean it up after usage to avoid accessing outdated data. * Assert for context creation failure during displayBlock. (#1373) Nothing good can possibly happen if we continue without one. * Fix an issue where state change notifications can be sent mulitple times. (#1372) Before the change: both - (void)setShouldInvertStrongReference:(BOOL)shouldInvertStrongReference and - (void)setNode:(ASDisplayNode *)node will call through [self setupReferencesWithNode:node]; which call the [node addInterfaceStateDelegate:self]; * Add Yoga support to ASButtonNode (#1381) * Add Yoga support to ASButtonNode * Drop unowned ASLayoutElementStyle parameter * Fix access of Yoga properties * Move ASButtonNode Yoga logic to Category * Update header * Fix CTLineRef leaks (#1386) Found by Clang Static Analyzer: ~/Texture/Source/ASTextNode2.mm:663:39: warning: Potential leak of an object stored into 'truncationTokenLine' CTLineRef truncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)_truncationAttributedText); ^ ~/Texture/Source/ASTextNode2.mm:666:49: warning: Potential leak of an object stored into 'additionalTruncationTokenLine' CTLineRef additionalTruncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)_additionalTruncationMessage); ^ 2 warnings generated. * Correct attributes lookup for supplementary elements. (#1318) * Need some more locks for working with calculated yoga layouts (#1388) * Adds support for using UIGraphicsImageRenderer in ASTextNode. (#1384) * Adds support for using UIGraphicsImageRenderer in ASTextNode. In many cases this reduces the backing store of text nodes by 1/2. * Guard for UIGraphicsRenderer availability. * Comma * Add UIDataSourceModelAssociation to ASTableView and ASCollectionView (#1354) * Add UIDataSourceModelAssociation protocol conformance to ASTableView and ASCollectionView. * Implementing review feedback from @Adlai-Holler * Rename ASDN C++ namespace to AS (#1366) * Rename ASDN C++ namespace to "AS." Referring to the framework as ASDisplayNode is pretty out-dated and verbose. See CoreAnimation which usees CA for their internal namespace. More using * More cases * Clean up a clang analyzer cast error (#1387) ~/Texture/Source/Private/ASMutableElementMap.mm:32:24: warning: Conversion from value of type 'NSMutableArray *' to incompatible type 'ASMutableCollectionElementTwoDimensionalArray *' _sectionsOfItems = (id)ASTwoDimensionalArrayDeepMutableCopy(items); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. * Update for 9.4.1 CI (#1392) * Remove experimental features (exp_skip_a11y_wait && exp_new_default_cell_layout_mode) (#1383) * Remove experimental features * prevent blocking main thread * remove small content all together as none is the default * Update ASExperimentalFeatures.h * Make experiment checks faster (#1393) * Make experiment checks use dispatch_once when not debugging, clean up singleton * One more * Pull out the variable * Make shared CA transaction queue variable extern so it's actually shared (#1397) * Fix header typo (#1402) * Context is a pretty general name that will cause conflicts with subclasses (#1399) * Suppress documentation warnings when using external libraries (#1401) Fixes 1400 * Add layer-action support to nodes (#1396) * Add layer-action support to nodes, unify hierarchy notifications on it * Better pending state * Fix bool * Skip extra copy * Never run default actions * Continue the search * Avoid an unnecessary lock & unlock pair in ASMainSerialQueue (#1409) * Add clang-format for a common source code format (#1365) * Add clang-format * Update format to be as close as our current style * Fix GIF Caching (#1405) * Add support for reverse direction to yoga layouts (#1413) * Add support for reverse direction to yoga layouts * #ifdef YOGA yoga-specific additions * oops * Only set ASLayoutElementStyle delegate if Yoga is enabled (#1417) * Fix bug in ASRangeController that causes some cell nodes of a collection view which is about to becomes invisible to load their backing view/layer and render (#1418) * Fix a bug with Yoga nodes whose position change and don't update. (#1408) * Follow up on the ASRangeController fix in #1418 (#1419) The changes in #1418 is a bit too aggressive when it comes to nodes that are in display range. It forces those nodes to not preload. Also update the changes to avoid diluting the experiment data by triggering too broadly (i.e avoid triggering when the old and new implementations yield the same result leading to no behavior change). * Dev docs for threading in Texture (#1319) * Getting started on adding threading by example * writing writing writing * more info * More threading * More more more * Threading * self lock * Some language fixes * Update docs/_docs/development/threading.md Co-Authored-By: mikezucc * fix image references * Removed locked jekyll version (#1322) * showcase.md updated (#1421) * Experiment with disabling ASViewController background dealloc (#1420) * [Experiment] Dont forget about these collection view background deallocs (#1424) * Dont forget about these collection view background deallocs * Also Table view for completeness * Fix retain cycle with transaction operations (#1429) Add unit tests that help find cycles. `-testWeakWithSingleOperation` fails without the code fix applied. * Replace +load initializers with __attribute__((constructor)) functions (#1425) * Replace +load initializers with __attribute__((constructor)) functions * Updating the documentation for textureDidInitialize, per @nguyenhuy * Fix dealloc on bg (#1410) * fix SIMULATE_WEB_RESPONSE not imported #449 * Fix to make rangeMode update in right time * remove uncessary assert * Fix collection cell editing bug for iOS 9 & 10 * Revert "Fix collection cell editing bug for iOS 9 & 10" This reverts commit 06e18a10596622ff8a68835c95a23986d7bf61ea. * Fix dealloc long gesture in background * Add support for clipping only specific corners, add unit tests (#1415) * Add support for clipping only specific corners, add unit tests * Remove some cleanup to make the diff smaller * Fix * [ASImageNode]fix incorrect backing size calculation (#1189) * fix backing size for image node which content mode is scaleAspectFit * chore: update comments and naming * add change log * Update CHANGELOG.md * Update CHANGELOG.md Co-Authored-By: junjielu <348649634@qq.com> * add unit test for backing size calculation * correct license * Have image nodes draw into opaque contexts automatically if possible (#1432) * Have image nodes draw into opaque contexts if the image is opaque and it fills the context * Call backingSize once * Fix typo in batch-fetching-api.md (#1437) * [ASDisplayNode] Stop infinite layout in _u_measureNodeWithBoundsIfNecessary (#1434) We came across an infinite layout loop in `_u_measureNodeWithBoundsIfNecessary`. After requesting a layout from above, the sizes between pending and caluclated layout still do not match. We continue to prefer to use the pending layout and ask for another layout loop from above. We can’t seem to break out of this loop. The solution (thanks to Huy for the guidance) was to nil out the pending layout we get from requesting the layout from above. I was only able to reproduce this when working with a node in a `UINavigationBarItem’s` `titleView`. I think that UIKit must be doing something sneaky with setting the frame on the view. While I was not able to create a unit test to catch this issue (I tried for a long time, and can post what I’ve come up with to see if anyone has any suggestions), I was able to create a pretty simple example project that shows the behavior: https://github.com/rcancro/TextureLayoutLoopExample * Add a verbose log for locking operations. Has no effect in production (#1436) * Add a verbose log for locking operations. Has no effect in production * Need check * Wrap transaction operation retain cycle fix in an experiment (#1438) * Wrap transaction operation retain cycle fix in an experiment This is a follow on to #1429. * fix typo in experiment name. fix copyright in tests file. * Fix scroll node in yoga (#1435) * fix SIMULATE_WEB_RESPONSE not imported #449 * Fix to make rangeMode update in right time * remove uncessary assert * Fix collection cell editing bug for iOS 9 & 10 * Revert "Fix collection cell editing bug for iOS 9 & 10" This reverts commit 06e18a10596622ff8a68835c95a23986d7bf61ea. * Fix child not fit to full scroll node's bounds when flex_grow = 1.0 is used on child * Fix the stub for layerActionForKey: to let CA continue the search (#1441) * Fix the stub for layerActionForKey: to let CA continue the search * Kick CI * Revert "Have image nodes draw into opaque contexts automatically if possible (#1432)" (#1443) This reverts commit 28522ce9778581bfd217c0f1baf72ddf70f03916. * Use instance lock for ASPrimitiveTraitCollection (#1442) * Use instance lock for ASPrimitiveTraitCollection * Remove the atomic * Simplify ASTraitCollection propagation in ASViewController (#1447) * Use AS::Mutex in ASCollectionElement (#1445) * [ASTextNode] Maintain isAccessibilityElement setting on text nodes when updating text (#1326) * Add didEnterHierarchy/didExitHierarchy to ASNodeController. (#1444) * Fix wrongly formatted RELEASE link (#1453) * Only create activities during debug (#1456) * [#1451] Add support for UIAccessibilityCustomAction (#1452) This PR adds support for UIAccessibilityCustomAction propagation through ASPendingState so that it can be picked up by VoiceOver. * Shut down graphics contexts experiment (#1458) * Shut down graphics contexts experiment * Remove dead import * Remove gone class * Remove lock of ASTextNodeRendererKey (#1454) * Remove lock of ASTextNodeRendererKey * Remove class check for isEqual * Add const specifier to function parameter * Fixes typo * Fixes typo * Disable ASAssertLocked and ASAssertUnlocked (#1412) * Try to remove global lock when initialising TextKit components (#1455) * Try to remove global lock when initialising TextKit components * Adding experiment flag to dis/enable lock of textkit component * Adding tests * code clean fix typo Make remove lock optional Keep locks code clean * Make ASCollectionNode's pan gesture customizable (#1457) * changes done * complete set of uigesturedeleagte methods * Remove iOS 8 support from logging code. (#1462) * Drop support for Xcode 8 and fix some compiler warnings (#1463) * Remove ASEventLog (#1460) * Remove ASEventLog. We'll focus on ASLog for the future, possibly making it triggerable on a per-node basis * See ya! * Hello semicolon * Remove refs to gone tree methods * Fix * Remove irrelevant change, kick CI * Clean up * Cover the other background dealloc surfaces (#1464) * Passthrough pagingEnabled for ASCollectionNode / ASTableNode (#1466) * Passthrough pagingEnabled for ASCollectionNode and ASTableNode * Add tvOS handling * Fix open context bug introduced in #1458 (#1468) * Make sure all ASDisplayNode properties have backing ivars for consistency. (#1475) * Make sure all ASDisplayNodes have backing ivars for consistency. Found this by enabling #pragma clang diagnostic error "-Wobjc-missing-property-synthesis" for ASDisplayNode. One property is unused, saving 8 bytes of heap space per instance on 64-bit builds. Implement setter/getters for these properties, and add appropriate locking. add the warning as error to the build for this file. * Ensure ASControlMode properties lock before accessing their ivars (#1476) Enable `#pragma clang diagnostic error "-Wobjc-missing-property-synthesis"` for this file. * Add a new "global drawing" experiment to use UIGraphicsRenderer (#1469) * Add a new "global drawing" experiment to use UIGraphicsRenderer everywhere, when available * Fix logic * Use preferredFormat * Cut version 2.8.1 (#1491) * Clean up documentation issues around periods (#1490) There were so unnecessary `'` around periods for some reason. Just deleting those because they are distracting. * Minor update in change log #changelog (#1492) * Ship ASExperimentalFixRangeController (#1486) * Shrink _ASCollectionPendingState from 144 to 128 bytes, a 12.5% reduction (#1485) * Shrink _ASCollectionPendingState from 144 to 128 bytes, a 12.5% reduction These objects accumulate in the heap, so reducing their size will allow more to accumulate before memory warnings. Group the `BOOL`s into a struct. Shrink the various stored `enum`s to fit the size of their contents. Move the ivars around so that the smaller `enum` are near eachother and the bitfield struct. * address review comments. move enums out. add comment. rename struct to _flags * fix a missing rename * Shrink _ASPendingState from 824 to 808 bytes, reduction of ~2% (#1483) * Shrink _ASPendingState from 824 to 808 bytes, reduction of ~2% These objects accumulate in the heap, so reducing their size will allow more to accumulate before memory warnings. Shrink ASPendingState BOOLs. Use unsigned int for these bitfields for clarity. Separate from `_flags` as that struct is compared to `0` for testing. The `_boolFlags` struct is just storing other `BOOL`s. * rename struct fields as suggested in garret's review. * Shrink ASDisplayNode from 1072 to 968 bytes, reduction of 10.74% (#1484) * Shrink ASDisplayNode from 1088 to 976 bytes, reduction of 11.48% These objects accumulate in the heap, so reducing their size will allow more to accumulate before memory warnings. Group the `BOOL`s into a struct. Shrink the various stored `enum`s to fit the size of their contents. Move the ivars around so that the smaller `enum` are near eachother and the bitfield struct. * Forgot to bit-field-ify placeholderEnable; new small size is 968, old size is 1072 (measured consistentlyl on iPhoneSE simulator). 10.74% reduction. * Shrink Button Node (#1494) Button: 1312 to 1288 bytes, running on iPhone SE simulator. 1.9% reduction. Shrink the enums it stores, and place them next to each other (along with a BOOL) to reduce instance size. * Shrink TextNode(2) (#1495) Running in iPhone SE Simulator: - ASTextNode: 1360 to 1352 bytes .6% reduction - ASTextNode2: 1360 to 1304 bytes 4.3% redction Shrink stored enum sizes. Group BOOLs near these smaller enums. Override -usingExperiment to return constant instead of never set, but allocated ivar. * Shrink Pager and Scroll Node (#1496) Running on iPhone SE Simulator: ASPagerNode 1240 to 1232 bytes .7% reduction ASScrollNode 1104 to 1096 bytes .7% reduction - make ASScrollNode smaller by shrinking ASScrollDirection, which requires a change to ASRangeController - shrink ASPagerNode by declaring the BOOL next to the struct * Shrink ASImageNode by .6% and ASNetworkImageNode by 2.2% (#1487) * Shrink ASImageNode by .6% and ASNetworkImageNode by 2.2% ASImageNode goes from 1384 to 1376. ASNetworkImageNode goes from 1496 to 1464. These objects accumulate in the heap, so reducing their size will allow more to accumulate before memory warnings. Group the `BOOL`s into a struct. Shrink the various stored `enum`s to fit the size of their contents. Move the ivars around so that the smaller `enum` are near eachother and the bitfield struct. * add comments as requested in garrett's review. * access ivar directly since already locked as suggested in review. * Remove unused declaration, missed in #1460 (#1497) * Keep the atomics - does not affect memory work (#1498) Revert "Ensure ASControlMode properties lock before accessing their ivars (#1476)" This reverts commit ce1e1956f402a7b762119b0f5fa8df4fccd927e6. Revert "Make sure all ASDisplayNode properties have backing ivars for consistency. (#1475)" This reverts commit d6061f4390f64d0faff1b3432084362f8f9e147d. - Except the unused property `interfaceStateSuspended` is still removed (this is a memory saver). * Shrink ASCellNode by 8 bytes (#1499) Group the BOOLs together, since there are only 4 (and there are no other auto-generated ivars that are < 64 bits) this is sufficient and keeps the properties `atomic`. * Shrink ASEditableTextNode by 16 bytes (#1500) Just shuffle some BOOLs around and explicitly declare an ivar so it is grouped with the others. * ASSignpost: Add support for the os_signpost API, fixes (#1501) * ASSignpost: Add support for the os_signpost API - Removes support for colored intervals. These weren't really useful and they aren't part of the signpost api. - Fixes an issue with range controller interval logging. - Adds an interval for interface orientation changes. * Rename * Support Xcode 9 * Commentary * Shrink ASLayout (#1503) - Shrink the enum. Save 8 bytes. There are 1000s of these in the heap after running Pinterest for 10 minutes. * Cleanup whitespace #trivial (#1507) (It's easier to deal with these as silly oneoffs IMO than to have them conflated with real work) * Shrink LayoutSpec classes (#1502) - Resize enums to make `ASStackLayoutSpec` 40 bytes smaller. This applies to the subclasses too. Co-authored-by: Adlai Holler Co-authored-by: Garrett Moon Co-authored-by: dirtmelon <272485887@qq.com> Co-authored-by: Michael Schneider Co-authored-by: Kevin Co-authored-by: dirtmelon <0xffdirtmelon@gmail.com> Co-authored-by: Jonathan Downing Co-authored-by: Xavier Deloge Co-authored-by: Eric Scheers Co-authored-by: Huy Nguyen Co-authored-by: Greg Bolsinga Co-authored-by: Jacob Farkas Co-authored-by: ernestmama <43187788+ernestmama@users.noreply.github.com> Co-authored-by: Andrew Yates Co-authored-by: Tim Norman Co-authored-by: Michael Zuccarino Co-authored-by: Dmitry Gridnev Co-authored-by: Max Wang Co-authored-by: Ballad <348649634@qq.com> Co-authored-by: ricky Co-authored-by: Patrick Balestra Co-authored-by: Harry Shamansky Co-authored-by: Wu Zhong Co-authored-by: Oskar Zhang Co-authored-by: Adlai Holler Co-authored-by: Greg Bolsinga Co-authored-by: Huy Nguyen Co-authored-by: Andrew Monshizadeh --- .../Private/ASIGListAdapterBasedDataSource.mm | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Source/Private/ASIGListAdapterBasedDataSource.mm b/Source/Private/ASIGListAdapterBasedDataSource.mm index 3cf77afc0..2f89b42cf 100644 --- a/Source/Private/ASIGListAdapterBasedDataSource.mm +++ b/Source/Private/ASIGListAdapterBasedDataSource.mm @@ -86,6 +86,21 @@ - (void)collectionNode:(ASCollectionNode *)collectionNode didSelectItemAtIndexPa [self.delegate collectionView:collectionNode.view didSelectItemAtIndexPath:indexPath]; } +- (void)collectionNode:(ASCollectionNode *)collectionNode didDeselectItemAtIndexPath:(NSIndexPath *)indexPath +{ + [self.delegate collectionView:collectionNode.view didDeselectItemAtIndexPath:indexPath]; +} + +- (void)collectionNode:(ASCollectionNode *)collectionNode didHighlightItemAtIndexPath:(NSIndexPath *)indexPath +{ + [self.delegate collectionView:collectionNode.view didHighlightItemAtIndexPath:indexPath]; +} + +- (void)collectionNode:(ASCollectionNode *)collectionNode didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath +{ + [self.delegate collectionView:collectionNode.view didUnhighlightItemAtIndexPath:indexPath]; +} + - (void)scrollViewDidScroll:(UIScrollView *)scrollView { [self.delegate scrollViewDidScroll:scrollView]; @@ -147,6 +162,32 @@ - (void)collectionNode:(ASCollectionNode *)collectionNode willBeginBatchFetchWit [ctrl beginBatchFetchWithContext:context]; } +- (void)collectionNode:(ASCollectionNode *)collectionNode willDisplayItemWithNode:(ASCellNode *)node +{ + NSIndexPath *indexPath = [collectionNode.view indexPathForNode:node]; + UIView *contentView = node.view.superview; + UICollectionViewCell *cell = contentView.superview; + + if (cell == nil || indexPath == nil) { + return; + } + + [self.delegate collectionView:collectionNode.view willDisplayCell:cell forItemAtIndexPath:indexPath]; +} + +- (void)collectionNode:(ASCollectionNode *)collectionNode didEndDisplayingItemWithNode:(ASCellNode *)node +{ + NSIndexPath *indexPath = [collectionNode.view indexPathForNode:node]; + UIView *contentView = node.view.superview; + UICollectionViewCell *cell = contentView.superview; + + if (cell == nil || indexPath == nil) { + return; + } + + [self.delegate collectionView:collectionNode.view didEndDisplayingCell:cell forItemAtIndexPath:indexPath]; +} + /** * Note: It is not documented that ASCollectionNode will forward these UIKit delegate calls if they are implemented. * It is not considered harmful to do so, and adding them to documentation will confuse most users, who should From 6eb5c88720f4053ab5358f4ce2aaddf2a9af9975 Mon Sep 17 00:00:00 2001 From: vovasty Date: Thu, 21 May 2020 13:52:54 -0700 Subject: [PATCH 24/56] use iOS 13.4.1 and default Xcode 11.4.1 for CI (#1831) --- .github/workflows/ci-master-only.yml | 4 ++-- .github/workflows/ci-pull-requests-only.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/danger.yml | 4 ++-- build.sh | 14 +++++++++++--- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-master-only.yml b/.github/workflows/ci-master-only.yml index 0ed0b5e5e..9f6a4a8bd 100644 --- a/.github/workflows/ci-master-only.yml +++ b/.github/workflows/ci-master-only.yml @@ -8,11 +8,11 @@ on: jobs: cocoapods-lint: env: - DEVELOPER_DIR: /Applications/Xcode_11.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_11.4.1.app/Contents/Developer name: Verify that podspec lints runs-on: macOS-latest steps: - name: Checkout the Git repository - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Run build.sh with cocoapods-lint mode run: ./build.sh cocoapods-lint diff --git a/.github/workflows/ci-pull-requests-only.yml b/.github/workflows/ci-pull-requests-only.yml index 0aee87211..6dbf42b00 100644 --- a/.github/workflows/ci-pull-requests-only.yml +++ b/.github/workflows/ci-pull-requests-only.yml @@ -8,7 +8,7 @@ on: jobs: buildsh: env: - DEVELOPER_DIR: /Applications/Xcode_11.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_11.4.1.app/Contents/Developer strategy: matrix: mode: [cocoapods-lint-default-subspecs, cocoapods-lint-other-subspecs] @@ -21,6 +21,6 @@ jobs: runs-on: macOS-latest steps: - name: Checkout the Git repository - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Run build script run: ./build.sh ${{ matrix.mode }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4b26d585..72b78d44b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,7 @@ on: [push, pull_request] jobs: buildsh: env: - DEVELOPER_DIR: /Applications/Xcode_11.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_11.4.1.app/Contents/Developer strategy: matrix: mode: [tests, framework, life-without-cocoapods, carthage, examples-pt1, examples-pt2, examples-pt3, examples-pt4] @@ -30,6 +30,6 @@ jobs: runs-on: macOS-latest steps: - name: Checkout the Git repository - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Run build script run: ./build.sh ${{ matrix.mode }} diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index 1c32cf05a..50e7a4816 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -4,8 +4,8 @@ on: [pull_request] jobs: buildsh: - env: - DEVELOPER_DIR: /Applications/Xcode_11.app/Contents/Developer + env: + DEVELOPER_DIR: /Applications/Xcode_11.4.1.app/Contents/Developer strategy: matrix: mode: [danger] diff --git a/build.sh b/build.sh index 9701dfb9c..c24719789 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,15 @@ #!/bin/bash - -PLATFORM="${TEXTURE_BUILD_PLATFORM:-platform=iOS Simulator,OS=13.0,name=iPhone 8}" -SDK="${TEXTURE_BUILD_SDK:-iphonesimulator13.0}" +# echo ************* diagnostics +# echo available devices +# instruments -s devices +# echo available sdk +# xcodebuild -showsdks +# echo available Xcode +# ls -ld /Applications/Xcode* +# echo ************* diagnostics end + +PLATFORM="${TEXTURE_BUILD_PLATFORM:-platform=iOS Simulator,OS=13.4.1,name=iPhone 8}" +SDK="${TEXTURE_BUILD_SDK:-iphonesimulator13.4}" DERIVED_DATA_PATH="~/ASDKDerivedData" # It is pitch black. From ddc2dfa1133845152e56ca8f343b286bbcbff777 Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Thu, 21 May 2020 16:09:30 -0700 Subject: [PATCH 25/56] Do not use xcpretty in builds so that CI errors are logged. (#1830) --- build.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build.sh b/build.sh index c24719789..b1db5e420 100755 --- a/build.sh +++ b/build.sh @@ -43,7 +43,7 @@ function build_example { -sdk "$SDK" \ -destination "$PLATFORM" \ -derivedDataPath "$DERIVED_DATA_PATH" \ - build | xcpretty -s + build elif [ -f "${example}/Cartfile" ]; then echo "Using Carthage" local_repo=`pwd` @@ -58,7 +58,7 @@ function build_example { -scheme Sample \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build | xcpretty -s + build cd ../.. fi @@ -88,7 +88,7 @@ tests|all) -scheme AsyncDisplayKit \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build-for-testing test | xcpretty -s + build-for-testing test success="1" ;; @@ -107,7 +107,7 @@ tests_listkit) -scheme ASDKListKitTests \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build-for-testing test | xcpretty -s + build-for-testing test success="1" ;; @@ -206,7 +206,7 @@ life-without-cocoapods|all) -scheme "Life Without CocoaPods" \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build | xcpretty -s + build success="1" ;; @@ -218,7 +218,7 @@ framework|all) -scheme Sample \ -sdk "$SDK" \ -destination "$PLATFORM" \ - build | xcpretty -s + build success="1" ;; From 38852e16cdbe07b54df52b813d7cddbfd62f9e9e Mon Sep 17 00:00:00 2001 From: ricky Date: Thu, 21 May 2020 18:54:58 -0700 Subject: [PATCH 26/56] =?UTF-8?q?[Accessibility]=20Do=20not=20exclude=20el?= =?UTF-8?q?ements=20outside=20the=20window=E2=80=99s=20rect=20that=20are?= =?UTF-8?q?=20subviews=20of=20UIScrollView=20(#1821)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Accessibility] Do not exclude elements outside the window’s rect that are subviews of UIScrollView Previously I put up a diff to exclude accessibility elements that were outside of the current window rect. However, I didn’t take the case of scrollViews (including table and collection views) into consideration. By ignoring cells outside of the window, the scroll view would not advance to additional elements in the scrollView but off screen. I did some side-by-side testing with UIKit and it appears that no elements are excluded that are in a scroll view, even if the element’s rect is outside of the scroll view’s visible rect. In order to match this behavior, I added a recursive superview check to see if an element that is off screen has a scrollView as a parent. If so, we do not exclude it: ``` if (!CGRectIntersectsRect(view.window.frame, nodeInWindowCoords) && !recusivelyCheckSuperviewsForScrollView(view)) { continue; }``` * fix some spacings * force a build * build bump again * Removes unnecessary `-tearDown` code. (#1822) * Update Texture.podspec (#1773) 3.0.0 * support cancelation in ASGraphicsCreateImage (#1814) * support cancelation in ASGraphicsCreateImage * updated comment * [IGListKit] Extended IGListKit support for displaying delegates (#1011) * Extended IGListKit support for node deselect, highlight and unhighlight * Proposal of renaming willDisplayItemWithNode and didEndDisplayingItemWithNode to be similiar to UICollectionView * Extended support for IGListDisplayDelegate * Updated changelog with displaying delegates change * Removed extra deprecation supression flag * Reverted ASCollectionNode changes and implemented displaing delegate with indexPathForNode: * Sending a real UICollectionViewCell to the delegate if not nil * Added safety check for nil indexPaths * Discard any CHANGELOG changes for fix Danger error * Add an experimental flag to use native dispatch_apply (#1345) * Add an experimental flag to use native dispatch_apply instead of our core count * 2 approach. This has shown performance wins in some profiling. * Add in other places * Don't return non-animated GIFs for animation (update to latest PINRemoteImage beta) (#940) * Don't return non-animated GIFs for animation * Update to latest PINRemoteImage beta * Fix typos (#1348) * Update containers-overview.md * Update subclassing.md * Update node-overview.md ASImageNode, ASNetworkImageNode and ASMultiplexImageNode are in place of UIImageView, not UIImage. * Revert "Have node and controller share lock (#1227)" (#1347) This reverts commit 2baa9438d798b9cf5689b46038383d0a9b7d007c. * Don't compile out ASExperimentalTextNode if ASTextNode is compiled out (#1353) * Lock up to yogaRoot during layout to avoid deadlocks. (#1356) * Lock up to yogaRoot during layout to avoid dead lock. 1) lock to root for tree 2) lock self to change parent (& consequently root) 3) Implement ASLocking (tryLock) on ASNodeController 4) add lockPair to try-lock node & controller together 5) lock controllers if they exist in lockToRoot... Disable some asserts due to lock to root. :( LL# No commands remaining. * Add macro so non-Yoga still builds :) * wut * Update layout-transition-api.md (#1357) * Optimize ASTwoDimensionalArrayUtils (#1351) * Optimize ASTwoDimensionalArrayUtils These methods are called on the main thread during range controller updates (i.e. every frame) and so they should be as fast as possible. * Rename * Use vector instead of stack array to handle really big cases (e.g. photos) * If we check for batching before content size is available we'll always fetch (#1355) * Do not lock the nodeController if we are not locking to root. (#1360) Doing so leaves it locked when we elsewhere explicitly unlock the node to ascend. * Resolve root constrained size before informing delegate to resolve infinite layout loop. (#1359) * Add `setNeedsLayout` to yoga tree changes. (#1361) * Make ASCollectionElement Public (#1303) * Update AsyncDisplayKit.h * Update project.pbxproj * Optimize _assertSubnodeState (#1352) * Optimize _assertSubnodeState This method is actually pretty painful in today's world. In one iPad mini trace, the first page of nodes spent 6.6ms in this call, just in time profiler. * Clean it up, check count * Check the right value * _ASCollectionViewCell - The point isn't converted before to send to node, impossible to touch button into the node hierarchy (#1362) * Revert node call, useless, the node has a ASDisplayView, and this view forward on the node in first. * Use convertPoint to convert the given point in hittest & pointInside methods. Keep the standard usage if the node didn't rasterized a view. * Removed isNodeLoaded, finally it's useless in this case In these methods, we are on the mainThread, we can create the view if the view is not created. * Optimize ASCATransactionQueue (#1350) * Optimize ASCATransactionQueue. This queue is very busy, and it runs on the main thread so it's important for it to be fast. Avoid waking up the run loop for every single node. Avoid a ton of NSPointerArray overhead that we don't need. Avoid retain/release traffic on the singleton by using an inline function. I confirmed that in release mode, the static __strong is correctly inlined and no ARC traffic is incurred. * Comment * Unlock right * Remove magic number * Cleanup Yoga Categories (#1364) * Add forwarding of UIAccessibilityAction methods (#1344) * Add forwarding of UIAccessibilityAction methods * Use OCMock for testing UIAccessibilityAction method forwarding * Don't add extraneous truncation token during kCTLineTruncationMiddle. (#1297) * Don't add extraneous truncation token during kCTLineTruncationMiddle * Expand these comments a little. * Update the FAQ to throw less shade. (#1379) * Update the FAQ to throw less shade. Both of these technologies have their place, no point in being assholes. * Update faq.md * [Updated Snapshots] Don't add extraneous truncation token during kCTLineTruncationMiddle (#1375) * Don't add extraneous truncation token during kCTLineTruncationMiddle * Expand these comments a little. * Update snapshot tests with beautiful correct behavior * Launches switching ASNetworkImageNode callbacks to global queue. (#1369) * Launches switching ASNetworkImageNode callbacks to global queue. * Good catch configuration tests! * Make ASTextNode2 more forgiving when searching for links (#1374) * Make ASTextNode2 more forgiving when searching for links by searching a 44x44 square around the touch * Trailing whitespace * Safely handle end-of-line * Experiment with different strategies for image downloader priority (#1349) Right now when an image node enters preload state, we kick off an image request with the default priority. Then when it enters display state, we change the priority to "imminent" which is mapped to the default priority as well. This means that requests from preload and display nodes have the same priority and are put to the same pool. The right behavior would be that preload requests should have a lower priority from the beginning. Another problem is that, due to the execution order of -didEnter(Preload|Display|Visible)State calls, a node may kick off a low priority request when it enters preload state even though it knows that it's also visible. By the time -didEnterVisibleState is called, the low priority request may have already been consumed and the download/data task won't pick up the new higher priority, or some work needs to be done to move it to another queue. A better behavior would be to always use the current interface state to determine the priority. This means that visible nodes will kick off high priority requests as soon as -didEnterPreloadState is called. The last (and smaller) issue is that a node marks its request as preload/low priority as soon as it exits visible state. I'd argue that this is too agressive. It may be reasonble for nodes in the trailing direction. Even so, we already handle this case by (almost always) have smaller trailing buffers. So this diff makes sure that nodes that exited visible state will have imminent/default priority if they remain in the display range. All of these new behaviors are wrapped in an experiment and will be tested carefully before being rolled out. * Add imports * Fix build failure * Encapsulate common logics into methods * Address comments * Whoops, someone forgot an else! (#1385) Luckily it seems this didn't cause huge memory bloat because there's a check below that keeps the display flag from being set in low memory conditions when the node is off the screen. * Catch invalid sizes during yoga layout (#1376) * Correct View vs. Layer here (tho it doesn't make any difference) (#1378) Older FBSnapshot versions, however, don't use VerifyViewOrLayer * Expose initial constrained size before layout in case anyone is interested later during the layout on the same thread. (#1377) Optionally, clients are expected to clean it up after usage to avoid accessing outdated data. * Assert for context creation failure during displayBlock. (#1373) Nothing good can possibly happen if we continue without one. * Fix an issue where state change notifications can be sent mulitple times. (#1372) Before the change: both - (void)setShouldInvertStrongReference:(BOOL)shouldInvertStrongReference and - (void)setNode:(ASDisplayNode *)node will call through [self setupReferencesWithNode:node]; which call the [node addInterfaceStateDelegate:self]; * Add Yoga support to ASButtonNode (#1381) * Add Yoga support to ASButtonNode * Drop unowned ASLayoutElementStyle parameter * Fix access of Yoga properties * Move ASButtonNode Yoga logic to Category * Update header * Fix CTLineRef leaks (#1386) Found by Clang Static Analyzer: ~/Texture/Source/ASTextNode2.mm:663:39: warning: Potential leak of an object stored into 'truncationTokenLine' CTLineRef truncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)_truncationAttributedText); ^ ~/Texture/Source/ASTextNode2.mm:666:49: warning: Potential leak of an object stored into 'additionalTruncationTokenLine' CTLineRef additionalTruncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)_additionalTruncationMessage); ^ 2 warnings generated. * Correct attributes lookup for supplementary elements. (#1318) * Need some more locks for working with calculated yoga layouts (#1388) * Adds support for using UIGraphicsImageRenderer in ASTextNode. (#1384) * Adds support for using UIGraphicsImageRenderer in ASTextNode. In many cases this reduces the backing store of text nodes by 1/2. * Guard for UIGraphicsRenderer availability. * Comma * Add UIDataSourceModelAssociation to ASTableView and ASCollectionView (#1354) * Add UIDataSourceModelAssociation protocol conformance to ASTableView and ASCollectionView. * Implementing review feedback from @Adlai-Holler * Rename ASDN C++ namespace to AS (#1366) * Rename ASDN C++ namespace to "AS." Referring to the framework as ASDisplayNode is pretty out-dated and verbose. See CoreAnimation which usees CA for their internal namespace. More using * More cases * Clean up a clang analyzer cast error (#1387) ~/Texture/Source/Private/ASMutableElementMap.mm:32:24: warning: Conversion from value of type 'NSMutableArray *' to incompatible type 'ASMutableCollectionElementTwoDimensionalArray *' _sectionsOfItems = (id)ASTwoDimensionalArrayDeepMutableCopy(items); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. * Update for 9.4.1 CI (#1392) * Remove experimental features (exp_skip_a11y_wait && exp_new_default_cell_layout_mode) (#1383) * Remove experimental features * prevent blocking main thread * remove small content all together as none is the default * Update ASExperimentalFeatures.h * Make experiment checks faster (#1393) * Make experiment checks use dispatch_once when not debugging, clean up singleton * One more * Pull out the variable * Make shared CA transaction queue variable extern so it's actually shared (#1397) * Fix header typo (#1402) * Context is a pretty general name that will cause conflicts with subclasses (#1399) * Suppress documentation warnings when using external libraries (#1401) Fixes 1400 * Add layer-action support to nodes (#1396) * Add layer-action support to nodes, unify hierarchy notifications on it * Better pending state * Fix bool * Skip extra copy * Never run default actions * Continue the search * Avoid an unnecessary lock & unlock pair in ASMainSerialQueue (#1409) * Add clang-format for a common source code format (#1365) * Add clang-format * Update format to be as close as our current style * Fix GIF Caching (#1405) * Add support for reverse direction to yoga layouts (#1413) * Add support for reverse direction to yoga layouts * #ifdef YOGA yoga-specific additions * oops * Only set ASLayoutElementStyle delegate if Yoga is enabled (#1417) * Fix bug in ASRangeController that causes some cell nodes of a collection view which is about to becomes invisible to load their backing view/layer and render (#1418) * Fix a bug with Yoga nodes whose position change and don't update. (#1408) * Follow up on the ASRangeController fix in #1418 (#1419) The changes in #1418 is a bit too aggressive when it comes to nodes that are in display range. It forces those nodes to not preload. Also update the changes to avoid diluting the experiment data by triggering too broadly (i.e avoid triggering when the old and new implementations yield the same result leading to no behavior change). * Dev docs for threading in Texture (#1319) * Getting started on adding threading by example * writing writing writing * more info * More threading * More more more * Threading * self lock * Some language fixes * Update docs/_docs/development/threading.md Co-Authored-By: mikezucc * fix image references * Removed locked jekyll version (#1322) * showcase.md updated (#1421) * Experiment with disabling ASViewController background dealloc (#1420) * [Experiment] Dont forget about these collection view background deallocs (#1424) * Dont forget about these collection view background deallocs * Also Table view for completeness * Fix retain cycle with transaction operations (#1429) Add unit tests that help find cycles. `-testWeakWithSingleOperation` fails without the code fix applied. * Replace +load initializers with __attribute__((constructor)) functions (#1425) * Replace +load initializers with __attribute__((constructor)) functions * Updating the documentation for textureDidInitialize, per @nguyenhuy * Fix dealloc on bg (#1410) * fix SIMULATE_WEB_RESPONSE not imported #449 * Fix to make rangeMode update in right time * remove uncessary assert * Fix collection cell editing bug for iOS 9 & 10 * Revert "Fix collection cell editing bug for iOS 9 & 10" This reverts commit 06e18a10596622ff8a68835c95a23986d7bf61ea. * Fix dealloc long gesture in background * Add support for clipping only specific corners, add unit tests (#1415) * Add support for clipping only specific corners, add unit tests * Remove some cleanup to make the diff smaller * Fix * [ASImageNode]fix incorrect backing size calculation (#1189) * fix backing size for image node which content mode is scaleAspectFit * chore: update comments and naming * add change log * Update CHANGELOG.md * Update CHANGELOG.md Co-Authored-By: junjielu <348649634@qq.com> * add unit test for backing size calculation * correct license * Have image nodes draw into opaque contexts automatically if possible (#1432) * Have image nodes draw into opaque contexts if the image is opaque and it fills the context * Call backingSize once * Fix typo in batch-fetching-api.md (#1437) * [ASDisplayNode] Stop infinite layout in _u_measureNodeWithBoundsIfNecessary (#1434) We came across an infinite layout loop in `_u_measureNodeWithBoundsIfNecessary`. After requesting a layout from above, the sizes between pending and caluclated layout still do not match. We continue to prefer to use the pending layout and ask for another layout loop from above. We can’t seem to break out of this loop. The solution (thanks to Huy for the guidance) was to nil out the pending layout we get from requesting the layout from above. I was only able to reproduce this when working with a node in a `UINavigationBarItem’s` `titleView`. I think that UIKit must be doing something sneaky with setting the frame on the view. While I was not able to create a unit test to catch this issue (I tried for a long time, and can post what I’ve come up with to see if anyone has any suggestions), I was able to create a pretty simple example project that shows the behavior: https://github.com/rcancro/TextureLayoutLoopExample * Add a verbose log for locking operations. Has no effect in production (#1436) * Add a verbose log for locking operations. Has no effect in production * Need check * Wrap transaction operation retain cycle fix in an experiment (#1438) * Wrap transaction operation retain cycle fix in an experiment This is a follow on to #1429. * fix typo in experiment name. fix copyright in tests file. * Fix scroll node in yoga (#1435) * fix SIMULATE_WEB_RESPONSE not imported #449 * Fix to make rangeMode update in right time * remove uncessary assert * Fix collection cell editing bug for iOS 9 & 10 * Revert "Fix collection cell editing bug for iOS 9 & 10" This reverts commit 06e18a10596622ff8a68835c95a23986d7bf61ea. * Fix child not fit to full scroll node's bounds when flex_grow = 1.0 is used on child * Fix the stub for layerActionForKey: to let CA continue the search (#1441) * Fix the stub for layerActionForKey: to let CA continue the search * Kick CI * Revert "Have image nodes draw into opaque contexts automatically if possible (#1432)" (#1443) This reverts commit 28522ce9778581bfd217c0f1baf72ddf70f03916. * Use instance lock for ASPrimitiveTraitCollection (#1442) * Use instance lock for ASPrimitiveTraitCollection * Remove the atomic * Simplify ASTraitCollection propagation in ASViewController (#1447) * Use AS::Mutex in ASCollectionElement (#1445) * [ASTextNode] Maintain isAccessibilityElement setting on text nodes when updating text (#1326) * Add didEnterHierarchy/didExitHierarchy to ASNodeController. (#1444) * Fix wrongly formatted RELEASE link (#1453) * Only create activities during debug (#1456) * [#1451] Add support for UIAccessibilityCustomAction (#1452) This PR adds support for UIAccessibilityCustomAction propagation through ASPendingState so that it can be picked up by VoiceOver. * Shut down graphics contexts experiment (#1458) * Shut down graphics contexts experiment * Remove dead import * Remove gone class * Remove lock of ASTextNodeRendererKey (#1454) * Remove lock of ASTextNodeRendererKey * Remove class check for isEqual * Add const specifier to function parameter * Fixes typo * Fixes typo * Disable ASAssertLocked and ASAssertUnlocked (#1412) * Try to remove global lock when initialising TextKit components (#1455) * Try to remove global lock when initialising TextKit components * Adding experiment flag to dis/enable lock of textkit component * Adding tests * code clean fix typo Make remove lock optional Keep locks code clean * Make ASCollectionNode's pan gesture customizable (#1457) * changes done * complete set of uigesturedeleagte methods * Remove iOS 8 support from logging code. (#1462) * Drop support for Xcode 8 and fix some compiler warnings (#1463) * Remove ASEventLog (#1460) * Remove ASEventLog. We'll focus on ASLog for the future, possibly making it triggerable on a per-node basis * See ya! * Hello semicolon * Remove refs to gone tree methods * Fix * Remove irrelevant change, kick CI * Clean up * Cover the other background dealloc surfaces (#1464) * Passthrough pagingEnabled for ASCollectionNode / ASTableNode (#1466) * Passthrough pagingEnabled for ASCollectionNode and ASTableNode * Add tvOS handling * Fix open context bug introduced in #1458 (#1468) * Make sure all ASDisplayNode properties have backing ivars for consistency. (#1475) * Make sure all ASDisplayNodes have backing ivars for consistency. Found this by enabling #pragma clang diagnostic error "-Wobjc-missing-property-synthesis" for ASDisplayNode. One property is unused, saving 8 bytes of heap space per instance on 64-bit builds. Implement setter/getters for these properties, and add appropriate locking. add the warning as error to the build for this file. * Ensure ASControlMode properties lock before accessing their ivars (#1476) Enable `#pragma clang diagnostic error "-Wobjc-missing-property-synthesis"` for this file. * Add a new "global drawing" experiment to use UIGraphicsRenderer (#1469) * Add a new "global drawing" experiment to use UIGraphicsRenderer everywhere, when available * Fix logic * Use preferredFormat * Cut version 2.8.1 (#1491) * Clean up documentation issues around periods (#1490) There were so unnecessary `'` around periods for some reason. Just deleting those because they are distracting. * Minor update in change log #changelog (#1492) * Ship ASExperimentalFixRangeController (#1486) * Shrink _ASCollectionPendingState from 144 to 128 bytes, a 12.5% reduction (#1485) * Shrink _ASCollectionPendingState from 144 to 128 bytes, a 12.5% reduction These objects accumulate in the heap, so reducing their size will allow more to accumulate before memory warnings. Group the `BOOL`s into a struct. Shrink the various stored `enum`s to fit the size of their contents. Move the ivars around so that the smaller `enum` are near eachother and the bitfield struct. * address review comments. move enums out. add comment. rename struct to _flags * fix a missing rename * Shrink _ASPendingState from 824 to 808 bytes, reduction of ~2% (#1483) * Shrink _ASPendingState from 824 to 808 bytes, reduction of ~2% These objects accumulate in the heap, so reducing their size will allow more to accumulate before memory warnings. Shrink ASPendingState BOOLs. Use unsigned int for these bitfields for clarity. Separate from `_flags` as that struct is compared to `0` for testing. The `_boolFlags` struct is just storing other `BOOL`s. * rename struct fields as suggested in garret's review. * Shrink ASDisplayNode from 1072 to 968 bytes, reduction of 10.74% (#1484) * Shrink ASDisplayNode from 1088 to 976 bytes, reduction of 11.48% These objects accumulate in the heap, so reducing their size will allow more to accumulate before memory warnings. Group the `BOOL`s into a struct. Shrink the various stored `enum`s to fit the size of their contents. Move the ivars around so that the smaller `enum` are near eachother and the bitfield struct. * Forgot to bit-field-ify placeholderEnable; new small size is 968, old size is 1072 (measured consistentlyl on iPhoneSE simulator). 10.74% reduction. * Shrink Button Node (#1494) Button: 1312 to 1288 bytes, running on iPhone SE simulator. 1.9% reduction. Shrink the enums it stores, and place them next to each other (along with a BOOL) to reduce instance size. * Shrink TextNode(2) (#1495) Running in iPhone SE Simulator: - ASTextNode: 1360 to 1352 bytes .6% reduction - ASTextNode2: 1360 to 1304 bytes 4.3% redction Shrink stored enum sizes. Group BOOLs near these smaller enums. Override -usingExperiment to return constant instead of never set, but allocated ivar. * Shrink Pager and Scroll Node (#1496) Running on iPhone SE Simulator: ASPagerNode 1240 to 1232 bytes .7% reduction ASScrollNode 1104 to 1096 bytes .7% reduction - make ASScrollNode smaller by shrinking ASScrollDirection, which requires a change to ASRangeController - shrink ASPagerNode by declaring the BOOL next to the struct * Shrink ASImageNode by .6% and ASNetworkImageNode by 2.2% (#1487) * Shrink ASImageNode by .6% and ASNetworkImageNode by 2.2% ASImageNode goes from 1384 to 1376. ASNetworkImageNode goes from 1496 to 1464. These objects accumulate in the heap, so reducing their size will allow more to accumulate before memory warnings. Group the `BOOL`s into a struct. Shrink the various stored `enum`s to fit the size of their contents. Move the ivars around so that the smaller `enum` are near eachother and the bitfield struct. * add comments as requested in garrett's review. * access ivar directly since already locked as suggested in review. * Remove unused declaration, missed in #1460 (#1497) * Keep the atomics - does not affect memory work (#1498) Revert "Ensure ASControlMode properties lock before accessing their ivars (#1476)" This reverts commit ce1e1956f402a7b762119b0f5fa8df4fccd927e6. Revert "Make sure all ASDisplayNode properties have backing ivars for consistency. (#1475)" This reverts commit d6061f4390f64d0faff1b3432084362f8f9e147d. - Except the unused property `interfaceStateSuspended` is still removed (this is a memory saver). * Shrink ASCellNode by 8 bytes (#1499) Group the BOOLs together, since there are only 4 (and there are no other auto-generated ivars that are < 64 bits) this is sufficient and keeps the properties `atomic`. * Shrink ASEditableTextNode by 16 bytes (#1500) Just shuffle some BOOLs around and explicitly declare an ivar so it is grouped with the others. * ASSignpost: Add support for the os_signpost API, fixes (#1501) * ASSignpost: Add support for the os_signpost API - Removes support for colored intervals. These weren't really useful and they aren't part of the signpost api. - Fixes an issue with range controller interval logging. - Adds an interval for interface orientation changes. * Rename * Support Xcode 9 * Commentary * Shrink ASLayout (#1503) - Shrink the enum. Save 8 bytes. There are 1000s of these in the heap after running Pinterest for 10 minutes. * Cleanup whitespace #trivial (#1507) (It's easier to deal with these as silly oneoffs IMO than to have them conflated with real work) * Shrink LayoutSpec classes (#1502) - Resize enums to make `ASStackLayoutSpec` 40 bytes smaller. This applies to the subclasses too. Co-authored-by: Adlai Holler Co-authored-by: Garrett Moon Co-authored-by: dirtmelon <272485887@qq.com> Co-authored-by: Michael Schneider Co-authored-by: Kevin Co-authored-by: dirtmelon <0xffdirtmelon@gmail.com> Co-authored-by: Jonathan Downing Co-authored-by: Xavier Deloge Co-authored-by: Eric Scheers Co-authored-by: Huy Nguyen Co-authored-by: Greg Bolsinga Co-authored-by: Jacob Farkas Co-authored-by: ernestmama <43187788+ernestmama@users.noreply.github.com> Co-authored-by: Andrew Yates Co-authored-by: Tim Norman Co-authored-by: Michael Zuccarino Co-authored-by: Dmitry Gridnev Co-authored-by: Max Wang Co-authored-by: Ballad <348649634@qq.com> Co-authored-by: ricky Co-authored-by: Patrick Balestra Co-authored-by: Harry Shamansky Co-authored-by: Wu Zhong Co-authored-by: Oskar Zhang Co-authored-by: Adlai Holler Co-authored-by: Greg Bolsinga Co-authored-by: Huy Nguyen Co-authored-by: Andrew Monshizadeh * use iOS 13.4.1 and default Xcode 11.4.1 for CI (#1831) Co-authored-by: dmaclach Co-authored-by: Jeffrey Macko Co-authored-by: vovasty Co-authored-by: Heberti Almeida Co-authored-by: Adlai Holler Co-authored-by: Garrett Moon Co-authored-by: dirtmelon <272485887@qq.com> Co-authored-by: Michael Schneider Co-authored-by: Kevin Co-authored-by: dirtmelon <0xffdirtmelon@gmail.com> Co-authored-by: Jonathan Downing Co-authored-by: Xavier Deloge Co-authored-by: Eric Scheers Co-authored-by: Huy Nguyen Co-authored-by: Greg Bolsinga Co-authored-by: Jacob Farkas Co-authored-by: ernestmama <43187788+ernestmama@users.noreply.github.com> Co-authored-by: Andrew Yates Co-authored-by: Tim Norman Co-authored-by: Michael Zuccarino Co-authored-by: Dmitry Gridnev Co-authored-by: Max Wang Co-authored-by: Ballad <348649634@qq.com> Co-authored-by: Patrick Balestra Co-authored-by: Harry Shamansky Co-authored-by: Wu Zhong Co-authored-by: Oskar Zhang Co-authored-by: Adlai Holler Co-authored-by: Greg Bolsinga Co-authored-by: Huy Nguyen Co-authored-by: Andrew Monshizadeh --- Source/Details/_ASDisplayViewAccessiblity.mm | 21 ++++++-- Tests/ASDisplayViewAccessibilityTests.mm | 55 ++++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index 8115eea53..367f53687 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -210,6 +210,17 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, U [elements addObject:accessiblityElement]; } +/// Check if a view is a subviews of an UIScrollView. This is used to determine whether to enforce that +/// accessibility elements must be on screen +static BOOL recusivelyCheckSuperviewsForScrollView(UIView *view) { + if (!view) { + return NO; + } else if ([view isKindOfClass:[UIScrollView class]]) { + return YES; + } + return recusivelyCheckSuperviewsForScrollView(view.superview); +} + /// Collect all accessibliity elements for a given view and view node static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *elements) { @@ -226,7 +237,7 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el })); UIView *view = node.view; - + // If we don't have a window, let's just bail out if (!view.window) { return; @@ -246,11 +257,13 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el for (ASDisplayNode *subnode in node.subnodes) { // If a node is hidden or has an alpha of 0.0 we should not include it if (subnode.hidden || subnode.alpha == 0.0) { - continue; + continue; } - // If a subnode is outside of the view's window, exclude it + + // If a subnode is outside of the view's window, exclude it UNLESS it is a subview of an UIScrollView. + // In this case UIKit will return the element even if it is outside of the window or the scrollView's visible rect (contentOffset + contentSize) CGRect nodeInWindowCoords = [node convertRect:subnode.frame toNode:nil]; - if (!CGRectIntersectsRect(view.window.frame, nodeInWindowCoords)) { + if (!CGRectIntersectsRect(view.window.frame, nodeInWindowCoords) && !recusivelyCheckSuperviewsForScrollView(view)) { continue; } diff --git a/Tests/ASDisplayViewAccessibilityTests.mm b/Tests/ASDisplayViewAccessibilityTests.mm index d52151cd6..4dc68e37d 100644 --- a/Tests/ASDisplayViewAccessibilityTests.mm +++ b/Tests/ASDisplayViewAccessibilityTests.mm @@ -20,6 +20,7 @@ #import #import #import +#import #import #import #import "ASDisplayNodeTestsHelper.h" @@ -382,6 +383,60 @@ - (void)testAccessibilityElementsNotInAppWindow { XCTAssertTrue([elements containsObject:partiallyOnScreenNodeY.view]); } +- (void)testAccessibilityElementsNotInAppWindowButInScrollView { + + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 568)]; + ASScrollNode *node = [[ASScrollNode alloc] init]; + node.automaticallyManagesSubnodes = YES; + + ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + window.rootViewController = vc; + [window makeKeyAndVisible]; + [window layoutIfNeeded]; + + CGSize windowSize = window.frame.size; + node.view.contentSize = CGSizeMake(window.frame.size.width, window.frame.size.height * 2.0); + ASTextNode *label = [[ASTextNode alloc] init]; + label.attributedText = [[NSAttributedString alloc] initWithString:@"on screen"]; + label.frame = CGRectMake(0, 0, 100, 20); + + ASTextNode *partiallyOnScreenNodeY = [[ASTextNode alloc] init]; + partiallyOnScreenNodeY.attributedText = [[NSAttributedString alloc] initWithString:@"partially on screen y"]; + partiallyOnScreenNodeY.frame = CGRectMake(0, windowSize.height - 10, 100, 20); + + ASTextNode *partiallyOnScreenNodeX = [[ASTextNode alloc] init]; + partiallyOnScreenNodeX.attributedText = [[NSAttributedString alloc] initWithString:@"partially on screen x"]; + partiallyOnScreenNodeX.frame = CGRectMake(windowSize.width - 10, 100, 100, 20); + + ASTextNode *offScreenNodeY = [[ASTextNode alloc] init]; + offScreenNodeY.attributedText = [[NSAttributedString alloc] initWithString:@"off screen y"]; + offScreenNodeY.frame = CGRectMake(0, windowSize.height + 10, 100, 20); + + ASTextNode *offScreenNodeX = [[ASTextNode alloc] init]; + offScreenNodeX.attributedText = [[NSAttributedString alloc] initWithString:@"off screen x"]; + offScreenNodeX.frame = CGRectMake(windowSize.width + 1, 200, 100, 20); + + ASTextNode *offScreenNode = [[ASTextNode alloc] init]; + offScreenNode.attributedText = [[NSAttributedString alloc] initWithString:@"off screen"]; + offScreenNode.frame = CGRectMake(windowSize.width + 1, windowSize.height + 1, 100, 20); + + [node addSubnode:label]; + [node addSubnode:partiallyOnScreenNodeY]; + [node addSubnode:partiallyOnScreenNodeX]; + [node addSubnode:offScreenNodeY]; + [node addSubnode:offScreenNodeX]; + [node addSubnode:offScreenNode]; + + NSArray *elements = [node accessibilityElements]; + XCTAssertTrue(elements.count == 6); + XCTAssertTrue([elements containsObject:label.view]); + XCTAssertTrue([elements containsObject:partiallyOnScreenNodeX.view]); + XCTAssertTrue([elements containsObject:partiallyOnScreenNodeY.view]); + XCTAssertTrue([elements containsObject:offScreenNodeY.view]); + XCTAssertTrue([elements containsObject:offScreenNodeX.view]); + XCTAssertTrue([elements containsObject:offScreenNode.view]); +} + - (void)testAccessibilitySort { ASDisplayNode *node1 = [[ASDisplayNode alloc] init]; node1.accessibilityFrame = CGRectMake(0, 0, 50, 200); From 8d6c4e67cd02a7111b7b1dc3265af9c5ee480f63 Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Thu, 21 May 2020 19:52:05 -0700 Subject: [PATCH 27/56] Update to OCMock 3.6 (#1829) - The issues in #1038 are not explained. - In `ASCollectionViewTests` do not mock every `collectionViewLayout`, only do it for the test that requires it. In addition, call `-stopMocking` when done. OCMock 3.6 found this code using stuff after it should have been. - 5c42bb4e2f2424f09097a461ffbaa53cc3e21695 says the layer tests are not typically run, but they are in the project. That diff refers to ASUIViewTests being skipped, but those tests do not exist. So I've just disabled them in this diff. It is not clear how they ever worked. --- .../xcschemes/AsyncDisplayKit.xcscheme | 25 +++++++++---------- Podfile | 2 +- Podfile.lock | 8 +++--- Tests/ASCollectionViewTests.mm | 11 ++++---- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/AsyncDisplayKit.xcodeproj/xcshareddata/xcschemes/AsyncDisplayKit.xcscheme b/AsyncDisplayKit.xcodeproj/xcshareddata/xcschemes/AsyncDisplayKit.xcscheme index f06fd13c8..4cfa046b3 100644 --- a/AsyncDisplayKit.xcodeproj/xcshareddata/xcschemes/AsyncDisplayKit.xcscheme +++ b/AsyncDisplayKit.xcodeproj/xcshareddata/xcschemes/AsyncDisplayKit.xcscheme @@ -27,6 +27,15 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -38,23 +47,15 @@ ReferencedContainer = "container:AsyncDisplayKit.xcodeproj"> + + - - - - - - - - 3.6' pod 'FBSnapshotTestCase/Core', '~> 2.1' pod 'JGMethodSwizzler', :git => 'https://github.com/JonasGessner/JGMethodSwizzler', :branch => 'master' end diff --git a/Podfile.lock b/Podfile.lock index ce77f9d72..77af05031 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,12 +1,12 @@ PODS: - FBSnapshotTestCase/Core (2.1.4) - JGMethodSwizzler (2.0.1) - - OCMock (3.4.1) + - OCMock (3.6) DEPENDENCIES: - FBSnapshotTestCase/Core (~> 2.1) - JGMethodSwizzler (from `https://github.com/JonasGessner/JGMethodSwizzler`, branch `master`) - - OCMock (= 3.4.1) + - OCMock (~> 3.6) SPEC REPOS: https://github.com/CocoaPods/Specs.git: @@ -26,8 +26,8 @@ CHECKOUT OPTIONS: SPEC CHECKSUMS: FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a JGMethodSwizzler: 7328146117fffa8a4038c42eb7cd3d4c75006f97 - OCMock: 2cd0716969bab32a2283ff3a46fd26a8c8b4c5e3 + OCMock: 5ea90566be239f179ba766fd9fbae5885040b992 -PODFILE CHECKSUM: 345a6700f5fdec438ef5553e1eebf62653862733 +PODFILE CHECKSUM: 7e86f0142d0db2230d763087056ba6d9eb2afd54 COCOAPODS: 1.9.1 diff --git a/Tests/ASCollectionViewTests.mm b/Tests/ASCollectionViewTests.mm index 2c748d1f8..65dc1bd60 100644 --- a/Tests/ASCollectionViewTests.mm +++ b/Tests/ASCollectionViewTests.mm @@ -147,8 +147,7 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB // Populate these immediately so that they're not unexpectedly nil during tests. self.asyncDelegate = [[ASCollectionViewTestDelegate alloc] initWithNumberOfSections:10 numberOfItemsInSection:10]; id realLayout = [UICollectionViewFlowLayout new]; - id mockLayout = [OCMockObject partialMockForObject:realLayout]; - self.collectionNode = [[ASCollectionNode alloc] initWithFrame:self.view.bounds collectionViewLayout:mockLayout]; + self.collectionNode = [[ASCollectionNode alloc] initWithFrame:self.view.bounds collectionViewLayout:realLayout]; self.collectionView = self.collectionNode.view; self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.collectionNode.dataSource = self.asyncDelegate; @@ -636,14 +635,14 @@ - (void)testThatDisappearingSupplementariesWithLayerBackedNodesDontFailAssert - (void)testThatNodeCalculatedSizesAreUpdatedBeforeFirstPrepareLayoutAfterRotation { updateValidationTestPrologue - id layout = cv.collectionViewLayout; + id collectionViewLayoutMock = OCMPartialMock(cv.collectionViewLayout); CGSize initialItemSize = [cv nodeForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]].calculatedSize; CGSize initialCVSize = cv.bounds.size; // Capture the node size before first call to prepareLayout after frame change. __block CGSize itemSizeAtFirstLayout = CGSizeZero; __block CGSize boundsSizeAtFirstLayout = CGSizeZero; - [[[[layout expect] andDo:^(NSInvocation *) { + [[[[collectionViewLayoutMock expect] andDo:^(NSInvocation *) { itemSizeAtFirstLayout = [cv nodeForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]].calculatedSize; boundsSizeAtFirstLayout = [cv bounds].size; }] andForwardToRealObject] prepareLayout]; @@ -658,10 +657,12 @@ - (void)testThatNodeCalculatedSizesAreUpdatedBeforeFirstPrepareLayoutAfterRotati XCTAssertNotEqualObjects(NSStringFromCGSize(initialCVSize), NSStringFromCGSize(boundsSizeAtFirstLayout)); XCTAssertEqualObjects(NSStringFromCGSize(itemSizeAtFirstLayout), NSStringFromCGSize(finalItemSize)); XCTAssertEqualObjects(NSStringFromCGSize(boundsSizeAtFirstLayout), NSStringFromCGSize(finalCVSize)); - [layout verify]; + [collectionViewLayoutMock verify]; // Teardown [[UIDevice currentDevice] setValue:@(oldDeviceOrientation) forKey:@"orientation"]; + + [collectionViewLayoutMock stopMocking]; } /** From 0fec66c71ff135b7e475974661e867d73dcefc54 Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Fri, 22 May 2020 14:55:11 -0700 Subject: [PATCH 28/56] Remove Danger from the development workflow (#1835) This has proven hard to maintain, and it has limited benefit now that our CHANGELOG points to GitHub commit ranges. --- .github/workflows/danger.yml | 23 ---------- Dangerfile | 83 ------------------------------------ Gemfile | 4 -- build.sh | 13 ++---- 4 files changed, 3 insertions(+), 120 deletions(-) delete mode 100644 .github/workflows/danger.yml delete mode 100644 Dangerfile delete mode 100644 Gemfile diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml deleted file mode 100644 index 50e7a4816..000000000 --- a/.github/workflows/danger.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Danger - -on: [pull_request] - -jobs: - buildsh: - env: - DEVELOPER_DIR: /Applications/Xcode_11.4.1.app/Contents/Developer - strategy: - matrix: - mode: [danger] - include: - - mode: danger - name: Run Danger - name: ${{ matrix.name }} - runs-on: macOS-latest - steps: - - name: Checkout the Git repository - uses: actions/checkout@v1 - - name: Run build script - run: ./build.sh ${{ matrix.mode }} - env: - DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Dangerfile b/Dangerfile deleted file mode 100644 index 147d38906..000000000 --- a/Dangerfile +++ /dev/null @@ -1,83 +0,0 @@ -require 'open-uri' - -source_pattern = /(\.m|\.mm|\.h)$/ - -modified_source_files = git.modified_files.grep(source_pattern) -has_modified_source_files = !modified_source_files.empty? -added_source_files = git.added_files.grep(source_pattern) -has_added_source_files = !added_source_files.empty? - -# Make it more obvious that a PR is a work in progress and shouldn't be merged yet -warn("PR is classed as Work in Progress") if github.pr_title.include? "[WIP]" - -# Warn when there is a big PR -warn("This is a big PR, please consider splitting it up to ease code review.") if git.lines_of_code > 500 - -# Modifying the changelog will probably get overwritten. -if git.modified_files.include?("CHANGELOG.md") && !github.pr_title.include?("#changelog") - warn("PR modifies CHANGELOG.md, which is a generated file. Add #changelog to the title to suppress this warning.") -end - -def full_license(partial_license, filename) - license_header = <<-HEREDOC -// - HEREDOC - license_header += "// " + filename + "\n" - license_header += <<-HEREDOC -// Texture -// - HEREDOC - license_header += partial_license - return license_header -end - -def check_file_header(files_to_check, licenses) - repo_name = github.pr_json["base"]["repo"]["full_name"] - pr_number = github.pr_json["number"] - files = github.api.pull_request_files(repo_name, pr_number) - files.each do |file| - if files_to_check.include?(file["filename"]) - filename = File.basename(file["filename"]) - - data = "" - contents = github.api.get file["contents_url"] - open(contents["download_url"]) { |io| - data += io.read - } - - correct_license = false - licenses.each do |license| - license_header = full_license(license, filename) - if data.include? "Pinterest, Inc." - correct_license = true - end - end - - if correct_license == false - warn ("Please ensure license is correct for #{filename}: \n```\n" + full_license(licenses[0], filename) + "```") - end - - end - end -end - -# Ensure new files have proper header -new_source_license_header = <<-HEREDOC -// Copyright (c) Pinterest, Inc. All rights reserved. -// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 -HEREDOC - -if has_added_source_files - check_file_header(added_source_files, [new_source_license_header]) -end - -# Ensure modified files have proper header -modified_source_license_header = <<-HEREDOC -// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. -// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved. -// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 -HEREDOC - -if has_modified_source_files - check_file_header(modified_source_files, [modified_source_license_header, new_source_license_header]) -end diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 38bfbc8e0..000000000 --- a/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source 'https://rubygems.org' - -gem 'danger' -gem 'danger-slack' \ No newline at end of file diff --git a/build.sh b/build.sh index b1db5e420..b2115aa5b 100755 --- a/build.sh +++ b/build.sh @@ -32,7 +32,7 @@ function build_example { example="$1" clean_derived_data - + if [ -f "${example}/Podfile" ]; then echo "Using CocoaPods" pod install --project-directory=$example @@ -92,13 +92,6 @@ tests|all) success="1" ;; -danger|all) - bundle install - echo "Running Danger..." - bundle exec danger --fail-on-errors=true - success="1" - ;; - tests_listkit) echo "Building & testing AsyncDisplayKit+IGListKit." pod install --project-directory=SubspecWorkspaces/ASDKListKit @@ -253,7 +246,7 @@ cocoapods-lint-other-subspecs) carthage|all) echo "Verifying carthage works." - + set -o pipefail && carthage update && carthage build --no-skip-current success="1" ;; @@ -263,7 +256,7 @@ carthage|all) ;; esac -if [ "$success" = "1" ]; then +if [ "$success" = "1" ]; then trap - EXIT exit 0 fi From 0d7f705aaa002d8ac6b9c2fd700837d5d0b570b5 Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Fri, 22 May 2020 14:58:36 -0700 Subject: [PATCH 29/56] Use ASReplaceMethodWithBlock instead of swizzling with a library (#1832) - I tried to make these tests work with OCMock, but that only ever saw 1 call. - All these do is count `-reloadData` calls. I'm not sure why so many other methods are recorded. - Why we are doing this is the library targets iOS 5 and is flagged as a warning in builds. --- Podfile | 1 - Podfile.lock | 15 +------ Tests/ASTableViewTests.mm | 87 +++++++-------------------------------- 3 files changed, 16 insertions(+), 87 deletions(-) diff --git a/Podfile b/Podfile index 8f50ce5fe..17fdc321a 100644 --- a/Podfile +++ b/Podfile @@ -5,5 +5,4 @@ platform :ios, '9.0' target :'AsyncDisplayKitTests' do pod 'OCMock', '~>3.6' pod 'FBSnapshotTestCase/Core', '~> 2.1' - pod 'JGMethodSwizzler', :git => 'https://github.com/JonasGessner/JGMethodSwizzler', :branch => 'master' end diff --git a/Podfile.lock b/Podfile.lock index 77af05031..77ad0ce02 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,11 +1,9 @@ PODS: - FBSnapshotTestCase/Core (2.1.4) - - JGMethodSwizzler (2.0.1) - OCMock (3.6) DEPENDENCIES: - FBSnapshotTestCase/Core (~> 2.1) - - JGMethodSwizzler (from `https://github.com/JonasGessner/JGMethodSwizzler`, branch `master`) - OCMock (~> 3.6) SPEC REPOS: @@ -13,21 +11,10 @@ SPEC REPOS: - FBSnapshotTestCase - OCMock -EXTERNAL SOURCES: - JGMethodSwizzler: - :branch: master - :git: https://github.com/JonasGessner/JGMethodSwizzler - -CHECKOUT OPTIONS: - JGMethodSwizzler: - :commit: 8791eccc5342224bd293b5867348657e3a240c7f - :git: https://github.com/JonasGessner/JGMethodSwizzler - SPEC CHECKSUMS: FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a - JGMethodSwizzler: 7328146117fffa8a4038c42eb7cd3d4c75006f97 OCMock: 5ea90566be239f179ba766fd9fbae5885040b992 -PODFILE CHECKSUM: 7e86f0142d0db2230d763087056ba6d9eb2afd54 +PODFILE CHECKSUM: 6c5ab754458e18efcf3a8b39a3b97bf96c3d2237 COCOAPODS: 1.9.1 diff --git a/Tests/ASTableViewTests.mm b/Tests/ASTableViewTests.mm index 9a437c44f..846f69e45 100644 --- a/Tests/ASTableViewTests.mm +++ b/Tests/ASTableViewTests.mm @@ -8,10 +8,6 @@ // #import -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdocumentation" -#import -#pragma clang diagnostic pop #import #import @@ -42,13 +38,6 @@ - (void)relayoutAllNodesWithInvalidationBlock:(nullable void (^)())invalidationB @end -@interface UITableView (Testing) -// This will start recording all editing calls to UITableView -// into the provided array. -// Make sure to call [UITableView deswizzleInstanceMethods] to reset this. -+ (void)as_recordEditingCallsIntoArray:(NSMutableArray *)selectors; -@end - @interface ASTestTableView : ASTableView @property (nonatomic) void (^willDeallocBlock)(ASTableView *tableView); @end @@ -608,7 +597,6 @@ - (void)testThatTableNodeConformsToExpectedProtocols - (void)testThatInitialDataLoadHappensInOneShot { - NSMutableArray *selectors = [NSMutableArray array]; ASTableNode *node = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain]; ASTableViewFilledDataSource *dataSource = [ASTableViewFilledDataSource new]; @@ -617,23 +605,25 @@ - (void)testThatInitialDataLoadHappensInOneShot node.dataSource = dataSource; node.delegate = dataSource; - [UITableView as_recordEditingCallsIntoArray:selectors]; + __block NSUInteger reloadCallCount = 0; + __block IMP originalIMP = ASReplaceMethodWithBlock(UITableView.class, @selector(reloadData), ^(UITableView *_tableView) { + reloadCallCount += 1; + ((void (*)(id,SEL))originalIMP)(_tableView, @selector(reloadData)); + }); + XCTAssertGreaterThan(node.numberOfSections, 0); [node waitUntilAllUpdatesAreProcessed]; XCTAssertGreaterThan(node.view.numberOfSections, 0); // The first reloadData call helps prevent UITableView from calling it multiple times while ASDataController is working. // The second reloadData call is the real one. - NSArray *expectedSelectors = @[ NSStringFromSelector(@selector(reloadData)), - NSStringFromSelector(@selector(reloadData)) ]; - XCTAssertEqualObjects(selectors, expectedSelectors); + XCTAssertEqual(reloadCallCount, 2); - [UITableView deswizzleAllInstanceMethods]; + method_setImplementation(class_getInstanceMethod(UITableView.class, @selector(reloadData)), (IMP)originalIMP); } - (void)testThatReloadDataHappensInOneShot { - NSMutableArray *selectors = [NSMutableArray array]; ASTableNode *node = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain]; ASTableViewFilledDataSource *dataSource = [ASTableViewFilledDataSource new]; @@ -648,16 +638,19 @@ - (void)testThatReloadDataHappensInOneShot XCTAssertGreaterThan(node.view.numberOfSections, 0); // Reload data. - [UITableView as_recordEditingCallsIntoArray:selectors]; + __block NSUInteger reloadCallCount = 0; + __block IMP originalIMP = ASReplaceMethodWithBlock(UITableView.class, @selector(reloadData), ^(UITableView *_tableView) { + reloadCallCount += 1; + ((void (*)(id,SEL))originalIMP)(_tableView, @selector(reloadData)); + }); [node reloadData]; [node waitUntilAllUpdatesAreProcessed]; // Assert that the beginning of the call pattern is correct. // There is currently noise that comes after that we will allow for this test. - NSArray *expectedSelectors = @[ NSStringFromSelector(@selector(reloadData)) ]; - XCTAssertEqualObjects(selectors, expectedSelectors); + XCTAssertEqual(reloadCallCount, 1); - [UITableView deswizzleAllInstanceMethods]; + method_setImplementation(class_getInstanceMethod(UITableView.class, @selector(reloadData)), (IMP)originalIMP); } /** @@ -908,53 +901,3 @@ - (void)testTintColorIsPropagatedToTableViewCell } @end - -@implementation UITableView (Testing) - -+ (void)as_recordEditingCallsIntoArray:(NSMutableArray *)selectors -{ - [UITableView swizzleInstanceMethod:@selector(reloadData) withReplacement:JGMethodReplacementProviderBlock { - return JGMethodReplacement(void, UITableView *) { - JGOriginalImplementation(void); - [selectors addObject:NSStringFromSelector(_cmd)]; - }; - }]; - [UITableView swizzleInstanceMethod:@selector(beginUpdates) withReplacement:JGMethodReplacementProviderBlock { - return JGMethodReplacement(void, UITableView *) { - JGOriginalImplementation(void); - [selectors addObject:NSStringFromSelector(_cmd)]; - }; - }]; - [UITableView swizzleInstanceMethod:@selector(endUpdates) withReplacement:JGMethodReplacementProviderBlock { - return JGMethodReplacement(void, UITableView *) { - JGOriginalImplementation(void); - [selectors addObject:NSStringFromSelector(_cmd)]; - }; - }]; - [UITableView swizzleInstanceMethod:@selector(insertRowsAtIndexPaths:withRowAnimation:) withReplacement:JGMethodReplacementProviderBlock { - return JGMethodReplacement(void, UITableView *, NSArray *indexPaths, UITableViewRowAnimation anim) { - JGOriginalImplementation(void, indexPaths, anim); - [selectors addObject:NSStringFromSelector(_cmd)]; - }; - }]; - [UITableView swizzleInstanceMethod:@selector(deleteRowsAtIndexPaths:withRowAnimation:) withReplacement:JGMethodReplacementProviderBlock { - return JGMethodReplacement(void, UITableView *, NSArray *indexPaths, UITableViewRowAnimation anim) { - JGOriginalImplementation(void, indexPaths, anim); - [selectors addObject:NSStringFromSelector(_cmd)]; - }; - }]; - [UITableView swizzleInstanceMethod:@selector(insertSections:withRowAnimation:) withReplacement:JGMethodReplacementProviderBlock { - return JGMethodReplacement(void, UITableView *, NSIndexSet *indexes, UITableViewRowAnimation anim) { - JGOriginalImplementation(void, indexes, anim); - [selectors addObject:NSStringFromSelector(_cmd)]; - }; - }]; - [UITableView swizzleInstanceMethod:@selector(deleteSections:withRowAnimation:) withReplacement:JGMethodReplacementProviderBlock { - return JGMethodReplacement(void, UITableView *, NSIndexSet *indexes, UITableViewRowAnimation anim) { - JGOriginalImplementation(void, indexes, anim); - [selectors addObject:NSStringFromSelector(_cmd)]; - }; - }]; -} - -@end From 74fd8f3d33ddd52005af3b287e61fe7a0503e3d6 Mon Sep 17 00:00:00 2001 From: vovasty Date: Fri, 22 May 2020 20:15:09 -0700 Subject: [PATCH 30/56] deprecate ASGraphicsCreateImageWithTraitCollectionAndOptions (#1836) --- AsyncDisplayKit.xcodeproj/project.pbxproj | 4 ++ Source/ASDisplayNode.mm | 2 +- Source/ASImageNode.h | 3 +- Source/ASImageNode.mm | 18 ++--- Source/ASMapNode.mm | 2 +- Source/ASTextNode.mm | 2 +- Source/Debug/AsyncDisplayKit+Debug.mm | 6 +- Source/Details/ASGraphicsContext.h | 2 +- Source/Private/ASDisplayNode+AsyncDisplay.mm | 4 +- Source/UIImage+ASConvenience.h | 59 ++++++++++++++- Source/UIImage+ASConvenience.mm | 56 ++++++++++++++- Tests/ASImageNodeSnapshotTests.mm | 26 ++++++- .../testTintColorBlock@2x.png | Bin 0 -> 1543 bytes .../testRoundedAllCorners@2x.png | Bin 0 -> 82135 bytes .../testRoundedBorderless@2x.png | Bin 0 -> 78368 bytes .../testRoundedPartial@2x.png | Bin 0 -> 81839 bytes Tests/UIImage+ASConvenienceTests.mm | 68 ++++++++++++++++++ docs/_docs/corner-rounding.md | 3 +- docs/_docs/development/layout-specs.md | 2 +- docs/_docs/image-modification-block.md | 2 +- .../ASDKTube/Sample/Nodes/VideoContentCell.m | 2 +- examples/ASDKgram/Sample/PhotoCellNode.m | 2 +- examples/ASMapNode/Sample/MapHandlerNode.m | 6 +- .../Sample/LayoutExampleNode.swift | 2 +- .../Sample/LayoutExampleNodes.m | 15 ++-- .../Sample/PostNode.m | 4 +- examples/SocialAppLayout/Sample/PostNode.m | 4 +- 27 files changed, 253 insertions(+), 41 deletions(-) create mode 100644 Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorBlock@2x.png create mode 100644 Tests/ReferenceImages_iOS_10/UIImage_ASConvenienceTests/testRoundedAllCorners@2x.png create mode 100644 Tests/ReferenceImages_iOS_10/UIImage_ASConvenienceTests/testRoundedBorderless@2x.png create mode 100644 Tests/ReferenceImages_iOS_10/UIImage_ASConvenienceTests/testRoundedPartial@2x.png create mode 100644 Tests/UIImage+ASConvenienceTests.mm diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 7cb9587b1..6649ed03a 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -379,6 +379,7 @@ CC583AD81EF9BDC300134156 /* OCMockObject+ASAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC583AC71EF9BAB400134156 /* OCMockObject+ASAdditions.mm */; }; CC583AD91EF9BDC600134156 /* ASDisplayNode+OCMock.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC583AC01EF9BAB400134156 /* ASDisplayNode+OCMock.mm */; }; CC58AA4B1E398E1D002C8CB4 /* ASBlockTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CC698827247855F200487428 /* UIImage+ASConvenienceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC698826247855F200487428 /* UIImage+ASConvenienceTests.mm */; }; CC6AA2DA1E9F03B900978E87 /* ASDisplayNode+Ancestry.h in Headers */ = {isa = PBXBuildFile; fileRef = CC6AA2D81E9F03B900978E87 /* ASDisplayNode+Ancestry.h */; settings = {ATTRIBUTES = (Public, ); }; }; CC6AA2DB1E9F03B900978E87 /* ASDisplayNode+Ancestry.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC6AA2D91E9F03B900978E87 /* ASDisplayNode+Ancestry.mm */; }; CC7AF196200D9BD500A21BDE /* ASExperimentalFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7AF195200D9BD500A21BDE /* ASExperimentalFeatures.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -911,6 +912,7 @@ CC583AC61EF9BAB400134156 /* OCMockObject+ASAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OCMockObject+ASAdditions.h"; sourceTree = ""; }; CC583AC71EF9BAB400134156 /* OCMockObject+ASAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "OCMockObject+ASAdditions.mm"; sourceTree = ""; }; CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBlockTypes.h; sourceTree = ""; }; + CC698826247855F200487428 /* UIImage+ASConvenienceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "UIImage+ASConvenienceTests.mm"; sourceTree = ""; }; CC6AA2D81E9F03B900978E87 /* ASDisplayNode+Ancestry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Ancestry.h"; path = "Base/ASDisplayNode+Ancestry.h"; sourceTree = ""; }; CC6AA2D91E9F03B900978E87 /* ASDisplayNode+Ancestry.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASDisplayNode+Ancestry.mm"; path = "Base/ASDisplayNode+Ancestry.mm"; sourceTree = ""; }; CC7AF195200D9BD500A21BDE /* ASExperimentalFeatures.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASExperimentalFeatures.h; sourceTree = ""; }; @@ -1391,6 +1393,7 @@ CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.mm */, 695BE2541DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm */, 407B8BAD2310E2ED00CB979E /* ASLayoutSpecUtilitiesTests.mm */, + CC698826247855F200487428 /* UIImage+ASConvenienceTests.mm */, 057D02C01AC0A66700C7AC3C /* AsyncDisplayKitTestHost */, CC583ABF1EF9BAB400134156 /* Common */, 058D09C6195D04C000B7D73C /* Supporting Files */, @@ -2302,6 +2305,7 @@ ACF6ED5C1B178DC700DA7C62 /* ASCenterLayoutSpecSnapshotTests.mm in Sources */, 9F06E5CD1B4CAF4200F015D8 /* ASCollectionViewTests.mm in Sources */, 2911485C1A77147A005D0878 /* ASControlNodeTests.mm in Sources */, + CC698827247855F200487428 /* UIImage+ASConvenienceTests.mm in Sources */, CC01EB6F23105C7F00CDB61A /* ASImageNodeSnapshotTests.mm in Sources */, CC3B208E1C3F7D0A00798563 /* ASWeakSetTests.mm in Sources */, F711994E1D20C21100568860 /* ASDisplayNodeExtrasTests.mm in Sources */, diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index c9495389f..ede474528 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -1505,7 +1505,7 @@ - (void)_updateClipCornerLayerContentsWithRadius:(CGFloat)radius backgroundColor BOOL isRight = (idx == 1 || idx == 3); CGSize size = CGSizeMake(radius + 1, radius + 1); - UIImage *newContents = ASGraphicsCreateImageWithTraitCollectionAndOptions(self.primitiveTraitCollection, size, NO, self.contentsScaleForDisplay, nil, ^{ + UIImage *newContents = ASGraphicsCreateImage(self.primitiveTraitCollection, size, NO, self.contentsScaleForDisplay, nil, nil, ^{ CGContextRef ctx = UIGraphicsGetCurrentContext(); if (isRight == YES) { CGContextTranslateCTM(ctx, -radius + 1, 0); diff --git a/Source/ASImageNode.h b/Source/ASImageNode.h index d6271f55a..6c71eaa0a 100644 --- a/Source/ASImageNode.h +++ b/Source/ASImageNode.h @@ -21,8 +21,7 @@ NS_ASSUME_NONNULL_BEGIN * * @return A transformed image. */ -typedef UIImage * _Nullable (^asimagenode_modification_block_t)(UIImage *image); - +typedef UIImage * _Nullable (^asimagenode_modification_block_t)(UIImage *image, ASPrimitiveTraitCollection traitCollection); /** * @abstract Draws images. diff --git a/Source/ASImageNode.mm b/Source/ASImageNode.mm index 0650933eb..15a831a8e 100644 --- a/Source/ASImageNode.mm +++ b/Source/ASImageNode.mm @@ -212,7 +212,7 @@ - (UIImage *)placeholderImage __instanceLock__.lock(); ASPrimitiveTraitCollection tc = _primitiveTraitCollection; __instanceLock__.unlock(); - return ASGraphicsCreateImageWithTraitCollectionAndOptions(tc, size, NO, 1, nil, ^{ + return ASGraphicsCreateImage(tc, size, NO, 1, nil, nil, ^{ AS::MutexLocker l(__instanceLock__); [_placeholderColor setFill]; UIRectFill(CGRectMake(0, 0, size.width, size.height)); @@ -382,7 +382,7 @@ + (UIImage *)displayWithParameters:(id)parameter isCancelled:(NS_NOESC BOOL stretchable = !UIEdgeInsetsEqualToEdgeInsets(image.capInsets, UIEdgeInsetsZero); if (stretchable) { if (imageModificationBlock != NULL) { - image = imageModificationBlock(image); + image = imageModificationBlock(image, drawParameter->_traitCollection); } return image; } @@ -498,7 +498,7 @@ + (ASWeakMapEntry *)contentsForkey:(ASImageNodeContentsKey *)key drawParameters: + (UIImage *)createContentsForkey:(ASImageNodeContentsKey *)key drawParameters:(id)parameter isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled { - // The following `ASGraphicsCreateImageWithTraitCollectionAndOptions` call will sometimes take take longer than 5ms on an + // The following `ASGraphicsCreateImage` call will sometimes take take longer than 5ms on an // A5 processor for a 400x800 backingSize. // Check for cancellation before we call it. if (isCancelled()) { @@ -509,7 +509,7 @@ + (UIImage *)createContentsForkey:(ASImageNodeContentsKey *)key drawParameters:( // Use contentsScale of 1.0 and do the contentsScale handling in boundsSizeInPixels so ASCroppedImageBackingSizeAndDrawRectInBounds // will do its rounding on pixel instead of point boundaries - UIImage *result = ASGraphicsCreateImageWithTraitCollectionAndOptions(drawParameters->_traitCollection, key.backingSize, key.isOpaque, 1.0, key.image, ^{ + UIImage *result = ASGraphicsCreateImage(drawParameters->_traitCollection, key.backingSize, key.isOpaque, 1.0, key.image, isCancelled, ^{ BOOL contextIsClean = YES; CGContextRef context = UIGraphicsGetCurrentContext(); @@ -561,7 +561,7 @@ + (UIImage *)createContentsForkey:(ASImageNodeContentsKey *)key drawParameters:( } if (key.imageModificationBlock) { - result = key.imageModificationBlock(result); + result = key.imageModificationBlock(result, drawParameters->_traitCollection); } return result; @@ -810,8 +810,8 @@ - (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTra asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor *borderColor) { - return ^(UIImage *originalImage) { - return ASGraphicsCreateImageWithOptions(originalImage.size, NO, originalImage.scale, originalImage, nil, ^{ + return ^(UIImage *originalImage, ASPrimitiveTraitCollection traitCollection) { + return ASGraphicsCreateImage(traitCollection, originalImage.size, NO, originalImage.scale, originalImage, nil, ^{ UIBezierPath *roundOutline = [UIBezierPath bezierPathWithOvalInRect:(CGRect){CGPointZero, originalImage.size}]; // Make the image round @@ -832,8 +832,8 @@ asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat asimagenode_modification_block_t ASImageNodeTintColorModificationBlock(UIColor *color) { - return ^(UIImage *originalImage) { - UIImage *modifiedImage = ASGraphicsCreateImageWithOptions(originalImage.size, NO, originalImage.scale, originalImage, nil, ^{ + return ^(UIImage *originalImage, ASPrimitiveTraitCollection traitCollection) { + UIImage *modifiedImage = ASGraphicsCreateImage(traitCollection, originalImage.size, NO, originalImage.scale, originalImage, nil, ^{ // Set color and render template [color setFill]; UIImage *templateImage = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; diff --git a/Source/ASMapNode.mm b/Source/ASMapNode.mm index 074c1a5a9..599851e91 100644 --- a/Source/ASMapNode.mm +++ b/Source/ASMapNode.mm @@ -221,7 +221,7 @@ - (void)takeSnapshot CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height); - image = ASGraphicsCreateImageWithTraitCollectionAndOptions(strongSelf.primitiveTraitCollection, image.size, YES, image.scale, image, ^{ + image = ASGraphicsCreateImage(strongSelf.primitiveTraitCollection, image.size, YES, image.scale, image, nil, ^{ [image drawAtPoint:CGPointZero]; UIImage *pinImage; diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index 5d0bf79d3..afffba507 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -575,7 +575,7 @@ + (UIImage *)displayWithParameters:(id)parameters isCancelled:(NS_NOES UIEdgeInsets textContainerInsets = drawParameter ? drawParameter->_textContainerInsets : UIEdgeInsetsZero; ASTextKitRenderer *renderer = [drawParameter rendererForBounds:drawParameter->_bounds]; - UIImage *result = ASGraphicsCreateImageWithTraitCollectionAndOptions(drawParameter->_traitCollection, CGSizeMake(drawParameter->_bounds.size.width, drawParameter->_bounds.size.height), drawParameter->_opaque, drawParameter->_contentScale, nil, ^{ + UIImage *result = ASGraphicsCreateImage(drawParameter->_traitCollection, CGSizeMake(drawParameter->_bounds.size.width, drawParameter->_bounds.size.height), drawParameter->_opaque, drawParameter->_contentScale, nil, nil, ^{ CGContextRef context = UIGraphicsGetCurrentContext(); ASDisplayNodeAssert(context, @"This is no good without a context."); diff --git a/Source/Debug/AsyncDisplayKit+Debug.mm b/Source/Debug/AsyncDisplayKit+Debug.mm index 05fa4a0be..de4159f6d 100644 --- a/Source/Debug/AsyncDisplayKit+Debug.mm +++ b/Source/Debug/AsyncDisplayKit+Debug.mm @@ -140,7 +140,7 @@ - (void)layout UIColor *clipsBorderColor = [UIColor colorWithRed:30/255.0 green:90/255.0 blue:50/255.0 alpha:0.7]; CGRect imgRect = CGRectMake(0, 0, 2.0 * borderWidth + 1.0, 2.0 * borderWidth + 1.0); - UIImage *debugHighlightImage = ASGraphicsCreateImageWithTraitCollectionAndOptions(self.primitiveTraitCollection, imgRect.size, NO, 1, nil, ^{ + UIImage *debugHighlightImage = ASGraphicsCreateImage(self.primitiveTraitCollection, imgRect.size, NO, 1, nil, nil, ^{ [fillColor setFill]; UIRectFill(imgRect); @@ -729,13 +729,15 @@ - (ASTextNode *)createDebugTextNode - (ASImageNode *)createRangeNodeWithColor:(UIColor *)color { ASImageNode *rangeBarImageNode = [[ASImageNode alloc] init]; + ASPrimitiveTraitCollection primitiveTraitCollection = ASPrimitiveTraitCollectionFromUITraitCollection(self.traitCollection); rangeBarImageNode.image = [UIImage as_resizableRoundedImageWithCornerRadius:RANGE_BAR_CORNER_RADIUS cornerColor:[UIColor clearColor] fillColor:[color colorWithAlphaComponent:0.5] borderColor:[[UIColor blackColor] colorWithAlphaComponent:0.9] borderWidth:RANGE_BAR_BORDER_WIDTH roundedCorners:UIRectCornerAllCorners - scale:[[UIScreen mainScreen] scale]]; + scale:[[UIScreen mainScreen] scale] + traitCollection:primitiveTraitCollection]; [self addSubnode:rangeBarImageNode]; return rangeBarImageNode; diff --git a/Source/Details/ASGraphicsContext.h b/Source/Details/ASGraphicsContext.h index 65781efa0..02c18f1a5 100644 --- a/Source/Details/ASGraphicsContext.h +++ b/Source/Details/ASGraphicsContext.h @@ -60,6 +60,6 @@ AS_EXTERN UIImage *ASGraphicsCreateImage(ASPrimitiveTraitCollection traitCollect * * @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext. */ -AS_EXTERN UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, void (NS_NOESCAPE ^work)(void)); +AS_EXTERN UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, void (NS_NOESCAPE ^work)(void)) ASDISPLAYNODE_DEPRECATED_MSG("Use ASGraphicsCreateImage instead"); NS_ASSUME_NONNULL_END diff --git a/Source/Private/ASDisplayNode+AsyncDisplay.mm b/Source/Private/ASDisplayNode+AsyncDisplay.mm index e7a875532..fd77a0697 100644 --- a/Source/Private/ASDisplayNode+AsyncDisplay.mm +++ b/Source/Private/ASDisplayNode+AsyncDisplay.mm @@ -209,7 +209,7 @@ - (asyncdisplaykit_async_transaction_operation_block_t)_displayBlockWithAsynchro displayBlock = ^id{ CHECK_CANCELLED_AND_RETURN_NIL(); - UIImage *image = ASGraphicsCreateImageWithTraitCollectionAndOptions(self.primitiveTraitCollection, bounds.size, opaque, contentsScaleForDisplay, nil, ^{ + UIImage *image = ASGraphicsCreateImage(self.primitiveTraitCollection, bounds.size, opaque, contentsScaleForDisplay, nil, isCancelledBlock, ^{ for (dispatch_block_t block in displayBlocks) { if (isCancelledBlock()) return; block(); @@ -247,7 +247,7 @@ - (asyncdisplaykit_async_transaction_operation_block_t)_displayBlockWithAsynchro }; if (shouldCreateGraphicsContext) { - return ASGraphicsCreateImageWithTraitCollectionAndOptions(self.primitiveTraitCollection, bounds.size, opaque, contentsScaleForDisplay, nil, workWithContext); + return ASGraphicsCreateImage(self.primitiveTraitCollection, bounds.size, opaque, contentsScaleForDisplay, nil, isCancelledBlock, workWithContext); } else { workWithContext(); return image; diff --git a/Source/UIImage+ASConvenience.h b/Source/UIImage+ASConvenience.h index b24c97d1c..e662a6a5a 100644 --- a/Source/UIImage+ASConvenience.h +++ b/Source/UIImage+ASConvenience.h @@ -9,6 +9,7 @@ #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -68,7 +69,20 @@ NS_ASSUME_NONNULL_BEGIN */ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius cornerColor:(nullable UIColor *)cornerColor - fillColor:(UIColor *)fillColor NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; + fillColor:(UIColor *)fillColor NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use as_resizableRoundedImageWithCornerRadius:cornerColor:fillColor:traitCollection: instead"); + +/** + * This generates a flat-color, rounded-corner resizeable image + * + * @param cornerRadius The radius of the rounded-corner + * @param cornerColor The fill color of the corners (For Alpha corners use clearColor) + * @param fillColor The fill color of the rounded-corner image + * @param traitCollection The trait collection. + */ ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(nullable UIColor *)cornerColor + fillColor:(UIColor *)fillColor + traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; /** * This generates a flat-color, rounded-corner resizeable image with a border @@ -83,7 +97,43 @@ NS_ASSUME_NONNULL_BEGIN cornerColor:(UIColor *)cornerColor fillColor:(UIColor *)fillColor borderColor:(nullable UIColor *)borderColor - borderWidth:(CGFloat)borderWidth NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; + borderWidth:(CGFloat)borderWidth NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use as_resizableRoundedImageWithCornerRadius:cornerColor:fillColor:borderColor:borderWidth:traitCollection: instead"); + +/** + * This generates a flat-color, rounded-corner resizeable image with a border + * + * @param cornerRadius The radius of the rounded-corner + * @param cornerColor The fill color of the corners (For Alpha corners use clearColor) + * @param fillColor The fill color of the rounded-corner image + * @param borderColor The border color. Set to nil for no border. + * @param borderWidth The border width. Dummy value if borderColor = nil. + * @param traitCollection The trait collection. + */ ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(UIColor *)cornerColor + fillColor:(UIColor *)fillColor + borderColor:(nullable UIColor *)borderColor + borderWidth:(CGFloat)borderWidth traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; + +/** + * This generates a flat-color, rounded-corner resizeable image with a border + * + * @param cornerRadius The radius of the rounded-corner + * @param cornerColor The fill color of the corners (For Alpha corners use clearColor) + * @param fillColor The fill color of the rounded-corner image + * @param borderColor The border color. Set to nil for no border. + * @param borderWidth The border width. Dummy value if borderColor = nil. + * @param roundedCorners Select individual or multiple corners to round. Set to UIRectCornerAllCorners to round all 4 corners. + * @param scale The number of pixels per point. Provide 0.0 to use the screen scale. + */ ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(nullable UIColor *)cornerColor + fillColor:(UIColor *)fillColor + borderColor:(nullable UIColor *)borderColor + borderWidth:(CGFloat)borderWidth + roundedCorners:(UIRectCorner)roundedCorners + scale:(CGFloat)scale NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use as_resizableRoundedImageWithCornerRadius:cornerColor:fillColor:borderColor:borderWidth:roundedCorners:traitCollection: instead"); +; /** * This generates a flat-color, rounded-corner resizeable image with a border @@ -95,6 +145,7 @@ NS_ASSUME_NONNULL_BEGIN * @param borderWidth The border width. Dummy value if borderColor = nil. * @param roundedCorners Select individual or multiple corners to round. Set to UIRectCornerAllCorners to round all 4 corners. * @param scale The number of pixels per point. Provide 0.0 to use the screen scale. + * @param traitCollection The trait collection. */ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius cornerColor:(nullable UIColor *)cornerColor @@ -102,7 +153,9 @@ NS_ASSUME_NONNULL_BEGIN borderColor:(nullable UIColor *)borderColor borderWidth:(CGFloat)borderWidth roundedCorners:(UIRectCorner)roundedCorners - scale:(CGFloat)scale NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; + scale:(CGFloat)scale + traitCollection:(ASPrimitiveTraitCollection) traitCollection +NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; @end diff --git a/Source/UIImage+ASConvenience.mm b/Source/UIImage+ASConvenience.mm index f766fbfcd..567a377c6 100644 --- a/Source/UIImage+ASConvenience.mm +++ b/Source/UIImage+ASConvenience.mm @@ -79,6 +79,38 @@ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius scale:0.0]; } ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(UIColor *)cornerColor + fillColor:(UIColor *)fillColor + traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED +{ + return [self as_resizableRoundedImageWithCornerRadius:cornerRadius + cornerColor:cornerColor + fillColor:fillColor + borderColor:nil + borderWidth:1.0 + roundedCorners:UIRectCornerAllCorners + scale:0.0 + traitCollection:traitCollection]; +} + ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(UIColor *)cornerColor + fillColor:(UIColor *)fillColor + borderColor:(UIColor *)borderColor + borderWidth:(CGFloat)borderWidth + traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED { + return [self as_resizableRoundedImageWithCornerRadius:cornerRadius + cornerColor:cornerColor + fillColor:fillColor + borderColor:borderColor + borderWidth:borderWidth + roundedCorners:UIRectCornerAllCorners + scale:0.0 + traitCollection:traitCollection]; +} + + + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius cornerColor:(UIColor *)cornerColor fillColor:(UIColor *)fillColor @@ -100,7 +132,27 @@ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth roundedCorners:(UIRectCorner)roundedCorners - scale:(CGFloat)scale NS_RETURNS_RETAINED + scale:(CGFloat)scale NS_RETURNS_RETAINED { + + return [self as_resizableRoundedImageWithCornerRadius:cornerRadius + cornerColor:cornerColor + fillColor:fillColor + borderColor:borderColor + borderWidth:borderWidth + roundedCorners:roundedCorners + scale:scale + traitCollection:ASPrimitiveTraitCollectionMakeDefault()]; +} + + ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(UIColor *)cornerColor + fillColor:(UIColor *)fillColor + borderColor:(UIColor *)borderColor + borderWidth:(CGFloat)borderWidth + roundedCorners:(UIRectCorner)roundedCorners + scale:(CGFloat)scale + traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED { static NSCache *__pathCache = nil; static dispatch_once_t onceToken; @@ -134,7 +186,7 @@ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius // We should probably check if the background color has any alpha component but that // might be expensive due to needing to check mulitple color spaces. - UIImage *result = ASGraphicsCreateImageWithOptions(bounds.size, cornerColor != nil, scale, nil, nil, ^{ + UIImage *result = ASGraphicsCreateImage(traitCollection, bounds.size, cornerColor != nil, scale, nil, nil, ^{ BOOL contextIsClean = YES; if (cornerColor) { contextIsClean = NO; diff --git a/Tests/ASImageNodeSnapshotTests.mm b/Tests/ASImageNodeSnapshotTests.mm index fafebf789..431e28d09 100644 --- a/Tests/ASImageNodeSnapshotTests.mm +++ b/Tests/ASImageNodeSnapshotTests.mm @@ -194,7 +194,31 @@ - (void)testRoundedCornerBlock UIRectFill(CGRectMake(0, 0, 100, 100)); UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); - UIImage *rounded = ASImageNodeRoundBorderModificationBlock(2, [UIColor redColor])(result); + + ASPrimitiveTraitCollection traitCollection; + + if (@available(iOS 13.0, *)) { + traitCollection = ASPrimitiveTraitCollectionFromUITraitCollection(UITraitCollection.currentTraitCollection); + } else { + traitCollection = ASPrimitiveTraitCollectionMakeDefault(); + } + + UIImage *rounded = ASImageNodeRoundBorderModificationBlock(2, [UIColor redColor])(result, traitCollection); + ASImageNode *node = [[ASImageNode alloc] init]; + node.image = rounded; + ASDisplayNodeSizeToFitSize(node, rounded.size); + ASSnapshotVerifyNode(node, nil); +} + +- (void)testTintColorBlock +{ + UIGraphicsBeginImageContext(CGSizeMake(100, 100)); + [[UIColor blueColor] setFill]; + UIRectFill(CGRectMake(0, 0, 100, 100)); + UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + UIImage *rounded = ASImageNodeTintColorModificationBlock([UIColor redColor])(result, ASPrimitiveTraitCollectionMakeDefault()); ASImageNode *node = [[ASImageNode alloc] init]; node.image = rounded; ASDisplayNodeSizeToFitSize(node, rounded.size); diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorBlock@2x.png b/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorBlock@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..77cf9afb66ee3c5e0b025c0b04b92f53a2d07e18 GIT binary patch literal 1543 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>sYs3RO!M_+ z&;qhK7+4sk7+66{fY^>v8qRiO)L>u+i!(7Wv}ZD~K-KsGX%LtI#2`Hont1^uR5eg+ z0TW#Hi3Q9EHb|T2wN?`##aZAHSB|Ursro{jMqkR*jfyuBElnmdF lCPGpIa5U3Vp6Na@*#C;$W&Eq>1u!)-c)I$ztaD0e0sz9aE^Gh* literal 0 HcmV?d00001 diff --git a/Tests/ReferenceImages_iOS_10/UIImage_ASConvenienceTests/testRoundedAllCorners@2x.png b/Tests/ReferenceImages_iOS_10/UIImage_ASConvenienceTests/testRoundedAllCorners@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..54bb3fda78bd45d2c2290f4286553346634b32c8 GIT binary patch literal 82135 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 +#import +#import "ASSnapshotTestCase.h" + +@interface UIImage_ASConvenienceTests : ASSnapshotTestCase + +@end + +@implementation UIImage_ASConvenienceTests +- (UIImage*) imageWithColor:(UIColor *)color { + UIGraphicsBeginImageContext(CGSizeMake(100, 100)); + [color setFill]; + UIRectFill(CGRectMake(0, 0, 100, 100)); + UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return result; +} + +- (void)testRoundedPartial { + ASImageNode *node = [[ASImageNode alloc] init]; + UIImage *image = [UIImage as_resizableRoundedImageWithCornerRadius:50.0 + cornerColor:UIColor.redColor + fillColor:UIColor.greenColor + borderColor:UIColor.blueColor + borderWidth:4.0 + roundedCorners:UIRectCornerTopLeft | UIRectCornerBottomRight + scale:2.0 + traitCollection:ASPrimitiveTraitCollectionMakeDefault()]; + + node.image = image; + ASDisplayNodeSizeToFitSize(node, CGSizeMake(1000, 1000)); + ASSnapshotVerifyNode(node, nil); +} + +- (void)testRoundedAllCorners { + ASImageNode *node = [[ASImageNode alloc] init]; + UIImage *image = [UIImage as_resizableRoundedImageWithCornerRadius:50.0 + cornerColor:UIColor.redColor + fillColor:UIColor.greenColor + borderColor:UIColor.blueColor + borderWidth:4.0 + traitCollection:ASPrimitiveTraitCollectionMakeDefault()]; + + node.image = image; + ASDisplayNodeSizeToFitSize(node, CGSizeMake(1000, 1000)); + ASSnapshotVerifyNode(node, nil); +} + +- (void)testRoundedBorderless { + ASImageNode *node = [[ASImageNode alloc] init]; + UIImage *image = [UIImage as_resizableRoundedImageWithCornerRadius:50.0 + cornerColor:UIColor.redColor + fillColor:UIColor.greenColor + traitCollection:ASPrimitiveTraitCollectionMakeDefault()]; + + node.image = image; + ASDisplayNodeSizeToFitSize(node, CGSizeMake(1000, 1000)); + ASSnapshotVerifyNode(node, nil); +} +@end diff --git a/docs/_docs/corner-rounding.md b/docs/_docs/corner-rounding.md index 5dfdbb9fc..8081bc7e3 100755 --- a/docs/_docs/corner-rounding.md +++ b/docs/_docs/corner-rounding.md @@ -183,7 +183,8 @@ _photoImageNode.willDisplayNodeContentWithRenderingContext = ^(CGContextRef cont CGFloat radius = cornerRadius * screenScale; UIImage *overlay = [UIImage as_resizableRoundedImageWithCornerRadius:radius cornerColor:[UIColor clearColor] - fillColor:[UIColor clearColor]]; + fillColor:[UIColor clearColor] + traitCollection:self.primitiveTraitCollection]; [overlay drawInRect:bounds]; [[UIBezierPath bezierPathWithRoundedRect:bounds cornerRadius:radius] addClip]; }; diff --git a/docs/_docs/development/layout-specs.md b/docs/_docs/development/layout-specs.md index 826774c25..771d4ca05 100644 --- a/docs/_docs/development/layout-specs.md +++ b/docs/_docs/development/layout-specs.md @@ -28,7 +28,7 @@ Here is an example from the project `LayoutSpecExamples` where an `ASDisplayNode _iconNode = [[ASNetworkImageNode alloc] init]; _iconNode.URL = [NSURL URLWithString:@"http://texturegroup.org/static/images/layout-examples-photo-with-outset-icon-overlay-icon.png"]; - [_iconNode setImageModificationBlock:^UIImage *(UIImage *image) { // FIXME: in framework autocomplete for setImageModificationBlock line seems broken + [_iconNode setImageModificationBlock:^UIImage *(UIImage *image, ASPrimitiveTraitCollection traitCollection) { // FIXME: in framework autocomplete for setImageModificationBlock line seems broken CGSize profileImageSize = CGSizeMake(60, 60); return [image makeCircularImageWithSize:profileImageSize withBorderWidth:10]; }]; diff --git a/docs/_docs/image-modification-block.md b/docs/_docs/image-modification-block.md index 1e2e2716a..d676ae149 100755 --- a/docs/_docs/image-modification-block.md +++ b/docs/_docs/image-modification-block.md @@ -59,7 +59,7 @@ In the following example we assume we have an avatar node that will be setup in - (instancetype)init { // ... - _userAvatarImageNode.imageModificationBlock = ^UIImage *(UIImage *image) { + _userAvatarImageNode.imageModificationBlock = ^UIImage *(UIImage *image, ASPrimitiveTraitCollection traitCollection) { CGSize profileImageSize = CGSizeMake(USER_IMAGE_HEIGHT, USER_IMAGE_HEIGHT); return [image makeCircularImageWithSize:profileImageSize]; }; diff --git a/examples/ASDKTube/Sample/Nodes/VideoContentCell.m b/examples/ASDKTube/Sample/Nodes/VideoContentCell.m index fac4e389d..034513f1f 100644 --- a/examples/ASDKTube/Sample/Nodes/VideoContentCell.m +++ b/examples/ASDKTube/Sample/Nodes/VideoContentCell.m @@ -45,7 +45,7 @@ - (instancetype)initWithVideoObject:(VideoModel *)video _avatarNode = [[ASNetworkImageNode alloc] init]; _avatarNode.URL = _videoModel.avatarUrl; - [_avatarNode setImageModificationBlock:^UIImage *(UIImage *image) { + [_avatarNode setImageModificationBlock:^UIImage *(UIImage *image, ASPrimitiveTraitCollection traitCollection) { CGSize profileImageSize = CGSizeMake(AVATAR_IMAGE_HEIGHT, AVATAR_IMAGE_HEIGHT); return [image makeCircularImageWithSize:profileImageSize]; }]; diff --git a/examples/ASDKgram/Sample/PhotoCellNode.m b/examples/ASDKgram/Sample/PhotoCellNode.m index 5353da65b..f66636359 100644 --- a/examples/ASDKgram/Sample/PhotoCellNode.m +++ b/examples/ASDKgram/Sample/PhotoCellNode.m @@ -58,7 +58,7 @@ - (instancetype)initWithPhotoObject:(PhotoModel *)photo; _userAvatarImageNode.URL = photo.ownerUserProfile.userPicURL; // FIXME: make round // FIXME: autocomplete for this line seems broken - [_userAvatarImageNode setImageModificationBlock:^UIImage *(UIImage *image) { + [_userAvatarImageNode setImageModificationBlock:^UIImage *(UIImage *image, ASPrimitiveTraitCollection traitCollection) { CGSize profileImageSize = CGSizeMake(USER_IMAGE_HEIGHT, USER_IMAGE_HEIGHT); return [image makeCircularImageWithSize:profileImageSize backgroundColor:nil]; }]; diff --git a/examples/ASMapNode/Sample/MapHandlerNode.m b/examples/ASMapNode/Sample/MapHandlerNode.m index 9226253a1..da08daef0 100644 --- a/examples/ASMapNode/Sample/MapHandlerNode.m +++ b/examples/ASMapNode/Sample/MapHandlerNode.m @@ -49,13 +49,15 @@ - (instancetype)init UIImage *backgroundImage = [UIImage as_resizableRoundedImageWithCornerRadius:5 cornerColor:[UIColor whiteColor] - fillColor:[UIColor lightGrayColor]]; + fillColor:[UIColor lightGrayColor] + traitCollection:self.primitiveTraitCollection]; UIImage *backgroundHiglightedImage = [UIImage as_resizableRoundedImageWithCornerRadius:5 cornerColor:[UIColor whiteColor] fillColor:[[UIColor lightGrayColor] colorWithAlphaComponent:0.4] borderColor:[UIColor lightGrayColor] - borderWidth:2.0]; + borderWidth:2.0 + traitCollection:self.primitiveTraitCollection]; [_updateRegionButton setBackgroundImage:backgroundImage forState:UIControlStateNormal]; [_updateRegionButton setBackgroundImage:backgroundHiglightedImage forState:UIControlStateHighlighted]; diff --git a/examples/LayoutSpecExamples-Swift/Sample/LayoutExampleNode.swift b/examples/LayoutSpecExamples-Swift/Sample/LayoutExampleNode.swift index c113e07d3..c2231d7dd 100644 --- a/examples/LayoutSpecExamples-Swift/Sample/LayoutExampleNode.swift +++ b/examples/LayoutSpecExamples-Swift/Sample/LayoutExampleNode.swift @@ -97,7 +97,7 @@ class PhotoWithOutsetIconOverlay : LayoutExampleNode { iconNode.url = URL(string: "http://texturegroup.org/static/images/layout-examples-photo-with-outset-icon-overlay-icon.png") - iconNode.imageModificationBlock = { image in + iconNode.imageModificationBlock = { (image, traitCollection) -> UIImage in let profileImageSize = CGSize(width: 60, height: 60) return image.makeCircularImage(size: profileImageSize, borderWidth: 10) } diff --git a/examples/LayoutSpecExamples/Sample/LayoutExampleNodes.m b/examples/LayoutSpecExamples/Sample/LayoutExampleNodes.m index 5d9d63663..1c0bcc26b 100644 --- a/examples/LayoutSpecExamples/Sample/LayoutExampleNodes.m +++ b/examples/LayoutSpecExamples/Sample/LayoutExampleNodes.m @@ -172,7 +172,7 @@ - (instancetype)init _iconNode = [[ASNetworkImageNode alloc] init]; _iconNode.URL = [NSURL URLWithString:@"http://texturegroup.org/static/images/layout-examples-photo-with-outset-icon-overlay-icon.png"]; - [_iconNode setImageModificationBlock:^UIImage *(UIImage *image) { // FIXME: in framework autocomplete for setImageModificationBlock line seems broken + [_iconNode setImageModificationBlock:^UIImage *(UIImage *image, ASPrimitiveTraitCollection traitCollection) { // FIXME: in framework autocomplete for setImageModificationBlock line seems broken CGSize profileImageSize = CGSizeMake(60, 60); return [image makeCircularImageWithSize:profileImageSize withBorderWidth:10]; }]; @@ -222,7 +222,10 @@ - (instancetype)init self.backgroundColor = [UIColor whiteColor]; _topSeparator = [[ASImageNode alloc] init]; - _topSeparator.image = [UIImage as_resizableRoundedImageWithCornerRadius:1.0 cornerColor:[UIColor blackColor] fillColor:[UIColor blackColor]]; + _topSeparator.image = [UIImage as_resizableRoundedImageWithCornerRadius:1.0 + cornerColor:[UIColor blackColor] + fillColor:[UIColor blackColor] + traitCollection:self.primitiveTraitCollection]; _textNode = [[ASTextNode alloc] init]; _textNode.attributedText = [NSAttributedString attributedStringWithString:@"this is a long text node" @@ -230,7 +233,10 @@ - (instancetype)init color:[UIColor blackColor]]; _bottomSeparator = [[ASImageNode alloc] init]; - _bottomSeparator.image = [UIImage as_resizableRoundedImageWithCornerRadius:1.0 cornerColor:[UIColor blackColor] fillColor:[UIColor blackColor]]; + _bottomSeparator.image = [UIImage as_resizableRoundedImageWithCornerRadius:1.0 + cornerColor:[UIColor blackColor] + fillColor:[UIColor blackColor] + traitCollection:self.primitiveTraitCollection]; } return self; @@ -297,7 +303,8 @@ - (instancetype)init _badgeImageNode = [ASImageNode new]; _badgeImageNode.image = [UIImage as_resizableRoundedImageWithCornerRadius:kSampleBadgeCornerRadius cornerColor:UIColor.clearColor - fillColor:UIColor.redColor]; + fillColor:UIColor.redColor + traitCollection:self.primitiveTraitCollection]; _photoNode2 = [ASImageNode new]; _photoNode2.image = avatarImage; diff --git a/examples/SocialAppLayout-Inverted/Sample/PostNode.m b/examples/SocialAppLayout-Inverted/Sample/PostNode.m index defafc006..a0711d78e 100644 --- a/examples/SocialAppLayout-Inverted/Sample/PostNode.m +++ b/examples/SocialAppLayout-Inverted/Sample/PostNode.m @@ -108,7 +108,7 @@ - (instancetype)initWithPost:(Post *)post _mediaNode.cornerRadius = 4.0; _mediaNode.URL = [NSURL URLWithString:_post.media]; _mediaNode.delegate = self; - _mediaNode.imageModificationBlock = ^UIImage *(UIImage *image) { + _mediaNode.imageModificationBlock = ^UIImage *(UIImage *image, ASPrimitiveTraitCollection traitCollection) { UIImage *modifiedImage; CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); @@ -134,7 +134,7 @@ - (instancetype)initWithPost:(Post *)post _avatarNode.style.height = ASDimensionMakeWithPoints(44); _avatarNode.cornerRadius = 22.0; _avatarNode.URL = [NSURL URLWithString:_post.photo]; - _avatarNode.imageModificationBlock = ^UIImage *(UIImage *image) { + _avatarNode.imageModificationBlock = ^UIImage *(UIImage *image, ASPrimitiveTraitCollection traitCollection) { UIImage *modifiedImage; CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); diff --git a/examples/SocialAppLayout/Sample/PostNode.m b/examples/SocialAppLayout/Sample/PostNode.m index defafc006..a0711d78e 100644 --- a/examples/SocialAppLayout/Sample/PostNode.m +++ b/examples/SocialAppLayout/Sample/PostNode.m @@ -108,7 +108,7 @@ - (instancetype)initWithPost:(Post *)post _mediaNode.cornerRadius = 4.0; _mediaNode.URL = [NSURL URLWithString:_post.media]; _mediaNode.delegate = self; - _mediaNode.imageModificationBlock = ^UIImage *(UIImage *image) { + _mediaNode.imageModificationBlock = ^UIImage *(UIImage *image, ASPrimitiveTraitCollection traitCollection) { UIImage *modifiedImage; CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); @@ -134,7 +134,7 @@ - (instancetype)initWithPost:(Post *)post _avatarNode.style.height = ASDimensionMakeWithPoints(44); _avatarNode.cornerRadius = 22.0; _avatarNode.URL = [NSURL URLWithString:_post.photo]; - _avatarNode.imageModificationBlock = ^UIImage *(UIImage *image) { + _avatarNode.imageModificationBlock = ^UIImage *(UIImage *image, ASPrimitiveTraitCollection traitCollection) { UIImage *modifiedImage; CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); From f0c0fae38a4673160a660dea975c3d85166931b3 Mon Sep 17 00:00:00 2001 From: Alexander Telegin Date: Tue, 26 May 2020 21:06:19 +0300 Subject: [PATCH 31/56] Update Swift collection view interop example (#1837) * Update uicollectionviewinterop.md --- docs/_docs/uicollectionviewinterop.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/_docs/uicollectionviewinterop.md b/docs/_docs/uicollectionviewinterop.md index a918a0cf8..d1f9fb668 100755 --- a/docs/_docs/uicollectionviewinterop.md +++ b/docs/_docs/uicollectionviewinterop.md @@ -71,7 +71,14 @@ For this example, the data source method `collectionNode:nodeBlockForItemAtIndex From 44c68a3fefae0d4c335681d734399a151b64dd5d Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Tue, 26 May 2020 13:55:16 -0700 Subject: [PATCH 32/56] Update Texture Xcode project to 11.4 and fix resulting warnings - 4 (#1838) * Update Texture Xcode project to 11.4 and fix resulting warnings - 4 * Some tests require testing deprecated functionality --- AsyncDisplayKit.xcodeproj/project.pbxproj | 11 +++- .../xcshareddata/IDEWorkspaceChecks.plist | 8 +++ .../xcschemes/AsyncDisplayKit.xcscheme | 2 +- Source/ASCellNode.mm | 4 +- Source/ASCollectionView.mm | 16 ++--- Source/ASControlNode.mm | 18 +++--- Source/ASDisplayNode+Layout.mm | 16 ++--- Source/ASDisplayNode.mm | 58 +++++++++---------- Source/ASEditableTextNode.mm | 34 +++++------ Source/ASImageNode.mm | 8 +-- Source/ASMultiplexImageNode.mm | 2 +- Source/ASTableView.mm | 10 ++-- Source/ASVideoNode.mm | 6 +- Source/ASVideoPlayerNode.mm | 18 +++--- Source/Debug/AsyncDisplayKit+Debug.mm | 12 ++-- Source/Details/ASBasicImageDownloader.mm | 2 +- Source/Details/ASDataController.mm | 18 +++--- Source/Details/ASMainSerialQueue.mm | 6 +- ...SCollectionViewFlowLayoutInspectorTests.mm | 20 +++---- Tests/ASCollectionViewTests.mm | 10 ++-- Tests/ASCollectionViewThrashTests.mm | 4 +- Tests/ASDisplayNodeAppearanceTests.mm | 4 +- Tests/ASLayoutEngineTests.mm | 22 +++---- Tests/ASRecursiveUnfairLockTests.mm | 6 +- Tests/ASTableViewTests.mm | 24 ++++++++ Tests/ASThrashUtility.m | 10 +++- 26 files changed, 197 insertions(+), 152 deletions(-) create mode 100644 AsyncDisplayKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 6649ed03a..a69d1e093 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -2192,7 +2192,7 @@ isa = PBXProject; attributes = { CLASSPREFIX = AS; - LastUpgradeCheck = 0940; + LastUpgradeCheck = 1140; ORGANIZATIONNAME = Pinterest; TargetAttributes = { 057D02BE1AC0A66700C7AC3C = { @@ -2208,10 +2208,9 @@ }; buildConfigurationList = 058D09A7195D04C000B7D73C /* Build configuration list for PBXProject "AsyncDisplayKit" */; compatibilityVersion = "Xcode 6.3"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( - English, en, Base, ); @@ -2628,6 +2627,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -2635,6 +2635,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES_ERROR; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -2686,6 +2687,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -2693,6 +2695,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES_ERROR; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -2844,6 +2847,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -2851,6 +2855,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES_ERROR; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; diff --git a/AsyncDisplayKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/AsyncDisplayKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/AsyncDisplayKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/AsyncDisplayKit.xcodeproj/xcshareddata/xcschemes/AsyncDisplayKit.xcscheme b/AsyncDisplayKit.xcodeproj/xcshareddata/xcschemes/AsyncDisplayKit.xcscheme index 4cfa046b3..717ca42d1 100644 --- a/AsyncDisplayKit.xcodeproj/xcshareddata/xcschemes/AsyncDisplayKit.xcscheme +++ b/AsyncDisplayKit.xcodeproj/xcshareddata/xcschemes/AsyncDisplayKit.xcscheme @@ -1,6 +1,6 @@ _interactionDelegate nodeSelectedStateDidChange:self]; }); } } @@ -153,7 +153,7 @@ - (void)setHighlighted:(BOOL)highlighted if (ASLockedSelfCompareAssign(_highlighted, highlighted)) { if (!_suspendInteractionDelegate) { ASPerformBlockOnMainThread(^{ - [_interactionDelegate nodeHighlightedStateDidChange:self]; + [self->_interactionDelegate nodeHighlightedStateDidChange:self]; }); } } diff --git a/Source/ASCollectionView.mm b/Source/ASCollectionView.mm index 032f68bb3..8b8168519 100644 --- a/Source/ASCollectionView.mm +++ b/Source/ASCollectionView.mm @@ -63,7 +63,7 @@ // ASCellLayoutMode is an NSUInteger-based NS_OPTIONS field. Be careful with BOOL handling on the // 32-bit Objective-C runtime, and pattern after ASInterfaceStateIncludesVisible() & friends. -#define ASCellLayoutModeIncludes(layoutMode) ((_cellLayoutMode & layoutMode) == layoutMode) +#define ASCellLayoutModeIncludes(layoutMode) ((self->_cellLayoutMode & layoutMode) == layoutMode) /// What, if any, invalidation should we perform during the next -layoutSubviews. typedef NS_ENUM(NSUInteger, ASCollectionViewInvalidationStyle) { @@ -1875,14 +1875,14 @@ - (void)_beginBatchFetching if (_asyncDelegateFlags.collectionNodeWillBeginBatchFetch) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ GET_COLLECTIONNODE_OR_RETURN(collectionNode, (void)0); - os_log_debug(ASCollectionLog(), "Beginning batch fetch for %@ with context %@", collectionNode, _batchContext); - [_asyncDelegate collectionNode:collectionNode willBeginBatchFetchWithContext:_batchContext]; + os_log_debug(ASCollectionLog(), "Beginning batch fetch for %@ with context %@", collectionNode, self->_batchContext); + [self->_asyncDelegate collectionNode:collectionNode willBeginBatchFetchWithContext:self->_batchContext]; }); } else if (_asyncDelegateFlags.collectionViewWillBeginBatchFetch) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [_asyncDelegate collectionView:self willBeginBatchFetchWithContext:_batchContext]; + [self->_asyncDelegate collectionView:self willBeginBatchFetchWithContext:self->_batchContext]; #pragma clang diagnostic pop }); } @@ -2248,20 +2248,20 @@ - (void)rangeController:(ASRangeController *)rangeController updateWithChangeSet ASPerformBlockWithoutAnimation(!changeSet.animated, ^{ as_activity_scope(as_activity_create("Commit collection update", changeSet.rootActivity, OS_ACTIVITY_FLAG_DEFAULT)); if (changeSet.includesReloadData) { - _superIsPendingDataLoad = YES; + self->_superIsPendingDataLoad = YES; updates(); [self _superReloadData:nil completion:nil]; os_log_debug(ASCollectionLog(), "Did reloadData %@", self.collectionNode); [changeSet executeCompletionHandlerWithFinished:YES]; } else { - [_layoutFacilitator collectionViewWillPerformBatchUpdates]; + [self->_layoutFacilitator collectionViewWillPerformBatchUpdates]; __block NSUInteger numberOfUpdates = 0; const auto completion = ^(BOOL finished) { as_activity_scope(as_activity_create("Handle collection update completion", changeSet.rootActivity, OS_ACTIVITY_FLAG_DEFAULT)); as_log_verbose(ASCollectionLog(), "Update animation finished %{public}@", self.collectionNode); // Flush any range changes that happened as part of the update animations ending. - [_rangeController updateIfNeeded]; + [self->_rangeController updateIfNeeded]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:numberOfUpdates]; [changeSet executeCompletionHandlerWithFinished:finished]; }; @@ -2317,7 +2317,7 @@ - (void)rangeController:(ASRangeController *)rangeController updateWithChangeSet // Flush any range changes that happened as part of submitting the update. as_activity_scope(changeSet.rootActivity); - [_rangeController updateIfNeeded]; + [self->_rangeController updateIfNeeded]; } }); } diff --git a/Source/ASControlNode.mm b/Source/ASControlNode.mm index 39a686e8f..6336d9947 100644 --- a/Source/ASControlNode.mm +++ b/Source/ASControlNode.mm @@ -297,10 +297,10 @@ - (void)addTarget:(id)target action:(SEL)action forControlEvents:(ASControlNodeE dispatch_async(dispatch_get_main_queue(), ^{ // add a highlight overlay node with area of ASControlNode + UIEdgeInsets self.clipsToBounds = NO; - _debugHighlightOverlay = [[ASImageNode alloc] init]; - _debugHighlightOverlay.zPosition = 1000; // ensure we're over the top of any siblings - _debugHighlightOverlay.layerBacked = YES; - [self addSubnode:_debugHighlightOverlay]; + self->_debugHighlightOverlay = [[ASImageNode alloc] init]; + self->_debugHighlightOverlay.zPosition = 1000; // ensure we're over the top of any siblings + self->_debugHighlightOverlay.layerBacked = YES; + [self addSubnode:self->_debugHighlightOverlay]; }); } } @@ -316,7 +316,7 @@ - (void)addTarget:(id)target action:(SEL)action forControlEvents:(ASControlNodeE { // Do we already have an event table for this control event? id eventKey = _ASControlNodeEventKeyForControlEvent(controlEvent); - NSMutableArray *eventTargetActionArray = _controlEventDispatchTable[eventKey]; + NSMutableArray *eventTargetActionArray = self->_controlEventDispatchTable[eventKey]; if (!eventTargetActionArray) { eventTargetActionArray = [[NSMutableArray alloc] init]; @@ -329,7 +329,7 @@ - (void)addTarget:(id)target action:(SEL)action forControlEvents:(ASControlNodeE [eventTargetActionArray addObject:targetAction]; if (eventKey) { - [_controlEventDispatchTable setObject:eventTargetActionArray forKey:eventKey]; + [self->_controlEventDispatchTable setObject:eventTargetActionArray forKey:eventKey]; } }); @@ -390,7 +390,7 @@ - (void)removeTarget:(id)target action:(SEL)action forControlEvents:(ASControlNo { // Grab the dispatch table for this event (if we have it). id eventKey = _ASControlNodeEventKeyForControlEvent(controlEvent); - NSMutableArray *eventTargetActionArray = _controlEventDispatchTable[eventKey]; + NSMutableArray *eventTargetActionArray = self->_controlEventDispatchTable[eventKey]; if (!eventTargetActionArray) { return; } @@ -410,7 +410,7 @@ - (void)removeTarget:(id)target action:(SEL)action forControlEvents:(ASControlNo if (eventTargetActionArray.count == 0) { // If there are no targets for this event anymore, remove it. - [_controlEventDispatchTable removeObjectForKey:eventKey]; + [self->_controlEventDispatchTable removeObjectForKey:eventKey]; } }); } @@ -432,7 +432,7 @@ - (void)sendActionsForControlEvents:(ASControlNodeEvent)controlEvents withEvent: (ASControlNodeEvent controlEvent) { // Iterate on each target action pair - for (ASControlTargetAction *targetAction in _controlEventDispatchTable[_ASControlNodeEventKeyForControlEvent(controlEvent)]) { + for (ASControlTargetAction *targetAction in self->_controlEventDispatchTable[_ASControlNodeEventKeyForControlEvent(controlEvent)]) { ASControlTargetAction *resolvedTargetAction = [[ASControlTargetAction alloc] init]; resolvedTargetAction.action = targetAction.action; resolvedTargetAction.target = targetAction.target; diff --git a/Source/ASDisplayNode+Layout.mm b/Source/ASDisplayNode+Layout.mm index 2a46df8e3..79b485897 100644 --- a/Source/ASDisplayNode+Layout.mm +++ b/Source/ASDisplayNode+Layout.mm @@ -656,7 +656,7 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize as_log_verbose(ASLayoutLog(), "Transition ID is %d", transitionID); // NOTE: This block captures self. It's cheaper than hitting the weak table. asdisplaynode_iscancelled_block_t isCancelled = ^{ - BOOL result = (_transitionID != transitionID); + BOOL result = (self->_transitionID != transitionID); if (result) { as_log_verbose(ASLayoutLog(), "Transition %d canceled, superseded by %d", transitionID, _transitionID.load()); } @@ -677,7 +677,7 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize } // Perform a full layout creation pass with passed in constrained size to create the new layout for the transition - NSUInteger newLayoutVersion = _layoutVersion; + NSUInteger newLayoutVersion = self->_layoutVersion; ASLayout *newLayout; { ASScopedLockSelfOrToRoot(); @@ -712,10 +712,10 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize { // Grab __instanceLock__ here to make sure this transition isn't invalidated // right after it passed the validation test and before it proceeds - MutexLocker l(__instanceLock__); + MutexLocker l(self->__instanceLock__); // Update calculated layout - const auto previousLayout = _calculatedDisplayNodeLayout; + const auto previousLayout = self->_calculatedDisplayNodeLayout; const auto pendingLayout = ASDisplayNodeLayout(newLayout, constrainedSize, constrainedSize.max, @@ -723,12 +723,12 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize [self _locked_setCalculatedDisplayNodeLayout:pendingLayout]; // Setup pending layout transition for animation - _pendingLayoutTransition = pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self + self->_pendingLayoutTransition = pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self pendingLayout:pendingLayout previousLayout:previousLayout]; // Setup context for pending layout transition. we need to hold a strong reference to the context - _pendingLayoutTransitionContext = pendingLayoutTransitionContext = [[_ASTransitionContext alloc] initWithAnimation:animated - layoutDelegate:_pendingLayoutTransition + self->_pendingLayoutTransitionContext = pendingLayoutTransitionContext = [[_ASTransitionContext alloc] initWithAnimation:animated + layoutDelegate:self->_pendingLayoutTransition completionDelegate:self]; } @@ -1043,7 +1043,7 @@ - (void)_pendingLayoutTransitionDidComplete if (self.isNodeLoaded) { ASPerformBlockOnMainThread(^{ if (self.contents == nil) { - _placeholderImage = [self placeholderImage]; + self->_placeholderImage = [self placeholderImage]; } }); } else { diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index ede474528..5b4e3b2ed 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -449,20 +449,20 @@ - (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTra // we need to run that on main thread, cause accessing CALayer properties. // It seems than in iOS 13 sometimes it causes deadlock. ASPerformBlockOnMainThread(^{ - __instanceLock__.lock(); - CGFloat cornerRadius = _cornerRadius; - ASCornerRoundingType cornerRoundingType = _cornerRoundingType; - UIColor *backgroundColor = _backgroundColor; - __instanceLock__.unlock(); + self->__instanceLock__.lock(); + CGFloat cornerRadius = self->_cornerRadius; + ASCornerRoundingType cornerRoundingType = self->_cornerRoundingType; + UIColor *backgroundColor = self->_backgroundColor; + self->__instanceLock__.unlock(); // TODO: we should resolve color using node's trait collection // but Texture changes it from many places, so we may receive the wrong one. CGColorRef cgBackgroundColor = backgroundColor.CGColor; - if (!CGColorEqualToColor(_layer.backgroundColor, cgBackgroundColor)) { + if (!CGColorEqualToColor(self->_layer.backgroundColor, cgBackgroundColor)) { // Background colors do not dynamically update for layer backed nodes since they utilize CGColorRef // instead of UIColor. Non layer backed node also receive color to the layer (see [_ASPendingState -applyToView:withSpecialPropertiesHandling:]). // We utilize the _backgroundColor instance variable to track the full dynamic color // and apply any changes here when trait collection updates occur. - _layer.backgroundColor = cgBackgroundColor; + self->_layer.backgroundColor = cgBackgroundColor; } // If we have clipping corners, re-render the clipping corner layer upon user interface style change @@ -1349,7 +1349,7 @@ - (void)_pendingNodeDidDisplay:(ASDisplayNode *)node __instanceLock__.lock(); if (_placeholderLayer.superlayer && !placeholderShouldPersist) { void (^cleanupBlock)() = ^{ - [_placeholderLayer removeFromSuperlayer]; + [self->_placeholderLayer removeFromSuperlayer]; }; if (_placeholderFadeDuration > 0.0 && ASInterfaceStateIncludesVisible(self.interfaceState)) { @@ -1495,7 +1495,7 @@ - (void)_updateClipCornerLayerContentsWithRadius:(CGFloat)radius backgroundColor ASPerformBlockOnMainThread(^{ for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) { // Skip corners that aren't clipped (we have already set up & torn down layers based on maskedCorners.) - if (_clipCornerLayers[idx] == nil) { + if (self->_clipCornerLayers[idx] == nil) { continue; } @@ -1521,7 +1521,7 @@ - (void)_updateClipCornerLayerContentsWithRadius:(CGFloat)radius backgroundColor }); // No lock needed, as _clipCornerLayers is only modified on the main thread. - unowned CALayer *clipCornerLayer = _clipCornerLayers[idx]; + unowned CALayer *clipCornerLayer = self->_clipCornerLayers[idx]; clipCornerLayer.contents = (id)(newContents.CGImage); clipCornerLayer.bounds = CGRectMake(0.0, 0.0, size.width, size.height); clipCornerLayer.anchorPoint = CGPointMake(isRight ? 1.0 : 0.0, isTop ? 0.0 : 1.0); @@ -1536,7 +1536,7 @@ - (void)_setClipCornerLayersVisible:(CACornerMask)visibleCornerLayers ASDisplayNodeAssertMainThread(); for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) { BOOL visible = (0 != (visibleCornerLayers & (1 << idx))); - if (visible == (_clipCornerLayers[idx] != nil)) { + if (visible == (self->_clipCornerLayers[idx] != nil)) { continue; } else if (visible) { static ASDisplayNodeCornerLayerDelegate *clipCornerLayers; @@ -1544,15 +1544,15 @@ - (void)_setClipCornerLayersVisible:(CACornerMask)visibleCornerLayers dispatch_once(&onceToken, ^{ clipCornerLayers = [[ASDisplayNodeCornerLayerDelegate alloc] init]; }); - _clipCornerLayers[idx] = [[CALayer alloc] init]; - _clipCornerLayers[idx].zPosition = 99999; - _clipCornerLayers[idx].delegate = clipCornerLayers; + self->_clipCornerLayers[idx] = [[CALayer alloc] init]; + self->_clipCornerLayers[idx].zPosition = 99999; + self->_clipCornerLayers[idx].delegate = clipCornerLayers; } else { - [_clipCornerLayers[idx] removeFromSuperlayer]; - _clipCornerLayers[idx] = nil; + [self->_clipCornerLayers[idx] removeFromSuperlayer]; + self->_clipCornerLayers[idx] = nil; } } - [self _updateClipCornerLayerContentsWithRadius:_cornerRadius backgroundColor:self.backgroundColor]; + [self _updateClipCornerLayerContentsWithRadius:self->_cornerRadius backgroundColor:self.backgroundColor]; }); } @@ -2809,13 +2809,13 @@ - (void)didExitHierarchy if (ASInterfaceStateIncludesVisible(self.pendingInterfaceState)) { void(^exitVisibleInterfaceState)(void) = ^{ // This block intentionally retains self. - __instanceLock__.lock(); - unsigned isStillInHierarchy = _flags.isInHierarchy; - BOOL isVisible = ASInterfaceStateIncludesVisible(_pendingInterfaceState); - ASInterfaceState newState = (_pendingInterfaceState & ~ASInterfaceStateVisible); + self->__instanceLock__.lock(); + unsigned isStillInHierarchy = self->_flags.isInHierarchy; + BOOL isVisible = ASInterfaceStateIncludesVisible(self->_pendingInterfaceState); + ASInterfaceState newState = (self->_pendingInterfaceState & ~ASInterfaceStateVisible); // layer may be thrashed, we need to remember the state so we can reset if it enters in same runloop later. - _preExitingInterfaceState = _pendingInterfaceState; - __instanceLock__.unlock(); + self->_preExitingInterfaceState = self->_pendingInterfaceState; + self->__instanceLock__.unlock(); if (!isStillInHierarchy && isVisible) { #if ENABLE_NEW_EXIT_HIERARCHY_BEHAVIOR if (![self supportsRangeManagedInterfaceState]) { @@ -2974,9 +2974,9 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState [self setDisplaySuspended:YES]; //schedule clear contents on next runloop dispatch_async(dispatch_get_main_queue(), ^{ - __instanceLock__.lock(); - ASInterfaceState interfaceState = _interfaceState; - __instanceLock__.unlock(); + self->__instanceLock__.lock(); + ASInterfaceState interfaceState = self->_interfaceState; + self->__instanceLock__.unlock(); if (ASInterfaceStateIncludesDisplay(interfaceState) == NO) { [self clearContents]; } @@ -2994,9 +2994,9 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState [[self asyncLayer] cancelAsyncDisplay]; //schedule clear contents on next runloop dispatch_async(dispatch_get_main_queue(), ^{ - __instanceLock__.lock(); - ASInterfaceState interfaceState = _interfaceState; - __instanceLock__.unlock(); + self->__instanceLock__.lock(); + ASInterfaceState interfaceState = self->_interfaceState; + self->__instanceLock__.unlock(); if (ASInterfaceStateIncludesDisplay(interfaceState) == NO) { [self clearContents]; } diff --git a/Source/ASEditableTextNode.mm b/Source/ASEditableTextNode.mm index 0c9cd4136..60be21f98 100644 --- a/Source/ASEditableTextNode.mm +++ b/Source/ASEditableTextNode.mm @@ -176,11 +176,11 @@ - (void)didLoad [super didLoad]; void (^configureTextView)(UITextView *) = ^(UITextView *textView) { - if (!_displayingPlaceholder || textView != _textKitComponents.textView) { + if (!self->_displayingPlaceholder || textView != self->_textKitComponents.textView) { // If showing the placeholder, don't propagate backgroundColor/opaque to the editable textView. It is positioned over the placeholder to accept taps to begin editing, and if it's opaque/colored then it'll obscure the placeholder. textView.backgroundColor = self.backgroundColor; textView.opaque = self.opaque; - } else if (_displayingPlaceholder && textView == _textKitComponents.textView) { + } else if (self->_displayingPlaceholder && textView == self->_textKitComponents.textView) { // The default backgroundColor for a textView is white. Due to the reason described above, make sure the editable textView starts out transparent. textView.backgroundColor = nil; textView.opaque = NO; @@ -189,16 +189,16 @@ - (void)didLoad // Configure textView with UITextInputTraits { - AS::MutexLocker l(_textInputTraitsLock); - if (_textInputTraits) { - textView.autocapitalizationType = _textInputTraits.autocapitalizationType; - textView.autocorrectionType = _textInputTraits.autocorrectionType; - textView.spellCheckingType = _textInputTraits.spellCheckingType; - textView.keyboardType = _textInputTraits.keyboardType; - textView.keyboardAppearance = _textInputTraits.keyboardAppearance; - textView.returnKeyType = _textInputTraits.returnKeyType; - textView.enablesReturnKeyAutomatically = _textInputTraits.enablesReturnKeyAutomatically; - textView.secureTextEntry = _textInputTraits.isSecureTextEntry; + AS::MutexLocker l(self->_textInputTraitsLock); + if (self->_textInputTraits) { + textView.autocapitalizationType = self->_textInputTraits.autocapitalizationType; + textView.autocorrectionType = self->_textInputTraits.autocorrectionType; + textView.spellCheckingType = self->_textInputTraits.spellCheckingType; + textView.keyboardType = self->_textInputTraits.keyboardType; + textView.keyboardAppearance = self->_textInputTraits.keyboardAppearance; + textView.returnKeyType = self->_textInputTraits.returnKeyType; + textView.enablesReturnKeyAutomatically = self->_textInputTraits.enablesReturnKeyAutomatically; + textView.secureTextEntry = self->_textInputTraits.isSecureTextEntry; } } @@ -815,8 +815,8 @@ - (void)_delegateDidChangeSelectionFromSelectedRange:(NSRange)fromSelectedRange // 2. This delegate method (-textViewDidChangeSelection:) is called both before -textViewDidChange: and before the layout manager/etc. has necessarily generated+laid out its glyphs. Because of the former, we need to wait until -textViewDidChange: has had an opportunity to be called so can accurately determine whether this selection change is due to editing (_selectionChangedForEditedText). // Thus, to avoid calling out to client code in the middle of UITextView's processing, we call the delegate on the next run of the runloop, when all such internal processing is surely done. dispatch_async(dispatch_get_main_queue(), ^{ - if ([_delegate respondsToSelector:@selector(editableTextNodeDidChangeSelection:fromSelectedRange:toSelectedRange:dueToEditing:)]) - [_delegate editableTextNodeDidChangeSelection:self fromSelectedRange:fromSelectedRange toSelectedRange:toSelectedRange dueToEditing:_selectionChangedForEditedText]; + if ([self->_delegate respondsToSelector:@selector(editableTextNodeDidChangeSelection:fromSelectedRange:toSelectedRange:dueToEditing:)]) + [self->_delegate editableTextNodeDidChangeSelection:self fromSelectedRange:fromSelectedRange toSelectedRange:toSelectedRange dueToEditing:self->_selectionChangedForEditedText]; }); } @@ -831,9 +831,9 @@ - (void)_delegateDidUpdateText // UITextView invokes its delegate methods when it's in the middle of text-processing. For example, -textViewDidChange: is invoked before you can truly rely on the changes being propagated throughout the Text Kit hierarchy. // Thus, to avoid calling out to client code in the middle of UITextView's processing, we call the delegate on the next run of the runloop, when all such internal processing is surely done. dispatch_async(dispatch_get_main_queue(), ^{ - _delegateDidUpdateEnqueued = NO; - if ([_delegate respondsToSelector:@selector(editableTextNodeDidUpdateText:)]) - [_delegate editableTextNodeDidUpdateText:self]; + self->_delegateDidUpdateEnqueued = NO; + if ([self->_delegate respondsToSelector:@selector(editableTextNodeDidUpdateText:)]) + [self->_delegate editableTextNodeDidUpdateText:self]; }); } diff --git a/Source/ASImageNode.mm b/Source/ASImageNode.mm index 15a831a8e..fd44a7803 100644 --- a/Source/ASImageNode.mm +++ b/Source/ASImageNode.mm @@ -260,9 +260,9 @@ - (void)_locked_setImage:(UIImage *)image // do not use ASPerformBlockOnMainThread here, if it performs the block synchronously it will continue // holding the lock while calling addSubnode. dispatch_async(dispatch_get_main_queue(), ^{ - _debugLabelNode = [[ASTextNode alloc] init]; - _debugLabelNode.layerBacked = YES; - [self addSubnode:_debugLabelNode]; + self->_debugLabelNode = [[ASTextNode alloc] init]; + self->_debugLabelNode.layerBacked = YES; + [self addSubnode:self->_debugLabelNode]; }); } } else { @@ -333,7 +333,7 @@ - (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer // Hack for now to retain the weak entry that was created while this drawing happened drawParameters->_didDrawBlock = ^(ASWeakMapEntry *entry){ ASLockScopeSelf(); - _weakCacheEntry = entry; + self->_weakCacheEntry = entry; }; } diff --git a/Source/ASMultiplexImageNode.mm b/Source/ASMultiplexImageNode.mm index 926480a05..00dcec84a 100644 --- a/Source/ASMultiplexImageNode.mm +++ b/Source/ASMultiplexImageNode.mm @@ -742,7 +742,7 @@ - (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identif PHAsset *imageAsset = nil; // Try to get the asset immediately from the data source. - if (_dataSourceFlags.asset) { + if (strongSelf->_dataSourceFlags.asset) { imageAsset = [strongSelf.dataSource multiplexImageNode:strongSelf assetForLocalIdentifier:request.assetIdentifier]; } diff --git a/Source/ASTableView.mm b/Source/ASTableView.mm index 0589dbfb9..3781a8c10 100644 --- a/Source/ASTableView.mm +++ b/Source/ASTableView.mm @@ -1502,13 +1502,13 @@ - (void)_beginBatchFetching if (_asyncDelegateFlags.tableNodeWillBeginBatchFetch) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ GET_TABLENODE_OR_RETURN(tableNode, (void)0); - [_asyncDelegate tableNode:tableNode willBeginBatchFetchWithContext:_batchContext]; + [self->_asyncDelegate tableNode:tableNode willBeginBatchFetchWithContext:self->_batchContext]; }); } else if (_asyncDelegateFlags.tableViewWillBeginBatchFetch) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [_asyncDelegate tableView:self willBeginBatchFetchWithContext:_batchContext]; + [self->_asyncDelegate tableView:self willBeginBatchFetchWithContext:self->_batchContext]; #pragma clang diagnostic pop }); } @@ -1566,7 +1566,7 @@ - (void)rangeController:(ASRangeController *)rangeController updateWithChangeSet updates(); [super reloadData]; // Flush any range changes that happened as part of submitting the reload. - [_rangeController updateIfNeeded]; + [self->_rangeController updateIfNeeded]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:1]; [changeSet executeCompletionHandlerWithFinished:YES]; }); @@ -1684,7 +1684,7 @@ - (void)rangeController:(ASRangeController *)rangeController updateWithChangeSet LOG(@"--- UITableView endUpdates"); ASPerformBlockWithoutAnimation(!changeSet.animated, ^{ [super endUpdates]; - [_rangeController updateIfNeeded]; + [self->_rangeController updateIfNeeded]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:numberOfUpdates]; }); if (shouldAdjustContentOffset) { @@ -1789,7 +1789,7 @@ - (ASCellNodeBlock)dataController:(ASDataController *)dataController nodeBlockAt if (node.interactionDelegate == nil) { node.interactionDelegate = strongSelf; } - if (_inverted) { + if (self->_inverted) { node.transform = CATransform3DMakeScale(1, -1, 1) ; } return node; diff --git a/Source/ASVideoNode.mm b/Source/ASVideoNode.mm index 6646c3dbd..141ca2eac 100644 --- a/Source/ASVideoNode.mm +++ b/Source/ASVideoNode.mm @@ -289,7 +289,7 @@ - (void)generatePlaceholderImage - (void)imageAtTime:(CMTime)imageTime completionHandler:(void(^)(UIImage *image))completionHandler { ASPerformBlockOnBackgroundThread(^{ - AVAsset *asset = self.asset; + AVAsset *asset = self->_asset; // Skip the asset image generation if we don't have any tracks available that are capable of supporting it NSArray* visualAssetArray = [asset tracksWithMediaCharacteristic:AVMediaCharacteristicVisual]; @@ -300,7 +300,7 @@ - (void)imageAtTime:(CMTime)imageTime completionHandler:(void(^)(UIImage *image) AVAssetImageGenerator *previewImageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset]; previewImageGenerator.appliesPreferredTrackTransform = YES; - previewImageGenerator.videoComposition = _videoComposition; + previewImageGenerator.videoComposition = self->_videoComposition; [previewImageGenerator generateCGImagesAsynchronouslyForTimes:@[[NSValue valueWithCMTime:imageTime]] completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) { @@ -415,7 +415,7 @@ - (void)didEnterPreloadState NSArray *requestedKeys = @[@"playable"]; [asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:^{ ASPerformBlockOnMainThread(^{ - if (_delegateFlags.delegateVideoNodeDidFinishInitialLoading) { + if (self->_delegateFlags.delegateVideoNodeDidFinishInitialLoading) { [self.delegate videoNodeDidFinishInitialLoading:self]; } [self prepareToPlayAsset:asset withKeys:requestedKeys]; diff --git a/Source/ASVideoPlayerNode.mm b/Source/ASVideoPlayerNode.mm index 696531c75..36b4a3fb5 100644 --- a/Source/ASVideoPlayerNode.mm +++ b/Source/ASVideoPlayerNode.mm @@ -435,19 +435,19 @@ - (void)_locked_createScrubber slider.minimumValue = 0.0; slider.maximumValue = 1.0; - if (_delegateFlags.delegateScrubberMinimumTrackTintColor) { + if (strongSelf->_delegateFlags.delegateScrubberMinimumTrackTintColor) { slider.minimumTrackTintColor = [strongSelf.delegate videoPlayerNodeScrubberMinimumTrackTint:strongSelf]; } - if (_delegateFlags.delegateScrubberMaximumTrackTintColor) { + if (strongSelf->_delegateFlags.delegateScrubberMaximumTrackTintColor) { slider.maximumTrackTintColor = [strongSelf.delegate videoPlayerNodeScrubberMaximumTrackTint:strongSelf]; } - if (_delegateFlags.delegateScrubberThumbTintColor) { + if (strongSelf->_delegateFlags.delegateScrubberThumbTintColor) { slider.thumbTintColor = [strongSelf.delegate videoPlayerNodeScrubberThumbTint:strongSelf]; } - if (_delegateFlags.delegateScrubberThumbImage) { + if (strongSelf->_delegateFlags.delegateScrubberThumbImage) { UIImage *thumbImage = [strongSelf.delegate videoPlayerNodeScrubberThumbImage:strongSelf]; [slider setThumbImage:thumbImage forState:UIControlStateNormal]; } @@ -645,14 +645,14 @@ - (void)showSpinner UIActivityIndicatorView *spinnnerView = [[UIActivityIndicatorView alloc] init]; spinnnerView.backgroundColor = [UIColor clearColor]; - if (_delegateFlags.delegateSpinnerTintColor) { - spinnnerView.color = [_delegate videoPlayerNodeSpinnerTint:strongSelf]; + if (strongSelf->_delegateFlags.delegateSpinnerTintColor) { + spinnnerView.color = [strongSelf->_delegate videoPlayerNodeSpinnerTint:strongSelf]; } else { - spinnnerView.color = _defaultControlsColor; + spinnnerView.color = strongSelf->_defaultControlsColor; } - if (_delegateFlags.delegateSpinnerStyle) { - spinnnerView.activityIndicatorViewStyle = [_delegate videoPlayerNodeSpinnerStyle:strongSelf]; + if (strongSelf->_delegateFlags.delegateSpinnerStyle) { + spinnnerView.activityIndicatorViewStyle = [strongSelf->_delegate videoPlayerNodeSpinnerStyle:strongSelf]; } return spinnnerView; diff --git a/Source/Debug/AsyncDisplayKit+Debug.mm b/Source/Debug/AsyncDisplayKit+Debug.mm index de4159f6d..965b265cd 100644 --- a/Source/Debug/AsyncDisplayKit+Debug.mm +++ b/Source/Debug/AsyncDisplayKit+Debug.mm @@ -424,10 +424,10 @@ - (void)addRangeController:(ASRangeController *)rangeController } [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ - _animating = YES; + self->_animating = YES; [self layoutToFitAllBarsExcept:0]; } completion:^(BOOL finished) { - _animating = NO; + self->_animating = NO; }]; } @@ -653,15 +653,15 @@ - (void)layoutSubviews BOOL animate = !_firstLayoutOfRects; [UIView animateWithDuration:animate ? 0.3 : 0.0 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^{ - _visibleRect.frame = CGRectMake(HORIZONTAL_INSET + visiblePoint, rect.origin.y, visibleDimension, subCellHeight); - _displayRect.frame = CGRectMake(HORIZONTAL_INSET + displayPoint, rect.origin.y, displayDimension, subCellHeight); - _preloadRect.frame = CGRectMake(HORIZONTAL_INSET + preloadPoint, rect.origin.y, preloadDimension, subCellHeight); + self->_visibleRect.frame = CGRectMake(HORIZONTAL_INSET + visiblePoint, rect.origin.y, visibleDimension, subCellHeight); + self->_displayRect.frame = CGRectMake(HORIZONTAL_INSET + displayPoint, rect.origin.y, displayDimension, subCellHeight); + self->_preloadRect.frame = CGRectMake(HORIZONTAL_INSET + preloadPoint, rect.origin.y, preloadDimension, subCellHeight); } completion:^(BOOL finished) {}]; if (!animate) { _visibleRect.alpha = _displayRect.alpha = _preloadRect.alpha = 0; [UIView animateWithDuration:0.3 animations:^{ - _visibleRect.alpha = _displayRect.alpha = _preloadRect.alpha = 1; + self->_visibleRect.alpha = self->_displayRect.alpha = self->_preloadRect.alpha = 1; }]; } diff --git a/Source/Details/ASBasicImageDownloader.mm b/Source/Details/ASBasicImageDownloader.mm index 927a2d0aa..f577eb1e2 100644 --- a/Source/Details/ASBasicImageDownloader.mm +++ b/Source/Details/ASBasicImageDownloader.mm @@ -290,7 +290,7 @@ - (nullable id)downloadImageWithURL:(NSURL *)URL [context addCallbackData:[[NSDictionary alloc] initWithDictionary:callbackData]]; // Create new task if necessary - NSURLSessionDownloadTask *task = (NSURLSessionDownloadTask *)[context createSessionTaskIfNecessaryWithBlock:^(){return [_session downloadTaskWithURL:URL];}]; + NSURLSessionDownloadTask *task = (NSURLSessionDownloadTask *)[context createSessionTaskIfNecessaryWithBlock:^(){return [self->_session downloadTaskWithURL:URL];}]; if (task) { task.priority = NSURLSessionTaskPriorityWithImageDownloaderPriority(priority); diff --git a/Source/Details/ASDataController.mm b/Source/Details/ASDataController.mm index 2ec2eb699..76e58d8be 100644 --- a/Source/Details/ASDataController.mm +++ b/Source/Details/ASDataController.mm @@ -533,13 +533,13 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet _synchronized = NO; [changeSet addCompletionHandler:^(BOOL finished) { - _synchronized = YES; + self->_synchronized = YES; [self onDidFinishProcessingUpdates:^{ - if (_synchronized) { - for (ASDataControllerSynchronizationBlock block in _onDidFinishSynchronizingBlocks) { + if (self->_synchronized) { + for (ASDataControllerSynchronizationBlock block in self->_onDidFinishSynchronizingBlocks) { block(); } - [_onDidFinishSynchronizingBlocks removeAllObjects]; + [self->_onDidFinishSynchronizingBlocks removeAllObjects]; } }]; }]; @@ -646,9 +646,9 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet } // Step 4: Inform the delegate on main thread - [_mainSerialQueue performBlockOnMainThread:^{ + [self->_mainSerialQueue performBlockOnMainThread:^{ as_activity_scope_leave(&preparationScope); - [_delegate dataController:self updateWithChangeSet:changeSet updates:^{ + [self->_delegate dataController:self updateWithChangeSet:changeSet updates:^{ // Step 5: Deploy the new data as "completed" // // Note that since the backing collection view might be busy responding to user events (e.g scrolling), @@ -659,7 +659,7 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet self.visibleMap = newMap; }]; }]; - --_editingTransactionGroupCount; + --self->_editingTransactionGroupCount; }); // We've now dispatched node allocation and layout to a concurrent background queue. @@ -898,7 +898,7 @@ - (void)_relayoutAllNodes - (void)environmentDidChange { ASPerformBlockOnMainThread(^{ - if (!_initialReloadDataHasBeenCalled) { + if (!self->_initialReloadDataHasBeenCalled) { return; } @@ -906,7 +906,7 @@ - (void)environmentDidChange // i.e there might be some elements that were allocated using the old trait collection but haven't been added to _visibleMap [self _scheduleBlockOnMainSerialQueue:^{ ASPrimitiveTraitCollection newTraitCollection = [self.node primitiveTraitCollection]; - for (ASCollectionElement *element in _visibleMap) { + for (ASCollectionElement *element in self->_visibleMap) { element.traitCollection = newTraitCollection; } }]; diff --git a/Source/Details/ASMainSerialQueue.mm b/Source/Details/ASMainSerialQueue.mm index 472214390..ba2c74347 100644 --- a/Source/Details/ASMainSerialQueue.mm +++ b/Source/Details/ASMainSerialQueue.mm @@ -44,11 +44,11 @@ - (void)runBlocks dispatch_block_t mainThread = ^{ AS::UniqueLock l(self->_serialQueueLock); do { - if (_blocks.empty()) { + if (self->_blocks.empty()) { break; } - dispatch_block_t block = _blocks.front(); - _blocks.pop(); + dispatch_block_t block = self->_blocks.front(); + self->_blocks.pop(); { l.unlock(); block(); diff --git a/Tests/ASCollectionViewFlowLayoutInspectorTests.mm b/Tests/ASCollectionViewFlowLayoutInspectorTests.mm index 555fe2113..df457448d 100644 --- a/Tests/ASCollectionViewFlowLayoutInspectorTests.mm +++ b/Tests/ASCollectionViewFlowLayoutInspectorTests.mm @@ -32,22 +32,22 @@ @interface InspectorTestDataSource : NSObject @implementation InspectorTestDataSource -- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath +- (ASCellNode *)collectionNode:(ASCollectionNode *)collectionNode nodeForItemAtIndexPath:(NSIndexPath *)indexPath { return [[ASCellNode alloc] init]; } -- (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath +- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath { return ^{ return [[ASCellNode alloc] init]; }; } -- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +- (NSInteger)collectionNode:(ASCollectionNode *)collectionNode numberOfItemsInSection:(NSInteger)section { return 0; } -- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView +- (NSInteger)numberOfSectionsInCollectionNode:(ASCollectionNode *)collectionNode { return 2; } @@ -63,12 +63,12 @@ @interface InspectorTestDataSourceDelegateWithoutNodeConstrainedSize : NSObject @implementation InspectorTestDataSourceDelegateWithoutNodeConstrainedSize -- (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath +- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath { return ^{ return [[ASCellNode alloc] init]; }; } -- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +- (NSInteger)collectionNode:(ASCollectionNode *)collectionNode numberOfItemsInSection:(NSInteger)section { return 0; } @@ -88,9 +88,9 @@ @interface HeaderReferenceSizeTestDelegate : NSObject _update = [[ASThrashUpdate alloc] initWithData:sections]; ASThrashDataSource *ds = [[ASThrashDataSource alloc] initCollectionViewDataSourceWithData:sections]; - [self applyUpdateUsingBatchUpdates:_update + [self applyUpdateUsingBatchUpdates:self->_update toDataSource:ds animated:NO useXCTestWait:NO]; diff --git a/Tests/ASDisplayNodeAppearanceTests.mm b/Tests/ASDisplayNodeAppearanceTests.mm index 5496bc3a4..b771da353 100644 --- a/Tests/ASDisplayNodeAppearanceTests.mm +++ b/Tests/ASDisplayNodeAppearanceTests.mm @@ -82,11 +82,11 @@ - (void)setUp _didExitHierarchyCounts = [[NSCountedSet alloc] init]; dispatch_block_t cleanupBlock = modifyMethodByAddingPrologueBlockAndReturnCleanupBlock([ASDisplayNode class], @selector(willEnterHierarchy), ^(id blockSelf){ - [_willEnterHierarchyCounts addObject:blockSelf]; + [self->_willEnterHierarchyCounts addObject:blockSelf]; }); [_swizzleCleanupBlocks addObject:cleanupBlock]; cleanupBlock = modifyMethodByAddingPrologueBlockAndReturnCleanupBlock([ASDisplayNode class], @selector(didExitHierarchy), ^(id blockSelf){ - [_didExitHierarchyCounts addObject:blockSelf]; + [self->_didExitHierarchyCounts addObject:blockSelf]; }); [_swizzleCleanupBlocks addObject:cleanupBlock]; } diff --git a/Tests/ASLayoutEngineTests.mm b/Tests/ASLayoutEngineTests.mm index 3222f78b5..7a0b87599 100644 --- a/Tests/ASLayoutEngineTests.mm +++ b/Tests/ASLayoutEngineTests.mm @@ -63,7 +63,7 @@ - (void)setUp allNodes = @[ nodeA, nodeB, nodeC, nodeD, nodeE ]; ASSetDebugNames(nodeA, nodeB, nodeC, nodeD, nodeE); ASLayoutSpecBlock b = ^ASLayoutSpec * _Nonnull(__kindof ASDisplayNode * _Nonnull node, ASSizeRange constrainedSize) { - return [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:0 justifyContent:ASStackLayoutJustifyContentSpaceBetween alignItems:ASStackLayoutAlignItemsStart children:@[ nodeB, nodeC, nodeD ]]; + return [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:0 justifyContent:ASStackLayoutJustifyContentSpaceBetween alignItems:ASStackLayoutAlignItemsStart children:@[ self->nodeB, self->nodeC, self->nodeD ]]; }; fixture1and3and5NodeALayoutSpecBlock = b; fixture1 = [self createFixture1]; @@ -162,10 +162,10 @@ - (void)testLayoutTransitionWithAsyncMeasurement injectedMainThreadWork = ^{ injectedMainThreadWorkDone = YES; - [window layoutIfNeeded]; + [self->window layoutIfNeeded]; // Ensure we're still on the old layout. We should stay on this until the transition completes. - [self verifyFixture:fixture1]; + [self verifyFixture:self->fixture1]; }; measurementCompletionBlock = ^{ @@ -286,7 +286,7 @@ - (void)DISABLE_testASetNeedsLayoutInterferingWithTheCurrentTransition as_log_verbose(OS_LOG_DEFAULT, "Begin injectedMainThreadWork"); injectedMainThreadWorkDone = YES; - [fixture4 apply]; + [self->fixture4 apply]; as_log_verbose(OS_LOG_DEFAULT, "Did apply new fixture"); if (enforceCorrectBehavior) { @@ -294,10 +294,10 @@ - (void)DISABLE_testASetNeedsLayoutInterferingWithTheCurrentTransition // are common to both fixture2 and fixture4 are available from the cache. } else { // Incorrect behavior: nodeC will get measured against its new bounds on main. - const auto cPendingSize = [fixture2 layoutForNode:nodeC].size; - OCMExpect([nodeC.mock calculateLayoutThatFits:ASSizeRangeMake(cPendingSize)]).onMainThread(); + const auto cPendingSize = [self->fixture2 layoutForNode:self->nodeC].size; + OCMExpect([self->nodeC.mock calculateLayoutThatFits:ASSizeRangeMake(cPendingSize)]).onMainThread(); } - [window layoutIfNeeded]; + [self->window layoutIfNeeded]; as_log_verbose(OS_LOG_DEFAULT, "End injectedMainThreadWork"); }; @@ -342,7 +342,7 @@ - (void)testCallingSetNeedsLayoutOnANodeThatWasSubjectToMultipassLayout OCMExpect([nodeB.mock calculateLayoutThatFits:[fixture3 firstSizeRangeForNode:nodeB]]); [fixture1 withSizeRangesForNode:nodeA block:^(ASSizeRange sizeRange) { - OCMExpect([nodeA.mock calculateLayoutThatFits:sizeRange]); + OCMExpect([self->nodeA.mock calculateLayoutThatFits:sizeRange]); }]; [window layoutIfNeeded]; @@ -456,7 +456,7 @@ - (ASTLayoutFixture *)createFixture2 fixture.layout = layoutA; ASLayoutSpecBlock specBlockA = ^ASLayoutSpec * _Nonnull(__kindof ASDisplayNode * _Nonnull node, ASSizeRange constrainedSize) { - return [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:0 justifyContent:ASStackLayoutJustifyContentSpaceBetween alignItems:ASStackLayoutAlignItemsStart children:@[ nodeB, nodeC, nodeE ]]; + return [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:0 justifyContent:ASStackLayoutJustifyContentSpaceBetween alignItems:ASStackLayoutAlignItemsStart children:@[ self->nodeB, self->nodeC, self->nodeE ]]; }; [fixture.layoutSpecBlocks setObject:specBlockA forKey:nodeA]; return fixture; @@ -535,7 +535,7 @@ - (ASTLayoutFixture *)createFixture4 fixture.layout = layoutA; ASLayoutSpecBlock specBlockA = ^ASLayoutSpec * _Nonnull(__kindof ASDisplayNode * _Nonnull node, ASSizeRange constrainedSize) { - return [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:0 justifyContent:ASStackLayoutJustifyContentSpaceBetween alignItems:ASStackLayoutAlignItemsStart children:@[ nodeB, nodeD, nodeE ]]; + return [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:0 justifyContent:ASStackLayoutJustifyContentSpaceBetween alignItems:ASStackLayoutAlignItemsStart children:@[ self->nodeB, self->nodeD, self->nodeE ]]; }; [fixture.layoutSpecBlocks setObject:specBlockA forKey:nodeA]; return fixture; @@ -576,7 +576,7 @@ - (void)runFirstLayoutPassWithFixture:(ASTLayoutFixture *)fixture [fixture withSizeRangesForAllNodesUsingBlock:^(ASLayoutTestNode * _Nonnull node, ASSizeRange sizeRange) { OCMExpect([node.mock calculateLayoutThatFits:sizeRange]).onMainThread(); - if (!stubbedCalculatedLayoutDidChange) { + if (!self->stubbedCalculatedLayoutDidChange) { OCMExpect([node.mock calculatedLayoutDidChange]).onMainThread(); } }]; diff --git a/Tests/ASRecursiveUnfairLockTests.mm b/Tests/ASRecursiveUnfairLockTests.mm index 3916b319e..c76adb65b 100644 --- a/Tests/ASRecursiveUnfairLockTests.mm +++ b/Tests/ASRecursiveUnfairLockTests.mm @@ -62,7 +62,7 @@ - (void)testThatUnlockingWithoutHoldingMakesAssertion ASRecursiveUnfairLockLock(&lock); XCTestExpectation *e1 = [self expectationWithDescription:@"Other thread tried lock."]; [NSThread detachNewThreadWithBlock:^{ - XCTAssertThrows(ASRecursiveUnfairLockUnlock(&lock)); + XCTAssertThrows(ASRecursiveUnfairLockUnlock(&self->lock)); [e1 fulfill]; }]; [self waitForExpectationsWithTimeout:10 handler:nil]; @@ -93,7 +93,7 @@ - (void)testRecursiveUnfairLockContested { __block int value = 0; [self measureBlock:^{ - CHAOS_TEST_BODY(YES, ASRecursiveUnfairLockLock(&lock), {}, ASRecursiveUnfairLockUnlock(&lock)); + CHAOS_TEST_BODY(YES, ASRecursiveUnfairLockLock(&self->lock), {}, ASRecursiveUnfairLockUnlock(&self->lock)); }]; XCTAssertEqual(value, 0); } @@ -102,7 +102,7 @@ - (void)testRecursiveUnfairLockUncontested { __block int value = 0; [self measureBlock:^{ - CHAOS_TEST_BODY(NO, ASRecursiveUnfairLockLock(&lock), {}, ASRecursiveUnfairLockUnlock(&lock)); + CHAOS_TEST_BODY(NO, ASRecursiveUnfairLockLock(&self->lock), {}, ASRecursiveUnfairLockUnlock(&self->lock)); }]; XCTAssertEqual(value, 0); } diff --git a/Tests/ASTableViewTests.mm b/Tests/ASTableViewTests.mm index 846f69e45..29bb72c81 100644 --- a/Tests/ASTableViewTests.mm +++ b/Tests/ASTableViewTests.mm @@ -72,20 +72,29 @@ @interface ASTableViewTestDelegate : NSObject *)sectionIndexTitlesForTableView:(UITableView *)tableView { @@ -201,10 +222,13 @@ @interface ASTableViewFilledDelegate : NSObject @implementation ASTableViewFilledDelegate +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" - (ASSizeRange)tableView:(ASTableView *)tableView constrainedSizeForRowAtIndexPath:(NSIndexPath *)indexPath { return ASSizeRangeMake(CGSizeMake(10, 42)); } +#pragma clang diagnostic pop @end diff --git a/Tests/ASThrashUtility.m b/Tests/ASThrashUtility.m index c555d3f77..ac2da5315 100644 --- a/Tests/ASThrashUtility.m +++ b/Tests/ASThrashUtility.m @@ -236,16 +236,21 @@ - (void)setData:(NSArray *)data _data = data; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.data[section].items.count; } +#pragma clang diagnostic pop - +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return self.data.count; } +#pragma clang diagnostic pop - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { @@ -297,6 +302,8 @@ - (ASCellNode *)collectionNode:(ASCollectionNode *)collectionNode nodeForItemAtI return node; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" - (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath { ASThrashTestNode *node = [[ASThrashTestNode alloc] init]; @@ -304,6 +311,7 @@ - (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSInde [self.allNodes addObject:node]; return node; } +#pragma clang diagnostic pop #endif From 343bbb1592e875458112db8ddf7f1936d1f4cd61 Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Tue, 26 May 2020 15:44:31 -0700 Subject: [PATCH 33/56] Ship ASExperimentalOOMBackgroundDeallocDisable since it decreases OOMs (#1840) --- Source/ASCollectionView.mm | 6 ------ Source/ASExperimentalFeatures.h | 9 ++++----- Source/ASExperimentalFeatures.mm | 1 - Source/ASImageNode+AnimatedImage.mm | 5 ----- Source/ASImageNode.mm | 13 ------------- Source/ASMultiplexImageNode.mm | 12 ------------ Source/ASTableView.mm | 6 ------ Source/ASViewController.mm | 8 -------- Tests/ASConfigurationTests.mm | 2 -- 9 files changed, 4 insertions(+), 58 deletions(-) diff --git a/Source/ASCollectionView.mm b/Source/ASCollectionView.mm index 8b8168519..afe9716ce 100644 --- a/Source/ASCollectionView.mm +++ b/Source/ASCollectionView.mm @@ -331,12 +331,6 @@ - (void)dealloc [self setAsyncDelegate:nil]; [self setAsyncDataSource:nil]; } - - // Data controller & range controller may own a ton of nodes, let's deallocate those off-main. - if (ASActivateExperimentalFeature(ASExperimentalOOMBackgroundDeallocDisable) == NO) { - ASPerformBackgroundDeallocation(&_dataController); - ASPerformBackgroundDeallocation(&_rangeController); - } } #pragma mark - diff --git a/Source/ASExperimentalFeatures.h b/Source/ASExperimentalFeatures.h index 82995b214..cc6d9cfe0 100644 --- a/Source/ASExperimentalFeatures.h +++ b/Source/ASExperimentalFeatures.h @@ -27,11 +27,10 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { ASExperimentalSkipClearData = 1 << 6, // exp_skip_clear_data ASExperimentalDidEnterPreloadSkipASMLayout = 1 << 7, // exp_did_enter_preload_skip_asm_layout ASExperimentalDispatchApply = 1 << 8, // exp_dispatch_apply - ASExperimentalOOMBackgroundDeallocDisable = 1 << 9, // exp_oom_bg_dealloc_disable - ASExperimentalDrawingGlobal = 1 << 10, // exp_drawing_global - ASExperimentalOptimizeDataControllerPipeline = 1 << 11, // exp_optimize_data_controller_pipeline - ASExperimentalTraitCollectionDidChangeWithPreviousCollection = 1 << 12, // exp_trait_collection_did_change_with_previous_collection - ASExperimentalDoNotCacheAccessibilityElements = 1 << 13, // exp_do_not_cache_accessibility_elements + ASExperimentalDrawingGlobal = 1 << 9, // exp_drawing_global + ASExperimentalOptimizeDataControllerPipeline = 1 << 10, // exp_optimize_data_controller_pipeline + ASExperimentalTraitCollectionDidChangeWithPreviousCollection = 1 << 11, // exp_trait_collection_did_change_with_previous_collection + ASExperimentalDoNotCacheAccessibilityElements = 1 << 12, // exp_do_not_cache_accessibility_elements ASExperimentalFeatureAll = 0xFFFFFFFF }; diff --git a/Source/ASExperimentalFeatures.mm b/Source/ASExperimentalFeatures.mm index f936525bc..1ec5fb17d 100644 --- a/Source/ASExperimentalFeatures.mm +++ b/Source/ASExperimentalFeatures.mm @@ -21,7 +21,6 @@ @"exp_skip_clear_data", @"exp_did_enter_preload_skip_asm_layout", @"exp_dispatch_apply", - @"exp_oom_bg_dealloc_disable", @"exp_drawing_global", @"exp_optimize_data_controller_pipeline", @"exp_trait_collection_did_change_with_previous_collection", diff --git a/Source/ASImageNode+AnimatedImage.mm b/Source/ASImageNode+AnimatedImage.mm index b2ad40320..9716f8529 100644 --- a/Source/ASImageNode+AnimatedImage.mm +++ b/Source/ASImageNode+AnimatedImage.mm @@ -79,11 +79,6 @@ - (void)_locked_setAnimatedImage:(id )animatedImage // not fire e.g. while scrolling down CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^(void) { [self animatedImageSet:animatedImage previousAnimatedImage:previousAnimatedImage]; - - // Animated image can take while to dealloc, do it off the main queue - if (previousAnimatedImage != nil && ASActivateExperimentalFeature(ASExperimentalOOMBackgroundDeallocDisable) == NO) { - ASPerformBackgroundDeallocation(&previousAnimatedImage); - } }); // Don't need to wakeup the runloop as the current is already running // CFRunLoopWakeUp(runLoop); // Should not be necessary diff --git a/Source/ASImageNode.mm b/Source/ASImageNode.mm index fd44a7803..95ac20143 100644 --- a/Source/ASImageNode.mm +++ b/Source/ASImageNode.mm @@ -30,8 +30,6 @@ // TODO: It would be nice to remove this dependency; it's the only subclass using more than +FrameworkSubclasses.h #import -static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; - typedef void (^ASImageNodeDrawParametersBlock)(ASWeakMapEntry *entry); @interface ASImageNodeDrawParameters : NSObject { @@ -247,7 +245,6 @@ - (void)_locked_setImage:(UIImage *)image return; } - UIImage *oldImage = _image; _image = image; if (image != nil) { @@ -268,16 +265,6 @@ - (void)_locked_setImage:(UIImage *)image } else { self.contents = nil; } - - // Destruction of bigger images on the main thread can be expensive - // and can take some time, so we dispatch onto a bg queue to - // actually dealloc. - CGSize oldImageSize = oldImage.size; - BOOL shouldReleaseImageOnBackgroundThread = oldImageSize.width > kMinReleaseImageOnBackgroundSize.width - || oldImageSize.height > kMinReleaseImageOnBackgroundSize.height; - if (shouldReleaseImageOnBackgroundThread && ASActivateExperimentalFeature(ASExperimentalOOMBackgroundDeallocDisable) == NO) { - ASPerformBackgroundDeallocation(&oldImage); - } } - (UIImage *)image diff --git a/Source/ASMultiplexImageNode.mm b/Source/ASMultiplexImageNode.mm index 00dcec84a..55de28ddc 100644 --- a/Source/ASMultiplexImageNode.mm +++ b/Source/ASMultiplexImageNode.mm @@ -39,8 +39,6 @@ static NSString *const kAssetsLibraryURLScheme = @"assets-library"; #endif -static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; - /** @abstract Signature for the block to be performed after an image has loaded. @param image The image that was loaded, or nil if no image was loaded. @@ -533,17 +531,7 @@ - (void)_updateProgressImageBlockOnDownloaderIfNeeded - (void)_clearImage { - // Destruction of bigger images on the main thread can be expensive - // and can take some time, so we dispatch onto a bg queue to - // actually dealloc. - UIImage *image = self.image; - CGSize imageSize = image.size; - BOOL shouldReleaseImageOnBackgroundThread = imageSize.width > kMinReleaseImageOnBackgroundSize.width || - imageSize.height > kMinReleaseImageOnBackgroundSize.height; [self _setImage:nil]; - if (shouldReleaseImageOnBackgroundThread && ASActivateExperimentalFeature(ASExperimentalOOMBackgroundDeallocDisable) == NO) { - ASPerformBackgroundDeallocation(&image); - } } #pragma mark - diff --git a/Source/ASTableView.mm b/Source/ASTableView.mm index 3781a8c10..97eb09f28 100644 --- a/Source/ASTableView.mm +++ b/Source/ASTableView.mm @@ -373,12 +373,6 @@ - (void)dealloc [self setAsyncDelegate:nil]; [self setAsyncDataSource:nil]; } - - // Data controller & range controller may own a ton of nodes, let's deallocate those off-main - if (ASActivateExperimentalFeature(ASExperimentalOOMBackgroundDeallocDisable) == NO) { - ASPerformBackgroundDeallocation(&_dataController); - ASPerformBackgroundDeallocation(&_rangeController); - } } #pragma mark - diff --git a/Source/ASViewController.mm b/Source/ASViewController.mm index 6bc855666..672d90422 100644 --- a/Source/ASViewController.mm +++ b/Source/ASViewController.mm @@ -105,14 +105,6 @@ - (void)_initializeInstance } } -- (void)dealloc -{ - if (ASActivateExperimentalFeature(ASExperimentalOOMBackgroundDeallocDisable)) { - return; - } - ASPerformBackgroundDeallocation(&_node); -} - - (void)loadView { // Apple applies a frame and autoresizing masks we need. Allocating a view is not diff --git a/Tests/ASConfigurationTests.mm b/Tests/ASConfigurationTests.mm index 67a0b0090..3a5dfff9c 100644 --- a/Tests/ASConfigurationTests.mm +++ b/Tests/ASConfigurationTests.mm @@ -27,7 +27,6 @@ ASExperimentalSkipClearData, ASExperimentalDidEnterPreloadSkipASMLayout, ASExperimentalDispatchApply, - ASExperimentalOOMBackgroundDeallocDisable, ASExperimentalDrawingGlobal, ASExperimentalOptimizeDataControllerPipeline, ASExperimentalTraitCollectionDidChangeWithPreviousCollection, @@ -53,7 +52,6 @@ + (NSArray *)names { @"exp_skip_clear_data", @"exp_did_enter_preload_skip_asm_layout", @"exp_dispatch_apply", - @"exp_oom_bg_dealloc_disable", @"exp_drawing_global", @"exp_optimize_data_controller_pipeline", @"exp_trait_collection_did_change_with_previous_collection", From a6f9ceec710722cd61be7ad570f4f9439463b29d Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Tue, 26 May 2020 20:56:28 -0700 Subject: [PATCH 34/56] Ship ASExperimentalUnfairLock experiment (#1841) - Followup to #1742 - At Pinterest this shipped with D516974 in late 02/2020 - As discussed in #858 this is iOS10 or later, so the runtime `gMutex_unfair` check is still necessary for Texture. --- Schemas/configuration.json | 1 - Source/ASExperimentalFeatures.h | 21 ++++++++++----------- Source/ASExperimentalFeatures.mm | 1 - Source/Details/ASThread.h | 2 +- Tests/ASConfigurationTests.mm | 2 -- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/Schemas/configuration.json b/Schemas/configuration.json index d2d041851..4ce900e5d 100644 --- a/Schemas/configuration.json +++ b/Schemas/configuration.json @@ -16,7 +16,6 @@ "exp_graphics_contexts", "exp_text_node", "exp_interface_state_coalesce", - "exp_unfair_lock", "exp_infer_layer_defaults", "exp_collection_teardown", "exp_framesetter_cache", diff --git a/Source/ASExperimentalFeatures.h b/Source/ASExperimentalFeatures.h index cc6d9cfe0..29939a556 100644 --- a/Source/ASExperimentalFeatures.h +++ b/Source/ASExperimentalFeatures.h @@ -20,17 +20,16 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { // will be used in all cases ASExperimentalTextNode = 1 << 0, // exp_text_node ASExperimentalInterfaceStateCoalescing = 1 << 1, // exp_interface_state_coalesce - ASExperimentalUnfairLock = 1 << 2, // exp_unfair_lock - ASExperimentalLayerDefaults = 1 << 3, // exp_infer_layer_defaults - ASExperimentalCollectionTeardown = 1 << 4, // exp_collection_teardown - ASExperimentalFramesetterCache = 1 << 5, // exp_framesetter_cache - ASExperimentalSkipClearData = 1 << 6, // exp_skip_clear_data - ASExperimentalDidEnterPreloadSkipASMLayout = 1 << 7, // exp_did_enter_preload_skip_asm_layout - ASExperimentalDispatchApply = 1 << 8, // exp_dispatch_apply - ASExperimentalDrawingGlobal = 1 << 9, // exp_drawing_global - ASExperimentalOptimizeDataControllerPipeline = 1 << 10, // exp_optimize_data_controller_pipeline - ASExperimentalTraitCollectionDidChangeWithPreviousCollection = 1 << 11, // exp_trait_collection_did_change_with_previous_collection - ASExperimentalDoNotCacheAccessibilityElements = 1 << 12, // exp_do_not_cache_accessibility_elements + ASExperimentalLayerDefaults = 1 << 2, // exp_infer_layer_defaults + ASExperimentalCollectionTeardown = 1 << 3, // exp_collection_teardown + ASExperimentalFramesetterCache = 1 << 4, // exp_framesetter_cache + ASExperimentalSkipClearData = 1 << 5, // exp_skip_clear_data + ASExperimentalDidEnterPreloadSkipASMLayout = 1 << 6, // exp_did_enter_preload_skip_asm_layout + ASExperimentalDispatchApply = 1 << 7, // exp_dispatch_apply + ASExperimentalDrawingGlobal = 1 << 8, // exp_drawing_global + ASExperimentalOptimizeDataControllerPipeline = 1 << 9, // exp_optimize_data_controller_pipeline + ASExperimentalTraitCollectionDidChangeWithPreviousCollection = 1 << 10, // exp_trait_collection_did_change_with_previous_collection + ASExperimentalDoNotCacheAccessibilityElements = 1 << 11 , // exp_do_not_cache_accessibility_elements ASExperimentalFeatureAll = 0xFFFFFFFF }; diff --git a/Source/ASExperimentalFeatures.mm b/Source/ASExperimentalFeatures.mm index 1ec5fb17d..e89aebe46 100644 --- a/Source/ASExperimentalFeatures.mm +++ b/Source/ASExperimentalFeatures.mm @@ -14,7 +14,6 @@ { NSArray *allNames = ASCreateOnce((@[@"exp_text_node", @"exp_interface_state_coalesce", - @"exp_unfair_lock", @"exp_infer_layer_defaults", @"exp_collection_teardown", @"exp_framesetter_cache", diff --git a/Source/Details/ASThread.h b/Source/Details/ASThread.h index 501022e83..cb840e167 100644 --- a/Source/Details/ASThread.h +++ b/Source/Details/ASThread.h @@ -218,7 +218,7 @@ namespace AS { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if (AS_AVAILABLE_IOS_TVOS(10, 10)) { - gMutex_unfair = ASActivateExperimentalFeature(ASExperimentalUnfairLock); + gMutex_unfair = YES; } }); diff --git a/Tests/ASConfigurationTests.mm b/Tests/ASConfigurationTests.mm index 3a5dfff9c..083251adf 100644 --- a/Tests/ASConfigurationTests.mm +++ b/Tests/ASConfigurationTests.mm @@ -20,7 +20,6 @@ ASExperimentalTextNode, #endif ASExperimentalInterfaceStateCoalescing, - ASExperimentalUnfairLock, ASExperimentalLayerDefaults, ASExperimentalCollectionTeardown, ASExperimentalFramesetterCache, @@ -45,7 +44,6 @@ + (NSArray *)names { return @[ @"exp_text_node", @"exp_interface_state_coalesce", - @"exp_unfair_lock", @"exp_infer_layer_defaults", @"exp_collection_teardown", @"exp_framesetter_cache", From bbb03b1e5685e1bafb92b7943f126c68480536fa Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Wed, 27 May 2020 08:01:06 -0700 Subject: [PATCH 35/56] Ship ASExperimentalTraitCollectionDidChangeWithPreviousCollection (#1842) - PINS shipped this experiment in 08/2019 --- Source/ASDisplayNode+Layout.mm | 5 ----- Source/ASDisplayNode+Subclasses.h | 11 ----------- Source/ASDisplayNode.mm | 1 - Source/ASExperimentalFeatures.h | 3 +-- Source/ASExperimentalFeatures.mm | 1 - Tests/ASConfigurationTests.mm | 2 -- Tests/ASDisplayNodeSnapshotTests.mm | 15 --------------- Tests/ASImageNodeSnapshotTests.mm | 10 ---------- 8 files changed, 1 insertion(+), 47 deletions(-) diff --git a/Source/ASDisplayNode+Layout.mm b/Source/ASDisplayNode+Layout.mm index 79b485897..25d44b87b 100644 --- a/Source/ASDisplayNode+Layout.mm +++ b/Source/ASDisplayNode+Layout.mm @@ -137,12 +137,7 @@ - (void)setPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traitCollection _primitiveTraitCollection = traitCollection; l.unlock(); - if (ASActivateExperimentalFeature(ASExperimentalTraitCollectionDidChangeWithPreviousCollection)) { [self asyncTraitCollectionDidChangeWithPreviousTraitCollection:previousTraitCollection]; - } else { - [self asyncTraitCollectionDidChange]; - } - } } diff --git a/Source/ASDisplayNode+Subclasses.h b/Source/ASDisplayNode+Subclasses.h index 8caa64666..9adb9336a 100644 --- a/Source/ASDisplayNode+Subclasses.h +++ b/Source/ASDisplayNode+Subclasses.h @@ -201,23 +201,12 @@ AS_CATEGORY_IMPLEMENTABLE - (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState ASDISPLAYNODE_REQUIRES_SUPER; -/** - * @abstract Called when the node's ASTraitCollection changes - * - * @discussion Subclasses can override this method to react to a trait collection change. - */ -AS_CATEGORY_IMPLEMENTABLE -- (void)asyncTraitCollectionDidChange ASDISPLAYNODE_REQUIRES_SUPER ASDISPLAYNODE_DEPRECATED_MSG("Use asyncTraitCollectionDidChangeWithPreviousTraitCollection: instead."); - - /** * @abstract Called when the node's ASTraitCollection changes * * @discussion Subclasses can override this method to react to a trait collection change. * * @param previousTraitCollection The ASPrimitiveTraitCollection object before the interface environment changed. - * - * @note Enable `ASExperimentalTraitCollectionDidChangeWithPreviousCollection` experiment to have this method called instead of `asyncTraitCollectionDidChange`. */ AS_CATEGORY_IMPLEMENTABLE - (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTraitCollection)previousTraitCollection ASDISPLAYNODE_REQUIRES_SUPER; diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 5b4e3b2ed..45f3df870 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -241,7 +241,6 @@ + (void)initialize class_addMethod(self, @selector(didEnterVisibleState), noArgsImp, "v@:"); class_addMethod(self, @selector(didExitVisibleState), noArgsImp, "v@:"); class_addMethod(self, @selector(hierarchyDisplayDidFinish), noArgsImp, "v@:"); - class_addMethod(self, @selector(asyncTraitCollectionDidChange), noArgsImp, "v@:"); class_addMethod(self, @selector(calculatedLayoutDidChange), noArgsImp, "v@:"); auto type0 = "v@:" + std::string(@encode(ASSizeRange)); diff --git a/Source/ASExperimentalFeatures.h b/Source/ASExperimentalFeatures.h index 29939a556..306c57d41 100644 --- a/Source/ASExperimentalFeatures.h +++ b/Source/ASExperimentalFeatures.h @@ -28,8 +28,7 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { ASExperimentalDispatchApply = 1 << 7, // exp_dispatch_apply ASExperimentalDrawingGlobal = 1 << 8, // exp_drawing_global ASExperimentalOptimizeDataControllerPipeline = 1 << 9, // exp_optimize_data_controller_pipeline - ASExperimentalTraitCollectionDidChangeWithPreviousCollection = 1 << 10, // exp_trait_collection_did_change_with_previous_collection - ASExperimentalDoNotCacheAccessibilityElements = 1 << 11 , // exp_do_not_cache_accessibility_elements + ASExperimentalDoNotCacheAccessibilityElements = 1 << 10, // exp_do_not_cache_accessibility_elements ASExperimentalFeatureAll = 0xFFFFFFFF }; diff --git a/Source/ASExperimentalFeatures.mm b/Source/ASExperimentalFeatures.mm index e89aebe46..fef124b45 100644 --- a/Source/ASExperimentalFeatures.mm +++ b/Source/ASExperimentalFeatures.mm @@ -22,7 +22,6 @@ @"exp_dispatch_apply", @"exp_drawing_global", @"exp_optimize_data_controller_pipeline", - @"exp_trait_collection_did_change_with_previous_collection", @"exp_do_not_cache_accessibility_elements"])); if (flags == ASExperimentalFeatureAll) { return allNames; diff --git a/Tests/ASConfigurationTests.mm b/Tests/ASConfigurationTests.mm index 083251adf..755375af8 100644 --- a/Tests/ASConfigurationTests.mm +++ b/Tests/ASConfigurationTests.mm @@ -28,7 +28,6 @@ ASExperimentalDispatchApply, ASExperimentalDrawingGlobal, ASExperimentalOptimizeDataControllerPipeline, - ASExperimentalTraitCollectionDidChangeWithPreviousCollection, ASExperimentalDoNotCacheAccessibilityElements, }; @@ -52,7 +51,6 @@ + (NSArray *)names { @"exp_dispatch_apply", @"exp_drawing_global", @"exp_optimize_data_controller_pipeline", - @"exp_trait_collection_did_change_with_previous_collection", @"exp_do_not_cache_accessibility_elements", ]; } diff --git a/Tests/ASDisplayNodeSnapshotTests.mm b/Tests/ASDisplayNodeSnapshotTests.mm index 07ebbc632..8cf7c6a6d 100644 --- a/Tests/ASDisplayNodeSnapshotTests.mm +++ b/Tests/ASDisplayNodeSnapshotTests.mm @@ -16,13 +16,6 @@ @interface ASDisplayNodeSnapshotTests : ASSnapshotTestCase @implementation ASDisplayNodeSnapshotTests -- (void)setUp { - [super setUp]; - ASConfiguration *config = [ASConfiguration new]; - config.experimentalFeatures = ASExperimentalTraitCollectionDidChangeWithPreviousCollection; - [ASConfigurationManager test_resetWithConfiguration:config]; -} - - (void)testBasicHierarchySnapshotTesting { ASDisplayNode *node = [[ASDisplayNode alloc] init]; @@ -68,14 +61,6 @@ - (void)testPrecompositedCornerRounding - (void)testClippingCornerRounding { -#if AS_AT_LEAST_IOS13 - if (@available(iOS 13.0, *)) { - ASConfiguration *config = [ASConfiguration new]; - config.experimentalFeatures = ASExperimentalTraitCollectionDidChangeWithPreviousCollection; - [ASConfigurationManager test_resetWithConfiguration:config]; - } -#endif - for (CACornerMask c = 1; c <= kASCACornerAllCorners; c |= (c << 1)) { auto node = [[ASImageNode alloc] init]; auto bounds = CGRectMake(0, 0, 100, 100); diff --git a/Tests/ASImageNodeSnapshotTests.mm b/Tests/ASImageNodeSnapshotTests.mm index 431e28d09..13364930b 100644 --- a/Tests/ASImageNodeSnapshotTests.mm +++ b/Tests/ASImageNodeSnapshotTests.mm @@ -242,11 +242,6 @@ - (void)testUIGraphicsRendererDrawingExperiment - (void)testDynamicAssetImage { if (@available(iOS 13.0, *)) { - // enable experimantal callback for traits change - ASConfiguration *config = [ASConfiguration new]; - config.experimentalFeatures = ASExperimentalTraitCollectionDidChangeWithPreviousCollection; - [ASConfigurationManager test_resetWithConfiguration:config]; - UIImage *image = [UIImage imageNamed:@"light-dark" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil]; ASImageNode *node = [[ASImageNode alloc] init]; node.image = image; @@ -265,11 +260,6 @@ - (void)testDynamicAssetImage - (void)testDynamicTintColor { if (@available(iOS 13.0, *)) { - // enable experimental callback for traits change - ASConfiguration *config = [ASConfiguration new]; - config.experimentalFeatures = ASExperimentalTraitCollectionDidChangeWithPreviousCollection; - [ASConfigurationManager test_resetWithConfiguration:config]; - UIImage *image = makeImageWithColor(UIColor.redColor, CGSize{.width = 100, .height = 100}); image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; UIColor* tintColor = UIColor.systemBackgroundColor; From 3c0e044ce503335df9a94dc349845734cebe6f0f Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Thu, 28 May 2020 10:24:35 -0700 Subject: [PATCH 36/56] Run the tests with iOS10 and as a framework in preparation of updating snapshot test case. (#1856) Doing this to separate these items from the iOSSnapshotTestCase update. --- AsyncDisplayKit.xcodeproj/project.pbxproj | 29 +++++++++++++++++++---- Podfile | 2 ++ Podfile.lock | 2 +- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index a69d1e093..27ffc73b5 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -177,6 +177,7 @@ 83A7D95B1D44547700BF333E /* ASWeakMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83A7D9591D44542100BF333E /* ASWeakMap.mm */; }; 83A7D95C1D44548100BF333E /* ASWeakMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A7D9581D44542100BF333E /* ASWeakMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; 83A7D95E1D446A6E00BF333E /* ASWeakMapTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83A7D95D1D446A6E00BF333E /* ASWeakMapTests.mm */; }; + 89DA454A9BB6CF35A02F9DD2 /* Pods_AsyncDisplayKitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA42D0ECAA484A6B9934110F /* Pods_AsyncDisplayKitTests.framework */; }; 8BBBAB8C1CEBAF1700107FC6 /* ASDefaultPlaybackButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B0768B11CE752EC002E1453 /* ASDefaultPlaybackButton.h */; settings = {ATTRIBUTES = (Private, ); }; }; 8BBBAB8D1CEBAF1E00107FC6 /* ASDefaultPlaybackButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.mm */; }; 8BDA5FC71CDBDF91007D13B2 /* ASVideoPlayerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BDA5FC31CDBDDE1007D13B2 /* ASVideoPlayerNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -456,7 +457,6 @@ D933F041224AD17F00FF495E /* ASTransactionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = D933F040224AD17F00FF495E /* ASTransactionTests.mm */; }; D99F9158232990F30083CC8E /* ASImageNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D99F9157232990F30083CC8E /* ASImageNodeTests.m */; }; DB55C2671C641AE4004EDCF5 /* ASContextTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DB7121BCD50849C498C886FB /* libPods-AsyncDisplayKitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */; }; DB78412E1C6BCE1600A9E2B4 /* _ASTransitionContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = DB55C2601C6408D6004EDCF5 /* _ASTransitionContext.mm */; }; DBABFAFC1C6A8D2F0039EA4A /* _ASTransitionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = DB55C25F1C6408D6004EDCF5 /* _ASTransitionContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; DBC452DE1C5C6A6A00B16017 /* ArrayDiffingTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.mm */; }; @@ -792,6 +792,7 @@ 9F98C0241DBDF2A300476D92 /* ASControlTargetAction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASControlTargetAction.mm; sourceTree = ""; }; A32FEDD31C501B6A004F642A /* ASTextKitFontSizeAdjuster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitFontSizeAdjuster.h; path = TextKit/ASTextKitFontSizeAdjuster.h; sourceTree = ""; }; A373200E1C571B050011FC94 /* ASTextNode+Beta.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASTextNode+Beta.h"; sourceTree = ""; }; + AA42D0ECAA484A6B9934110F /* Pods_AsyncDisplayKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AsyncDisplayKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AC026B571BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASAbsoluteLayoutSpecSnapshotTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASHierarchyChangeSet.h; sourceTree = ""; }; AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASHierarchyChangeSet.mm; sourceTree = ""; }; @@ -1055,7 +1056,6 @@ E5E281751E71C845006B67C2 /* ASCollectionLayoutState.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionLayoutState.mm; sourceTree = ""; }; E5E2D72D1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionGalleryLayoutDelegate.h; sourceTree = ""; }; E5E2D72F1EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCollectionGalleryLayoutDelegate.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F325E48B21745F9E00AC93A4 /* ASButtonNodeTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASButtonNodeTests.mm; sourceTree = ""; }; F325E48F217460B000AC93A4 /* ASTextNode2Tests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextNode2Tests.mm; sourceTree = ""; }; F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayViewAccessibilityTests.mm; sourceTree = ""; }; @@ -1083,7 +1083,7 @@ 058D09BE195D04C000B7D73C /* XCTest.framework in Frameworks */, 058D09C1195D04C000B7D73C /* UIKit.framework in Frameworks */, 058D09BF195D04C000B7D73C /* Foundation.framework in Frameworks */, - DB7121BCD50849C498C886FB /* libPods-AsyncDisplayKitTests.a in Frameworks */, + 89DA454A9BB6CF35A02F9DD2 /* Pods_AsyncDisplayKitTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1170,7 +1170,7 @@ 058D09AF195D04C000B7D73C /* Foundation.framework */, 058D09BD195D04C000B7D73C /* XCTest.framework */, 058D09C0195D04C000B7D73C /* UIKit.framework */, - EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */, + AA42D0ECAA484A6B9934110F /* Pods_AsyncDisplayKitTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -2156,6 +2156,7 @@ 058D09B8195D04C000B7D73C /* Sources */, 058D09B9195D04C000B7D73C /* Frameworks */, 058D09BA195D04C000B7D73C /* Resources */, + F7D0C9EDE1FC3D066B45EE7C /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -2276,6 +2277,26 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + F7D0C9EDE1FC3D066B45EE7C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework", + "${BUILT_PRODUCTS_DIR}/OCMock/OCMock.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBSnapshotTestCase.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OCMock.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/Podfile b/Podfile index 17fdc321a..ac3c342c1 100644 --- a/Podfile +++ b/Podfile @@ -3,6 +3,8 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '9.0' target :'AsyncDisplayKitTests' do + platform :ios, '10.0' + use_frameworks! pod 'OCMock', '~>3.6' pod 'FBSnapshotTestCase/Core', '~> 2.1' end diff --git a/Podfile.lock b/Podfile.lock index 77ad0ce02..3a987d42e 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -15,6 +15,6 @@ SPEC CHECKSUMS: FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a OCMock: 5ea90566be239f179ba766fd9fbae5885040b992 -PODFILE CHECKSUM: 6c5ab754458e18efcf3a8b39a3b97bf96c3d2237 +PODFILE CHECKSUM: 9f751863f64737ce61a8b6aaa6a8bfe0aadcc165 COCOAPODS: 1.9.1 From a97b6890f001d25b9998d18b3a41d60d407ce1c2 Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Thu, 28 May 2020 14:28:35 -0700 Subject: [PATCH 37/56] Reference Image Updates in preparation for iOSSnapshotTestCase 6.2 (#1857) - Update all the tests identifiers in code to use `_` instead of `-`. -- Rename all the reference images with `_` instead of `-`. -- The above two changes are in preparation for iOSSnapshotTestsCase doing this for us. - Move all the reference images in the path "ReferenceImages_iOS_10" to "ReferenceImages_64". -- When copying these reference images, prefer the iOS10 reference images since we now run under iOS10. -- The exception is testRoundedCornerBlock where we prefer the 64 one. -- Remove "_iOS_10" as a suffix in code. Co-authored-by: Rahul Malik --- AsyncDisplayKit.xcodeproj/project.pbxproj | 4 ---- Tests/ASDisplayNodeSnapshotTests.mm | 4 ++-- Tests/ASInsetLayoutSpecSnapshotTests.mm | 2 +- Tests/ASSnapshotTestCase.mm | 7 ------- .../testChangingTintColor@2x.png | Bin ...testChangingTintColor_modified_tint@2x.png | Bin .../testTintColor@2x.png | Bin ...testTintColorWithForegroundColorSet@2x.png | Bin ...ritedTintColor_green_inherited_tint@2x.png | Bin ...heritedTintColor_red_inherited_tint@2x.png | Bin ...otTesting_user_interface_style_dark@2x.png | Bin ...tTesting_user_interface_style_light@2x.png | Bin ...erOffset_bottomLeft_inner_childSize@2x.png | Bin ...nerOffset_bottomLeft_inner_fullSize@2x.png | Bin ...rOffset_bottomRight_inner_childSize@2x.png | Bin ...erOffset_bottomRight_inner_fullSize@2x.png | Bin ...InnerOffset_topLeft_inner_childSize@2x.png | Bin ...hInnerOffset_topLeft_inner_fullSize@2x.png | Bin ...nnerOffset_topRight_inner_childSize@2x.png | Bin ...InnerOffset_topRight_inner_fullSize@2x.png | Bin ...erOffset_bottomLeft_outer_childSize@2x.png | Bin ...terOffset_bottomLeft_outer_fullSize@2x.png | Bin ...rOffset_bottomRight_outer_childSize@2x.png | Bin ...erOffset_bottomRight_outer_fullSize@2x.png | Bin ...OuterOffset_topLeft_outer_childSize@2x.png | Bin ...hOuterOffset_topLeft_outer_fullSize@2x.png | Bin ...uterOffset_topRight_outer_childSize@2x.png | Bin ...OuterOffset_topRight_outer_fullSize@2x.png | Bin ...cations_bottomLeft_center_childSize@2x.png | Bin ...ocations_bottomLeft_center_fullSize@2x.png | Bin ...ations_bottomRight_center_childSize@2x.png | Bin ...cations_bottomRight_center_fullSize@2x.png | Bin ...lLocations_topLeft_center_childSize@2x.png | Bin ...llLocations_topLeft_center_fullSize@2x.png | Bin ...Locations_topRight_center_childSize@2x.png | Bin ...lLocations_topRight_center_fullSize@2x.png | Bin ...kgroundDynamicColorLayerBacked_dark@2x.png | Bin ...groundDynamicColorLayerBacked_light@2x.png | Bin .../testBackgroundDynamicColor_dark@2x.png | Bin .../testBackgroundDynamicColor_light@2x.png | Bin .../testClippingCornerRounding@2x.png | Bin .../testClippingCornerRounding_15@2x.png | Bin ...testClippingCornerRounding_15_dark@2x.png} | Bin ...estClippingCornerRounding_15_light@2x.png} | Bin .../testClippingCornerRounding_1@2x.png | Bin .../testClippingCornerRounding_1_dark@2x.png} | Bin ...testClippingCornerRounding_1_light@2x.png} | Bin .../testClippingCornerRounding_3@2x.png | Bin .../testClippingCornerRounding_3_dark@2x.png} | Bin ...testClippingCornerRounding_3_light@2x.png} | Bin .../testClippingCornerRounding_7@2x.png | Bin .../testClippingCornerRounding_7_dark@2x.png} | Bin ...testClippingCornerRounding_7_light@2x.png} | Bin .../testPrecompositedCornerRounding@2x.png | Bin .../testPrecompositedCornerRounding_15@2x.png | Bin .../testPrecompositedCornerRounding_1@2x.png | Bin .../testPrecompositedCornerRounding_3@2x.png | Bin .../testPrecompositedCornerRounding_7@2x.png | Bin ...otTesting_user_interface_style_dark@2x.png | Bin ...tTesting_user_interface_style_light@2x.png | Bin ...ssetImage_user_interface_style_dark@2x.png | Bin ...setImage_user_interface_style_light@2x.png | Bin ...TintColor_user_interface_style_dark@2x.png | Bin ...intColor_user_interface_style_light@2x.png | Bin .../testForcedScaling_first@2x.png | Bin 14527 -> 14720 bytes .../testForcedScaling_second@2x.png | Bin 61553 -> 61702 bytes .../testRenderLogoSquare@2x.png | Bin 14527 -> 14720 bytes .../testTintColorBlock@2x.png | Bin 363058 -> 1543 bytes ...lorInheritsFromSupernodeLayerBacked@2x.png | Bin ...olorInheritsFromSupernodeViewBacked@2x.png | Bin ...odePropertyAlwaysTemplate_blue_tint@2x.png | Bin ...NodePropertyAlwaysTemplate_red_tint@2x.png | Bin ...ntColorOnNodePropertyAlwaysOriginal@2x.png | Bin ...opertyAlwaysTemplateLayerBackedNode@2x.png | Bin ...odePropertyAlwaysTemplate_blue_tint@2x.png | Bin ...NodePropertyAlwaysTemplate_red_tint@2x.png | Bin ...estTintColorOnNodePropertyAutomatic@2x.png | Bin ...UIGraphicsRendererDrawingExperiment@2x.png | Bin ...estInsetsWithFixedSize_10_10_10_10@2x.png} | Bin ...stInsetsWithFixedSize_10_10_10_inf@2x.png} | Bin ...stInsetsWithFixedSize_10_10_inf_10@2x.png} | Bin ...tInsetsWithFixedSize_10_10_inf_inf@2x.png} | Bin ...stInsetsWithFixedSize_10_inf_10_10@2x.png} | Bin ...tInsetsWithFixedSize_10_inf_10_inf@2x.png} | Bin ...tInsetsWithFixedSize_10_inf_inf_10@2x.png} | Bin ...InsetsWithFixedSize_10_inf_inf_inf@2x.png} | Bin ...stInsetsWithFixedSize_inf_10_10_10@2x.png} | Bin ...tInsetsWithFixedSize_inf_10_10_inf@2x.png} | Bin ...tInsetsWithFixedSize_inf_10_inf_10@2x.png} | Bin ...InsetsWithFixedSize_inf_10_inf_inf@2x.png} | Bin ...tInsetsWithFixedSize_inf_inf_10_10@2x.png} | Bin ...InsetsWithFixedSize_inf_inf_10_inf@2x.png} | Bin ...InsetsWithFixedSize_inf_inf_inf_10@2x.png} | Bin ...nsetsWithFixedSize_inf_inf_inf_inf@2x.png} | Bin ...hInfinityAndZeroInsetValue_0_0_0_0@2x.png} | Bin ...nfinityAndZeroInsetValue_0_0_0_inf@2x.png} | Bin ...nfinityAndZeroInsetValue_0_0_inf_0@2x.png} | Bin ...inityAndZeroInsetValue_0_0_inf_inf@2x.png} | Bin ...nfinityAndZeroInsetValue_0_inf_0_0@2x.png} | Bin ...inityAndZeroInsetValue_0_inf_0_inf@2x.png} | Bin ...inityAndZeroInsetValue_0_inf_inf_0@2x.png} | Bin ...ityAndZeroInsetValue_0_inf_inf_inf@2x.png} | Bin ...nfinityAndZeroInsetValue_inf_0_0_0@2x.png} | Bin ...inityAndZeroInsetValue_inf_0_0_inf@2x.png} | Bin ...inityAndZeroInsetValue_inf_0_inf_0@2x.png} | Bin ...ityAndZeroInsetValue_inf_0_inf_inf@2x.png} | Bin ...inityAndZeroInsetValue_inf_inf_0_0@2x.png} | Bin ...ityAndZeroInsetValue_inf_inf_0_inf@2x.png} | Bin ...ityAndZeroInsetValue_inf_inf_inf_0@2x.png} | Bin ...yAndZeroInsetValue_inf_inf_inf_inf@2x.png} | Bin ...InsetsWithVariableSize_10_10_10_10@2x.png} | Bin ...nsetsWithVariableSize_10_10_10_inf@2x.png} | Bin ...nsetsWithVariableSize_10_10_inf_10@2x.png} | Bin ...setsWithVariableSize_10_10_inf_inf@2x.png} | Bin ...nsetsWithVariableSize_10_inf_10_10@2x.png} | Bin ...setsWithVariableSize_10_inf_10_inf@2x.png} | Bin ...setsWithVariableSize_10_inf_inf_10@2x.png} | Bin ...etsWithVariableSize_10_inf_inf_inf@2x.png} | Bin ...nsetsWithVariableSize_inf_10_10_10@2x.png} | Bin ...setsWithVariableSize_inf_10_10_inf@2x.png} | Bin ...setsWithVariableSize_inf_10_inf_10@2x.png} | Bin ...etsWithVariableSize_inf_10_inf_inf@2x.png} | Bin ...setsWithVariableSize_inf_inf_10_10@2x.png} | Bin ...etsWithVariableSize_inf_inf_10_inf@2x.png} | Bin ...etsWithVariableSize_inf_inf_inf_10@2x.png} | Bin ...tsWithVariableSize_inf_inf_inf_inf@2x.png} | Bin ...stBaselineAlignmentWithSpaceBetween@2x.png | Bin 6414 -> 6430 bytes ...tBaselineAlignmentWithStretchedItem@2x.png | Bin 6480 -> 6509 bytes ...testBaselineAlignment_baselineFirst@2x.png | Bin 6646 -> 6691 bytes .../testBaselineAlignment_baselineLast@2x.png | Bin 6479 -> 6559 bytes .../testNestedBaselineAlignments@2x.png | Bin 8690 -> 8786 bytes .../testShadowing_ASTextNode2@2x.png | Bin ...ContainerInsetHighlight_ASTextNode2@2x.png | Bin ...hSmallerConstrainedSize_ASTextNode2@2x.png | Bin .../testTextContainerInset_ASTextNode2@2x.png | Bin .../testTextTintColor_ASTextNode2@2x.png | Bin ...e2_NSLineBreakByCharWrapping_0Lines@2x.png | Bin ...e2_NSLineBreakByCharWrapping_1Lines@2x.png | Bin ...e2_NSLineBreakByCharWrapping_2Lines@2x.png | Bin ...e2_NSLineBreakByCharWrapping_3Lines@2x.png | Bin ..._NSLineBreakByTruncatingHead_0Lines@2x.png | Bin ..._NSLineBreakByTruncatingHead_1Lines@2x.png | Bin ..._NSLineBreakByTruncatingHead_2Lines@2x.png | Bin ..._NSLineBreakByTruncatingHead_3Lines@2x.png | Bin ...SLineBreakByTruncatingMiddle_0Lines@2x.png | Bin ...SLineBreakByTruncatingMiddle_1Lines@2x.png | Bin ...SLineBreakByTruncatingMiddle_2Lines@2x.png | Bin ...SLineBreakByTruncatingMiddle_3Lines@2x.png | Bin ..._NSLineBreakByTruncatingTail_0Lines@2x.png | Bin ..._NSLineBreakByTruncatingTail_1Lines@2x.png | Bin ..._NSLineBreakByTruncatingTail_2Lines@2x.png | Bin ..._NSLineBreakByTruncatingTail_3Lines@2x.png | Bin ...e2_NSLineBreakByWordWrapping_0Lines@2x.png | Bin ...e2_NSLineBreakByWordWrapping_1Lines@2x.png | Bin ...e2_NSLineBreakByWordWrapping_2Lines@2x.png | Bin ...e2_NSLineBreakByWordWrapping_3Lines@2x.png | Bin ...edFromTextWhenTruncated_ASTextNode2@2x.png | Bin ...SlowPathTruncationWorks_ASTextNode2@2x.png | Bin ...rarchyChange_green_tint_from_parent@2x.png | Bin ...ierarchyChange_red_tint_from_parent@2x.png | Bin .../testTextContainerInset2@2x.png | Bin .../testTextContainerInset@2x.png | Bin 2651 -> 2725 bytes .../testTextContainerInsetHighlight@2x.png | Bin 4877 -> 4908 bytes ...sIncludedWithSmallerConstrainedSize@2x.png | Bin 5945 -> 5914 bytes .../testThatFastPathTruncationWorks@2x.png | Bin 4025 -> 3978 bytes .../testThatSlowPathTruncationWorks@2x.png | Bin 3491 -> 3446 bytes ...heritedFromTextWhenTruncateTailMode@2x.png | Bin ...rarchyChange_green_tint_from_parent@2x.png | Bin ...ierarchyChange_red_tint_from_parent@2x.png | Bin ...UIGraphicsRendererDrawingExperiment@2x.png | Bin ...TintColor_user_interface_style_dark@2x.png | Bin ...TintColor_user_interface_style_dark@3x.png | Bin ...intColor_user_interface_style_light@2x.png | Bin ...intColor_user_interface_style_light@3x.png | Bin ...otTesting_user_interface_style_dark@2x.png | Bin ...otTesting_user_interface_style_dark@3x.png | Bin ...tTesting_user_interface_style_light@2x.png | Bin ...tTesting_user_interface_style_light@3x.png | Bin .../testRoundedAllCorners@2x.png | Bin .../testRoundedBorderless@2x.png | Bin .../testRoundedPartial@2x.png | Bin .../testForcedScaling_first@2x.png | Bin 14720 -> 0 bytes .../testForcedScaling_second@2x.png | Bin 61702 -> 0 bytes .../testRenderLogoSquare@2x.png | Bin 14720 -> 0 bytes .../testRoundedCornerBlock@2x.png | Bin 7330 -> 0 bytes .../testTintColorBlock@2x.png | Bin 1543 -> 0 bytes ...stBaselineAlignmentWithSpaceBetween@2x.png | Bin 6430 -> 0 bytes ...tBaselineAlignmentWithStretchedItem@2x.png | Bin 6509 -> 0 bytes ...testBaselineAlignment_baselineFirst@2x.png | Bin 6691 -> 0 bytes .../testBaselineAlignment_baselineLast@2x.png | Bin 6559 -> 0 bytes .../testNestedBaselineAlignments@2x.png | Bin 8786 -> 0 bytes .../testFontPointSizeScaling@2x.png | Bin 1770 -> 0 bytes .../testShadowing@2x.png | Bin 6381 -> 0 bytes .../testTextContainerInset@2x.png | Bin 2725 -> 0 bytes .../testTextContainerInsetHighlight@2x.png | Bin 4908 -> 0 bytes ...sIncludedWithSmallerConstrainedSize@2x.png | Bin 5914 -> 0 bytes .../testThatFastPathTruncationWorks@2x.png | Bin 3978 -> 0 bytes .../testThatSlowPathTruncationWorks@2x.png | Bin 3446 -> 0 bytes 198 files changed, 3 insertions(+), 14 deletions(-) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASButtonNodeSnapshotTests/testChangingTintColor@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASButtonNodeSnapshotTests/testChangingTintColor_modified_tint@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASButtonNodeSnapshotTests/testTintColor@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASButtonNodeSnapshotTests/testTintColorWithForegroundColorSet@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_green_inherited_tint@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_red_inherited_tint@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_childSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_fullSize@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_dark@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_light@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_dark@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_light@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testClippingCornerRounding@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15@2x.png (100%) rename Tests/{ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15-dark@2x.png => ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15_dark@2x.png} (100%) rename Tests/{ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15-light@2x.png => ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15_light@2x.png} (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1@2x.png (100%) rename Tests/{ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1-dark@2x.png => ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1_dark@2x.png} (100%) rename Tests/{ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1-light@2x.png => ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1_light@2x.png} (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3@2x.png (100%) rename Tests/{ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3-dark@2x.png => ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3_dark@2x.png} (100%) rename Tests/{ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3-light@2x.png => ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3_light@2x.png} (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7@2x.png (100%) rename Tests/{ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7-dark@2x.png => ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7_dark@2x.png} (100%) rename Tests/{ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7-light@2x.png => ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7_light@2x.png} (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_15@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_1@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_3@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_7@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_dark@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_light@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_dark@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_light@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeLayerBacked@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeViewBacked@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_blue_tint@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_red_tint@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysOriginal@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplateLayerBackedNode@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_blue_tint@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_red_tint@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAutomatic@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASImageNodeSnapshotTests/testUIGraphicsRendererDrawingExperiment@2x.png (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_10-10-10-10@2x.png => testInsetsWithFixedSize_10_10_10_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_10-10-10-inf@2x.png => testInsetsWithFixedSize_10_10_10_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_10-10-inf-10@2x.png => testInsetsWithFixedSize_10_10_inf_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_10-10-inf-inf@2x.png => testInsetsWithFixedSize_10_10_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_10-inf-10-10@2x.png => testInsetsWithFixedSize_10_inf_10_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_10-inf-10-inf@2x.png => testInsetsWithFixedSize_10_inf_10_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_10-inf-inf-10@2x.png => testInsetsWithFixedSize_10_inf_inf_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_10-inf-inf-inf@2x.png => testInsetsWithFixedSize_10_inf_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_inf-10-10-10@2x.png => testInsetsWithFixedSize_inf_10_10_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_inf-10-10-inf@2x.png => testInsetsWithFixedSize_inf_10_10_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_inf-10-inf-10@2x.png => testInsetsWithFixedSize_inf_10_inf_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_inf-10-inf-inf@2x.png => testInsetsWithFixedSize_inf_10_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_inf-inf-10-10@2x.png => testInsetsWithFixedSize_inf_inf_10_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_inf-inf-10-inf@2x.png => testInsetsWithFixedSize_inf_inf_10_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_inf-inf-inf-10@2x.png => testInsetsWithFixedSize_inf_inf_inf_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithFixedSize_inf-inf-inf-inf@2x.png => testInsetsWithFixedSize_inf_inf_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_0-0-0-0@2x.png => testInsetsWithInfinityAndZeroInsetValue_0_0_0_0@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_0-0-0-inf@2x.png => testInsetsWithInfinityAndZeroInsetValue_0_0_0_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_0-0-inf-0@2x.png => testInsetsWithInfinityAndZeroInsetValue_0_0_inf_0@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_0-0-inf-inf@2x.png => testInsetsWithInfinityAndZeroInsetValue_0_0_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_0-inf-0-0@2x.png => testInsetsWithInfinityAndZeroInsetValue_0_inf_0_0@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_0-inf-0-inf@2x.png => testInsetsWithInfinityAndZeroInsetValue_0_inf_0_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_0-inf-inf-0@2x.png => testInsetsWithInfinityAndZeroInsetValue_0_inf_inf_0@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_0-inf-inf-inf@2x.png => testInsetsWithInfinityAndZeroInsetValue_0_inf_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_inf-0-0-0@2x.png => testInsetsWithInfinityAndZeroInsetValue_inf_0_0_0@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_inf-0-0-inf@2x.png => testInsetsWithInfinityAndZeroInsetValue_inf_0_0_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_inf-0-inf-0@2x.png => testInsetsWithInfinityAndZeroInsetValue_inf_0_inf_0@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_inf-0-inf-inf@2x.png => testInsetsWithInfinityAndZeroInsetValue_inf_0_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_inf-inf-0-0@2x.png => testInsetsWithInfinityAndZeroInsetValue_inf_inf_0_0@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_inf-inf-0-inf@2x.png => testInsetsWithInfinityAndZeroInsetValue_inf_inf_0_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_inf-inf-inf-0@2x.png => testInsetsWithInfinityAndZeroInsetValue_inf_inf_inf_0@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithInfinityAndZeroInsetValue_inf-inf-inf-inf@2x.png => testInsetsWithInfinityAndZeroInsetValue_inf_inf_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_10-10-10-10@2x.png => testInsetsWithVariableSize_10_10_10_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_10-10-10-inf@2x.png => testInsetsWithVariableSize_10_10_10_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_10-10-inf-10@2x.png => testInsetsWithVariableSize_10_10_inf_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_10-10-inf-inf@2x.png => testInsetsWithVariableSize_10_10_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_10-inf-10-10@2x.png => testInsetsWithVariableSize_10_inf_10_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_10-inf-10-inf@2x.png => testInsetsWithVariableSize_10_inf_10_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_10-inf-inf-10@2x.png => testInsetsWithVariableSize_10_inf_inf_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_10-inf-inf-inf@2x.png => testInsetsWithVariableSize_10_inf_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_inf-10-10-10@2x.png => testInsetsWithVariableSize_inf_10_10_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_inf-10-10-inf@2x.png => testInsetsWithVariableSize_inf_10_10_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_inf-10-inf-10@2x.png => testInsetsWithVariableSize_inf_10_inf_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_inf-10-inf-inf@2x.png => testInsetsWithVariableSize_inf_10_inf_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_inf-inf-10-10@2x.png => testInsetsWithVariableSize_inf_inf_10_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_inf-inf-10-inf@2x.png => testInsetsWithVariableSize_inf_inf_10_inf@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_inf-inf-inf-10@2x.png => testInsetsWithVariableSize_inf_inf_inf_10@2x.png} (100%) rename Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/{testInsetsWithVariableSize_inf-inf-inf-inf@2x.png => testInsetsWithVariableSize_inf_inf_inf_inf@2x.png} (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testShadowing_ASTextNode2@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextContainerInsetHighlight_ASTextNode2@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextContainerInsetIsIncludedWithSmallerConstrainedSize_ASTextNode2@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextContainerInset_ASTextNode2@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTintColor_ASTextNode2@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_0Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_1Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_2Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_3Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_0Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_1Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_2Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_3Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_0Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_1Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_2Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_3Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_0Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_1Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_2Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_3Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_0Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_1Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_2Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_3Lines@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testThatDefaultTruncationTokenAttributesAreInheritedFromTextWhenTruncated_ASTextNode2@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testThatSlowPathTruncationWorks_ASTextNode2@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTintColorHierarchyChange_green_tint_from_parent@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNode2SnapshotTests/testTintColorHierarchyChange_red_tint_from_parent@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testTextContainerInset2@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testThatTruncationTokenAttributesPrecedeThoseInheritedFromTextWhenTruncateTailMode@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testTintColorHierarchyChange_green_tint_from_parent@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testTintColorHierarchyChange_red_tint_from_parent@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testUIGraphicsRendererDrawingExperiment@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testUserInterfaceStyleSnapshotTestingTintColor_user_interface_style_dark@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testUserInterfaceStyleSnapshotTestingTintColor_user_interface_style_dark@3x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testUserInterfaceStyleSnapshotTestingTintColor_user_interface_style_light@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testUserInterfaceStyleSnapshotTestingTintColor_user_interface_style_light@3x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@3x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/ASTextNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@3x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/UIImage_ASConvenienceTests/testRoundedAllCorners@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/UIImage_ASConvenienceTests/testRoundedBorderless@2x.png (100%) rename Tests/{ReferenceImages_iOS_10 => ReferenceImages_64}/UIImage_ASConvenienceTests/testRoundedPartial@2x.png (100%) delete mode 100644 Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testForcedScaling_first@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testForcedScaling_second@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testRenderLogoSquare@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testRoundedCornerBlock@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorBlock@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithSpaceBetween@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithStretchedItem@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineFirst@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineLast@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testNestedBaselineAlignments@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testFontPointSizeScaling@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testShadowing@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testTextContainerInset@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testTextContainerInsetHighlight@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testTextContainerInsetIsIncludedWithSmallerConstrainedSize@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testThatFastPathTruncationWorks@2x.png delete mode 100644 Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testThatSlowPathTruncationWorks@2x.png diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 27ffc73b5..6db281328 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -337,7 +337,6 @@ CC0F88621E4281E200576FED /* ASSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = CCE04B1E1E313EA7006AEBBB /* ASSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; CC0F88631E4281E700576FED /* ASSupplementaryNodeSource.h in Headers */ = {isa = PBXBuildFile; fileRef = CCE04B2B1E314A32006AEBBB /* ASSupplementaryNodeSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; CC0F886C1E4286FA00576FED /* ReferenceImages_64 in Resources */ = {isa = PBXBuildFile; fileRef = CC0F88691E4286FA00576FED /* ReferenceImages_64 */; }; - CC0F886D1E4286FA00576FED /* ReferenceImages_iOS_10 in Resources */ = {isa = PBXBuildFile; fileRef = CC0F886A1E4286FA00576FED /* ReferenceImages_iOS_10 */; }; CC11F97A1DB181180024D77B /* ASNetworkImageNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.mm */; }; CC18248C200D49C800875940 /* ASTextNodeCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = CC18248B200D49C800875940 /* ASTextNodeCommon.h */; settings = {ATTRIBUTES = (Public, ); }; }; CC224E962066CA6D00BBA57F /* configuration.json in Resources */ = {isa = PBXBuildFile; fileRef = CC224E952066CA6D00BBA57F /* configuration.json */; }; @@ -867,7 +866,6 @@ CC0F885D1E4280B800576FED /* _ASCollectionViewCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASCollectionViewCell.mm; sourceTree = ""; }; CC0F885E1E4280B800576FED /* _ASCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASCollectionViewCell.h; sourceTree = ""; }; CC0F88691E4286FA00576FED /* ReferenceImages_64 */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ReferenceImages_64; sourceTree = ""; }; - CC0F886A1E4286FA00576FED /* ReferenceImages_iOS_10 */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ReferenceImages_iOS_10; sourceTree = ""; }; CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASNetworkImageNodeTests.mm; sourceTree = ""; }; CC18248B200D49C800875940 /* ASTextNodeCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASTextNodeCommon.h; sourceTree = ""; }; CC224E952066CA6D00BBA57F /* configuration.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = configuration.json; sourceTree = ""; }; @@ -1407,7 +1405,6 @@ children = ( CC01EB6C23105C2000CDB61A /* TestAsset.xcassets */, CC0F88691E4286FA00576FED /* ReferenceImages_64 */, - CC0F886A1E4286FA00576FED /* ReferenceImages_iOS_10 */, 058D09C7195D04C000B7D73C /* AsyncDisplayKitTests-Info.plist */, 058D09C8195D04C000B7D73C /* InfoPlist.strings */, ); @@ -2241,7 +2238,6 @@ buildActionMask = 2147483647; files = ( CC0F886C1E4286FA00576FED /* ReferenceImages_64 in Resources */, - CC0F886D1E4286FA00576FED /* ReferenceImages_iOS_10 in Resources */, 052EE06B1A15A0D8002C6279 /* TestResources in Resources */, CC01EB6D23105C2000CDB61A /* TestAsset.xcassets in Resources */, 058D09CA195D04C000B7D73C /* InfoPlist.strings in Resources */, diff --git a/Tests/ASDisplayNodeSnapshotTests.mm b/Tests/ASDisplayNodeSnapshotTests.mm index 8cf7c6a6d..964bbb50f 100644 --- a/Tests/ASDisplayNodeSnapshotTests.mm +++ b/Tests/ASDisplayNodeSnapshotTests.mm @@ -84,11 +84,11 @@ - (void)testClippingCornerRounding #if AS_AT_LEAST_IOS13 if (@available(iOS 13.0, *)) { [[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight] performAsCurrentTraitCollection:^{ - ASSnapshotVerifyNode(node, ([NSString stringWithFormat:@"%d-light", (int)c])); + ASSnapshotVerifyNode(node, ([NSString stringWithFormat:@"%d_light", (int)c])); }]; [[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark] performAsCurrentTraitCollection:^{ - ASSnapshotVerifyNode(node, ([NSString stringWithFormat:@"%d-dark", (int)c])); + ASSnapshotVerifyNode(node, ([NSString stringWithFormat:@"%d_dark", (int)c])); }]; } else { ASSnapshotVerifyNode(node, ([NSString stringWithFormat:@"%d", (int)c])); diff --git a/Tests/ASInsetLayoutSpecSnapshotTests.mm b/Tests/ASInsetLayoutSpecSnapshotTests.mm index d6047d35f..99ffa6e82 100644 --- a/Tests/ASInsetLayoutSpecSnapshotTests.mm +++ b/Tests/ASInsetLayoutSpecSnapshotTests.mm @@ -36,7 +36,7 @@ static UIEdgeInsets insetsForCombination(NSUInteger combination, CGFloat insetVa static NSString *nameForInsets(UIEdgeInsets insets) { - return [NSString stringWithFormat:@"%.f-%.f-%.f-%.f", insets.top, insets.left, insets.bottom, insets.right]; + return [NSString stringWithFormat:@"%.f_%.f_%.f_%.f", insets.top, insets.left, insets.bottom, insets.right]; } @interface ASInsetLayoutSpecSnapshotTests : ASLayoutSpecSnapshotTestCase diff --git a/Tests/ASSnapshotTestCase.mm b/Tests/ASSnapshotTestCase.mm index b6530b05a..ce50b7cb3 100644 --- a/Tests/ASSnapshotTestCase.mm +++ b/Tests/ASSnapshotTestCase.mm @@ -16,13 +16,6 @@ NSOrderedSet *ASSnapshotTestCaseDefaultSuffixes(void) { NSMutableOrderedSet *suffixesSet = [[NSMutableOrderedSet alloc] init]; - // In some rare cases, slightly different rendering may occur on iOS 10 (text rasterization). - // If the test folders find any image that exactly matches, they pass; - // if an image is not present at all, or it fails, it moves on to check the others. - // This means the order doesn't matter besides reducing logging / performance. - if (AS_AT_LEAST_IOS10) { - [suffixesSet addObject:@"_iOS_10"]; - } [suffixesSet addObject:@"_64"]; return [suffixesSet copy]; } diff --git a/Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testChangingTintColor@2x.png b/Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testChangingTintColor@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testChangingTintColor@2x.png rename to Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testChangingTintColor@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testChangingTintColor_modified_tint@2x.png b/Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testChangingTintColor_modified_tint@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testChangingTintColor_modified_tint@2x.png rename to Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testChangingTintColor_modified_tint@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testTintColor@2x.png b/Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testTintColor@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testTintColor@2x.png rename to Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testTintColor@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testTintColorWithForegroundColorSet@2x.png b/Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testTintColorWithForegroundColorSet@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testTintColorWithForegroundColorSet@2x.png rename to Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testTintColorWithForegroundColorSet@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_green_inherited_tint@2x.png b/Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_green_inherited_tint@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_green_inherited_tint@2x.png rename to Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_green_inherited_tint@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_red_inherited_tint@2x.png b/Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_red_inherited_tint@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_red_inherited_tint@2x.png rename to Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testTintColorWithInheritedTintColor_red_inherited_tint@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png b/Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png rename to Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png b/Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png rename to Tests/ReferenceImages_64/ASButtonNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomLeft_inner_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_bottomRight_inner_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topLeft_inner_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithInnerOffset_topRight_inner_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomLeft_outer_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_bottomRight_outer_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topLeft_outer_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocationsWithOuterOffset_topRight_outer_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomLeft_center_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_bottomRight_center_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topLeft_center_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_childSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_childSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_childSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_childSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_fullSize@2x.png b/Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_fullSize@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_fullSize@2x.png rename to Tests/ReferenceImages_64/ASCornerLayoutSpecSnapshotTests/testCornerSpecForAllLocations_topRight_center_fullSize@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_dark@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_dark@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_light@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_light@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testBackgroundDynamicColorLayerBacked_light@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_dark@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_dark@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_light@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_light@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testBackgroundDynamicColor_light@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15-dark@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15-dark@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15-light@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15-light@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_15_light@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1-dark@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1-dark@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1-light@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1-light@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_1_light@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3-dark@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3-dark@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3-light@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3-light@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_3_light@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7-dark@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7-dark@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7-light@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7-light@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testClippingCornerRounding_7_light@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_15@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_15@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_15@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_15@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_1@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_1@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_1@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_1@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_3@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_3@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_3@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_3@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_7@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_7@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_7@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testPrecompositedCornerRounding_7@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png b/Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png rename to Tests/ReferenceImages_64/ASDisplayNodeSnapshotTests/testUserInterfaceStyleSnapshotTesting_user_interface_style_light@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_dark@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_dark@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_light@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_light@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testDynamicAssetImage_user_interface_style_light@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_dark@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_dark@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_dark@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_dark@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_light@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_light@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_light@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testDynamicTintColor_user_interface_style_light@2x.png diff --git a/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testForcedScaling_first@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testForcedScaling_first@2x.png index 896dc7abf09a39cb792b6ed956e39c11b3019f20..d593e113a35ca4a9eca6dbbdde998c92b4e6d40d 100644 GIT binary patch literal 14720 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 diff --git a/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testForcedScaling_second@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testForcedScaling_second@2x.png index 79d4c747d8c8e64eb0e59331496273a629dcf77d..f85d1a9f0200f8fc1b3a8bf170076c867ea1e107 100644 GIT binary patch literal 61702 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%0APP* z;mOo85ehQtCeWL9Cm*5Ia$p~-P*+ygD!C@LZE#gu(RfCJd;A4xEc>Rnn^*{L-FIOi znHXwYq8P|J0|xRY!SvXQ>nvE}9u?2i>Iaf*q&r|B*D-$v`m!^NS>N9g7fF+6Bf({2 zRabKd$oF6$qME88$10cxfUM>Q?|?rkftL|ILf~dtl?=U$OZuj zlVt(NnxsZ@6@#z-ls=K*I_|A=`K)#@o5%N6?@^2bn;w>KvPj##K?+i_4*|&jDogkM z%4H}35zB*x^u&$zDz3{<0gsKiu}YZ>>ZZDgUS@sB%Ie;h^vu0A!*t;B3wTHt0uW_m zslx&_AukY2|I{X$$Fs(x zRX$L!o~ud^5HzU9X-qZ$hoWyyyM;3Vjzxe*F+)Xr3zWmHTyB^~GX=y18lI)0=c+i> z##2}lub^a7d<((`-<9)D4Z(30E15k@O#3C^7P%4k$Uv0T3IM2>W0VkES%U(51xsu| zgVCm^f6&~smK_jO4g}Sejb$JJwcLdq<9eDe-p4$ci!rdu=d0fgvmC>mc)4{htdh(* zdoTTxA{=P^8Z`Xn;mvzh_eYPz;3DG?w!Iz~q4vwrUOQ7@At#VBAEWr9l2g337L1S5 z59*C40HJkGSKQoJvc8uAmZgA6A!9bzc$C{8q#8OqpuPfyY>6u=CdZsl9AharxjelP z5IF<)Qdew8LQ-7_***6Y zUwIMmP}`GT{C*LOX9=yxpHSA7Scm-c4mfHaFe(C#m9dZIslS-AvgAetM1HhxNj1f! z@D10?N3Bo@6nwh9)b{~A?YswceU7Xk{Z0XZ5a5~<1HZxQLahJ2Vzh|YX&f*6Z+LCKAkVFqKV-l>Ls{tQHm zNJH#{PP?bUQq)}S8-BBx-`>t~rqkpvi@^Eya$9-8;XPJVdhY+40~SxldSu~W$UV5c zDMkPd|3(1t>ZGc)>W$2eAEW@)uPlx|?GwhZpSoXigum78p8vu~tm}3pDZL{}C}Hj^ zJCV7s-cagxU4n95M!nP3xROs%Trt>pDzrKSuZ6l-$ismf>lBR9S?GqfJ{S3NuKN

62f!q;K6HE0rv)OeR1r98J0gK9H zp?&97O9S|JX@&B{fSSX)Stk~Pd{^;!GX~T-0+3MHsnBzK10F3gHctdVrlMC?*u;z+ z+obhM)_fN{9DfNct?16C$`bIeKqp6g1F3eu1ohafprR!t0P(1)tOq7VcP7C?EK_}N z8(^{oT6&{;DEaR^Xqg8+fkfd^JXfhr1`|oKj}pFD%;H(qEXAhmKF|O^eEl)bbyXW+ zVwni8EW5`F7BQJ{{kXT^a*vk#Tv?ms#=>}bR_!@lUC7>n!vhp+M8VeVe(CAvbk@#z z+#Pz!#W9lg~mTpz%QpLKfU~pUQ=^W7&?HL(d@3&;16*Jc2Hou?!elBwxOjTK3 z2i^y5t~MDGDDYPSkV5jbw=$7)ncVL+9c5Zqw1mV&RCK7!tmY}E3*Wzj&o2QuicvIM z7z-(ux(fHz>Ha$pS|6})i(1&p?XZ-m01x%Y*~O$P;(JRP)2^gps=2MfC;-Im?@@bM zXNrYrkUc}L{>|j^Pr*pAbqg@XEigyBzl$1Vs!fO80@t~*s?=!FW8(2+ap`23RObG4 zfLWazHqyxSMT%$dQ9Veg0Ep+Y@KvNI;l7%tIx~uu*WvXTh#}Iu!Dr?lfu|YW8C6LF z$~%WjKaW*87WPrZ*i1a+L#XCcr0}+=IFSV)%DxiK24pVdd-uw1Mf&Xy6w4B7Kfb1b z@LXaaon?91xChEbk80@MUv?rc)}CeX6v23f$?3Re0q&uha9 zugkyb$y|?eWgSjHojLLr{`n*o6)J0p`)s=`w@ft`Y9Dp)K6{q7d#s$5XdQH%XyW4X z*)WaGyVw&XRhuo*;zPaTl2|`4DYH>)%yS#>$+8dh_jC=?F{*K4-M@vt$fQ-$78$F! z?cT(2>@OWtC1vG46nGL)H7KdNugj{mHy2qikuBlI3 z4Nr;HWkp`w*X{v`(t62?8`2!m$K_aP{ny @h)8kSpTI9FnV2{(aqN2OgD!hX=Ik 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 EKaIPHhyVZp diff --git a/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testRenderLogoSquare@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testRenderLogoSquare@2x.png index 896dc7abf09a39cb792b6ed956e39c11b3019f20..d593e113a35ca4a9eca6dbbdde998c92b4e6d40d 100644 GIT binary patch literal 14720 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 diff --git a/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorBlock@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorBlock@2x.png index 0cc74697a6c962caaf7d753f2a0b470b0541100b..77cf9afb66ee3c5e0b025c0b04b92f53a2d07e18 100644 GIT binary patch literal 1543 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>sYs3RO!M_+ z&;qhK7+4sk7+66{fY^>v8qRiO)L>u+i!(7Wv}ZD~K-KsGX%LtI#2`Hont1^uR5eg+ z0TW#Hi3Q9EHb|T2wN?`##aZAHSB|Ursro{jMqkR*jfyuBElnmdF lCPGpIa5U3Vp6Na@*#C;$W&Eq>1u!)-c)I$ztaD0e0sz9aE^Gh* literal 363058 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

38&auRyF;}%!fg>f z(!(Mt(mqU2g0s@2TJf z&0egcLpqdqIZC9ue|n)WIAVgQ*_l&#N=v_j8$#ZTv5`Hrl~L$hN>%$gaTdab)cpcIK!0&Rb8`Af=D; zLb}r!G$qpz88x5I7r_AxxvyGYQ7?qlL1srh%E#6t${1<1OTW11VcIf#ObT6%ij~ag z#G1cx`k1O1g#{S$Ml*pb4&F-Y-wXGDmgJcIAl%Gin`Y5lo7|GcT+#mXgGB~~_S-k~ zTAuBW8uI*6Ap;0w4_4qu1ObZX-7P+xCs84?!N>*l4ROpG>@I)_2nR|ZXdJe;qZJdN z{=F>O#Q^1L$k1+L-7@|ege_FW@<HRVzq!eBY>L~>w4vKCnGGYjvY{c zJg>*H*d<*snmQkSyhaIxnQ)$EI>KG*z^{nul-?`r`&YZ{S^|`MRQ%ng0a%_~_M74! z^KI!y)dz(b<+k^4Zfwsw1GaV=1BhcZsGk|&fu16B)^4St{Dz^Fu-V$NL6KP`r-@{U zLJ&kVF#EsurbN3()nxC!h!lX{o2Sx6HmxXaRY^ z0OcP#@Mmj5pK7o-j`pm;Jp_t!?|BCrThQz>b4ktHLyKk#)XWx<&A(-i-c6&ts6^!=VnTeW<(5ZQ-#`y6@RiZK|J-<07#HUjdlYYx zd&C+nNY9XLm<Y$Dx?iLQZ zOCjQE*0NQO(xmn_Ize{g6(`XI-XyVAgc9;|K}t#;4Y^w73`A*Ba8O&(8uX?r4os)G zb;!>A4Rg56te~ZAs_dd1%p0u+LL(am-16P!zEmCPAcH@|(Q^uOVlmc0r6uJnmWazv zHN7jhjc(ykGEblbxBa#?VMc#})MMh~+3WIyt-#3E+^lS>HBHmuL$<3e%_fh zaxuT(W)SFD4jwmtSuUx<%U=9n$YT8OLSw13Z0{qgZYI~JYIq$)e4AnII*a+D{JXixIO~ERGF-xBy4u7*^EAfQ|giao09c!-^Y5w6mCXNdB z)Qth?*uW*=@^Gb?rfl5HihYm$@K*KY?SQpk;38 zTWJb>z0*gCaVc~jZ^)k`y=%Lpu*myT2EuadKRr$h9!<>&&N6v*lGx(F+;B_Bk&eHU zhC~+eK#cR1>%=x$L-uAQg;HnrY?1THD6iTFuC{@X*!XWz^JO2Es{)4N{?ky#Jk@_0 z%BM)oZ#6_f5dbOi(@_}iC|lfy-Te*dgF(h!*;@Kr7O20L}BVUwk9n(<9`_s{^KhN!Jq0Y*ay&)xFp%Z@F-d6O+_)zvw_i<=62wWsKoy-t{iVTW;5c&B2 zr@6xx4bGZCJ$3cEA{Dwd1@yM{C>_IB60ESM=5YrfB{O=<~dOB?o(EDATid=Nn) z*V?hi&l;d~ueM)BWAiuK|KPg*dq=-ZaYBCJjD53NV?eNYL#7l5H4|zW=&hr-@(fm)}u6(BbRQLjAH3^zv3Q|-_ z#EZuj^W7zU-WBjM6Cg1m+v!nHxc;H{D>qVk;jYf*{c%hg9>5o*+!xis4pE9HyG&4g zg5%u3EwV#5GxyWY=r|Buq}veM0KK+b``b!$3wPGkV4yuIpdl3=$`uT!d|l9GsAa-&$T!;YjCyM)A#N{d>g3|FF9fD+;O+(U}HO zZm#gy#a^}{sVPXjh1m%J(J_0y371egoyJM6ZNJalD}p@Dw*IkcQGC5k+nirmE`^jN zW-KjqT|eq44{xoIPQfizTmqsBSH1LF3V_EBf=b{_fK2WWN%?B>>+;x17m#2xGm?hI*Wp z>JkPsrDsj&dr!nekD?x5$m7cylEg}%>|HB$8qv_-vJGKRd&LHx)sJBuBCPJL$7p!4Agx`=ExQ6M^#1$AtMKUykE|Mvd4aaI% zLT(_3AJ_qfMUHblVr*8a6@1`Nz~2KDPRzt+nXnfrsQ6YYY{%A4=btWeX6*cl5#$0G zL5nlm48ZA`NVAi^y`cNjc5lvz+0?!YN23>%S zJLp)~6z&?YVZ0qL+W2geSm33rFp~MkZ=A}lG!nv-DBxc3m%bSQ7fjWs#@4zT{_1M~ z7Dk3)vY2}IMMlfGzob0Ffgo zWaBJiTQZ7Ux2arK>kJ3jc@CbQgweU!o@j#kGVS3LIXE5B?4*ufce+g`i`j`hdORE0M*% z%ZBikkQ*wq+v}E~KLtv90tws0Zk%O{QVRy|uyTrP>o&p7=Z+Q)Zl&X~+0n;AwEW3B zV(HU-&h*ibJvV_X>_HS?@6f01QlfV0EkRY>PlKdv%`XC?$mDBsJulhN z0iM01w|Z>d3c<=T%@RrlCfV!Hkl&D_$T8$NJx9>o!LU!$GnGsbSOYW~Nbe&K zJW(}-FNn;iXqDYqwZ)o23|DZYU6M0D0wL)c%$rVw7sBz;Of}f+ z$MaU)UV}LD-@V3uz&0AEcQe}lOVmDK()N~JK0s1VI=k$;oqip3X@PO5`-e_zPNngJ ze*d0cKkvIz21UN5MyXxqM#hg9D-+q56^>eo_Z>gH4dyr&X^1-;|0)Kgko$p3tPmD! zZ!B$HnKcYr8>z0?O38QiV`usV2A%u9aqVjes5}XkIi1rbi+4&$y20&x=Qq$Dx1AA( zzJ;2P9fa)%<}Jo`#I=CX{YnwH6+Ynn*q49@^m-NpV8X9G87+49>Raw8WXB~4`3Z33HYTa^N{vIw55=gG8;e^G`ucHjkboG`#F~eZjOz zGU7L+?*+nuiggEVXTkO5G|qoUcM!I%VbD_I4Jwc;+N1)bPw9|F2Xu2s26 zrWbrcg+}+{{?84Myr4AR{mZ`ZI#%p1_5F;G!9%pNIyp(Rq2s_P9Jxg2S$>LFw?I21 zwf-;Wd;6cip$158gUr&9BOTQizHA!;6@__`X3R%Mz}`x8B{{v988mK0%2}p?i*@{! ziFnE0o|v~;H)d|JHW0&MgowjHag29^jTb6H4o9m^-`k3-%4|iixTO>qLOyc=4V=vv zN3l#mZ4O|f z!wF(;HH%(|gOyZs>0ZWD^?LwpMcFM0|2pDffQN|K#j*ySlqx3DNrcwR=#F#NsiYj3 zZUOPgTYIlP4#1s<88n!lE)TEUr&pZpW*ik$&`KHbnp?>ENeu!jBOoMrJB+Vje>3|{ zW>F&X%Iqx}3Nlx#U$qT@Hhw&a7lz@%;aIolwd3%4b-&NdrXLv;ielzQYh;+A$SuzJQCzYV`7|>6{-+;DgLXrelyra~&H)JG`K(>Zyau4LI>*#% zJtOvZ5^YvK4WeE>2p9bYozkdn8|iE*lEJTa*+MY%@2(7Yn;PLsUoPD(vRN`TX)NCe zZTv}dke_-b4Y`icgzG(3r24L$F*nP%azP{GjI4D|G@hv)S&zli_9&O-D41a4{h2lYVOiHVTwah}%H(lZp>@JALAY z(QjhRT`AzEi5EF5NI-B4x>?X?b(}!!wd1GOD;ny+Qb9TICkx7UDkB>6KbHN2l)RH9 zR@#31@itAcWR}3kMl6loXbqI`Rmn+N7h*+wHGX+#{;=q0xfCPo;eWpZ&^Dp*lN;Qj z0e7Jh1(&~B9+YN0ByaSG)Z78Ru%(-)e%;3dTRGToELc1?2JLYFAUgarP64H_7U7kJ zMFGGuPw9uXyHI=akryIBc~&aM1BYvl1k{qo*Kc&v07!GboQqbEh8nfL;#6?F!?B`< zk1+s3O$ycgphJH-))*=J>=F&%xUd_Ctels0*d6YgEW7FQMJih8TXMJw>-6PD#Rn0P z8}YiAPr5+=FB=Cbg^&q&3I5ZUe`0PFUh!x=;fno{3E&FkF(*Kr_E&cHKkuui8uUT` z<4Q6H9lPO}?H)GZswt3Q*5NxTAD834G@J4JePf_wo)ut*Dw#=3~kuwrn^XcCG zXITP>q|l^CrNk?5QqPhp$-fG?alfMks9OP{i4}$RuhRKUR%EJ(KgtOs%MieigZolgErfrll%k5xRf)|o=8f#p?>A`nRaT%T0(O?sOil!@v`)S z_-Fn(oiF&;6~y_pM#BKj_rzzQ;V#-@D}E|?@tD(cw6kV;c0K;(%JZLIdCd4Yf8Tr) zODwwH#Xs8e?N>S5$s38n-mVP!vw?6WQEEmKd6po79{%JFsN;YL_BTM0BjFb>AK0Uvxu$PaNxI%3n^YW>T&bEbg|5|Sw3UwK= zp=57i;6(6}kIy@$L5$kDtn}iG1rJqwE(7B?JeF@ti`ZtG>aTXY^1SRrfKDU7T=n(s zv^S{8{T!Nq4FmjxrV;B;;le`h1~|w8IfOYRN-mvtk&@;({JRUni+2Yls-M_gi8dMS z7vD>ndOYQBu1<*0ay`!kL3G!6xW0m@MSkeoqnn?dHS}HA<@(dJ$egq%0)P!q{rV}V z9vJgd_BXX>-@kQCx`i66_dHUHb$rtEyyiRaXhlo;N;9=PU7)Rfivk`F1Q z+;oR=Fp!r|JSnNku4Cva16?>USe(sr2!$VrUh3%RDuM@C)l}8R#$9Z-&&%hhZ5XrG zqj}m-y>QsS09mPQPYkbTe{}v8)eYS+W%39VWo*l}A>6gnjYJDr+FNX03z07Py;`zv ze9Ta1`}KB4C)i8wINonx%+l)GN!wZFS6Nwj7{oWbYE{g+UM?-GF?#y0xD*jvT0<<1 zyQA`|zR;LNW;KOe7jvm&IkSHa_38&+l}1b6H|e>F`%*B+m%6K#wOd?Mo`lka_8 ze%&y6<-m&4Oo$vBFiP#t!1z3>TlV^)H`j(z!idTmri`acfL$wr8yf}7Gzj8;q~!kf z(}1z(N>{DwN3V;&jk*nG;pn#*`>msP%ITJlZqu7(+K_Z-b*1$3)ce@X7T30gHjP_v z?IUEb&qu9Z>iU*;?*B3N6;N4b(b_Z$AE43=21ti=et?Qf3VcY%(9$8DQVI$vAl;%! z3rM#^E2T(Ecb9bh=LHmWy#Kvxxn|9pVaYlB-SO;w_TG;{y4mdbpC$`Q()VKd+3=bAx%)7VL6p^sVd_=2yC?ar4H zu`sw-9k4eHT~yVWU39k)-SiWF6>AsnMZ6-wr>x)&R-<=jO=@m zYZK~H545BW*39JVQU^GHu%y+EDpXclJg~da+}(%3apjc0cXwX0arC7`13fO~e!kEz z=}Pqc+#!#(rEPi+ktlV$24ZCBr-8=2!5W`Zpf3iaoabh;nB_Xy1 zb)Z;JNpg$1hI`}i-l7U5p8UBofkZrDn)qIjm1VRILA;Y<(~yd@y!>$8MTvj9kuqYH zo5=EZ7Ey$~o_X)UJ7!jvi7nnF>SW;#B|pW3pvtCSpWYMpjN@2u!MA_p#>I0^#;~wh zpFeTJ#?v%Z4*Yr|(mU2OC}G0I&7+-h6o>5V76o+9g`KG2e_b>HDqS*tZyhPURJJ+J z1P>nN;@FV-B3juw@ARk(z!l@z@d@Cwh$Fmi)TJu6OUg%7F^CEy?1<15mhfX&vm`-Az!Db1U6DSQWDY4giEmOxWZ_GVaS+uZQGX{Kp+r5~k& z8_2o(VVm>d?+vJ5k|2s;&U$8JQfC`+NDv|Nyz&{aD?NwOe%}VwM`4DK;xkUw z^H~9KWJZZ*k!=#2$?1=qzEkX?ts@uk%+A)e`o+f7r6QD_&_!I)+^{A}az-DXZ>S{F z^vZj>{%=yK$2Yv6{tI$p;ReU9*YRl7@B^-(?)9a*1SH{GW;dV z`Wwd@TY`p|=y{*hDH7Rm$KGBg>nFZocfwH6X#PH?$dk>?nrbYBz2IM3p1^-!wi}3*CgS~mE6sm z@oN18&C3(#xG)h!5me(_L$^w9Ex2@S)r5LvTLTw6WjXZUpihi zjw-lx-^kL`E}wg$?fp}swO_>Sxe7u*pB-y@ zNk)xXs)RBd4KY~X!Fkj(7^m;l)|LBWu3z=n@b94Ukf^i5S-DQ|g-^D^qbLG`GD zq~YUuzf&dSnn5BTZ@ZZQpGw-5@2YnV5Ynql{jg>GfQ^D@a=_hJ0mTJ|*e(gtTkqpBwMiNJ#~}ww$;fVLgq@zu?q6h{Mn#Q#N!Mf6K=>qhy&)T4990{Anszm45hrYv!s9PCq&Y5f?WmGTRJ^u z;)s_Z`mwO8;u@Dw4EK$LkCS){d>mC2(v3?`<|0OPp*XH6U%5RDe23S9ApgdQ@q>bg zlJ!<+6ZgVFyzeExs>kW5MwJ+}-k#hYx#(+6*}M)KdBp|uvhwt!xBNuHeTy;q z4!YZg3NY0Mk(v*)dC!8O&{HtdF_83O`5a?Ob&Wid_JIp|l9 zY`smAXcsUx@Y_332ZMy9)0a@^R>`)`bK!jtOkb3a8SRuVAkHi1s&Q?jp8E+Sr{P8v zG*CQYSA%f2iH=UVvLe?R_ zebD$vD{NHg;^~KM_aYR8Z{-(%9l{3o)WWk~=#vFBV;WiM$N6Wj3c^DfZUTKcGF(qq zr<|{zvBKQTX8@GhF-Xa?1v?wM$Jb8mkP+D7PFVs!Rw{PeeM9|3USJYgj$bF`PMs$l z)7jb+#|Eel`o;>e5CiKz#svP?;G}f12JxVM+yeeSqz{EJ!bVz*IwsOei`TDF>EVJ% zdBNtE#2pVh>R)RAQ|I$bi^D*sVrKoWVlL`ic8*5yksPZ-Nprys_dl)d#vEvR0Ki`l zxzY%+*s6>(3X}T}@Sa8B2LnT7me)PnQ_|84!o~(45Bl(kvsh?>oRpm}swVO9w(PIC zqNWG@UQ9PJi`H5(o$8U7o`L?8$L5U&VuHQ0gJyu1jH*XF10>B4lunaPyF_Bl>lG?M z1#aC5kU9)xTq@*J*4TMKWhC)+^tLMak{yJNf~@=@X67_A&iV>xoDMAS=#C&8`{#{= zj0oGY5VAOrW5XCW*8g%tn&TT1L|EJocTgu|Vy$@5V6tL5n)mJlp#Zt2FHs7k=;{y3 zsbocYKj{{7`1a6`+dqFjlooOVx7T`mDrq(+KnkQRgO@%Ckl1UAocJJ?zn#ORE``S< z{fwmB15wRF)S=ry0R}+s%)lDwT^R)M%BIcU`_WF=fl!og*x~JjUvdWj@~Q#YJVPD5 zo-$Fy%NGp+QcbNaxW1a9ZGlHQ39w5b89RZcFCar`-x8}l3b0=Hb-~wQ^XBt-a7Oq# zb+}eF<{*|5KOl;DWj<@LWh0{InI0&$=J+fW^7SF$-aA7E5@ z!~Ba^;4B3W={d1AbO-G1wKM_(A-M!o;80ee;)LZivyxMs9dCo^#f4yH?G?M0gxOy% z!4uc6{v>7aQPCiCwPtXz-ys0H4hQY^cMsz-Py7Lr(sVWw68^^Bn_^0yFy`Q&UKGa( zq~6GCEU3k-y${J$b+%Z8X&a|9pZs|!BA1XnOQ&U9Sa}KS25da#nV4*O>=(ADo_dj6MoBeMty;&`2sMRuhqi=RKKX zn9E`ZhE%g1FLhd6@oMF(e&brnxJa;0XeSC%>4B#A!MB&hOp}#S9ICosjCN9kG<3os z2)KLP>%rZlbWwHJ{C$`NudWZZJp1|E;n=WGG}`JK57)?2>gK4ruQEZF%PtJva&hos z)#gLt_{>JQ2T0w%M!idF590BnA1ElDax6^=%6E}!rRN!U#mO9sj2-56h)U`Co zBb-cV8{9GbD9k<8`mg5~j}O21tw}Krk@y+b08j^p;L=T$r8!r8f+uHyV^VO~R4ywu zns;iN&xL&Ae{K#RnTVPWoffyFPG{@`k&n3#|4~Kpx@jwi763l>;~ZMPKy`MNT>Ye( z1S406=AwRH7?LBt>OXn6viLR$0~3JUZJs~pCG#NtH#(9zC@4q^z(I8y0(=v%+r ze5_K**a}i*J$ovxSfBE-m#7`Oq)$p^RYB4MAz&|iQV1hR*JqZCsC`-?PF%Zx?+~}< z$Ir4KU0ZdA(~=OOrq80J2WzJ=#U_{CIWVGM^F8fV=A9Aza zpD#?9TXBxWbJTdkm=n4S<`8IJ1 z$UsMg>a&47(bj}LGEXft&f0U?2=buH0J~sKFnywuKoq5GHNJNcS5L%|H;qy6h3_zz zQV4sdyXF>;>*Ph$yslyr{RLdcpv;m1)PzAj`|rtKihSuZg~4qMX9!jpy?Gq}!o*!d#4%zBg|QS$eCnu*Nm@u}X9~Xq1LD@KG8xa=|{bcTcaKfshM73y5Vd z%9_;2G1X{m_JYRG+PTgu6eyH9DwRft48$=WLbm%~$B3~_HZ8wST5t|w{%Pprd%0Vf zDUakIuwCUDA8>zcBl%iVK0KkwdY*Lp(RG7&P>%UIdev1MSS3PayhmGXJK*{E7ZUKF z^@=0oo`%YACDWIb;`IJn)&zmn!SX|fOMQIACtN|`V#s2bO0J$_YG5N~Avs%)LxsO`Ebl+ocH?q%?n@Nn>AmwG;p#Tv-Brk$C z^{kSBgl?7Djsbx9V<~~!_Nyt);I^kn#t*82ppIIRn3L2j=r&ZhVwCLGp=R6@h?zY! zB@gggIw)M34x8C=q?gN|C7M zl7!w;yuqNu2Q>|Wrytxdf|MtZ{}I0cc^w{R&@UT?l(`)n6?!6UiVXK|hgyR44FMcM zRb$00=Gg{t1SBb0j)y|jEO1a?$DHJZi;`7fW<7l)u)MjsE(;FX1J$y)l-!K^1RbBb zN;I}kn=r*&Y%87$wH-uZ@O&=-0P95d9Zx&O@{s7Hw+kF?(w{D^}V3PoE-zPP7fFx^A%4*<499iDWR8Jx)BtTb(-`(4=L-Ja|Psi#riAyJ%RMu+I}v&z;p9YXB<@lV@4Gw5hXkzdy2aI`fR|) z2S+{1sa_F8WZ$lm1W#Sy(LrRI1wfTP!_EwqFVbOh8AE~Kd0_QjX@f@Y(dMbQEc%4WuhV7TAED@+0F|GhC7Bm99PMksw zl|2{t-ec#1#7g+9E~{0sy(-BqP;T3yXvP!*pNV>y!yXPwHk?n^g-&6B&gGN3TG9_r zAsNTRYtH8ogb}Mv-grr{2Rvd~=9kS|ql3ha5^tq7`6Y@M!ZYX2DSbwOr?Okx zw}CHK*x-Df^LG;2G3tJrY-o`!cC!)14Ah; zIOI|{1FPGG3h+P*JxDy*d?(BnwLp)`Hu=bEK1eEX+je4Z@qog^Wt=kNjmXX#@9D?Z zDF#J{te_3ChLp1Vh~ZD&zHU^Mf!}WJ!#=Z6GS#J;#qPnNn#S-JLu>_h1;vL#udorR zZw{Qz@^1n%%w#paStXVva4CL494I+UBt9tvL?l8rbyq9_5><_dOU`dT%rSLexdOR{ zWqk~-mfb1db`MZbD*E~MmX<1fr+ajb79ij|Ko_F@E1!e(&*}SjY;*s3PK_@-56))h z>;}-|W)k$cNu1sndGfevV?C1^JM^GK?*2sLmAX`kb{HgZ!pylV(~4<%7l?y%Zats@ z#Z89aUu2z63S^*UT`F?#w#a!(pO5A$2OZaG-4(y~O@1@XG@%X?G(*^g%XNMCtn?kd#U=r|01wZm zzAqVWoU5Qh4A#(+ZjTvjhs_VD#XFpN+XUx9Stkb%WTnr?mV#Ct+iqnMp4T`E5Y>q! zjRRvS>uyT?n~igeRM)l7?`%r&SlE`FR*e%;6(50T3$o_PJ?peQ9UJNfQ9R1vZxY^E zU%lO9(YDxz!*lln2CnBc_+NAra=D{xny!EVu^?#RDS~R?X<_}YY`4UFP;_HO--Lv;aX?R` z6a&#JT(9L&G;R%^j~^{hEuG@_>Rf*KmO5btHl-IMHr=M}9$J5B$Br?{$8G&@d;heW zUl{rk`?8n5{UEJQtf57<+hSTiEayW;A6%{Zy`{M5O_yXXOvFJY74THRkwJf|jZYp4 zetXjVT`{^>2Dd?z!8$v5(yR>ETY6RqKYSLSwGI_VZjw5ZPPsAckOEItvB)~!Bbcml zWq%>}bH7H;DQ26lCZGfzi^T=l0x$$|1nVS+VG4L4YMrE5`*8^r+dbv1O^5`LKp5)_ z|3K*jB-wf^WxZ=kTuq>=H?(z%r+BwI{Qwtn$$y|d6^p>U0e;_*@ ze&#g`cog(fWN?DPdOb7nIxSA6q;n|zS8dgc{p7uy z|D4Rv_wGO5-(GFDmTSLN0Z)8=4$X0*gO7P`ANt%bDHtx<-D`oq&}b)OIs!_Au^Wbv zCsqy&r!g#8Rn8W79)c>mf=1uPBjGWuJR^)ySe%*lm2F*+Ugr+8&F^fml-AY1BnOQ%)6Qo z${16BZ3$@}>Jt5#^+Sp3aTCYsnsd~xc}pUGs`4LWl*a)+igvp zl{sq*`jqWy5hcQ5V(a-E?e~psA^hW)X<}Ny)NEds;o3N5ceZR~qGaBhpHZW0804ue(GYJ}E6tm~q-300u4nZ#70ahSqbNET!%6 zJ`hwevY`GGli4Y@Ga7yY^q;t3H7|q@1zSiW$k!NHS>W1m@DTKQl%nkxc=;(2s(*iU zU&7j2_x}05YCPu8W@-M=c_nT25${^iRALob?TZ*GsAa}$l5)!f z83_sL@G!Vg4)f#VStQEqH9tl4U5dxZ|4 zPwTv4o^Vdvk8tFWE5u;>3x*Y5`8kA|kYxX6O?EEB-rJ*zk>jBlXsDJ8u&6-SgOJSp5{R;ROceSw<&BBz*QYQx8ZeUlzQn3w0+GRl2s_D4GFq&Gj5 zCF8U)Qt@o7xT0`-hObSiqwFEJO*u#VxA*r>Sk%d>R9@~5BbI5v1J;rh==a1jM8S?= zq(e7XJe`?|PD2`5k_n-7DfCood4S$Z+gC~9jT5C4^)h4fCpp8(*BX*Yyg3dtJF6bwc>;|db=DloPB z|K;c2J+qyYQ9cp$Y&bV!Z{3#Pu03R4(8j6qt4sV$>t^GY;BVVciR<5x_z-D=p-%)q z$Q$s$px!h6Qp7}?P@6U&zHz@#^xUdR@aGZH-?n`NGJ;yr?t9#Rir^Ok?T}ChUCFz% zV=_;v8s7$R;=X!3){Gt*71mZfI7EX#9ZHV9el+6eCAM6x0DAI$=o4+cY_KATyc|4z zrO<63^SnFlv3{-ux{ScMz`6%oI(9_%1WA>bJF7-?%vwJ>u2=K0Z5vFd40c+A78brNYGT2TY~4y&VVr;NQ{klfZ27(mm`N7`x^b`mXt~vjY#CVBnzwnaI=i z%`jCOBXiWv{zFe}T5sxOg)ZSMS{PniKBqLZ&1EjxLj5tl{VQ@R_e{T&73#mJ2xoo5 zffu==X2^X=Rj1OzAjLk*oH(FI-&duV zyy)E`W}lqlEO)OgN@9op+1!D2B+FT*QZBWl!N*HN4}6+yQ_X0jH`u&ggDbVY4=7^$ zC3SeyDBz^Y`x(Q$?c-o1tA3H77%AQ_oj69CH4aVNKda_H(^QbGsgOmXzwKvNHJvQh z8K>Qa%AnB)+wcPio)2*pjztX=s|wO{*3yFL)ZdJIaSWg~)U3+$dxSZ854c!*SwD|g z%C|jjWlu!;{s7F|2}GXH>#{MZb1l5^*|WAQWT``r;X=`mrF@sJ(%dUTNaqI#rIWvt z4-0{fzXFK`oNl{BdoVh2Um}wm=7$tP{^q(5|31Ga{bv4_g|Oe)Ri-}$J?3OT8C5|o zgn}5821E6A5k}R??DVS8XjDBKAX3j+=~hOge2jWP#PkuUd_aT?#U$NK>7zSVD3 z`!tvGKZ8AB&-_o``t*TlFxVRl+HnWIo*7?jzlry3s<#A{0tuMUcEMaKm{vgBIh`=Q zhWBiOiceI(b&M*_S+04nL(dB5Q|I(uZo#u#``X>WjOLe`7+sNK)bz)Ie^VH3`}T?g zdn$b3TNQOfNfuJn)e`FT^-r7eipKW*ndmYU()SXQ>xhT>B9Rcz_-~HouRdJmmC=;NGNKWsDShfuUiJ2}gbGQYfULO!>4;&PQ zZHjlfZ94U}2FXTL_bj&g{O(-F2x-pA;`J`B@!avckJ$Re8(`^cKm#})``QQo^$=y6 z`aod@+Y}3b6-VQN-k?Gr%@-LaGST0?`>|-)I<4~x)5yWOD$mSv+dt7& zek!Z$`bI(E4plt-UTm#Z?-l%rnaQ{BC;bq1yjdA{qIi8ko9*ae5|dpO^` zj{W5MB5YSu#s{^j*ID};<1wlI-$lJ%JtaLon$o8sUEQ?ezN)TVfqxC(1Kr;DFaEu1 zx0W}_#%tha-{G~_J&t0I+OY{xL!YTg8icI~dr%mw*g2kVSo#dre)^t({<{Sz zgY7ZW6MI9nOaY7zn)d+gVy9o%8|hSOWkMzEMSr&w(?*)u#BFLb(&@NUgg>rG5)AJ` zlc$TY@C>Y}y+%(J=lTuxm-1A91zVq1FBelWVn@7uiuX89SBT46p-05&WG{5$yW<6> zBxzt|#9Pl570lvIzy5rSena!HQVmZZdFNp+p%7B|*skhpH=^Ii3mZ5^t$X+z=vdp!NC+BZ7(KN!JWMg#Hmi+zwa`zJgZa*qO0Eqvf9ohQ6L zJ#xK}$G0t(R=R}Sv0-3ER-UtaL#Ht96uB_AgUM=dhRdZCi~dtdjGlv1{R{<7Q(wV` z*$mI`Eo0Bd%JWc|L#e`V=|stw;D7VJmiQF)-uA%{jOFubuJ4~3DH1p=NHy4uTIbSJ zRUBw}{DQa;kSULbfXuc?m~^Zj^!C8Z@$nBoFF@gr2AmGQ@uABydL*7RfA;kIuj;8%4V+&-pDU?y3~WA2>&P z^WEOMmSh`jfEibYT;-lv*S*~HudipP)3B0>qB9V+NPYb(tF*oQ5Ky2UX*e`&RRaib zjwVG6+~tl&+bm{Bz28(Q_9RSJOgYJv(*f;z_6k#Za@&b{4~0&=i%(HRBBJeIH>^ot ziy+dzSI!XTrNjHwB+S0lTtY1ZLu`J3YqIOGtQq<4ui`)7Qsu9%b4dvuR3Pa=f5sS1 z!-C|i@$yxf$%aIm?$qfLhD;Qh*sVJpT{g@28)ttovT&Agp=}EdW#^Lq$KPLBfv>K! zhA{J^A$+Bd_ue!$%4j&UtKoN0bzeSr{DnxKVsail651nEFw@|6k6J0usi9)W`^0<% z3_PJFGwRiq@?fmcWyf+va5-LCI{kNIc>rceTt)XTW&42|f88N+-yqR9pWZ}m?Y$f4 ztr^A@Ey4v=ZnaVB3g3DE^$v!U^S)rmKbl*D`gLjsE1ePrhpJELqCCl(ZiZK-$o{fd zup|uZt2|lUqfEpileiy4)7z7rYFJsezN6VRHUlmDSO;tMbr4{aj8`B{nXS@uZ4vSQ z1hDstb-H^+s;$K|1N=moP>74pUJWM zt=VyB(M4 z8F^;SjdfltLLqEK+rl&LMHF(lXt4IiTrrrL1kZcV)F@+Y(T!WD^$KrLUgS ztzT^O{5`}nf&GuIXhZ(ki8dJ%iHo7lxDeu)ohuK7ys))Yc$62=^d z-7Pjztsru1Q-%*o;nT#Q8#JU_QJbDM1wo+|Q6fyrr^*L%yyB*_3zKAiz;o&&^7OW3 zm&GC}nP1668idh>x@Lp7N8pOeI21wGez1}&TAuNDDWgh$j9Mm8!s(e>!#UP;G%1wtJLHM6*J-cm2gt_5nFhan(9?PCTWv@hN>Q10aD)qQn$t1yR4s`Vv{5}$)A^~|G-g_iLPt@_1O#$WT>## zbG;=~lJb;ryb+QzcxCWFj+eVwD~qp=5!`^bXRN>j=8F5u{|&Cbfp4E~h-Mn&e)#uV z_uWqG!m+7w0NVvmIOCwo1#sDaX!qxuV z>{M+k+D;}|l+TE|j|Qm7E0LJsikK0dMQk;jG;Y~sD$Vyc)<(D*v$g)SmS-GtD4*P^ zu1YCSeAOSuAJ#Fpv9O%o_1S;8SQg)1e?)!4CY;OK))7Oi7r`dpWh>|_Wm@gZPV}2g z`D9CR{;kA>kYwf86{j9DL*u&F(Q#)NoKIJRy@L+5M#CzNtRe`ugE-2^A}t(~zQCi9 z_V8V(#Kup&*H+GKr)-h)Z-NWI3Kw@n^S8cU1Ew-(gC94;sle81?vST%gFpUN^w8Em z=~tPjYuFS+Q}<8zf-FaOGk;!N`xug(+?<>`Wqim(f=9&iW2wiyD(J3@mUCf0Rb#8| zke{~11nvjCF9(Cm9FFRnM%8Bb&jK+*0K|s271)IW5*S$1$#N6m{pU+}B?4SZDPPBQ zYPFh+-l0`#ErIrD#9^uaIC3u=^GKL*WjUo8j;Do|KBCpK|6jf5=RWc;jzWCMSr|Vf z*6l^FIwyNpRPt&!`5)!7Weob2gbLTY!mMxaj(mXDLKZ+9G?-ftSU~Mi_~x!lwcql$ zzsFKRR}@ezqO{HnUu#-ML{i^ovU))6VA0Bw@h;=XrxtN7GFhJ^0%WOnIA z3k2la*izy@wvrYy-a}=*O^Eb$tsij42S+*^t@sa6hr*lsb%rd;ij4Djc@Y&*=g;PlA7UeK=Y$fa4A^7Pnt`qWfn@OWHN z{+*E)(E&`RdKCeF9)CM2%yZCjighMhTKSj=~ zs1|VD+&y-gajx@nkX9V+bzKp%JSmkH=QM^4z%mcS|AthH(2{%pu z()hh6Z&aVRk0a+?n;ya(p$ukO>IESlwu zDsGDUe!6e-DOjmBHD#E~s}z)Ppl~3-N6x7_lr#3~WHr(YXPV900eoA_OjeD)5ItsG zBGwQ8D0j%7)|TL2KyixTBI>#LLSWkMn%tKSbgN6uuq!x?=DQWvvHc+T8o)z1%O)>) z)Kcrp7>^EjE{hnbFU?>vO)%L2;u_Y0?JCV>OalEqW7|5UO`t5zs7y&KH zhZa}jwbh^5D*EgbYRf9@J1Oqt<|%u7oMNYE<#;%AO0~Z6d=q zbj$0JDEW8K7HfDws_J?p6S-ePBwU``O7uD^(pb9{dgE&qpmB8Ki=HisIQX;-+4n~J zhIB6}ZO?P`iJ*vJt9yoqLMZ!Z!U2}s4IHi9hL8-RgzHG$#W>hFv2f~Mv{He0p}-cM z6N{is6_hyAm^GRox2z3gwzpxkmTC6rxDd5Wdma3M+dum}@bUYykWvM2>V7!Q8e@*- z$Jl7Mv!;4o-jkhAm>Gw>#!a3O4%oX)hnc6RSRxv1+_7u>Lb^~8&Xw@~UjZ(eWk zV!`e>540%>4DWP1r^ki)8QtBwrvEot^9tvj?!E&RNTy|&FjA23dHEj$?k@}F{IBRD z=aNW3t0GA3@R;i=mN6PDHg5qZGkCW@uv&2V1G=Kl*#bLbI|fKoEq!3pW=Naj2qaKo z{b7Z>4z_0q#g09M4xS{kU?@L9w1uQU_l*vh{n1VV*8VQ*YpVr@v{h9uew-jL^Zza+ zUOe8WT(94dt`QBWIAUP2%mYnz$NauWALz;^a3YmxL*CHQW$F0PanZq!2Nlxw$AqB! zoSNig1$*FkOTY4NrB>?!*6bE?-O+Ng08Uaz*zCY{xp z5Woa+W5$ZW;g-k8p{MqDujDiT=8iIu|Y ze@(|`q?r1^f}xco!MY_NtJx}{ZPy&eBo5vJv|)#Aps3RCD9=IwySz2y#}|{A&R*XST?S5>CH8+qM0G)R(?aytI;CBnTWvq z1#6uzXvPSfD}=fAV~L>RNrY2{LVUSKJ?H)86n>{&2AJ};^wCP<%+u}dGM{Hom-m2d zFI`B&17rjfvQLBC50Gn*HR$Z%tb;=fF5>{+V6>N`)N{w(0%s$UY zWSx3QPppF5$l@b*%l0ZHi=OE;(O5h4BI^z+WC|ripW)vN3NJ0*NL!VIL=>_idY)X| z-s$12j$-yUC@%@2Aw&YdF%Xqu0a|? zFUPlcgvgO7z1BD&f>SJ4=$W^c??MM(YjW&R+Xx#-yQ2+t3`Bc~qRU?j`f4!M(1plh z7-D8K%B*&VMx;v<7*v~V-TY$F)N zcc?N^nRgF)d;}A1av9W&e0Q}%h?)PCKMmC#9_ibe1IS#eTt@^E4niu$Uk5hB-c*YA zvIzr5Lr*c%yV&XripNx5%zC zDNn3HfJ^^^NN>^1_P~MD^CNffoY+LA;%_wbBZRU++cSO2fk-VI8(Ts&_(7$@i^qpC zbxhF3H>+a@FnN9DK7N#k7Akd?SV5mJz4xYI#%X2M7o2$rugVLCG5!Su;l(v{tCgN? zHE!IRU5H@wOTyIH04^X|KmiY}Xyyqp|C)gI@tQa5<_JD?R?qTSrP)=9K2elH40^`j zOxOD-ft3DqIz{xem`sR4s(;k?MHN<=IMMgR8GVxu(FkW9bj zxYt$(5wuo+bp%vOja^Xth_m+}PRM00?th6+rKmVOvNRjv4(;ALz^=psM{=UyU6E>Va)_Di zoX2iMZu0u%pn7K+vT$gEr zw=~(r4F?3OTwD7FHEo@vpywaNQBXZtH%}L$8A0I6)F0E(JbI}Hp_d~pFI|E8YMiu` z$P7mnO%(u~_(DaJN9fGR`vS5vPEO{4AAsZ?#Lx)JYuJnpOQ5H)NL%1r8P?lMGqtl? zE`xR9!Vqf1#}cUAbZ)$?F~LtpSC+&?$D)7fb6tr6!hw#N%8OC>#*EFyJ+#&BiZ^(E zERxilk3WuZq;(oRDa`S)rBUw}xc}}~dJ2w60`V8c1Ar+ZA1(n=Gln{ay2YF&j*6c4 zN_F(h#&mKQJqId#fRPrr7%i_wvA>>rA*Wj!WFi(WG}tAgtwfRcBgMX$INKJamR5QG>X&UhnwSiH>Zs9t zJzV8-QePUL>+m)%sw3D$R5=_(HSkuV|1Z*~jQ2gu?-GUiYJ@Zz-7CS@9~7R1Z}u}h zJh;Y;B}4k4fLaS1#M;{}fVP88h(OlMwKZ$@AjT=#HS4nASY?IPY|ERoaG~!t(umdV zJ7OKdpdAV8wW?R_a2eAl)D*(%j9@|XsaGsnMc$a876SPWjdP~rUoflvav}p+*~EQ$ z*xD`1H}IZx^I+05{cf`}Uivl1v~T)#0kCMZm}g~I^e;-}S$;XoR);Ul4wj5JjKI?d zoAxdRS(7oNbdC8I=F~&M>N|K7-x1g&07YpV%R?bEoErrute-2-LInawK!;4Puik3b z)*EO^ywql$w_yCmd#7N-lBm_3qtU0XLY{-;CC`nSmx%8Gcv2dV>U?S04MW&c`>E5g ziH6rnsfKUfYD{+sjKHu>?mYi6r|ek4kKaUe@{TC?3_29@%sDMU&|PY=%{|PbJ9axj z$dg_ZPCN)fv z4XW||F!*vd;+jJ|y||5@2N#z~K*T*?5I5{{VI3?iRB2^Hr7{Jr6RNSH$gx!)OLO_S z+%A}%-`PTLd@GQbm;7+`I#o~vp0}G0w$!> zCV`n4r(-G)^E=bHV$#98_zVJqJg|B-^^vC|YEj!hnnG@~z*$Fk(O1-GZNvm5Dk69K z6FkcWD^g`_O*Rl`%~&1;Tv#q41rn)M4p5;cI{}LG`;{+Eh+3_M24Jdj@~Y)_cncl` zue^B(*s^3r+a6cdUQpU*L6v`7Tcqwl$AP8-pgn-0_v=%g(?Sl9qt3PX z)LwH2y(i&qOUxM3vVbec*CcLw6Z9H_Pq;tob*qH<;8HdiL{zE}{VvxZQ){#QruH3M z%;~a4WI|(zEVD?A&RPU@+eaKh6L+V->akewW2d{VKQJPZRDCs5O&=f7g?PnXOPukR z&**57rqYD9!NXZs`lGBan_;gM|JI?00d_5VHa%|gY4Ssq+&H1-Et+xqJ=#VY%~;Ft z@3mSyldO(s$6J>g@tPX>aD?!Mb4fO9hpIm;Gef7A?5Fll)!E_soZ9=~EXWiGfy&a4 zTgSx_DILWGWBm|G)bEy#8mgW8!S~VFv0KY>j=1S|pTDIi_~6j$RyBFc&GZLYU5`bR z11Fa#a6{iCvPYw5_}yeD04*$Jw6tl>aS$Ul#26^kHn!1bdcy4~vjGqAZ1a?&(R+#j zG9TQ7nc>=stJjk+yzRaRTqYyn0w0sJ5>#q68j#t|sHIrm`K!En#q8&LF9E{3E>Ace z_5rMSmcKtp8GRlsDHTh!r7dHXdCaIuoxC8dgRepsEwmL@nT3Q|{T{R&+BKzz%+c2A zQDgoYX@4HRnegNPbas(4XF4TfDu?seT@L6&65N6iW6R6{O*(4ZMrU^T+)@5t0M! zSH5(3BB_=w)kMoCX?t8FfdvU&ONWoY(=biPX8yJl73PP@b7gk{>qKpwgrYVSL&~Ev z``3leKpgNCRhQ2t=stiIF6gemGWiNHH`a^g)ME<=sez4=pr7US6JsI$qEt{&E{~WX zSre;7a)P#!25;R zgLa2kLtHGogl_kJrsxo*UAu2-_C+Y#?JOnob!AV_Ej34CW()^$1iPD8A+^72y6#oDac5(22hLGlLDJJ;QMF_G0F}44Q@}2t+CT=QVl?8cu>qz~< zW!FA*!VoS^l=&(8n4A5-mhb~EqF6ws@0w>*l&bG7-D*^nDjgr}^^S6LZLccoE8e~BI}$Cr7PKB4(#T{7av}@$fJmeSNGgxU++)nbMyTU zfu=3-uC86%y@smHN^{3g=9SD*2%wC2Is+mi1@QFC+3Tu7e-PjOKAHPU_3(ToE1v01 zj%Ig;>}4Tlf=*O!sz~2m9ik6!tqN8Tc7+yhrF7(o%vBL`Sx-bFi}ybnU%K;Yn3(+%?EeK~9#wzd|6;?M==0RSbnrHY01j+Q?4mdpA2wj8#P#`@R@ zT%ll}e(Tyi(jQdAJD@YvwaLB7Go1ehzmO_VRG|$2UU*)~p}NapO1ZKYL@ouM2BlVo zG>HoVym}aW9ay#5s?DAEN>xEpCvR}KXT6w>+l)r@kY2AI2;SUP{ddpSQJZ|KeLnvW z;WHchc5DL*f8Vm{(-6Z8e5U@^=w(q$-nX9zUE%zGKMvzEEJ zVo>>|Pi*G4z0O>Qq-xxG8b4YfY?Lu}O}Z-DnJKQtU^SQ;*4SHyc$F649e=;VYn z%yi4~IK0(Y)5vHV?Nij@BBngJrIZEW0ZW-N^L)Sf#64e)j2POC3fuBR=}2Zd?M<&M zBi3oF>h^dpXvrNG7nb-{e?$M%a(Gwgt{p4?;?CVl}Aw@2N7s-;(4 zsa9b*Wc1Az&mwB&bT1k=^Cj;utAQV2SEGsybkW6<-1KhVT~aJaXfyM`9{f_z&$XL* z2L89BqMr*~@};h!re#|JlHU&6%g&|!gq%Xy2*C3zTXm9eplLU|^F}B~usBvL)OaRR zp^)$@IfvQ{wE0lJOLlqdI3s_sXOipqPL!T8&U2#_6e^F<8I;6~T>}>}sIJH}W+1&m z$^-O>r*|WqGv_d-^yv8+%5?x|2ihJ#9|j|FvCQlJgc@F5u{0{`0yl2Z6P7qb73uFX zLbc582uq*jh)-Ogt`=k0`|D?DMWe6XUglCl{|czxabn2xr)&7)#O?Rs5OU7nWK|RwA6l<&_OnK7V|phF_B;Jaw;J< zB<@W~Toq>A+!)jKaD4Dr1E?g&_5MP`wnFHQYI36tl@ccSaX_B3Trz+Eee6)D6^l~# zj_gXOTP|rPmK1o5PWIbm!WUvF3=mO$uZ0*O91=#a@>`Oii~NHM_t!mMf?ZWicMN6h zWq>#RVEm49iR$B!#9ls>ECPiR!pp3^@q>>KpD|&qSLSM2fWE^EWNK}VfN7Cme+up+*N#2|e2<|?oQZ~>H0TOt zH8ijbub)g~-O;_TZ1@2E5YyO&T!p-k%PEg&|F~`9Uc&rkd)ipse(yhW$%9omr&gX8 zr}hMHUQ?z+?L-Lk+<4Kinz`c-sz&j0z(1&w<{E_8`M8;m;ARgdw(UB6O*j{6^E-iE zJeHhz*B01EK6S%d)rwQ%@50C5@Ueum6{776HALa<>`xeQv~pzBWj{7bV%!py?%#!r zym${QFlc9Hnyti}f=>jLO0$1Qe;}d!=+C&tcB1tNqJQc04HdXUGn(?uo4#*+F-<*w z3jj4{G9kq_FViHOJ?1hx_e&yZ`4UyZQqJyLdO)W@v$Sssas0U|@8;SLe`Ajajr*Hf z!jY@17k<+Qj@*fbe0#br|-I*$P zIC_HEsiK8QxXUe>I=WM6GRBx5*x8B9SYK)A#VJJkBlq10Br9e5<@y!Uca+^9J6>L( zFQfaI4f~j%b%xjS%cK{#(;F=`-jBfXiM9ky^e$W}qie-5r*u?oUax;`&xc$;Q;6Sk^=HYhC%xF10D!ltcY>oVY zq8TG&H5 zgE!KK`+OWnJDI@J!-L)^$z4U=F2c89QnF0lyS1-ZM|dzPw$;2 zV}X|m=dwhx_AW}N4UBM+a;tJjarbhAU{J_X(*GMC>QJbE&*M8^f1jH!EID;P+L4kO z2XvJjM$TtYe)%yp_d;w1zWDJ0e6glYqN`jUOESWLz(c$HuOH-#gfh$$cK#g#nY;hF z78pzdkZ6ew$<{VV@MDeqHbcQ%lS7Ry$gWk4akVL73q3FeHb2c zcgLMNczv%NstP^(7cdl3v!Zubf0XBEO{h&BSQ|nG&+OKhIz&zr9XJ~S4Ra;cq$fee z01g5by{%(|((1gv@9G^CyBH56`&JHo@&q5uq{gyU#5?tU}jKMz# z%qp-xp>M`R74G2tfMIbAoF6YL=N+?Jv+x#CB=%r?;5KXUZziFDe(qV0H%BhT>z#^+ zi8M^Hc`1s8)RaDivia8WreY#e$|W{tmllR##A3?n+}7+5ZQSnF3(d*kCW`gVnxQvPr$>XWf$4b+}F} zE?{ML8dgrz$ci0J?bqdxBKaV%` z*!6MBy|)GAhX#a0Bg>=!6~*C)%d)$C|EVCbLd=&VFDFh+`-VQ}!@P%_rg^6QtA+bN zqEEaMzHo@qth*JLQV=Eti9X)XrFo_=-8OWe9$a*%7d0w^6pz}QnJdRR!a1n$2C*H- zvza=Lh=$)%gAx?9hHi=U`Fz{93$Mv48FSwRc-)GltcO=sqCJ}!nDlj(y_}Gf7A@cO z!5PJ70knz#Kf10mEDE%1(;zjjAR(=UG=d64he3lh(mIHWAPqwgA*&*cAl(QejevBs z3PTN|bW04~o!>L!?xOF0|M)T2Tyr?j>2u#F)(u$kEF2Raf1~W$pe?A?9maKOQYV{xJ#zU3T+HW&?!P9PN0e5Ux0S z*!I{HtPvm-EO2Lf?G=Bn{3=Qbg?NlB7tjwuhHI8x2I6iEiq@A4IkskWF4X*+Q@oeW zr)HIW*ExL-q!7BV)#R;RSoY5HQ5MxH;yW|=2*wIf^vde_*Wx6MjkG6mo3_mT$GZds#o(EV9S(V*7I@W@~`Tp;xA>G0t|ND|tAID=Pq9&qGH!d%wT+y(t4 zg?Hh4GY@8L?-|7ml`$?MTKo!#AIgM_?OrvBb1_lI9VA8OJ~}=_#TIBVyfL&=vevLc zyaWB8I&J{;mC9h{unJh^xM6;rk2+`jjmIOQVY=al;U<;PN7g_37TBSP{~SUW{w|Rm zQ~$NI-D+p0ggJe2;al0IHVQRHiDC^?TJZGTXA#hHT7XN|MtB_#$v2RaP;#f2DxKldd!>9_)c zVkg1wHtiB#kn9VIN;sNnq$j-i@Y0TORi*yAG4t)yZH_6@v&>e0EDbj`%e%M-LzgI7 z0-?!DDb=ZhWR4+RaxO(#->wPL!_PFUG!=H1$mMs>fP0r`bZ9!NW%s$)D(JTY0Iu%W zz$hV!T!t_xY{p!z+@-u$mCN;TpI}F_t?$28@=O6VV$v^oyEQLN zCrJ=qH{_NQE$05Fp<;%?FxKL6n<^VDzl&@fR0fA98Le+VTpRnwyUCw4(yY=}YJo>C zQ)+t*r80(dw|=N0Fhcz1qaT1_Eq^~hy?|jJDEW3pVm2h~SlP2{w4QDHXk%Z{4>zd2 z42D;E-Xu%DN}Y@LN$MWle^xN*A$H==HZOn-)a^e^}&fiTni@;YFt9j9eI-;<~s?j+lPQbp}VSY$Cy&7 z&$~Xpn^xGtX9=QcYG$1o`MumNZE&xus@hHR6ATM_{4HxK0u6-71-)w4B-GL+b_7hj040h?_tsc9O9+M0aCtz$#eQFd3`=wS{keD4Yw{&}nV^L>-#5V7g z1a(MbmHr_$4{d=}&=9(@M@XSH1O315tp?vEFdu9_Dw5t(4-k~k+TTC?#L8Q7u46kW zVAB@zm(xJ2dE2Kquk7#t%>{t`p5C4O++RC<{%hC}k0OUy+mwQjQJ}cRJ zd~@H&mjm2n-=|B%V6cU`IXkmK^uC3QQN>xF(QJoMbhWpMn@aw4xn#&`uibi{RkDW3 zCBPpf>lefn&mVIm6P#&$UkA)yKki_RpWrMI1v@VlAW)l)=@*C>+tl&#F0DPUd^M)$ zMrs?T?JmGl*HeLXqx_e<*3<Aj?5_$WUu4^QB`;9 zFIXq+3#<$F750sL%HY`a)!*3zb^~(Nc$kbbsD)`%JHS&Q9*0bhs)_vM79--zifp1j zZG#NJB~|MWD-6!d)>N!MGi`T-GyW@!CL)qo*3DA{mXWx~+P$KSxTbsHIu|#46(f zrTH62=D}KtG9`7Dmws*H%u*9qqL1hw2R=x;X#aE#T&?B1vU98XrRNJ%VK&Y423%jZ z)Q~1o!Yf}V&yMESw70+o$V3~cGm)~!o@LGO zFKxiHW6+`LO>^UJYQ9m&*BL5^Cn%HgNeumCIOw!*nf%q1^sO|7QJpZ@qRG;qGkTFL z{Aa|OMhR9yD41(A37Xd1gEhEccWK%|=)YTdcZ4NuSiHP+P$nE2#7cjaS&`FbLf%)u zrSItJqKDvGEF9~kXY>L3X?>HijE1MFi8<}i#2ml*#$jvI?7`D(C!QGzkLF`PKC9zx zf2oq+(&8Xps3gkKm|5ktI2zQfis}%kYaQkL$B zz~o_NG$0w$`;!GnqR#E%psc=WV%IXHQ4N_}&HHj@?cyfR5Kd*I-b&Ih2W=k)5Qnvg zeF^Ih>kk{Qh)D=4jcAKmh#`;Vi&c$%GEgFU%9DZl8LDU#qA9f%J%lu2==JMQ9&KWh zlF7%e{cEq)0UU2uZ?0E`70#LW^m1actm`pza}y z|0?qFu|7jp+|e>N#Q``ruH?50ASGA~AJa7WV?bOeO2g5Uw!<$Yc~HE%s(Qu+??&nG z`9R%_J8KMIKOcRru#BsNg)k<6+)a_j#yX^A)KubUo|Xl6T6SZV*7+VRNc!-4Pg6M^ z`{`QPHXB%dZKC+6qtu3~wxjA}V1D*u|LK6|g%1C!ruJ{QwXG6goQ|A==UG*2Xua{G zEC0&xsw!9HS$TM+%oK=x^4DeOmHH2YU0fA-sm5CT>JatuaE=w1o5VS0Y0{a zvCh{}MOGN+>Ec%S5OohZckk?A?|qxqI>{j_*FZi>IC<7mqoGq+`E!4Z&j7Cj=Q|x{ zq_up7pj7cB7=r3?b8rZ8*rzZQ)^Gsy&|GSf)0)$f(_^|1m1@)e zWoytHEUsV+8a3=4Xd@ZY-5YmkMD(P3L3rS|!@Us{^OJAp7>&Q4sxZx2b0$=w+sh5l z2BSingh^G1w1N|hA7q~hU^1&g{(bD&@fx~(V;XFi5}-C=KfXz$ucDu zo^=p4##cPyX9h-`eu^g|c7?xexpW#q*!?+P za)filalGZo)}02FkgyII8k+#ThUxj-PWaohKDHXuZ_jC|J2B?zz!dFVMfpZ}idPp6?gqP&k{(IPb z3TSX5`69t1yH1c$rMD_VFJdSXBhvphHQl8~qIlJ-NqQd3r$mIpZ(R=_W~m{JknmFd zIrEv>UcH4zTjzkS9Yram$M+9*oRg-8tF{r>*FQe@GN*DgVo^(g^Zb$k=zs@?|AZnb zNT*4kuuo?*iSo95*5U071%n43pb0>_WX(39cV5uaD%HbW#NhmZaaFPKp$zHwh!)zc z9ZBBZiPoyB1QNsZ-+#-J0d9jxg+}Fv7t40%QmRBnTY>wd3sA-I=EUq?fOW^ZF96n; zydUa6cV>NI+KFJ{jDJC+M_iNA;=XxskVitCV*>3|&5q*^8Q^q~(37rD_;i`KF3ufV zI`!dn3A3k&+b}t3erbm~O}vJu?!o-DS!1aM8{M0zXb!R7R<^*K5lPY>zFQ)*MU;GJ zsxSOGw`ITPw|;X+K-HH=#$~`O_P#MeOw|DM?}MKne3Uur9twtfkPxr8DMG*Qfkaz! zdALZR2NGld9@6b31v+!B$4fzYl9ofej^qkJz3(qPG6Q$d1v`+@VZ<~OiEh`8iP7@i z`?@ae!)IxNX7?Y?wQ1iuogJs+1)xOh3z27He<%VF;+*q7lev|oRj?FQYZlAtekb2ZPfYc=$waG7`lS|3XTEV2XfW2;1Rh&LEPt%-t zf3W`D7%cstVHN0!B?GM(8#N{(ftlz*lM_{ch?5fo#DSJSnH$Xv1)d8um}U@}+p;dh z1`KQPRMm$v#OEho!Aq?89H|VL9|V>J(++6lM}SX8Fw?aj+R-dBv_&jL0K?ZaEPm4# z6-bTcgpN^Fn||W>pk&!p=4WtBB^ItJ!+S!|eN)Adbtg0`L{vhiNjCg5!Q#ta00YC; zE-xZ!0;<+0rHwZeBV3Ah*q03^>Qd89)fZ03l^Ib&k~d%L$qUXNkR=9@FSy3(Y-$9= znM=0ez5Qdz!>bK0hOTBMyvaQ@SCW^om6*CHGA?F77%S#>?V8u!2uJL$c1uE*_}-_u zFUvRjXnr#rKt2+~+s{kSXP6V-n&r)@ZAv2Z4A!2BdUxt}HJDi!#*IHNfKIOG=%P1O zqcc`^-JA0+`U`jT&D*PmiqcK=nqrPBI?7q5V?Ij5^eeLV?WSLM9VJ;jscnygOP}^) zZFlf(03!@aZ-y5AA3+n(i2bu zdC%VpU7!rAd#jmllrfAE`!ul|tomqhs%8q$XfP%7x{@@?iz0uxeO~7h98h591?&&Fybs zZ4WEPMqRTM^7|Oy$Udo#zzv4f!-X|_K=^0FBwBouo>eR&O!?EipLr~^jKSQV%5=oQ z)qhjM_?nj;&t$rc;4$~~dsYeYMe_Ojh0aCuk>ah-4k7CbE^-xAJY1IIpHvv^X2wYYs;akIjn{94eeYE{K&t zxg_AyYbeK$TG(Bh4cTR>f^+Ep{CaK>!h`wWwHF^!i80dnzI#PHz>@zQ*!tTk(5vL~ z1{`vVjx0x4JkO6vk!s&%{)O6xE<2K(Wi ziLw)dS)&6w)NvNK&;e78=Aw#!+PZfx-#XT+dUGc1Wl9AO=8upMEKkTLEZF^()s7NC zU4m;^{pIEJ+$Z)PXJEcI#J|t-On^!b&jE6-h3>`eS5c)=Kj`~np7c*HSdUgoV;wLE zDK4OXEZQoyqmU#M^bv5Kua%fEGqMjZPiB~KElCLhpW5&zE+jJ<@lyA1S=|^4s>O*3 zingGBSNy-W;YqtdybEh2nCX#iXdQ&dmxTIxfnGsS6ykM!tG-h$dEy~max#twc_g-xJZTsg=uuk7J~JKNzEV>7c7JK*4qX7#@NMC(nPu`0 zv7+7qYbhv%ui0yrZs)wtlIOP2qE(0$NWcEmW*mr`tr#c+bXp-S8A|)&=LT!iB8ay^O*fo0Ii9%a?p}TJi-bIAd%cfNnj$lDxyKxvtV7TSNGy^V%?P*;-EUc-@344-Eh{Jx$G4a#hy7AZx6T! zD!BjE#x2Fj|J7J3@meqwgrUJ}WewvXdh7u@n3UYg9d3gL55Ll-cx}3aCZ^^r!gF{0 zNf{-NYgv2s(IsSR_w2rXN1Nm6(wL5rkR|jy{Y0a zQZkTcZ@Qnl9J_!RV#xO+PI16pF)2>+IQAHKek+td#daF-u?H56rWn}#uQ1eAYhJ5E zHpDK(I|=|XP;9kvUUB}8?KmB#nowU6z*mNN$;OM`v-Gv$=$K+a%BOOrv?KwLlGx{| z6^0%5Cue?ZE5B>UM`@vSPg-(Y`XTd2#GuXotCf2;7G@cqL3fNEk=Q8?oi9~Dp`?|P0DY2o1bjrZ;yR<}PbeD)%M z`PHy|CYK`4e+we%@QUoTVIjWOh!0Qg``7TdZBoWW_xD{I+NiWoRW)={ge0-~f%bNU zus{c0U2jgRrDx7;fm+;iv$w>ax-&r0sk zShII?L!y80os-lCm;~RqN}MCg@Z>pYl8JO-(N`{W+lPAw$tN3zoxG5?4yjfA75nBP zbR)r$)YICYO1WJ%#fmSE>O4Tj_nzg|t( z4E=LrfxO>26XkED{k2pV8pYBW*!l8#e$}6ro6UwRN{Vd1?_|7&v-We-^BD5PJSNE^ z>XcaIyu``N3An)2)p|DmWg@Km=D{lAl}{1VoX4!uCSQ$~7ycaIneB%Y`WE}n08+}) zPUC=X0T&{NIeb4TvtHx;$HCbLbMq)+4fRvaOY;qC)+aTz>IiBKSz*MzDfIlj>D?I6tBI?~w3O6v>xEQ|!Acum|Fr$jh^BSZhY-H zS<{9kgjI@TM}!OuMy#oUw%#O)Q$}f)J#X(ME5`oP)jB;v%M952Gnz5o;x-!J#rpfN z8D5FG(r;iMUB3pY1i zdcH3=QY##3V$Y%;_h_H4k9efNH{3EY{#5(2ZiZX752QShrbdGI!;N1A?J188FCLRanyF;F?_>ZneJS3xjYb+q=bop$) z2IiN_F3Qi8Bj+ZwvXZbkCDfm&7pUOFHwY<^g9CxF59$m41boDnY+r7w1B~RnUxcqi zE7I#z)9dL~5@P20foplUfbg6JAnSY68Od|i*+r~g_d`}ozQm!{norjSUb#3H>j}v7 zEw|+@EsqEWjs+M=*6Wk2JYlYx?dB|s&H3(#8S(yLxrk?0v28?iY(=)_I$K zyU*&(_B|49YW~mxI1v|Ee`^JdMF6&$H*IegzO`1l5H_{SdKG>zo>o0h7&zGi0;|#G z#F0}mmAsyWJhU^GrRjW~l_WGla`d-<`sd(p`2Ek9i0zmqDH7}#!F~<0WIeBxxhg%M zt5p(u+V;O_`xfl#?T{>-fykBm+hkPh93Inv^tl`762+L!akU||m%{?T3?lBXbI_LD zF^oj7=HeadR24H~if9=rBSsgNjH76w9cLwRMg!1|k-v-L1E^=X4Y^~u`yY{nrHhwm z%~=VL_nJRd)N|@G{3kGd^8lE)a>D~R9?3Jh=v_Ic+fVkz-XF5WUwN9pIb$|2xn4N9 z*e;a0;vGM{T&U@e>-OK~vP%Q{BG4iov_6Gc+MG;wnm2(Vh0tX|(fiO|>c_eGuCgy) zW?faUjNxmE9EO^bzT30xv^`M4d}NVv4Cxkk$@@aZI8Pu({Xa4L@A?GQR)ed zy1OEVLNP-9LjA6i8!Ahil2wr>-W#-TSqU9B>ztj{e)tWyHb)jlq6US=ARaEH^c>um;jT@*--(sZ|3=J&DYif+u` z_!F(hhoYXfvPxW(g6N7{#VtMQO|Ypf@^TF)u6+0I=}Sj}801}+Jl`rI-D)I7?RB(W zyi9|j`R_H(3P3;vZ#eGYvrAB*wa)vf6RFauavq!o>=C@`Y9*(=b1~eUKe3#i3q@x( zRi^s6l=4}Eg)JTGM$JiBCHEu#Y^M>AUx+`lsOc=I{zYqK8SL{dHGXY$dMg?}_4=3O z>@IG@^t=Tl`^*D8Rz&eVKekWet_m+)3#l~mwpgnaojR`I-=nSL7dpdpRXr}WQPjfB zfO+o`s{oajb;I(wJ7Aq~S}2aYZ%hGw@S+}Q=vQ3sF=z$6g{6(w>vm>)M)E~_Mm~A? zMa#$X$lKj#)%XXq{oyns7~_R=M7k|M)le1m$j7V?Z#tl3Csw9g9u%^2+W^?~e7#}L z4&wCrL*=2!`VFcvaj@@@KR^Hc_i%Hb)#=?`Y29_7AkVJcEVo(cKnIU+1e-tQeRECI zt2C3wp@AY67oGNRrhYXY=(rN%KQr{yAJ*!qzF+?ZP{?+`^^X|8i|qz~FCAAYI4^b@ z=TVmoc4aR2Uj}yb2msCuGZs(Ki?BxT*2=`tUY(!ee+EGfC;_%?u#sjWEGBpq$6;sz zCVhD#C^4h=E)a+tZqB&?p77iYHSW zQLj8Fo~f@b@vyoFy_*64w0{m|wAR^W(5m%ylp^pZ(2&0!YJ03Y-cM*pid~Rha0eIb z(9lJ4;(C1Ky)s+t9py!-dV7b(8eF5sWDOm6EI{Dzh@;4eMuv+6A+ny9rN;%QJOw;8b^Iq0k;9O&nB^HOh(U2CvD!@E@PF- zmR$r~+`UXWcsYtv+mP@B3#@Y9_OWFclwU zt+|RhIKCn6vnH`4CT5uZZ^rghVej>m{#2P(*;4soPpa1!N~`8~-PAzT$F_IDWdcW6 z7O`{8{x3d66~|nh8XVU^-s1*Gm*YQtjVT`i<6rX@=IFR%Go>$DF122OF|^6h^H5ui zab!5ykk8|nE!u6;v(lqv84XF}^zTWl3<+11cFw|_>yoR2+v>|7_*v4rkz{SO+Zu8Q zw_MMgZ|v&)3pZc?YX*l{2DPQ7Rc0+%&F?DuY8zrtHhC=L5=1>}L+USWF}n-kmOnSK z{4oevGAsp_iZv?JsSga$o?RqgwCc`d;q+s@!+&N^Lx2rxs68YIg!7r;D5rfZ;ZGEH z0+V|u+_QlA#EdzbSZXWaQgR{kYUNxa32{TPmyFzhD5-M16{#U5d1jc|ZKgO%7bi%T z)U8n5T$70PvqK(PV}%{Dj`w%IPb&TWk45`P_CB~hf_GTUh+SX~3aRDs0T4avz^UWg z;Nkg)e>_zokjD~-A;JQ~o`<~(d(9(a0IcZ*e<#Nk_YX=~c3HB32R*_fOZp=5S;u<$ zpbS^n7CkcOHTo}#ma-Jg>__ZoQyOz~^{S#6lLLBT%d70`2zEhnlJ}g*)%!H9rvIQ^ zz#kjccmZhFdT%>MRbO>k(40~gV2~$oGGbE*b;vJ zX1<)C5C8Cbv}mH^0Da+r;LW>eIm{5RkMt+|j)0u&{ggyDsa@-vvHxlaC5w_r-9X)n z=+FM@g2llUnhB4&&6IkcdUSyQa_8aShP&W1R;lW^#V8{-fAkNSQ84O7;`AYcfV8h=Kc_+zPvO% z`Z&oRPye6T4;=5RY@vp*W}&9=o%}U@Aj)Wv1yqqHK9YR4_KxV^FB0HNoZYreA^nI; z5?-#KlRzGSKP(B+ZlNA+`0a<6S*evQpmUEW?3JB5Xz(gNz5|G%o_^+wtUkT{JmWz~ zlJqnXQlE!>yk`rM1iN$U3fx0bT$*Qc488_$9HsFE{Mlw^x)zfF&oHeWUk>@9m{2JJ z<|9o!ey{x0%e$C8Nwht4Ky71&xkn#0k!4}m`UV!L{KImvjK}Nj`|S7}WE@l+49*T( zpne008An#&?+RFoaxs%wzMqq30qduRR@oOpPXia0?v(qxt=)W)CUOfZK|TPU-2Am( z@Z^-4n~T2V{a_99=<S7U08qy0CvnSVQwv@smtX%I+yo`n<3 z_3ySYr6Uu0dGb|9wZso@zO14;B;%}KxiW8i1eKV7XK>A|&5c2|_rF~mPQM>?G^ds! zi|FDx_jSYPGIDwdOzV)KU|joJOY;Rw@l;x@8{4c7nIw+9H(0N;og<6?&_xc zCwc@75|LB=al`$!c%ky$A~F+5jRv&>$u=VY>kq^fC*CH`o4*S3sIGLZb_5BKo?r03 z{zzz2%HdEbhDe60ce}_xG5OyJdsPt^Z^mhbGn&};S-{tLSwJ z?V+pRUE?#Pud%JOyt0tdyPxM8IGh<+pqHQh!E)E5yp(Lr{m)wEx!C)dr zLS7t+9P>T>CaR|qlVT|6uyyurB}$#FBq6aN6?Ip9V-nP+@FVVWvuya=+6y)M+E)*$rsTtQ9@v8mZ^xPB zK9CisODFbPnqriwyVaQuR+^I|o*UNs$|%U_%yz#HiFj_Y-6%Tdh&*$z`nu-q;g0G_ zgvOfWzmi?m^46I`??cgMW8{i?QSlllE(Sb!Sr4fKqSb8!&`qG!{k&J-)PmQ-r?`KG zkF1EHZu_`f5qwVt++1$p^Tx{u@{f=F2Rnh>&(n^HYXeGq@0qv7ohEUdkt9^SHA*BC z#LMbWsLNUH9~v>~E@8kD=G2@1_O&i)zvbf#2ULZ3b0;U$gP`7epQkpRv{UrSJo_so zD-FEpm2FL=`x!b@d4F_>CVuN zC0EO`bEyibgj}s1C=sP^cXIeki~Hpz5oM+P=B{P<%IXyi3sdnJt)24=`h8};qe(PL>T$>ql9(#3>DibM#1tC1BaVF`v2x7Blyp2`|J0Q$E4kels_Hu zRqbC$(<>9(kUvCwtU!V2n(4${*O&0jf{J6(2PO;|_X(OWhKYW=r};nn2@95guy~9U zmKLe(8*a=(UMa^!cCOW7R0ctoGD+|u=LLFhXTm~lW=h_K)8B@qzvh7SVN=~*m(~`z zR-FW1S4yijjwtOZ;9CV?2z~UAB$MhXue@(}gc}P$O&lsG-Kygo-JeREow%Wy8;~5u zgJE)E#IEgS=p$~ZtjmK@q8BvkgDu$agjeH1R~h$$#<5+Ou|X+`IUM z;rArbni+|i*?InP7cYg6s$|H+dagos%mZdh9c%l;B_v6%)d8Y!9Z-0Sy4TF zh!gwTUauu*`6Mz5lp8x#m?pWISu!ttaIeju5ZR&!L9$aF0{d>qdBukk5C%^ij!jr< z>A2iII6Jvn5S~oSN$&=cz70gr+K~NB6%tsKJn1Gsa`pr76Vm*=Ps!1ur_OZobizs5 z=>yfqM3C&xc5EpvK3wJMVF@q^CD#ZgPfSDI+n5D@DbA z`0E|t$__Dk-I%vd#Bt5b`?a*f57yT@80yzvoZiO(E)F%5ZO+t3S*Ye1p|m`9-;yht zY^pcCeAkg}@mMmORM8N>m{(hG-m@3pVU8BmN+RNoCSLU?#UJjreS7AVhB zWPNigyD!xawMEo6*cR|V!KK_gwJYCg!>mXdZp;Z)bBMz_zGtn7tOG-bl2bxv!?U-i zihkxR>RWYA_f{7E5=@U%+F36(`_PSqBr@-)>_M+T`coPAUE?)lJq zC2KZq7yX~ix^ogc2D5fBhi^wK_R)9=#*7T}A1(DWoyQ4wq+s8B%%zkMJ$%<;uG!R^ zApthYgG4;lrb#hB^@1yfR8qOEV0!I9h`otBLWV-x_HX$%_taDFx5Ez)N0z?sczV?U zOA0O}KKBwGG@k+!SP^TIq0+i-NHqP^aI2c}sXFgpX@;e$Ztwv^lvpsKfR6HtKiz2I zJv~i({|b*iP0+tomWVWrBq~;Oov*0_7MpEu30$D~d9Fg`d-jS!m$F-m@O3%qD444< z*GB1`#ObyIGKEG63%W4qzbX~RxR8|kN;bqY8RTV$xa!ZUOf7lsa12gm%(km_w^1g- zU!t9Lgpg(${Z>{$LsVQFcGumVNAJ_|TOe_QfJ|zdn7S&ZM)ITLby#gPVUN6oquDmPO`{( zR_^x6boLA%M3q3E4&q`{yR8D8;)W@$eiKTipJ@L{8BL-ej|2mVVm8%9kB=mTnB1$y zqH-OzVS|*m&xU*?I0dH|>Bm&K)>;dA#o(y=Ia~UiE%D7PtiqB1-`z(Vi-JFSX6!^yN#HitYX~g~kE@UM48QFFDtsEm1EST#U~%l^lMBLk zW3cQGPrN1nTl#|GA8Dx zvPkq-mBs0vZifylikp$FHi$hpo%Fn+VMLk)%9Tl9kH6lF1!wl`h8%YS1HQbzL&#6P~50$q1M=?3K7)NMB0;K6KlxFWqhev8jl%MJGbFIS@s>Jm?HhTrs_dbre zOWK=;(m#w$wQHJ%!lQ9s!tq;6_Ah3XfXANk)bD9M8n7W|30>I`gE%Z4vgQXGP|x+O z8pL~yFi|3cEZ$4&dL8pMsbeO@n|VsOS8Qkgx@Z{Ddo{vCwP{JS`Nf+qqj=Foebaqc zig-w6-F1Maznt@L<3=_EBuL5*5$HNXq&^))_EJ9g?zM75hvLb{sQ$1@-54@=zD+=0 z_M^HK5{IZ>qA9(PYcQt+QFzSt{FtnPAlmF_>3I=SY(4HcFzL_saiO=zR<@1dG#T5B zDq&cB1J}4UGVS9x-_r3U%KA;UC8zsbr`(HBc{(#+1yET-zXC0DY!t9vm ziU^OK)2GTcqUhW2p2&3{ODKNLRR`5vYp2_`2TYq%LQkzi?!t9X`|yw2zLOiZ=0vbC z6(XT50nMu+QN!`-{;CTG7w)Q!Rc>x`+M~1Ug2pJDd513yyxECWdKeR2!mAo6PR*!4 zCfyrUH2$bJ&?Tw5_+77==9^*vM;s^lpyc6RWbZv=98ra<^jX@vqoR7nOlWA2Zw2+L-n40H z!0@=bBJL9Oy>jpCkZ{Kv>kIET&-YOX(|0~UouGpNDy^)(X1F5`OOclee)CmlcYX3U zR3ED~)R(aAZVtiClcEARl}-SYd~Hy5#gkE3%+zv$Wyt{I5K?VH#7DZA*9e!!wm*^? zB!!-D*^|P?U0L4TeHga-XPgDpO{z_|68FkegVSDI3Y2co02sObrqlSn8tvL z#{Wzw1yc}D{*`=`1fw@)|M^E{sp{utTC;*xQ_IQMlta|{A|oo^k^gB!lF`V~*->9! z<#TXxhwup`?q}=bN6%nl0WryreTZN-H5uE^cnNCY@L>{$YL740$&atn$y>JHe2vwZ z`4eV?i0F6|x==7rj)@+bv(k!d>0pkNrMaRWz+?S{Sw#wznlpruG#gchn36S0Y({V6 zuono;2#*wZZ0T~4^8!qpW?vty_j50?uP9j z2_N7*s9)H4ym|b!9!_#Z$)G^=qHs{#gw(U&a*j@nN?0x@ErVF*ZH5@Qge<*)H|U!m z?1&dd)%Qa(Y|axz9OlnXtE3(_#Ex}^_2nv=K3v<%l##}KP{RZloLrTfMX#QWr&C2+ zhVzJ#wYsa{*LueYE*nNE3m`8{yaIz@LgyU(t%fwx<$9EydvXpj=U3@GqFIp#K|@+z z#ke6}Ob3+H`Iv{%uD?(ce<4M_f3T+IA|pmizj7=YyYJzU%k5#TrhcFkceLtPJ&t>DF z<_5>CR`f4J->>2{jgm=|zLd>A<5hYz;y1MJzH+6ELAdjTe*5e;KJVU~ahL#5LTR5H~=uTE+R$O|`$X>4a;wwsx2*bm1oDe@x zS;i<$@RhCH&}2<>`Kwj#3A`l%a8Lc&l&N%hAwn89+V|F@)zeGpdsKC~@)C z3Sr-w5&|y4Q)Q#(06q#@I6paJhY#zvMR__tWPalbZU=HG9>v7x+{nXR>DK+3f5@&g zH>agjm^19qZYa1YF=RcG+Zy_jlPRp1swoh-6 z`c(jh6Om0cp43JT-*C?@!JKrc-nZblcHUy9=%*0;cyP|fA!HZl0OCn!sy+HzXxaF* zFMNBR)zIr&6^jdEKSjqczCO5h46`Eeo~M4fWFk$$f&73-*+o&9nh7Lqsr*D` zIi}m3sthMD2>0^Ta(z=fjs+3vF&?}_!q*>lDwll&tSV%Z86`IWeKgD6;Yx9UJ3_3@ zR&Fr7rm@^>mG|@c%^<$rqV)Zix@T^8mBwiux|bOSS0`3b(OJ^b9LRl^n)(r;hG+~&PeNB?vGZ>HhlTqj;Kc^uLGynXap zk~~UWXDxV=rL_K50i$Zb-x3{H^oWlHQTHu3)QT-a~+4AR107BfU@_`rB@BQ zCN+6&QfObaoH%0DT&bOyMS`&M$!l+Lr9Osn#=P)U*Iw6y6)N&+=HPEGfLji)CK(~} zm1_wb40~*qo)5NrAPO&*olzpy8c832CQx8qIeFfAhbv9}N}27QsanT{c|fR$D|}g| z_Jjs_Ohyv9WpC&Pfoa{zR8pDE->e@szv6cDHbe(*e>yGP)bkB+7I2e-ap;tA@Jn^R zM!b4da8}i~;`|kdQHBOeI|$6-PDEg8N|Sr^1Pgi0r`5_=gwMw(;;~B0ty=DLEdpw`A7n)%ZV~0Gir24 zB3gJHp(m}eAEnD(Py%0E4qTYI<6tMbdrQWc(n{9!woa*g()K(sJ@;foh-&JqwtIu^ zW44#Oty%-#?~e&LLor#~z#INTT(U~a{wVOdoxl(|$7p6eN}RsWfQnP0=!{psr$G2e zn!wo=*BO6IvJUaom5@V`9m>ggXTF_u&C=_Plo@hYxzo2hC#L%!;9N=QY&4ho^O(t8 z5C5cY!sZS+po8{$=pyuowm8;XQsC;QqU%&*1Yv^`k1`X>U6}T1M~X~OvLfW&=KXOh zB-4A9p1rV38};^fIDEL(T21THp4e3sokhgWhnKACMl{!6k!v^{kd5DPvu=WD!4anw z#dDTW(R7ru)-O9{GEXIDDk)XTr5?4Upv!eMY*(c;+pP% z8pR)WpS_nZ*5}QEx9>XGSyGMNlguI2#XM!!_&Fn&g%mF#z9p0dNF`6!xm_A{i(dDn zatZvD!Z7D(`WCGO68Y5?S<}HSr5&EhMVwbI#dG<$W`?v8Qw1)&r}5-&uDMq}!TCrHkJ`<7h21ue54IH;CGwZsQloYmaZj(-Y9jJ9eJ3}&k;4zSd>1;kEyE;t z4EjxGLP33)r!esaIuqbHZPH`Zh)LOq9FD1a6VlRaAsS8U%rB`vK2jQ3&6bTzY+fLv zawLKOVm5es_&YbFEre3+A9e;T0qSW9!=P}P;| zE(d#uK!z09;-#h<<_^Spi*s#)Cn1sU3x3QP92e^hNRR`rd$HMdyp{KmEiX@xcQkRs zdf^sQeYi{h_4w4fN0mwUj|tU-T;)t&(v#UQFZ(C3Cj8ljukICpX}M^GR?lBuATOe- zg!;<}L_(g_8lv!Mk@)x!7L{Q==GjMBg5WnV#*g$iZT~xc|Axj#(T7R=t+G#J#&0KU z!$mk;l_?{Pd7!!u*>dzEz3!hG3^8$BIGdR9z1S94LKUq0|mnIO0iLkpWQoc4$WqHf zV{mlP_+dZ3Vu$DZ$4AIFATZ`Uj=cr6zhXMWA#tnl-U7n8MvA+I}>CG-r^kQ?mA zT^b3j*lgF^g-><%>_(Xd|J zy1Ul{@QLD9{P0JYG8*-e!;#7#(XSF5^1m~ZHA;qfpU$4%%j$E>p4%60hQ+=da{;Lq zN9VS~0=3rl09Dh+`ot+;JBrA+y+JC-9Hiwgv)!=zblO_{cE9~Y_t20z8l!OJuU$daOt?3>#OCB-EE(SnGDZ~HxY7n0ZRo!&>$Nd_a5C+Bu^z8`Us%VrYnd52U>c+v^4*J_KO zU91U7FWb(qSLzJ$)6#QH^WTs*_(QzBPj7EP*xs563-aVjPVo2L9c&Rn@79vVG?!i@ zXUf^|z%qZFxIi-qyXa5BWosKIjk)O*# z&3=_Eo0>Joi^`MCn=-V%^RLpZ<$bZO*DHhucopgXcQ&0LboB&*8!NCpP?XGyeK~yC z$D-$7L5rs^@88a96g!GXPyPf%tsM0>kzHEYO_*u*_sR4ytN7ufi^I=qq=;8OmJReY^eh!|urd3&Q+iPf*jHYqRRs)-fwp zT4d03P3QKulYFdt5}~@%=GGje>2PoM5~ED`TbICI=kBpLw5P5ofvkgqQ1QVijv1gy z<9qLplV)E(0Y><@~c;QR^rRy}c90$+ z_t8$jtk9Dec?#j_0V$Pp44A+}Uyk5(gcJbss}TH!SlCldAuZ z)rcSCr-WXS$W)09WyElX`|uf8r7%oLcg6 zB+bdRT@QCiq;M4X^>%hMBru01tM;{Wilxr)5Y6E2tHZU{MJy~|vrBNyTQMNe}<7c2hGir2hT z>83TDc@T#c{JxX(+qZ4!h+!~S;LS!1)DimjYZaW`{P(ES-Pa>lZiz50uS@p+J`g`Y z{eZyke_z!Xz#owY5D9t5z=?~j?8T(5_ai{8R4QskOy2bG{UzT0Eo!C=NV8S44{(ZX z<+WBKC-4Vq-gel2mRxMKItuWbjInZb5;TG}!i1$l%RuPh^(kE&9|oz`HPemD_@3Rb z0OS`M{^qXsIv0Khz~D5J$a}vx)t&aTA?>A}pc)EokUzqo<@cI+=5_jiJY)CXNcz*8 znEtf?+HVmwB7%^WUBzA)H-bw-=ika<$sUmHrL30-p|K~_oNe06tJvXwbmn8@j{KL) zK9OM7cUl0a1q3MBx^7wSnc)rMrti4L6-6D4kC@=cQcccf)^PHj-4G{-OG|)ksUjLC zp-C;l6-1{$ecPbis9catfz_;#M944=0}@9$rsrwenzHTRO7?3g*7$fO)s!L^QSFfS zHxtE`b<)il;uy^(r6$V70TktE>c2gXQ$D0Dlk6MpU}fH;7*Ye5Q2dy}3h;oU3^*k2 zIbH*Q{Pzo3c^TvWS}%hOCX%vJnOYd{-76va8N_{~MeWyoJl3ekk0XY%{VGbK=oMWZ z`;Ax{ zlF)Hc_j?s+kT6}6|Hb(GCT9X~LM`w!WVi+cbXWvk9Q$9$9MQHeXS%+_Pi`O5I4Z&M z8pu5P4abd&ksG)OCu=iHWWjQ5bKC@#!}n;W57?X*vuc$fxl>#cy4>x810gB6 zvi>5ds}rlV6Cxb11lYcpIz z+3~;+Rf;^Z(&~-B7)wX#Q4hY7W{ybL`!$1D$g@>VAk+HR2dC!-UF$C0EA2lnp_4aJ z5k;?!g2|03A9OR4N~`r_jOs2gO}-hI_B~r6r{X;Ph=ra{7)^j*H~;*z<3>s5V&Q80 z?IjT%f|9x{IEc3uUiBs2RC6vny`khBYURiNjdk3XGIHvDEI(4Np~K; zH{L>MKFNR2*LH9JbO<4YkXz04huI9e6^8>$G?*-Fl*=@iSBW%!Yx)?44jEt9iQ4;u zN0X;dSFoz%irc(ktT`nUZCFE4`mV-(;_^rwVX+_Rp+WM*#}{NxGF}yK#jg9ShM4)1J26-K8joN=59si;$v~fpIFa=`F;XQ-bABz7c%NnARzDb1Ik;H z_6G-y0s5nNd%?wc;Ou{4eA5FWAeApAAe}EQaG*=gNy@RlIw2f`YG*z<>15!)sIz*+ zwh=PnYhszmc=MnQIsV>v%~qUN@X}&h`p!>YuTtLG%IVqb(s}%Lzm<$hIks;-TVrMN z=O$`TV+E+5-!4n=on4`5tb?lz#{_H})0ANEj7e~4UO?xl4agNIv}Jy}4#gjG&Tde7 zPTT=0%iw>Yu}P$3A=uV#?6cGjsiR`gc-MLljwgkaP8d+PpF|8F29Jfp`6m`F2;r!I zyB?iig2~Fs>&TnQy8r>L@z7`ctbWk|A*z*+8H7Z;oXx<7#u1wT4MFP;71-osTId|- zbeFD)Uy2U0&;0E1N#CQ5Bxj?KfD zLd_p`@VF>L)33D_bJT8|v}bs>Qg-f8qpTE=J|DWYiz`%9p_$~f4a+;?8=J%QmAda~1cGx>tmG$tCLZ$Mg zo_N_cExefjKxgrGodIcJDG3X4?QWEMdBoT6_yp{{FJ6Hz5pqb>tlbMgBp1IpycH2B zeUNc3>N{uQu$1S9`i$yK1s-bu2Wyi67vL~Qx|V%b)aZ8M3&A^5mA@3#S@~ozdq@0o z6?PZO^ta!mj@XJK)}1+$FA9=LG+2+Pdc$*RMq5Ujf5S!V*-6gmg|=9 zy8}jBh@fXHg*nm!@zJWyiZPq*q$=$|9|2$@%%vlrk-^riPEU{i6)wQy5KBa!3J6a& z-ctoGp=USfBdgKHFLM2z8ZP7Y2w);}Dc+tT^nV(Q$J}B|j5(`Tm9=-DephfyB26wz z`^WmDjP$r&z1ZDD$b{zAO$GGT2gx?YQTwd)#I|zmRMQQs{aSJf>n65MYPh;jwuqv3 z%BiPIrssw)^x@m7_c9h^fj|9=9~dBhNajllK=Yvj73O1}X?x5Ps*W)e{6`!wmM=8z zgWsI8s{fR4-#sAtUe}cEpAe=c-*=SnzE6MnXp4s%-1?(v?}XQ71$5*v0eJ)l_?zfunGd&e~m5CrYVaPuRN+$gg{MSdy8J%w*#VwE*v|N1W

y6-?v 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 wrXBkA&0`Sdi!um>zk@Tp-28na;4~O-&Hy3 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 diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeLayerBacked@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeLayerBacked@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeLayerBacked@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeLayerBacked@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeViewBacked@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeViewBacked@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeViewBacked@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorInheritsFromSupernodeViewBacked@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_blue_tint@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_blue_tint@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_blue_tint@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_blue_tint@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_red_tint@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_red_tint@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_red_tint@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnGrayscaleNodePropertyAlwaysTemplate_red_tint@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysOriginal@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysOriginal@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysOriginal@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysOriginal@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplateLayerBackedNode@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplateLayerBackedNode@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplateLayerBackedNode@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplateLayerBackedNode@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_blue_tint@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_blue_tint@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_blue_tint@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_blue_tint@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_red_tint@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_red_tint@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_red_tint@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAlwaysTemplate_red_tint@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAutomatic@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAutomatic@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAutomatic@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testTintColorOnNodePropertyAutomatic@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testUIGraphicsRendererDrawingExperiment@2x.png b/Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testUIGraphicsRendererDrawingExperiment@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testUIGraphicsRendererDrawingExperiment@2x.png rename to Tests/ReferenceImages_64/ASImageNodeSnapshotTests/testUIGraphicsRendererDrawingExperiment@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-10-10-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_10_10_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-10-10-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_10_10_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-10-10-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_10_10_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-10-10-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_10_10_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-10-inf-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_10_inf_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-10-inf-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_10_inf_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-10-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_10_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-10-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_10_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-inf-10-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_inf_10_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-inf-10-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_inf_10_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-inf-10-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_inf_10_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-inf-10-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_inf_10_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-inf-inf-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_inf_inf_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-inf-inf-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_inf_inf_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-inf-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_inf_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10-inf-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_10_inf_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-10-10-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_10_10_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-10-10-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_10_10_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-10-10-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_10_10_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-10-10-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_10_10_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-10-inf-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_10_inf_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-10-inf-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_10_inf_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-10-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_10_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-10-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_10_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-inf-10-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_inf_10_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-inf-10-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_inf_10_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-inf-10-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_inf_10_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-inf-10-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_inf_10_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-inf-inf-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_inf_inf_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-inf-inf-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_inf_inf_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-inf-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_inf_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf-inf-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithFixedSize_inf_inf_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-0-0-0@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_0_0_0@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-0-0-0@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_0_0_0@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-0-0-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_0_0_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-0-0-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_0_0_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-0-inf-0@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_0_inf_0@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-0-inf-0@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_0_inf_0@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-0-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_0_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-0-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_0_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-inf-0-0@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_inf_0_0@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-inf-0-0@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_inf_0_0@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-inf-0-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_inf_0_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-inf-0-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_inf_0_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-inf-inf-0@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_inf_inf_0@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-inf-inf-0@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_inf_inf_0@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-inf-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_inf_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0-inf-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_0_inf_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-0-0-0@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_0_0_0@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-0-0-0@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_0_0_0@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-0-0-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_0_0_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-0-0-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_0_0_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-0-inf-0@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_0_inf_0@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-0-inf-0@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_0_inf_0@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-0-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_0_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-0-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_0_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-inf-0-0@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_inf_0_0@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-inf-0-0@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_inf_0_0@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-inf-0-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_inf_0_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-inf-0-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_inf_0_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-inf-inf-0@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_inf_inf_0@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-inf-inf-0@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_inf_inf_0@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-inf-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_inf_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf-inf-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithInfinityAndZeroInsetValue_inf_inf_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-10-10-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_10_10_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-10-10-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_10_10_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-10-10-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_10_10_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-10-10-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_10_10_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-10-inf-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_10_inf_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-10-inf-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_10_inf_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-10-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_10_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-10-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_10_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-inf-10-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_inf_10_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-inf-10-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_inf_10_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-inf-10-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_inf_10_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-inf-10-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_inf_10_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-inf-inf-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_inf_inf_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-inf-inf-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_inf_inf_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-inf-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_inf_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10-inf-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_10_inf_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-10-10-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_10_10_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-10-10-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_10_10_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-10-10-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_10_10_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-10-10-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_10_10_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-10-inf-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_10_inf_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-10-inf-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_10_inf_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-10-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_10_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-10-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_10_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-inf-10-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_inf_10_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-inf-10-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_inf_10_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-inf-10-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_inf_10_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-inf-10-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_inf_10_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-inf-inf-10@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_inf_inf_10@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-inf-inf-10@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_inf_inf_10@2x.png diff --git a/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-inf-inf-inf@2x.png b/Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_inf_inf_inf@2x.png similarity index 100% rename from Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf-inf-inf-inf@2x.png rename to Tests/ReferenceImages_64/ASInsetLayoutSpecSnapshotTests/testInsetsWithVariableSize_inf_inf_inf_inf@2x.png diff --git a/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithSpaceBetween@2x.png b/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithSpaceBetween@2x.png index 5174b92e271bf56e7cabac40683e9d427b682543..ce4006670208def60b0812ebe3f4746471c6b095 100644 GIT binary patch literal 6430 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 literal 6414 zcmYLN2UrtJ*G@uHLa{(Vs>+2Z5UPR*ger(2D2Rj}=?I7rdP}feRH{l-swhP%0i;Dr zqF_LZiGWloiWGr_Kqv_?40ME*_n6GyyxsZykcp}&nw0Y008*SE*e_{ z03ZbWS>*sX``+im`GMU4QP!r0fU3_Dzu29Fw=deG004;W?+P@t{)@&IO86REU1PT( zcKv;cvg@foE&G{E#(HpM2>{?+F*7!}76Dw&wR&**szj&jzU;Dz;Zb+*_m=kznKlry z8taB5U^7DvO@Du3Pt7pI#Zd&}isGw_`*P2P#E-pxVI0xsJ-6?bvO|4_qfjA|?4u!e`P#|5a_B=C0OxT4@IZ)mJonriW7KS~;{VHZfqd6T zSEfT_&1&=y=mS8%l~oX;id4{lJzhD?`wvKACu=?);2#+``0ht%_K5%J>%aePP;tln z(f8kP`7I+LZ&Wvd|LdK~2CxlmZ=0z~{4)=>hO>9IRF{hLgV58+{MwG)w^KYX=l)Y) zhyuBDFD3SNxm&q%%>9+PD!NGwa-Tb3e=vjv#$dYj!MdqEs#DMiBm-go%>JEmOZ}=pM8@gq_Ewy-2c!?zXZ5@ z|Gj+u^hNG}7g5Fm(#=-@{wg1TSqBhX=G=GCe=<%Ccy;nvFQo`XtVbsAA)| zW2y^yb6n-Cnrz(7#mO@c9_H@pTd6qHBd&P{Kl(@ux|i8Mr_pcsXI59u zf)!($KX7Xd0?v}d__Gg}eL%+cS7=@`YyUAR>>#^QB7u^dd*ng4Y2g>2c|lHK zL0w1BEcQmu_5^kmI+FYZ8PS&~&!6m+IPHBS8X6tUN@S|G|Dr|{ zm3uFx0Jet?WVqMtMcXb$zmi60#MEf@2bO=3)>JSmcrTbGBfQpQ#B$t|jM(TdWCF^=^s z;tG1DYo*>m5%=om7@feLuFGtZp?<&6CeDEsMp9ZXGVEEZ3t*zX5pJ)zGdB2@B-Xl?Q=dMSoVX)Sn2SN*u4P(l4iYFVQ z`y|qc*i~sZ1F~3$d~=%sfTL-@sgL3W9?6`MWZgSr*ma{eH}%sKjo<~;yC+6`4@Lc+ znSlFVc&;_XzLg-VR45q@o=K{Fb|Ep>OKHC6blodMC*Ff*i{mR>u`K)wYhq%H4kyv$ zR(3W=DevNjWA#|{J-iibD-!;7aCmU=C<}D6`(9^9!uIod#P@uauhixk-E@K{GRS`xL67T_b#7MEwer?~GDA+U;R*!OFDbyTZQ1ZTVbJ zLBV=LxI~HlMMKvgWbu@2`2l%J$1c|gE-4bar|31V$G1X1NFScgk|_xul~8aWRhmIG z5pk1SX0IDlx=0sKyH>55G*iDi?9X#$(~~{+6JExe4-qWtym?!7$8d(76290cT$vjm z@BC`#dp0Unn=D>bvTvB`@}5SAAZ(KPx1Up1Uq+(Fvm_>b}vB$HK=FyE_FiIM2bp}8C`$IDg`ac*+13R_NzsF zc8i~Nxw@)V=e4isw><8XrM2YGl^-s&A8=WRGFp_tLxT|%v{VJ695`!2r;yIxjGQ8p zCc^j2z`~}f>&$Qik`W26@Jmi^SWw<#Tt(m7(ej`;Hsm-@M2vRwT|2>XxrYW&w5O7^ zzZECW&)n0L3J^zv2@`H~;}VWBWyv;}lvlha_c=a>l!|D?;p$Ducc##LsDRb%!rl9m zf`I)y*P@0r{QRr-UejVB)yib?b373ew`bQ!w{6764>^05Jft|(MFWj6sJkPms@}95@~!Yf=v<&93fmz zdeZS>r^(U_0(^ifPB_nCV?ZERp8F__&{*4`XSTj+_S$Zl|N0oy@c_E_BN;Pgevfr8 zfwX%yi|*d}WDqS_`!c=_fC^C|Z0yQS4=Bt#F?TbfATdcnPTaYG+pQA(LYPKC0bW7h zTL5Plv-|4<{tHdo5G|zgkz7HIFGTV0w>`w_HWHpww{BK)?bwLrlCR2q1NmjQ+uDg#S61_0)9d-mI@sPK!lY^2w#n&bPj-BXXID|e(tz#=9#knqmYSAr(A39e z0h_t@|5}%kJnvZ-5h1x3_)r3Tc0$mv2rYtSZ_|_LA|tzFdll>@+Tq*+@<)8=;OSCK z$_@VYPz!%$?wGc(Q%4e{i)<|Q)XT76^#|bKuUnFiaQv$Yzx8Xb<2Q&Vd0ol+(T~5> z#A)d%20Ob(uC2MR2Ay??HGdOiFRdv5?tvncVu2P}cLjcnK-{wq6BHz6)RSPg$k}Ij znCu+RvbUEq_F?9E^=d5({5?pyS!aqK(p4#QzV~sJ!R9z9oTJJ`YrcDsYTJ~zM{f8XxD%hw z?FzJ2(TI&nY0OSa4%F+ifr8)Vh;qMsw_25Ytjv)6dFBc9UhvdvWxVr{6>lq+ys;LF zmMu^U9zMTaSIo0Dv_KzTMFSzXb~9oW_3=5t&491`hI+h}$)-Cx(`DhF7;NyzF`b$( zUIx2?cQ=8UENQ*^HL{mM_Xri>#9B-h!Oq@ai1NL4AQA$W1|$O8PK*f@7Q|udg%_3Y zN}ww4UssNl>m%AEc#ly){@`ysw9BB*aA@I7Gbnc04tQqK>rg)Uqt4hOylDUf!3;d19xt)AB0*2xvo zq{iNtj@ogXja&^pzUE!%8PvV;ehA^J4JGR~MiyM5E)Ke(a(2TJr1`U>l03kuhhc`!k)Ln3 zaAn4}H&k{eZ1dLdF27by3fU;XjWfwoWwSt<$N&)_n8$^=^}@A?6dIjJ&VTAHWh~zw zX8Iz>)z_77CnA-oQr-?%-u(Pwo~tOvr7R%69smJc^6t6&Bnw9Q%%iC6r)TBA@&Srw z(zAXkrm{X2s(LG8B78@)2Mb_6U0Yw6+;`#Upd`?cz)mi-)mUns<{TMYqBt|ITxbK0 znVZyvS8*-U4efIL>2nv9DSbEEt91RM&qb_jaaM-b!h=iW$M{##^O2Ri*IeysH(V@G=zZaANMD5IWo?zy%3n#PAu5Q_%X7wwLG-vDmo=r2jmux=K@H$e2~mryA!KqSco1h!8RS53}}V(GK!Q zV@v+ddU8wE#p2sjoiwwV?|q4BB6!Hbl^0ge0y*AzJHn(8x%Tfit%UZLB=>6!3l_+w z2U@X4cG321zuhy~g-X^s8_(H7O*Tq#1Blp=z1g@Xccaje6d^r5v$UGEWqSY57>Wq_ z_0c#yfED^ZJeUzlFUs1)rRa)pmHa?i>d!&GORvx(uLf7NO1`V7EcwM>m{82VvHLSm zukEbc`-aw&z&Xb1|&u?~X*_o+&>4G&LGYZ0f*hx#r ze^yV5{K+g{&pcJ_a$naO`>i=KId=7BIvboVO}++SRZ^f>eF{9>QKf+$5C@X@**wCx z+B&@e|FwAidvLOnJNI+t_MB=8j`jI512gOtr?Ky7PTOUzWBX9fYK4WQ)fG(g)6*Yfv{5Ik8hY~iN% zU~oWClGBc2|DzkQ$BkUqPt!Xa@2-;??C+$(0;Fx+k-q{O&tz!I3-i!xnl=xI-?0?M{;#8b03V3M1u*@~I1J zQ`DO!M_0D9&N4pT>4`W+nAiS^WA<;N_iNSa ztoBq>;L1nZWWQhdY@T=iRltD?o)`gycI5VpJEj3lw6*@bM4k@w)r0Q$kIar$t6n}jVI=u3V|4@i z&}Gajap^$|ton>}C{5F`4g`=vK5AIf51B)!X9FhLH`m%R7&F6lN6M($O00xNx~gl+$ZEh9JJ*%AiYdV0O9Ahjxv5w7-PRrh!eE!pTIu{f)o&>!)3t{4%2){fW&A9G`d4KKzl zd;?XJgXwAOy&wKws!9i$(;s{9=R;WAzqTTDP`f<RA31Qi6dsmaK|28VLjJPoL?%{1)upl^e~>3(!ZIhy5HWlaoFKB7X-ZI zf@$9Rs_d|V_ytNV=pQ>{p=eb0TJJDJh#c`PGqA!EBqm~XS(g?2Mo?#sOUC9>{08?j zIbnP0{=POwJPS?&23pBXN$ug_%s(8ZpnO5MBVxgyzk-K0{Ia=25R|+#EsIGA>Hkhu zkg8~X1zNISMF}}9E);K+={T}oDAG+_MztobYf=3t$rOKWm(PsW4o;)1s2C8FYn-^Q zPqqjtR9{E>Q#^CQYDoi<;hFPhKd|Yb@^q%704opUjKN}32tk+>1HEJUf?`{sVZteP z7ImeZYw#gZauyY9Fa9;Ryv`dq4Az6HL+N>pP{s7oYaWv-Y6;+EI<~e!6829*ae1LU ztQf4gE!m$YDpz`VS8tQbwTxf>Ou}pdcR=!;nXKy>#9QNc9xD_Riu&kDu!v=T8V!P&S2JcY14jG1|X<&B>m6$&~s5Bhh#d8^MSw#}r&c zUae9f3m^{AjvfN*Nu>>$OvdGpl(cK2>bPjW$5T2D3V3Ok3zK1NSkR*H*59^u3IwR} zG;^fmAk}eCwg)bFcVaB_Xr`Qu#QP+znz+GRLoGthb-!LVGFrw~U+*&;FZF8b37)>} z2vHcb8ehBP>0*Am`cfV~{z$urZ=i|a%>1`-jyPCMl~#|{;?|)&d}K%_X2_ml&jw)` z_AYWx{=f(t`xGN`}FMo~8#5%IPjeXl!j3L(I0j~xnw;xz*s zIrCUu-r9m_fX@roTP*UYIjkBUUn!HUD-PAOU1MSD&QR#C+4J~?DqO%2u^H}F$a@SC zsa1=dF6D4;r@pA_**Ys@G@1aM#Z_V>s?|R7Rw#6c=shJ5f0S}X={E~E@t+EAI-95- z=$}9kbpI}nApx}WRX@zg)(?Kazk7cnwgUp5yg-B~-+z0*^Ul+PhyHwKvD)G4I#Ho+ zn(Q!D5V`iGgy6PHh>OGQa-&rehKN^IFfP)}SoL zIm&^GCj)Y2RxS3!2;6|F5c@c5mPeO$R^^1UV!qW8DP|;ZMGGoJ2)ovw%atB$NUTG{b5Gf5@FKuqd7dLc%m>VNju{T>drZ+-=qa{FCX?Q`+i-1@3 zt1-rPMwF4Zl!i@oTL&W^$U3{c_+ij!TmwoJNgP8usq3ol37lCAqtOOav9`^-U#T+* zZqZz8j)3(~VF32;4=9a@fA|d4q+zsg7y>bhI_7^b&UIQ8^HF>+1i+XhZaiJ@#f|Y6 z!uN(iEr@HS0WXB;Y_7r*bkGU~ zDWfvgxaVlv1bt*+A&gM7iYjzWR{~Zh(r}GUB~4QeTpHX;9A!PbWzyqt`Iv6ToP~#N zvjbP=_WYDb9)|>AM9;(f#sGg4AVT^I^NJ(J!rg6+<$4c3jy2~?D5QAA(B9sVo}MS< zV5}OC!6r9UIc&QyXkV9;(Z!~3W#82;prUFjrO9mmv zS8)vHxgTMM$`y%n^9~|kWoSk*sM+7@CpRw ztuF+lXMqZa7d*_F1w7J$fEPU{$_r+zH*SE(PQ=M!CE6@2(nhD-Vh$oW84S4COo`=?ZeKm|?EKr)bso2#c>SF1 zc5Yd6=YEqG-(iHz80{wAFkgikn_?33SEd~VL-ud}#0E<1^}D(J5cApdJKkqc=AF~Z zw-$yM|DodY&G?;@DK8!ZTvzFo!H<{~TCTz_71(A4?cc>EMLvwQ7arChdyBM9nmB5s z^ST9!gWACU68SexLVj(tSe}xQyeH#pKaF?}IuBOahuJY3eCi}o;=}s&Lu|`JhgHvY zajQ4H1%rQ*2HTwvqRH+L0xPM&C;M|g0*ozC%+rk3!o)RI?;!rVJ7?226@6rP@WLJ~ z86Il0)a3BkUVUM;L*OTYL#jvS)jxYXaa1DtJ3tDaHwLZCalBc6A;;7Y{jXdZ<)aCT zIT##c@IR`lrHi+IofVIRZP5Z;8u+ut`!Vduwg|10u2@hsrUw6(ToqgzMVhjak5 M3zo)JhR8er2OfWK5&!@I diff --git a/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithStretchedItem@2x.png b/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithStretchedItem@2x.png index f3e20dbe002d6bc80a50f17e184f4e92ba75f9cd..0d638be53dd537eacb9e67f6d1023c9e598b1f6e 100644 GIT binary patch literal 6509 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 N^mUDODz)HI{{u5EX=VTb literal 6480 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 diff --git a/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineFirst@2x.png b/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineFirst@2x.png index e45ab35c683b340c6d895803d81c337bf1992af2..b2faf101bcf0b8ff2e13c25a4230ad318180b10f 100644 GIT binary patch literal 6691 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%0DwO%IL1$Zjl z{gL5FdZY0~Gs&E0m0{DU_3$DOIN(~LgO4+~`f8-*(~kXP$|`rW*+q|5hmWPl(zk6D zUds|OgS&F=B#wmA2^C~bAC)^ws>5hG00s?^x;R%p!Z8fq5p_)({m^yau-4%InkaPI z&6`CksxSAk-Cq9CxNkch#b;yzo)|(SQN=VRkAQZs>XJabTOW&JCa<-8!)!M0bvj;O z85-p&Gbm>pPD3+5xJlNkqci1dpVlw@9uxnur?EUu05`$Y8o9IO-DKzR)!tHia(UW= zNAr>;Q=k(~Y=HDQ>1^q)5PS8;^WcC>%1!F6;j!4%4@dhzl26_rT{Q7o$sNovG|LdV zcs1y2RfM9N=!uD4#@)eL(K%@mu_^ngwNXZCbOp~fN%u$<5ilCGl<_(7nXtbK!;6#c zwUDayi-Umv=GMAuXMM)$ZoFYlJ61x_+1yV@QU8b`htw*tG&R+6i>(Tc_kD{zjDFg- zHx}6pv@K}tQj%g|R`l972cLMb-p@7XCL7#n<5DOY(ZLJJ$O}sz@ospW7s@`nT>8UI zsl{J%@w1vklS%=ilGw-0gQzHwM-Qsz^s!#I%F&MBA>QT5$?_DYE)hf~Hq2oZS*BZF zY(u!Vb+hAI0u4BDl*%nW+qPd94-UR*XwtiHXt90A{C)UIfa_FZ+)4xbX6 zp!ZkXBz>9dJ`JAmi`H8U=liO>PlS@6ZtJpzv+ChxT9x~{2D%zu&N!)_H~U<(F3;tm zvHLV=)e5?*bhNeZBoLwTyOV5U)9bplD^1|e#0^K)QYC*O7mjp-_&wZlRV;jr?f~Eb zm!M3zWt|}^d4$%yxZ4TM(Xnt!&$V2(oZvM~Q#}*ZaF2cGG!_;S>SJ9faP!XlYn!>u z+xa(iEP5DU@JM*DJ#pZfTl-H1d`58@6sR{o;1tp0O?4CVm34*k&~d+mxt12sqz?Bs zpga3fcAWahA!jp`E=;E5205wh3FdTIm+-LOMs-ZNvr+AvSqxCIa$S69IE$(A)Mg}B zK^Z)C$71H-j!Sf{-dqj~x+F*ooFEs!^6q%>U$rZj4Ag%k1&SI-_#!A_6B#g-tjs)8 zvR!CXJh{=pQR`IV+=JKM$HRni WlzEq3ck#~z0J&>;r%cN(@_zv0ozZsy delta 6605 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 F{{fwNEDitw diff --git a/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineLast@2x.png b/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineLast@2x.png index 6cd4909902c6322b39ed0ac80a280f2841478def..0db8e01c31b82e3377014884a719c87eba4b79d2 100644 GIT binary patch delta 6515 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 diff --git a/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testNestedBaselineAlignments@2x.png b/Tests/ReferenceImages_64/ASStackLayoutSpecSnapshotTests/testNestedBaselineAlignments@2x.png index 67f32cb4df959473f1aaee1eb56c19d2052c8921..28e13ab82187707d0f49d4ae78a5c855ea5add93 100644 GIT binary patch literal 8786 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 literal 8690 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 diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testShadowing_ASTextNode2@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testShadowing_ASTextNode2@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testShadowing_ASTextNode2@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testShadowing_ASTextNode2@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextContainerInsetHighlight_ASTextNode2@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextContainerInsetHighlight_ASTextNode2@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextContainerInsetHighlight_ASTextNode2@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextContainerInsetHighlight_ASTextNode2@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextContainerInsetIsIncludedWithSmallerConstrainedSize_ASTextNode2@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextContainerInsetIsIncludedWithSmallerConstrainedSize_ASTextNode2@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextContainerInsetIsIncludedWithSmallerConstrainedSize_ASTextNode2@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextContainerInsetIsIncludedWithSmallerConstrainedSize_ASTextNode2@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextContainerInset_ASTextNode2@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextContainerInset_ASTextNode2@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextContainerInset_ASTextNode2@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextContainerInset_ASTextNode2@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTintColor_ASTextNode2@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTintColor_ASTextNode2@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTintColor_ASTextNode2@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTintColor_ASTextNode2@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_0Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_0Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_0Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_0Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_1Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_1Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_1Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_1Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_2Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_2Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_2Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_2Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_3Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_3Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_3Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByCharWrapping_3Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_0Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_0Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_0Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_0Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_1Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_1Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_1Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_1Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_2Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_2Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_2Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_2Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_3Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_3Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_3Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingHead_3Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_0Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_0Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_0Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_0Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_1Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_1Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_1Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_1Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_2Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_2Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_2Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_2Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_3Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_3Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_3Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingMiddle_3Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_0Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_0Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_0Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_0Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_1Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_1Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_1Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_1Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_2Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_2Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_2Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_2Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_3Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_3Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_3Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByTruncatingTail_3Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_0Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_0Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_0Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_0Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_1Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_1Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_1Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_1Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_2Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_2Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_2Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_2Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_3Lines@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_3Lines@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_3Lines@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTextTruncationModes_ASTextNode2_NSLineBreakByWordWrapping_3Lines@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testThatDefaultTruncationTokenAttributesAreInheritedFromTextWhenTruncated_ASTextNode2@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testThatDefaultTruncationTokenAttributesAreInheritedFromTextWhenTruncated_ASTextNode2@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testThatDefaultTruncationTokenAttributesAreInheritedFromTextWhenTruncated_ASTextNode2@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testThatDefaultTruncationTokenAttributesAreInheritedFromTextWhenTruncated_ASTextNode2@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testThatSlowPathTruncationWorks_ASTextNode2@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testThatSlowPathTruncationWorks_ASTextNode2@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testThatSlowPathTruncationWorks_ASTextNode2@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testThatSlowPathTruncationWorks_ASTextNode2@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTintColorHierarchyChange_green_tint_from_parent@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTintColorHierarchyChange_green_tint_from_parent@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTintColorHierarchyChange_green_tint_from_parent@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTintColorHierarchyChange_green_tint_from_parent@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTintColorHierarchyChange_red_tint_from_parent@2x.png b/Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTintColorHierarchyChange_red_tint_from_parent@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNode2SnapshotTests/testTintColorHierarchyChange_red_tint_from_parent@2x.png rename to Tests/ReferenceImages_64/ASTextNode2SnapshotTests/testTintColorHierarchyChange_red_tint_from_parent@2x.png diff --git a/Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testTextContainerInset2@2x.png b/Tests/ReferenceImages_64/ASTextNodeSnapshotTests/testTextContainerInset2@2x.png similarity index 100% rename from Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testTextContainerInset2@2x.png rename to Tests/ReferenceImages_64/ASTextNodeSnapshotTests/testTextContainerInset2@2x.png diff --git a/Tests/ReferenceImages_64/ASTextNodeSnapshotTests/testTextContainerInset@2x.png b/Tests/ReferenceImages_64/ASTextNodeSnapshotTests/testTextContainerInset@2x.png index 7e6cac14b804f09ecdece6aa2d7e8e59d44ecd48..3ef2b4b1a19788d723e8b1fa8ed27857f6e6d1e7 100644 GIT binary patch literal 2725 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 diff --git a/Tests/ReferenceImages_64/ASTextNodeSnapshotTests/testTextContainerInsetHighlight@2x.png b/Tests/ReferenceImages_64/ASTextNodeSnapshotTests/testTextContainerInsetHighlight@2x.png index 4a2fa33448404b42eb3f35c85d2b6ff8845c8e1b..8fcf950b841b22573bfeb2f0a055d9dcc4e12e74 100644 GIT binary patch literal 4908 zcmeHLX;f3$vJQv}DvF58Bybr7v;_f~nn{^y1r!hv2thy*BO-<&3?ZVef->3+GIYWy z*gzNq20~~T5NseIgG3+@+CajbW(YBaB=^MI_pWu<`|4@(GdMJhk*8wI1b91l;VFnc!fd>4Rx6^HBXV4j- zE)EhCkq7M+iU4FOqVS)(y@(cQ&$oV25a@X*NbGMJ7k~>(CO|@+fAKxVB7aK*eZ`{x zmKJd<-t(Wjj!^A-2c!#N5)T}2z(AlA8bT6ra#Q~c=u`}~b@c!^@WO8;4|r+;B;){z zldJiUYye*7WP8a2F0w*#{t)Ia3z{`E)YtzKsFE+Gkz$saiOw#S$;(bUl$w1sO4~{< z|EqSS!BzW1>KpF%`di0t7Q3oS>{0)N+P<&Svl`2u;1+cdn9yHC$V*cpXe_m3e3VNd zz?isn#Rw^ti;qAeqGICTE8ju*ACXWG6|L-k=K3-sF4f@BKHs^EeI?nKwJR0HqU~qL zKEI{^QEYd(obpg=!C!?p{;~8?_gq__NN0XD)&AajgqW`e9{qz4prp4y3A1-MzluIl z8cWx6Pd62hJeR47hdE=fAC3gu8aWhS|1-H-n_*f!@@=FYMymTh@_&lK<~E7>>cg9< z7ZFkTwQ0h#YNM%W$H~8LPEl>L9tw`r(%^{CKdcKWxN-kAM71RG^Mn$}eI(3lK5q z>Lbgf!tr|0a&X=+q}AUZ5shcQ=57x=#$ZQQ+M!7m3O#M`lTYbEIS~ zMdeb(Q8JN8+AIG~sfH+UY>CtQA-`cmK zp{Sl{~{Ewvr6cZ@YH`tOp8%28VLu`&p75{2$jkREc9) z-C;*|JjtDHWTcy{D7JH4_A=j-2|ihbB}V>$3EvqAKcmNl9AhTI1$BK0EH({%Sy{mJ z-mLjVXbCId-$4H~*~*bK7f$+~yW$juYnPcz3LVX0lf43YN6CXP^_q#ta^g2w33ALz zLC18H9x7wqGqppOQ?$E_hBGm;HbcH(>YFT7@>h;Q|E4F@zZOx5Ziw8Ul(@G=J3VX- zalx_QzJ9TnTY0v@|0UFBxm|yT+w{=YXJ|_A{tLZG<~p3&B|ASkx~v>jq#U#`6NwnL zkIRHAO%08)1DAy}yK?U53Pwd|g==R|j^yITJ0tcDYzC`$|CgfUWGjrhajhDnFrcp~ zgNV=D7l6%$?q1Sm#R%U zLq2Mkq43~<#KiE}MEx~wGTNVNDP6t28zp$YJ88ki(H~L^@rR{_{upV$s93}4diUFJ zIr$YH>)dYOFRMAvf;=R|ILqlhToBI>U5c| z5!jH#I5jXkZK3g<5$i^L4);0XXJn1Ou?3eX>yGvstmgI3vXk?+JqMlZ7)B#O5w43( zR48UOXbt=M*^`T%qOgO3i<~;KunDaZh^=$1%W4oWM2&5EBi3_AX(2mAlH??5fUqg1 zbXn|)01R~117SIYQ&RjpEKk6~B_Lz0|d1TMy-4$L$jt>wazVe_aGI@TwARqd9S-8s+-Kb+0gwd=1R4XL7$DV&7N#q!(`E}lc*%kOYWDQ> zyt}5XJbN~|z|FCvg`P(R7q7??Lu(|OQcLlbbZV3agVN!W>-S3oZn-PJftGJq2Ocy4)!R{%rLhU;I zTt=c)_bq*djbfos7q*m#rmeq>X-2|^6JIaeneAL5ft8RBw^o)TR-WcG*%< zkfM>YzjD+KOoe%G`s77)etsb|vED;q@#^-%@)z!gGwY78CMskwYItu; zA%jtj0YW=baP=02>73fGo<%QW)YHN7=y;u$QsG9suhM)c#_)B&?asQ15sC}WF*+g> zMqKS>BRv-jm9ukhh8^G&}vG2nri_N551vUyDNKp>SU zw4XU;@FJLnhvHB;Cy$@7I2@Q-qzTDMhp+~x$?>I-RbLjD_H|75^0CnLCRRb^cH3Lq72h?waylX`ic4rpCyHA-&`nix#vRr*hxA z*tZe2hi0_s!f2&2@Foi&+-RnW5SPf#F`VvHw{u{|kk?X$2@gCEFnqJ7F`_+>1!ASS8pos&(5&lMJ7iPkr z2~d7D{xy23&iYg%J+H?ve=gBfj{)cJnvNr`Z8nWoz?9Uo4#Qe}HqTT4(R!%@0BSaK z)+CCWz_oM1BQ z?RxKjdL+EJ;RLLZ_HK}8pZV)i6IyvBtY-DdwSL<+W=w(fY{aqI2J^iNKx&kJT&q`! zf%-`rp`Q-6wb=F}nstPlhY9CCsF&g=v9@bnnP9jRplH_1@)_kbDyZU(2BIMaukRwY zOa({E$*9FR4Yw2zecb!KEmuT2rVHnhe2`V=al!4ejhs7{mUFJtlCXC?bPV(*{D2Vq z=EGI%37lU_caKGLPW}?jGZ>(DbFMVg2x|glZ1-rTa9{WToSo9Vy#z~G$-lEXUge7! zr99{Mx>tQ0Q*Y4C;#+=ZCb!MYlMsr6M70lt;`fTm-$*ZFy~#G$AZ_bA>ccek;Ybf4 z`>wy$_)a5ulU=HuT42@OX||+Lb{}^dh9+8}JcY-nbZ@BiesW0rw!)=odlfM;^Cu_B zj{?*_VlTc_(SII19VIoPDB|Su3K}7qd_fd^uvuIc<~R=CpG7*FIj4>TgdP8X37cC* zlT|YZB4|G{4BtpC_{_#Om^r1t*RDJ-DZ%r&E9`c(9dsKVy-L3871tv~fldJHqk zxz@AKj(+fxd;g|4T6La`537o0U`+|Cb@~u-@DfRb?^N#?^=7E@~-pja-MzGJ_qG;&0b1U zNfH16NI6`#a|HlIJOpxTA5bu3wVJFaXhdRM?QH=KBPy$cfyBMb-Z21x{Bfa(IJh3$ z6ilkzwR3hCw4wqLe)$5?`MVYLB~;(J7rg`k_N_YD*|^7xQ0J}=MYyQ|?zw4cX>F@L z>e*YV`*``mkfWi?l|mVf{=SE{I>7BAM{U=`zyXs`aGk>g0v2JBE9gPXUtxBDyMPeAy6h z1*)Gn@nN!TjI=00a#z|zqyGA3hPmso`M$HdkM?%Q?0I$Lz*)45$)(a8hYRiBj6kfH zWI}GJAH2UT>0hrHVp0~KXB&Jy-Vf{}UeRRe%p@EbvJ}|*S2E3ap-xVWpq-Z`Q~Shj>3SnW z@lk?!k=&3Nx$~{3F0jZ+M_J277d2dQYuP}Z@x!66m^AGFwL^Z`%@SD|C<0reFx|aP z`5BMy$9<$%qsp3JdFyRa|4Af$>?9`sh``e;N{iA8moK(`%4=@Aso?Vc-x(BFtMs*o z;AdP@-A4EEGqih6H{8)qCzVN1k^ZQTUHvZ=wY0>gPskS0t8!9;#bN&oi<4*j=~Mu+ zVNBYNQXOVqaVD~8Jw*b7QDe=kZS;pk*>TR!wvSt(n2D{+6=bCiVhH+W9ID(WYy(a0 zhMDZDh|kKdr1UJUzbU2iA(}ZC1t=YLXK1I#U93ccpi{nFo>Ru!g6~g+_kSaRMw1kaxdA)zUkR!l+S_>l1DSE& zJ*;0B3X_~D{T$H6tCT8)%Es>@-#AI34x$*@I+1= zFc_~>1=>d_q2u1hA8b&h=dCzn^f-)~bzI0Qhb%UJC9Lxp88oSpoh%&wVph4LW8+p=$X>08$w<$NFieQ z&)%9v+57W*@58URPSgy4m0--tjphwFz*jAZ*m7tX-H)H$3xyC)z92O-J=EOTsY627 zPNEtqta-)Cn;L6=%Sn4S5x0v;<=EDF1xZ%5Cc3vqkBo1iv){(wJ-yxwdgkWd9=NgY zIM4&KlNODT%yjszie`T5GBW+69Fey3Vnx{^n61SF;|zEY*K_wnisj)|SQS70Ig41{ zeSbEmo;=$elak01No?nEbKl&LK%qpA}TH@&RZ*DJGuC?b-6(ec8--J<@`Xf*&KpSM|5AFF=d^%=Xx{ z0Py(+?dNR-#m^IA(X&Bzu8r_G3bVLIly4PyUJOFCf9w~brBqeF*&@3yXvhR;lZOH)fUg8>#$^j~y*5O#^InP=~XZ4Z$ z<(G?b(|+r};#)orb}kpg=-$C6Ir3%}K;H{or@pPo>-aM=q^f9|<2dgfim4zQ(cNTa z5lv9Z58KN|2A9*zn8>4d@vmlsPlTEHw{&= zbZkl`&Z)`SJUsDKb)_(gC!HE|VhgQ5^xbz>(H*ohAEWhIcW-xr5Bjnur5bcOM-#ul zwx%G9R$!5?H{GZg7#Nsdh^&C8!{h^3+fU~Xet6@TT?o3olS>cV+AU6w{Q|}R((u7b z?bGM3W=z>&j`UYJ#f}n_yH*qcD&o&UY$}9mX+d6HT=JVa=Yj-0U;g!0d@%^HLpp#f zQcX8P66yZ=EdQKD1hI^XR{L=9@qDHa6Hd0n|3IM-17F-6(-G`IfzPh-2;8vX1M4b1 z3vyGheUNLI5W#M%bw22ehLb<7$?E07sJwvTX%<7hy8sIz6vQ41CNEP_a-m_7`D}!cVJ>qO_35=>8Nk|J^X6%K&LG zLCKe1p`USp>Nmy3P?k*Mg;5M|F?ia=OesC(&*fTX!%ai;#TiV>b+8)rnu>in{M&7> z>E+aDT7@z*-#{83p9epWvjP3?@FENa&t`d%)LsAf1B5i|=)RNRjFYf2uTxn&;VSs=zabc0!m@n>-(H1J6qybl7GNZhl>)$-2?6vU!ZB0dX|9!V&(y{74wWp}vu~hUh zz0|}&O33QH`n;lLhQ$lWyLEart*4gM$ErZ_1_x9v5Zdf>=337p9*2%}22n``anl2` z!U){YNXlyewlMB>7^X9_p}7=g4~}xqG%`W(cb|9gx(c_#1revU1yIsp53oY&C@9}~ zZncejhuB`D;I&6KLgzk|WBo7bPZA&I|yT$MDf%&XXLd51t z0nKKDAk@X#Z3Pj-ajx0g1Y{YbIZUCw$LF%2)M7FcE!W0tujb$)`22%SdnGN8S)L{IrRli!Yk%1<@P= zf63>^yl{LG)9Z^LNIBtwckh{Bp%RXqf?2G z+mUy!5gJ>hd>%|5b!IRyvr@+=5CL4D*5^m-n&Q?$fB%1{nHvg@&L)rgd)6PVX^Nv$ zexN_eow9K-rg(C1e^ES6B%dIj^$^s-E=G4Vk53tul^~ssk*Uvvk_P-n@Smgt1H?nM zvvb6eJZKHw4rjcEs>PrL`CSx!6qdk`PnQ!A;j;RN6Nd))VRJu?zxAh4Z4)ruN>Gp! zX9O8MgeJRaU$Rcg{T%vI#6nox8=K@A9N!Ky%|ppN`h2WIDeU!#@S2b%73hfS`JwZe znMA{YQlqdycY$0u>ZTbLd!bNKMB-XXT@#Qhto8q&LvJn=cxO2U4zsYZ2JT(R!ThWpKJd=Zy*1Ycb_S7-hPRM!RFgeL=oY0mBYnrb`7?-QvM6VR`ksP diff --git a/Tests/ReferenceImages_64/ASTextNodeSnapshotTests/testTextContainerInsetIsIncludedWithSmallerConstrainedSize@2x.png b/Tests/ReferenceImages_64/ASTextNodeSnapshotTests/testTextContainerInsetIsIncludedWithSmallerConstrainedSize@2x.png index 5e2062b8e75dc660be17c8f7a4df24b3907ed906..fc14d5c55df4ef84734806cdb6ae158cb468d881 100644 GIT binary patch literal 5914 zcmeHL`9GB1`)80fMj{F`sAS7lmV~jCC|k;s7>`L3QzToKX(-KPErqhr6OSVMQq3?u z8fKLBp)6y|(8OS3Fc@P#GxhmCf5P|s!?*K#UH5hF>pt)6oa;L8b6)2@Xcs5D-D3O2 z`1tsC+n=#L&&S7););pLF0RE2eZ`Hd_`}cJS@Tu(D9&+Tq60kbuR1#NX>#i#e1iP@ z`Gj~)xMIP7;NSXb{v&(>KkWcMz6U{kg8yyf#MQi#$rT>vmli1I|8Hxqtr+k>t@%;K z0{_-cc(CYKpGUY#H1v#DI3J(fA)fHtpFjA6Yg7!fb-uvW+zx-1eD3oIS9qE$BCGb< z4pgpwZ*OaLA)0?-+_}6mTweGGwy~~mg&L|W=l*bb?iChXckx}VOC4D2z@Y#Y4RLYw zdAS|<(E|_LWKW5@p0S=e|D@FAXyIQ=)g8H}hK#%c9K(VULz^=X{KjUox)=!vX4hCa zy~IWiASeO^L+{MKuUOcfj>JW23p$8zbp5gB z2Q2HV6JD9%0(8I&_X?E1(~;Uc^-8FX64&;@c+jiu_;uK#~i?_CP?X(7pW30RgtT%Lzq^^t++orGz6F4vHZE z0a!bc=8!weN0cOY*+EQJ9|)L5?zsmE;#X0hS%n~^o=6HOseu)@J|LCMM6HV(?qJl7c6gBVw=__a{q=o%fuM@ZB?w8>)Vyy}p!CDvQz9Y{c0&D#PKmtX&)m!ZJ$#{L z$+rv}=C#2H*L|mU$D7;abLQolI&Kjmb~?#Fpw#?j122(5Sx@RW&!|bQq%}%8qG#}> z=cIh&QW&v`lO(gNdwN#swmg}ZJrvB%wjU{P}RP3CUtpEiP=e>$m)`LFuC``e6|n+qq2r zH_KuY$E{{!ps4Fv*4~Ky89u<{GZFBuvBRk4)`|XCa)1aSBc?Ljt!^wQDdeOS+qshSv)BDc>De;T6!%2^%hrhZg`>WydwsA@H({!q1A^)kJDyP|#Q^l=&5XYIru>*A{SnMl2LQB_0<{cSn>@V%Jc z77%OJ(mi*F<^;5($bWKjsjpH;NX_<_tHl0MNtHAbN4^8tOyt4}!7HyZaTQnHr;f5b zcfM>qDvvmf`UK;|i3g2@FEx+D!tzyEf22|+4Spe>a1j%!*~7XacoY?i{@ANrh`wVs zKU6*!??iyL$Pm5`Ge0O0L#P`@g`eyf=E`yDajYdq`G6}tZ*I+ec`VahzbRZe=VuOX zl4_lRQK!t#2?w)wUPmvLm3vifx)B9jE$tc?!`a<~%*|l~4v0{1xc({L^5F^PjYx|NXql(Y9c3C<^qpD$+)jX6RXQ|uYa7qAU@c+R!65$1Erw7rl-v& zFrupJdE0sRa8{FrLWT~@lF`lDzOrSrsuFvJ+^aP93(wERpOk*x*A{)NWnrcd$EZ)D ze^b=Tz+OuvaWJ=6wl~*amgk#{n##S_MZ+2J@;M5wp-o?|;Lk0FRe*|%hac%cbgB%& zxnFDm`5e!v+1L1L7H*jSIlbjtV)U(!R;j4VAJh!fvx{=qYv7=yM2>r+7>54EO;Idko40+h{|o0B1|HY7WzV2G*7Ziy?# z2YRgc>f@q|yX*AhBCLvvy#AraEHhH>ESDdGUx&qbHO%36;h*(6zoyIl;qBrj(x6q- zof6$Fi(s9!ZErG7em293|HcRq^6$~d!lf>xbB2b$j1wvC%G}iTRlPUT-5GZW zw}J+Wi@K^a;NcR^DeKIOTjLjy!ycwh0R5fgyDh|#kwV`NHot{Oc_T?t;%q>eeMlZH z^lT|q$iI~~HWYA<6=|4cs0IYUjwVJd)|15umTeVKa3NM88C0=q_7`NP1x2;PsZ6t_ zL1}MPROwMO@i|4d+XmAUD3;n5bw-J>K~vq(795rJ^jHB6&~Io0pWSAmj}=*(`ggsR zTnu+CrC$^$gkv)DR159| zVzdDSz1+Z}|@6C-Ho3thK2LL?QzGT|BSTfXk#l{e2w z!LW~*WeUpK4re$WN@$nfEO-=nY9S>$gfKzLV8tKd^$l+Lw{Nl#W<9XN2Kof6US?(a z%oj-hCVz#DLypm-${{nvOHuBl+pK7)u)lfaIhH1y3uhpI13$94jJr{kNPfF$7=MFxf8TJZssHbT=brH%>4(~qRxIx^u^m8)+nA%m@+ z%yl%ZTnUPl=iJ$a{pmr5?9|}R^`Of0uyH;l&mjBHr>)ttsO_T!yyoIctOVD={aNPI z9iHv6_vBZMC~Q~;zVzy69Ol2`&_Kig8m+tpu1e1-DU#1V=3e{%VZR=nbSj6bd*uV74ATwt7W6k29T7(y% zIc2CM>1ROabW+<|7wVH*f^`2lhfZvcYM!NVIpwgu-Q1Gkz$)rkKdZWhK0z;1O#hBJ zxwbX@1<&(@GZ=jeiyRtiUq4kn*{lgqZ*L0JzQ$-6_Qg`eX^HH8N>K%5*bzCvqF5zk z+UrY{&Im6@fja%Svj*#k&j?bdaq1X6Js0o@_C^om9lFJSLM3Vvk63(J73YJRU*3bMfZnKTF-U zEm$ZsOb%B!X*8rS!OK%qOqin%(D`A`pGAZ3I$RF_Tuj>*=W=(w``~O+g{XyR@PXB>J2n$QWJ}Q#oEwau9rH!ilB|50j@oB z+uu1_(l!(lYuDzG%_jMFP!5e3J3VFN3<0G2jyfKn4>F#$bMW%S5_^blVzy1OcDBr2 zu@gAUTIu#MCfPPiX79a={~sj zHdE(*Nu?CA37+0ryIE}@{M<>>DgC|Xz7I}Ic}$6=lq1~F48~T$$@JFfs&GjXSn#== zC$+u4oQ``L<87-U7EmArlQ9n8m-Z>L{mN(4zT3A#Zwb1$fXkLRUyEDSFzZo^rI5=? zmPMoZ$b}|-;VVFZqj<=Oqo zQR8TM@6hhWHUHqOOq%RV8{!VDOA+-lgvXHFl=l{oOHEyh1QxIE3Oo%Kyu2aNg`5kA z>{01!xI3d~ZdwBy`WeANQ~MspT#H}BJtH}g#r+3$R2NpagFMcf`3c$e{}M9ww-vZw zUr*S*NFZj>lgpwX#U^H*NTg}amLe&bXk8qH6ef(=OLEitnF{eWlLK^%pVaGdN%ZrR zOyy#_Jw@{M0Gni&)__Q7|G3AQF3#E&IHQ&Q%RMSU?cY~rzpn}ZkM2sR5CD!49=oiU T<^pl%T^!q=aB<0x#SiqBxQ0N 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 diff --git a/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorBlock@2x.png b/Tests/ReferenceImages_iOS_10/ASImageNodeSnapshotTests/testTintColorBlock@2x.png deleted file mode 100644 index 77cf9afb66ee3c5e0b025c0b04b92f53a2d07e18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1543 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>sYs3RO!M_+ z&;qhK7+4sk7+66{fY^>v8qRiO)L>u+i!(7Wv}ZD~K-KsGX%LtI#2`Hont1^uR5eg+ z0TW#Hi3Q9EHb|T2wN?`##aZAHSB|Ursro{jMqkR*jfyuBElnmdF lCPGpIa5U3Vp6Na@*#C;$W&Eq>1u!)-c)I$ztaD0e0sz9aE^Gh* diff --git a/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithSpaceBetween@2x.png b/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithSpaceBetween@2x.png deleted file mode 100644 index ce4006670208def60b0812ebe3f4746471c6b095..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6430 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 diff --git a/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithStretchedItem@2x.png b/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignmentWithStretchedItem@2x.png deleted file mode 100644 index 0d638be53dd537eacb9e67f6d1023c9e598b1f6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6509 zcmaKRcUV(R)AvaTT?{pJK}9+O;tkR}3eu!WQHTNp(pv;+0Yy-{5UM~x5s=|QfxXMbmA&+a+TO^vTJG4L<|0KlYwL&ppN zz}Ba-3?0pB{nZ}w;go^=&8}+!l{miNr;Q+IYyAgCMu7OKOb0+fJOK3{l~Ym!@&2!@ z2NDIS{`P|bAjS=V{71+5l>fPsPw9`%znlsU`j7T$9~%5$ZLl?(>c27|^T#YJr?}&k z(fi!6@dp6dr9TAHHxt@C?c{UQF|j!1rvv`IxK3-)Q~JYCiJH;no(~HEKqmBcG%bQa zYq{#K?3(N`CfeC_EcCH%I+~hK1*1v?qoUwN5M|w`>#$2w zb4ZPfvqD(9(CCI}9ZkCVgPdmR#MO1#jMf~*I)@LAONd!q&cQC>OH!X->6m+i(s(dU zgHk8+jq7L}6e0+K=yWcjxjVP#qqu&3j|>M*k_- zDwYOBrvZTJ%5Q+>7UvB-=w!w;fm2nDJ779V2+TXi5~=asE!y>uu^2(kN6YbFK=iDn;R%m1z zWZqap=gFxzK%{OY=|rKu6tNY)FY=Yj~$^7##eRyS0(xry`Z;?KF~9SIF}hAqvk zykNt?zf)k&K$=@Jp2RUnj!k*jyF8E4F!;aSDsw8vK6PpBPm7bNIgj~&X4&@3{{KIN zKj@sVey4%1tKw>0mHu7-G3)|uZ{%Vsl{~Ax--d@(T?{z#4MZttMn1vxLl&PPZ7&E5 zx;VrHcGqjwPpz%1Wvi8)3Y-ebBGujE-r_iOUQJha#yO1p_HQym51|hubFk}kPKd7! z%5--_KAbBk9L003^@9A6eAWhMxf;^It2Iyi?Xyl)?}UdH;rP?rQ*0vQ`k9IB^9xN! zTC&i7tKLJk1Je22R;#K7^9=*E@8hKr)WGJcryxJ{7@tg3DP)|3o=pTD+GS?t zAk`Ve^wcmmh=C|8Z2n@5cT!;jZ(bXmb$27<)RpcK-d7di$ocvm^E9RSzn-|doaOq; z4qo*$ZrfSj_L@?hlA0>9+K^RdTfhLUW0XxP>rG=Y+3k z&We;>tQJg8)9|&mecV{8Qi(|HU-~v`|MPYIr$)!U3Q7AZA|mmh`U=X_(ff9tw*|hN z5;m~8bI$fFPRB{JqX_RpwtWsOH26+?It zY9e22Qmy9|-WZ9E{`fM~|A7@|=9fS0Td|f{vYr>c zF(cb59LU}3?M&=XES{4~`B7DKxy|A0R^~7ljgz)f;^*gvdxm@rZC;K`>b%RdYu7fV zt<_rNN%3Sk@o$$`QJ$!T-nY&z6qoB;U@YgEit#vmhQ=w0Vwu}j3>P8)uM z>|cdZ*HMYyKNC{(y>dE0Q*vRcU%HlbW#MYcV|!pl@=vzIfBGurE-ve%=2wJ*6F!bEsj!xhAA|2&GnDZH^Rw31S1EdQ$21m>vK^P{bS4>Il~pU!m2 zu|XDpvnk{>mgw8OESFB?2h|0V20k1K)cFrsM5I$)_LlE^)$2!6%VJxL=-y)lfRhv6 zA>l~?V0-dsi6h*hug@Lf2-kw7FiXfn3!a(QKNI3GpB9WQK#5MXYToiUD7$}S;k>Q( zZH|9v=}T?W&%e9zWz@pa+Q8A3^^(Mehq336I`($Mr>1ZR8xbeU?QcXLg{{6iStG8= z5kihB!&j?H-Odpe(4~4o)*dAlQ$g!a9=U|&empiX{!0fa>)x{&1&!hkGnG0_-J2nQ zC!M4{0?oyb*RJHH(+(NsvqyI8qMemy62$rfJ34Z+-yWwA21;{zyCReXL_>?Ok>`hx zOWm7l6W&dHYszf54w0Jo>x}PdOd-0$$j@0GONG8e;cmW>UQM6k#QEa(D*XEcVaH;M z2kv9DZzlL_0=b~;?suIJV_qL-Ogd3+4R;9jD-I{h4%@1-mHSGu*(wm<1`pulM@4GK~e05iNq3J*O~u5z}KD_vV7C7w^fY z@7jiYiOHEioo-$-8FhGpzvkljzAj~P;k{mCQ|is%mM=84FAg?-=|~d$(h#f-7l*P; zkBKS+Wz<14EP0nj@k;NF&dopw9`M^}s1Nfd7@k4#P!SN^?;T1@lFwWwKtq{--kK?| zy)#>0S#>X?DS`sF1C*)ozyK(HV7#JTh0wo!H6V}i446#SNi9sJHr_8F{+n~5;o=~q zTy(&Lm$Af9ZspA?(|AJ32^cQmcA_E}kX#bl;@iSNUZ$d4W7=1hVV7j^qaF4g}p_61{{C>#WK>@}=wKvJ_(-s0ZyVLzQKO6*996;R7CMC+GZ1X4YKYeEVlTET?#+=8YN4Bs3$+}+R)(J2g zkzVw&SVe`x#Vet7G;USWk&$xuM_*yje;&RRYAEylorrM96IRb3$f8ISWCgI*4w-aD zc61Uw%wbPFsR2to;G>%o zSGcUs$vc7muCwxRL^#=8({5@|(K{_k!J-b>7$AN4==5czHm@uTj#3VHj~(z<&R74q zeMQUh{_i7o8`nG7JlNxKAT(F^neS*zA9)Mogu#yamA6TSU4GAL7=2O(UW4AlZr%P5+Lp&3*Ug^ z*=dF`6S-RcT*=3oYGUAoIE`;+KbssXn-YGohigqgN1~{J~A1F z(z?dc;(0M}B%+0W>f5`xqA-&*MoE|8C7SCk+ZT3{4NEFwy+{4CCLO33A;{VKS=w&k zds_yu4r()M*eiYgd0HAQK0XWDK{Zv=#n+(BXCKO1jVD%cPBE$>XWM~YM>-#MjG8+A8QMvlnopjM-I!r@ zbLBpDY@@uxV4~WXT-W{i;T6M?Hm?$Ib7m7Q<9`trS-v$(zV;_5y&S?2h}yyI|3ZAg zVBVyR@ecm}Du6ygE7$)-%PqtzuZ2Ynie-B9BlM>GYxgZ5bZP+~baza5*IqmSIr$}! z%Hd@(4ujtEN*q=GF(m1b_n2k&m@3B*olbp7W0a!+inm#g8GAS&d^L@}VL&5<7U}3G zGDnf4_Ph&B&x7WF*SKt%J@^)DST~rV*Y{*%^&oYSqG&tRyj<|riFCKv+*9D9Jd|OO z8!Hv9h8yxu-L1IWx{`oe(DiaoJKQp5cm<6Y>(L2>@v95hj|RpL>E?>uP}kbpkU&&kl9j93+Q-YXq*boBwTIPk?!bBn0%blK6itdzp$R_werAYO1+b& zxvD1DL8}~Ui_hR2KA<-FrnR_@t`cc$zcsDOaVUOw0J7>Ll{gYG(q>fK4kd|BTb+h& z3DJ{#v{U?}dd{`2J!>Aj^goF{NGB=7zvpQaVq~O}7Le`tBr3+}d-7EG*BsjOPzNK{ zpyXs1BaKCm(!P&x=)%-fCWMTgNeHY!Hd}N=MywiYz#K*-c-5S|jt%RMr59v-4dqXo z9+@mnD%fom#5S+b1(ck@Ixq|@pE-vecsv7fr^MnWK0SDJU7CkewI1qEE}sqiBn-X$ zt&*fp7uNiG)$?w-wD`tNqiU`bKR8=?;X;pM9Rx!)O>Usidrk|GohITM`H=_-^LjN4 z51E2$rH6{A5m%Mb$|+NNFaDhGaoNn2E1rCZrn)I$>_&C7T1m!kOEC^KTA4O&c8beW zSd6WRKkXuL(cvldD zi(R69#R|p>{oCiY9_8qNBgC7?r%9&^88WwrD77E%-k_*JEUyolvE}%MD&Jj`ljY;p zl>V9ZbeQ~hcT33nwN8u)PkD#zhmTafjV@!`!q!UAw#zf3SB`UEeJ%7I(*7oVW?a}? z(A8Z`5VpaB9x5h)BtnwvT`rZTJFLF48|`Ts5UOBb<~{I?vh3Ucz1rb6sGmQ>aU@dc zq!Q%c!izpm)XCkgQt&j8u*5}ud5w_*_K@3=QlOPqy6UY4J_+}p3G5VOK*wN&u$g^^ zS`{@DmPs-lF2iqJ-<5Bl8envFlkBP3O{7gP*NU7`X*;uZorI8ql>tJ}qFs`R1) ztF{Tm?vit8)!bsI7#qs?BjVr` za`S$T7k5o>4xA{{)L5@}-NWxreL@l0&g;(3;BHLIO1S3Q;?TDr2LbuL>ub}NkIMO^ z{o1+`h?Bdx58iB&3D;AI?y#_(Cx{*Fz>_V*AN2<;x-2dBv&L`AwU5P~C?V_B=QA-0_7e(4qjFtjcB-!@JqEOgbK_Zy zDwHLUlZ*TN1}St$KsygT?8IB@n1m)Tc^6)_?@*cQHAOJMgVC~KW)L3ENb2H?Z-qN+ z{9i96;O+r<6$kZ6HwsIhGC1^Z7a~0^OKc!LgJik|557+i3r?h7e&Q9yws-(fv${TX zx=JO&1QIoZz3JN)593e4S=~qsVq;yM^+e069mxf?c~r2L7y60?x^C}DtT}R`E!vLm zNQWlZYzYZAEc9I+qxG}u-Ga6R;k_6w) zEd{$cP#6d&8(xqNQK4O`;xl}&P5rT&u4)!7$vOMBmgCSVD{-bkFlCkgdbG16V^X_AeScpYPQ zag38@Ig$d@YbS=Co=AbbVv`pd3l}yM77KGGb2C4dE4~;Q@s!_fv{Df`i|sz%8$YI~3%rA`_6(kzN>PjiZU%&pNeuC%_Z)rOzru zYs?%R37je1l1kEkJ9>$hiXmM}^CwtbL;|hjH2vJnXX*H9+(c!(^P1&qRkYfd-VzV) zB7+I#uI%Tyitodkh*}Pp!e1w`m1;GIJaZDCErCTl2GRrw+w-`AwcG^lPNhMpQGo?P ztL1~)9?4c;MYom5gf~$q?&!0)-hsegz0a&NEWhR*`1+?_D`qDhzs)xrODEv0-S=cH z3k6T{c0}f!@64(MWQY`=YNZ$Bar?U$JmmDszzF|FH5Kr5JMx6-#uxjNBaYq?<415F zIH?Yo6So2Wb-+0Hy9Td+p-xlhtXwl1Mu8+dSl zuta}G6CaejyWu5oxk1l{$oxl$Se2IB5uWMGTMV}r{#D&h`D5=CZqDSaxW>h3d!ep( zPUW?s!crUdX!>7$k;k{75jYHyu(+J9kq|&wxvicefr6tl{ol3E(8CBbOp`eRH1`$Z zv~vKQxf(XegC2j`H)gGI)acy6D!Fo~tl?1ZNuK890((Hq0c)j*>IiC$V5raA|3r$| zf$Uq+s`0?H6r;Pvn`O^p+EPJ92UpTmtn(IhCzfLq{hwCmEV+R?xLsRmnlEeAHHNmw zdVg1W1ex5(1&;XRS01R}SXd%B-1@W@J?-Y=GW7Y$jIe)waPpw53kVC`VmO@tkvZ*`vgeYFtHVO>=!>y z1)~am8TN8;LbvZ}Y||B+u-f_s9RzRMj=9^N6Y}DV#yBBs-5!ImUh(ZU>a=`_kAUNM zFPd_k3-LQO{N%FlRsKEHklNUg-dxs|PcqldkM3+x0f{{*mUElpMJ)6%Pj#B|(Q$5q zMe`bU2PZ(9$~fIll~63{YN_j*{rgpIU z@{bZ}DwCIPiFeI+6)H84+e7#Ln5J)h6aRzKT~attO58zrj@Zn(L1Bm2>!3BJa{B6o zh_?hb&~)PIA#Wh^OF9sErEBu+B**fZYEKTh_#6dA`l1c@L~hl86KG~P&3Z7ZFQL#? z7@G12w~~p^NQl=yg-%E54L^# zUy+`bn&b`}Oj1m=9yu9M{Z-tk$`oE{*S`ydGn@ejX}8hHunSh)h|=YC)X7uYN<@*< zEtjSkEsh^gj_+4IQ<}ij0AUw0(c)Fe4BM&sQ92}SkJyge}0&=Bu1DoVZ(N}dUUaIr6nS6QRHpUWx0@mSw zPeqVoeAboXCORXV5k&o_uOlvdspglab0VkeYq_0eqq9&8RNbXiQ03>8zXv^o(1ovk zw}2BFjXlu0dPC$fy|uD!(kYbY>#9hFvxdt%7`R^u-R1@Kd#qS~Bws46u;AOTh7TEETIkWv z4vz=g2HI*?gmX{*$mj3W@_Kn-NI6J0^=gG&IH+nXnu-)C)b$8S_*mTX$B z!sgWA44B>BIefrA5#l4UDJa7+=fJ;2WYR|cyIJpW%XSf;$c)JmQjiZBxt}rVr4>=$ z9d4b|cIfG}XQx^lEBIkaN_3g>YLYbBS#2J5CU%xcd|$RTi)vd_;8AW4$Lyb zEDCjDu$OK$@V0)p8RXxxPg1&MO^VgL2%T_J))gcKih=(vqy)?fpv4ZjPG?H@p8kCR N^mUDODz)HI{{u5EX=VTb diff --git a/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineFirst@2x.png b/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineFirst@2x.png deleted file mode 100644 index b2faf101bcf0b8ff2e13c25a4230ad318180b10f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6691 zcmZu$cT`hBvkwrYNtfP3Q$Y|ALXoaOP>M-kzNfLM5Gr%qy#}hBtYmT5F$tb zDbhOxDFzHZ^!m{6d+)Ee=gj@h?#$esnR9o}&bcwhhPw2$+_V4yfF7cE=OF+{f{~$#k*?+Y!*7C^zSDQ>SkK%uMfc{^zu{L*x3!r(f zXXyg~u#5gBGRQ-b&5K1|w>w5A7kIJZzi}Z1T)m*bctP}L9KYZJ7YKsf(KHDpTZPi2 zOikG^U-C>`1(T8rz9-oUpI%S9dz<1se|VUdN0ccwO-3k_tm^@B;E! zUX{>v%>Q}xVX=HZjJq25vVy#Vyv8i=O4nCF<$Sc(35Nuegs~4L$eztF+LHA7EyEMa zCl|B3t#6A2&GNjiGto$}n9X>MzIR1xh#>VWwyu1q9X9x<@inWLn>C*84V;ZeA~(_^ zqOtg&hF_JXLw*H$G74nh{^;W6V775>i}GJ{XHfePda9tTZEZx&!PnohrRNX5$0)ar z93C0;4A=Tqi9WfonyDiXp(X|>&WT2)V5*}L-}FLiSfNoJ*q)`w*v zB#(CrMDGJYYfam(uCk}gNL$Cv-q7->Z{Gl!m+HPP)eq5#ZakZk<=-dzBAH8+PxWYZ~1i^`h7$(-_rkAWv$1d*6h9 znE{v{J1I<1%-YJ8@jlM3;sQ1pOspj;_)HZ0$`+M44Kzf}N9{l#Aanwnodep4rk<)^ zt=tThI{xdAzoSJZ!vOA{$2Rv76aJ`_SK&7&6UD@pEk2jLQzbPFIUrug4UT7je6m%x z!E7X1%(GO2WrhvAF-@i$e{4Ot>_TEQq_cxpO)zf1gBes+aXI18L-y4~3FSKDrli^5 zS-R&!)`&KkT#p|MKEB@vze)#}$CoJ2l0*je@xL1H#pewx0o@O zcgc4#ix<2v6Q(_J&mQ2YOe3btGDiI`i#YUm%zEhpG|00uiy9g zH~-Rb*?iG{6?Ho``WbS0T5C%y*tW0ck68opmY6X@2aJ(sV&6d3KZ~Xuee8Z?CUnb2 z#D0sLDh}F-JY6! zjt{JZkHl%Wmoqzl%de%FFx1~meqP8e5Ldfs43RP;1ula#8{T!kIg^;^xhbRYfph5v zZ{cr#m)|u3MliZj+&(|i1MDv$B0z(uAKz}8^ElF&%pe}!+*Tcv#}<*PDd#fYrg42~ zHGo*m!$-OC-~_#Mso?w%YQnxiJ-sG>X1(b}55-`0VUJ)$SO=MB(Uh_cck}pdS_Ga# z3_y<^!9K-~K3)w=397IWCl|HLBR;CTlB5*x>SMi*TGu!R!Q35Bg0Sa+in_|l#%Xff zo(T6)nggllvYTpH+yrpO6stJbhHb|}u_dtHSEr(YvBA3=sK+Okhq5#G%vUz-x4fk+ zt+x;E4(h);d&*CkLa>{Ggn^}c7Pclbm-2g++&<#F`MfUT&6=Jp;;DO=26<+9#qfIukmq-61RS4hvU@tNJD ze;~nZ)|T6TkGT?ZoO_kAmAm8xkGT_lnTgM#A64-Ur;rSU*Q!8)@2%6SA;h1Z%FLE$ zt5UxHU~bj0PJ7H1b{`kuPAB)S&6p%Y+W8 zGr`Ufz%1JtmFp!2at1&+#rS&`=^OSpV2q=L94u%q2<9Eglt`|qK#%ec4Vx`R;k2wf z&}x3l0u4A_Ep^U%)T0zVru@W`g5)_EeH!XI#i$v~3hCJm>MqMrnqFz>s?POP`jo2b zaQkXBMO?+h_-8t34s2U_Ox#)hwT6b30AafY)1jX!Q!UJ?@EryiRX5IxjBjiqWI$r; zmgaMeQ43A5S|sViG~KwOdmfSE=IHgG^)(r4o=PtF?FDt&%I?Ja^(!z+{wm}TYEEazo$+@64Xx1We|RR zjBj$@*#;;WIC-pQSHtBM=6p(HC-8ADrLjz-w-$^Dy(%K3^D(gAU9ZqWt_*Zn|6|`c z?n#y!z19ySW=!m&hc&!sRGcZgH)I)G8?BdcC!=P`Qvmt>RA-xx_4(QwaeVjuV9+=N zAmNhlwZi=;YEt4YdX?rUz06g9H++`lzkXLyQ3JVWQAMF<>mw5ct$x-8 zHt_U?!cpv;FXxXT9MbXlGh7FS*ZMUbX^c;-bnjoV-~L6`)gVrRx1O&yyf+F!ypiRi{7q>icHm$=SVdo+0dv< zDGO>lRk@}THz{_|;qC8F zx-UVzSq|4|OBOfyw<()@gp?rbAd;Zu(T9Tho3po#Bx4|lH}hH=)Nu|ib^6rvHuZsw zSQW0>k#VQ^R|&*$+GR3cDhr;KV}^pb2kFAd7W-`P#fr_)v2%(~d&xC9qIFhK27*(k z(3PJ>=f$z4Ls@U`oL;1?Lajp1T?FU1-Z>P*>UL_v#`)lT${JG@IUM$Du<~E9?*&a)0=fESf{N;ymg(Qzn8NJa z7!!+KQ@D~NB_xL*!^_i&63XB-ED8d(Sm%^MnFErK_MzCTfwgs!NbK%zp4nv3YQmOB{F7%R{_i)5!1)DsmG)hPsX{fB z59OeTw;wJx0U?RjNNL5O&*GzE%jtl+Ae^t{R9^}YBQ^#w7RIuvoOi0wP{EvZvYyIM zcM$|v^o9**w0h~tV(0r8bzO>90KOvYkQ*K=sTK>FW6QX&qDZ74MBAby>5&l?OR5b% zcA1f~oaABG?EaH+Khu~4@()mRbc7CqFSrG^T(5?UNme#UEE_x-tjt7GG`5oX- zRs@Z&iB3>J+HMW;-XA)<*}bClz7S%TpuomG%7ptg92ft|;5BXYXB@=$l1b>TC)eb= zv~>+o)X)2`J(BuD9j0Czo;&iQJZx_w0PoY+93n%?so6VH9d$Sl$2X5+vQ=I8^EA=l zUf3r^vz5&(mZsGOhi?WMC6tGV^6)GlFKiN1KkeHklyl`Ggh9b~eLcz;yF0$+8oiXX z4@=weO4x~M@ffIhs#_b4Qp#^z%eL@}urTX_S*}r1iOAR>9-w~%CAKIvBm5-e0dB8U@)})a7KvrzAO?J^~bjgFT@%8e{ z@D{op{xBnUXX+t%GjOty4h_URe@zu?5l%V`ZboJi44K(a)kS+)adhWaN$1jx#>Y{u zK9TX@5=kwcyS}0LokL;!$|QM(&OH|Ug1M=vU5_nmf{*?eerv?Wjv>Qjo0LPBYj7_$ zT{A1x7Wif2P_(Q4u{C${abtKh*kS4m26MH^6m<+p*0`ET6RvKSco9&?I^>rGIj~C` zjtR8L7Dcl61V}7hpWqYKh&(t>vD@>pw&H4S)h!`DOhavky}}-CCpk_dI|6^{3yDbV zNVE1U8N*yX6WB7s2o1Z;8-tRNP=Dw>_!K-EIEl8;&XP|!hT~}iXn5c`TFDh`CKB^s z6aCac=fE#5teZs#_Tnvdi5m&qugNj3AqpWoFkuC!#id9iS9N`G?_90{K+^shZFy1QtpP<$ig#!zG0t#N(Ova1F>AhU7ZV5&@?BP${;yt&;iR^wFe^f==oF$E+oCnu3u_z+yA zs{M$%hdt1((WEm3Tzz*NPj}98-8O$wuGEdh=~|X-R`FI|pC*@Ds$GLp#`vzRm_RQ? zmC~K^+hl0wqpJ)%^7;YwssW13W+3Dh3byYWAmkm3YsuI3KJCFD=#R~;*jkwhCToGB z{t2xr<^57}8S>pI?>Ai$^)c;<t~C66bDgcwW-R=)*BLJ}6aEyc-y0kKd1+*Se=)9m z=YZQyLj8wY>x7h<+u12gYdiSUN}b&63+JZZkz)#}G14twx=rFQd_%)RT7q;m!|=5N zV=5V~yMG#(znC(y8=XMNA)60=`G3?sD0m*BaZH5QL{f?)hCZJf*kpCh5*#}@C|~$H zR%>e&BFw`(RuWBvO0az{B{2LeU}&-jhEW*#>*>q*%^>?sl+Czg9vxS+0rt$=J|6X` z-d52v?^N+4b@BYOh^m<0*cmo80-eIBEHS}z1YTpJW+}mc6HKFk;ZEDlkMHZPWj4{V z5aEi+q)K=wLXT!q=X7b@D=={uUA8m~_q790)M(rMX4K*WWzYXG3YPW7T)TORW!hs~ z-~Ywe?gh7X#?9wWVhX;+6ES8AeI}(S=bk>ltV5IPX%0DwO%IL1$Zjl z{gL5FdZY0~Gs&E0m0{DU_3$DOIN(~LgO4+~`f8-*(~kXP$|`rW*+q|5hmWPl(zk6D zUds|OgS&F=B#wmA2^C~bAC)^ws>5hG00s?^x;R%p!Z8fq5p_)({m^yau-4%InkaPI z&6`CksxSAk-Cq9CxNkch#b;yzo)|(SQN=VRkAQZs>XJabTOW&JCa<-8!)!M0bvj;O z85-p&Gbm>pPD3+5xJlNkqci1dpVlw@9uxnur?EUu05`$Y8o9IO-DKzR)!tHia(UW= zNAr>;Q=k(~Y=HDQ>1^q)5PS8;^WcC>%1!F6;j!4%4@dhzl26_rT{Q7o$sNovG|LdV zcs1y2RfM9N=!uD4#@)eL(K%@mu_^ngwNXZCbOp~fN%u$<5ilCGl<_(7nXtbK!;6#c zwUDayi-Umv=GMAuXMM)$ZoFYlJ61x_+1yV@QU8b`htw*tG&R+6i>(Tc_kD{zjDFg- zHx}6pv@K}tQj%g|R`l972cLMb-p@7XCL7#n<5DOY(ZLJJ$O}sz@ospW7s@`nT>8UI zsl{J%@w1vklS%=ilGw-0gQzHwM-Qsz^s!#I%F&MBA>QT5$?_DYE)hf~Hq2oZS*BZF zY(u!Vb+hAI0u4BDl*%nW+qPd94-UR*XwtiHXt90A{C)UIfa_FZ+)4xbX6 zp!ZkXBz>9dJ`JAmi`H8U=liO>PlS@6ZtJpzv+ChxT9x~{2D%zu&N!)_H~U<(F3;tm zvHLV=)e5?*bhNeZBoLwTyOV5U)9bplD^1|e#0^K)QYC*O7mjp-_&wZlRV;jr?f~Eb zm!M3zWt|}^d4$%yxZ4TM(Xnt!&$V2(oZvM~Q#}*ZaF2cGG!_;S>SJ9faP!XlYn!>u z+xa(iEP5DU@JM*DJ#pZfTl-H1d`58@6sR{o;1tp0O?4CVm34*k&~d+mxt12sqz?Bs zpga3fcAWahA!jp`E=;E5205wh3FdTIm+-LOMs-ZNvr+AvSqxCIa$S69IE$(A)Mg}B zK^Z)C$71H-j!Sf{-dqj~x+F*ooFEs!^6q%>U$rZj4Ag%k1&SI-_#!A_6B#g-tjs)8 zvR!CXJh{=pQR`IV+=JKM$HRni WlzEq3ck#~z0J&>;r%cN(@_zv0ozZsy diff --git a/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineLast@2x.png b/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testBaselineAlignment_baselineLast@2x.png deleted file mode 100644 index 0db8e01c31b82e3377014884a719c87eba4b79d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6559 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 Tzxw_6?}fg$(cNlI`{(}wzAk>K diff --git a/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testNestedBaselineAlignments@2x.png b/Tests/ReferenceImages_iOS_10/ASStackLayoutSpecSnapshotTests/testNestedBaselineAlignments@2x.png deleted file mode 100644 index 28e13ab82187707d0f49d4ae78a5c855ea5add93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8786 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 diff --git a/Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testFontPointSizeScaling@2x.png b/Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testFontPointSizeScaling@2x.png deleted file mode 100644 index 111bd5004842fec4a3eab9adc46b4b649de4286d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1770 zcmbW2c{tRI8pmfEeq%7BXzWHvLn*REp)qELj578ma(<3#EXQ%O7o9VVt*KimLzWuM zSTad+Y*((IuB;g;OA#YvZ{+0KqBA|u{pbFB-{<+hpYQwr@%`(4p7(~clRa8mRT>6^ zp&ibUUBwI)i!23*dn%_IiZ zzb04LSwqfwoN>H(RLZ2XwtdL;Eq{QzPgnngyLO7bK6UrCZN>27@aBR=pCLgINE3+W zo9l-~@z%53Cm#ydx2R< zl$ff8ovLYgEOc;Ak|~Uj!-m-Sm}Sb~$x1ZcFpLv}P;_knqur?Hmi|7E#)r^|bnGGA zYE<`jtIq|`b|&_-3mZ%c{k}f$5eHhT=YPBrTOR4?-ox=Yw!SWi$Z{)=APitvjvFK^ zay~-m$&F|OnAZ?eNX|tP&vhk8ba|L3HEFrv>t759m^Fmt+vJtHZK4vS?zEq3b{LO; zF2^&%u4%La+IN=KnaZZ5fk;^xPXo{o zvc6wcg%B21We-lwTRBAYM zf&|i`Q&BE2k!mDr1fEyr!B^cJ12(1VAi=pN`Auvp&6F zJ~*_ygB-o)@M4J;HTsim*3tqH$xEO!ytX_ayHz+X0>5)V(q35^{)_5!zO1yi_JYY$4fT?Cz9ymltv z`+XKZ>~c4=Y-oxYs%{ZD_}e@Ylwk0C+>qx7f$;`vLz{0jM$tTR5AGyu&z=fKejGZ>Yw!?N1NYOVJRT z#4XKqUjxQr%Mk^?$v;bP4xCj>D;;|}a&}-%NX5yKIBkQ4`=XOpi|P_P&fx}^;F_*< z3{Y4e!@PbSUz>bX2=PS+G)!d^a_00zv5HZNgjVFy#D%>RK$%O6io4|qW}LMBpG1YW zFE3ktIa|b{QK8{iGd(njlAwpi<2UNB$hQ2xBK3;13sc~<@iM=F)+*0Hg-w~_)kZFR z@Ynt#A}zBK+XM+XZcIO{4g{)LFu7UKYM#H4Rfqs;a6uD*l<`V_i7jEkmT6`=#)y)) zQqP`(y3PBHw?gdu4UDt3y-S!BE?_^a$HW#~tfumBU9_=dz^`0tpJBgI`Xy2gMFkea zR6n)-L#U`E$My}(7>x;bw)e`V(q6=UMSX%l*gUV&BGDqlKa6(rp4- k8E^z3t84`RKPFB^Ij{Y)L_>GrcX24pf#O82vIUd=2G<-I2mk;8 diff --git a/Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testShadowing@2x.png b/Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testShadowing@2x.png deleted file mode 100644 index edb68c14aa424abbeef505134dedf464ca2a0b5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6381 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 Wmzr)V3+GIYWy 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 T<^pl%T^!q=aW$|M_TI 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 YrfUp-(iti}{6bhNN*apQ@|I!$1K%os`2YX_ diff --git a/Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testThatSlowPathTruncationWorks@2x.png b/Tests/ReferenceImages_iOS_10/ASTextNodeSnapshotTests/testThatSlowPathTruncationWorks@2x.png deleted file mode 100644 index 062724a0615d0ccb52c3e7a8a427e9992b3ce707..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3446 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 Date: Thu, 28 May 2020 15:36:05 -0700 Subject: [PATCH 38/56] Update FBSnapshotTestCase to iOSSnapshotTestCase (=6.2) (#1855) * Update FBSnapshotTestCase to iOSSnapshotTestCase (=6.1) * be explicit about iOSSnapshotTestCase 6.2 * get rid of iOS_10 suffix and move all the reference images from there into the true reference directory Co-authored-by: Rahul Malik --- AsyncDisplayKit.xcodeproj/project.pbxproj | 16 ++++++++-------- Podfile | 2 +- Podfile.lock | 10 +++++----- Tests/ASTextKitTests.mm | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 6db281328..4f8b9a3c9 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -102,6 +102,7 @@ 4080D66C2350384400CDC199 /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 471D04B1224CB98600649215 /* ASImageNodeBackingSizeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 471D04B0224CB98600649215 /* ASImageNodeBackingSizeTests.mm */; }; 4E9127691F64157600499623 /* ASRunLoopQueueTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4E9127681F64157600499623 /* ASRunLoopQueueTests.mm */; }; + 4EE3813FF44E20C399ACB962 /* Pods_AsyncDisplayKitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5039B74209A895E07057081C /* Pods_AsyncDisplayKitTests.framework */; }; 509E68601B3AED8E009B9150 /* ASScrollDirection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E111B371BD7007741D0 /* ASScrollDirection.mm */; }; 509E68611B3AEDA0009B9150 /* ASAbstractLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E171B37339C007741D0 /* ASAbstractLayoutController.h */; }; 509E68621B3AEDA5009B9150 /* ASAbstractLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E181B37339C007741D0 /* ASAbstractLayoutController.mm */; }; @@ -177,7 +178,6 @@ 83A7D95B1D44547700BF333E /* ASWeakMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83A7D9591D44542100BF333E /* ASWeakMap.mm */; }; 83A7D95C1D44548100BF333E /* ASWeakMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A7D9581D44542100BF333E /* ASWeakMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; 83A7D95E1D446A6E00BF333E /* ASWeakMapTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83A7D95D1D446A6E00BF333E /* ASWeakMapTests.mm */; }; - 89DA454A9BB6CF35A02F9DD2 /* Pods_AsyncDisplayKitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA42D0ECAA484A6B9934110F /* Pods_AsyncDisplayKitTests.framework */; }; 8BBBAB8C1CEBAF1700107FC6 /* ASDefaultPlaybackButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B0768B11CE752EC002E1453 /* ASDefaultPlaybackButton.h */; settings = {ATTRIBUTES = (Private, ); }; }; 8BBBAB8D1CEBAF1E00107FC6 /* ASDefaultPlaybackButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.mm */; }; 8BDA5FC71CDBDF91007D13B2 /* ASVideoPlayerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BDA5FC31CDBDDE1007D13B2 /* ASVideoPlayerNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -686,6 +686,7 @@ 4640521D1A3F83C40061C0BA /* ASLayoutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutController.h; sourceTree = ""; }; 471D04B0224CB98600649215 /* ASImageNodeBackingSizeTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASImageNodeBackingSizeTests.mm; sourceTree = ""; }; 4E9127681F64157600499623 /* ASRunLoopQueueTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRunLoopQueueTests.mm; sourceTree = ""; }; + 5039B74209A895E07057081C /* Pods_AsyncDisplayKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AsyncDisplayKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 68355B2E1CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASImageNode+AnimatedImage.mm"; sourceTree = ""; }; 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPINRemoteImageDownloader.mm; sourceTree = ""; }; 68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageContainerProtocolCategories.h; sourceTree = ""; }; @@ -791,7 +792,6 @@ 9F98C0241DBDF2A300476D92 /* ASControlTargetAction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASControlTargetAction.mm; sourceTree = ""; }; A32FEDD31C501B6A004F642A /* ASTextKitFontSizeAdjuster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitFontSizeAdjuster.h; path = TextKit/ASTextKitFontSizeAdjuster.h; sourceTree = ""; }; A373200E1C571B050011FC94 /* ASTextNode+Beta.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASTextNode+Beta.h"; sourceTree = ""; }; - AA42D0ECAA484A6B9934110F /* Pods_AsyncDisplayKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AsyncDisplayKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AC026B571BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASAbsoluteLayoutSpecSnapshotTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASHierarchyChangeSet.h; sourceTree = ""; }; AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASHierarchyChangeSet.mm; sourceTree = ""; }; @@ -1081,7 +1081,7 @@ 058D09BE195D04C000B7D73C /* XCTest.framework in Frameworks */, 058D09C1195D04C000B7D73C /* UIKit.framework in Frameworks */, 058D09BF195D04C000B7D73C /* Foundation.framework in Frameworks */, - 89DA454A9BB6CF35A02F9DD2 /* Pods_AsyncDisplayKitTests.framework in Frameworks */, + 4EE3813FF44E20C399ACB962 /* Pods_AsyncDisplayKitTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1168,7 +1168,7 @@ 058D09AF195D04C000B7D73C /* Foundation.framework */, 058D09BD195D04C000B7D73C /* XCTest.framework */, 058D09C0195D04C000B7D73C /* UIKit.framework */, - AA42D0ECAA484A6B9934110F /* Pods_AsyncDisplayKitTests.framework */, + 5039B74209A895E07057081C /* Pods_AsyncDisplayKitTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -2153,7 +2153,7 @@ 058D09B8195D04C000B7D73C /* Sources */, 058D09B9195D04C000B7D73C /* Frameworks */, 058D09BA195D04C000B7D73C /* Resources */, - F7D0C9EDE1FC3D066B45EE7C /* [CP] Embed Pods Frameworks */, + 572FAC967DD43A0D06367D02 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -2273,20 +2273,20 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F7D0C9EDE1FC3D066B45EE7C /* [CP] Embed Pods Frameworks */ = { + 572FAC967DD43A0D06367D02 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework", "${BUILT_PRODUCTS_DIR}/OCMock/OCMock.framework", + "${BUILT_PRODUCTS_DIR}/iOSSnapshotTestCase/FBSnapshotTestCase.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBSnapshotTestCase.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OCMock.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBSnapshotTestCase.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/Podfile b/Podfile index ac3c342c1..cb97714dc 100644 --- a/Podfile +++ b/Podfile @@ -6,5 +6,5 @@ target :'AsyncDisplayKitTests' do platform :ios, '10.0' use_frameworks! pod 'OCMock', '~>3.6' - pod 'FBSnapshotTestCase/Core', '~> 2.1' + pod 'iOSSnapshotTestCase/Core', '~> 6.2' end diff --git a/Podfile.lock b/Podfile.lock index 3a987d42e..95acfcef1 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,20 +1,20 @@ PODS: - - FBSnapshotTestCase/Core (2.1.4) + - iOSSnapshotTestCase/Core (6.2.0) - OCMock (3.6) DEPENDENCIES: - - FBSnapshotTestCase/Core (~> 2.1) + - iOSSnapshotTestCase/Core (~> 6.2) - OCMock (~> 3.6) SPEC REPOS: https://github.com/CocoaPods/Specs.git: - - FBSnapshotTestCase + - iOSSnapshotTestCase - OCMock SPEC CHECKSUMS: - FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a + iOSSnapshotTestCase: 9ab44cb5aa62b84d31847f40680112e15ec579a6 OCMock: 5ea90566be239f179ba766fd9fbae5885040b992 -PODFILE CHECKSUM: 9f751863f64737ce61a8b6aaa6a8bfe0aadcc165 +PODFILE CHECKSUM: ff1a1777e31f49e6e4b7b148d0f10e504db7fa26 COCOAPODS: 1.9.1 diff --git a/Tests/ASTextKitTests.mm b/Tests/ASTextKitTests.mm index efd93cf80..0f1a3ec72 100644 --- a/Tests/ASTextKitTests.mm +++ b/Tests/ASTextKitTests.mm @@ -91,7 +91,7 @@ static BOOL checkAttributes(const ASTextKitAttributes &attributes, const CGSize FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] init]; UIImage *labelImage = UITextViewImageWithAttributes(attributes, constrainedSize, linkTextAttributes); UIImage *textKitImage = ASTextKitImageWithAttributes(attributes, constrainedSize); - return [controller compareReferenceImage:labelImage toImage:textKitImage tolerance:0.0 error:nil]; + return [controller compareReferenceImage:labelImage toImage:textKitImage overallTolerance:0.0 error:nil]; } @implementation ASTextKitTests From 08bd6f6e3b0945689cf17c5cf9552eb87b520f07 Mon Sep 17 00:00:00 2001 From: ricky Date: Mon, 1 Jun 2020 12:58:44 -0700 Subject: [PATCH 39/56] [ASDisplayNode] Implement accessibilityViewIsModal (#1858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ASDisplayNode] Implement accessibilityViewIsModal A PR to add support for `accessibilityViewIsModal` in `CollectAccessibilityElements`. If in a list of subnodes more than 1 subnode has `accessibilityViewIsModal` marked as `YES`, then the node with the highest index in `subnodes` will be the one that is considered modal. This behavior matches UIKit. If the value of `accessibilityViewIsModal` changes, we need to clear all the cached `accessibilityElements` from that view up. I added this in ASDisplayNode’s `setAccessibilityViewIsModal` method. Note that if we ship `ASExperimentalDoNotCacheAccessibilityElements` then we can remove the invalidation step. Finally, I changed all the tests to ask the view for accessibilityElements, not the node. This is a better representation of what will really happen when UIKit asks a node’s view for its accessibility elements. It also allowed me to test that clearing the accessibilityElements was working. * add some experiment checks * fix tests and address jon’s comment * Fix tests * remove debug code --- Source/Details/_ASDisplayViewAccessiblity.mm | 16 ++- Source/Private/ASDisplayNode+UIViewBridge.mm | 23 ++++ Tests/ASDisplayViewAccessibilityTests.mm | 115 ++++++++++++++++++- 3 files changed, 147 insertions(+), 7 deletions(-) diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index 367f53687..7324c5c29 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -254,7 +254,21 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el return; } - for (ASDisplayNode *subnode in node.subnodes) { + // see if one of the subnodes is modal. If it is, then we only need to collect accessibilityElements from that + // node. If more than one subnode is modal, UIKit uses the last view in subviews as the modal view (it appears to + // be based on the index in the subviews array, not the location on screen). Let's do the same. + ASDisplayNode *modalSubnode = nil; + for (ASDisplayNode *subnode in node.subnodes.reverseObjectEnumerator) { + if (subnode.accessibilityViewIsModal) { + modalSubnode = subnode; + break; + } + } + + // If we have a modal subnode, just use that. Otherwise, use all subnodes + NSArray *subnodes = modalSubnode ? @[ modalSubnode ] : node.subnodes; + + for (ASDisplayNode *subnode in subnodes) { // If a node is hidden or has an alpha of 0.0 we should not include it if (subnode.hidden || subnode.alpha == 0.0) { continue; diff --git a/Source/Private/ASDisplayNode+UIViewBridge.mm b/Source/Private/ASDisplayNode+UIViewBridge.mm index 32f95b985..94d8ace0a 100644 --- a/Source/Private/ASDisplayNode+UIViewBridge.mm +++ b/Source/Private/ASDisplayNode+UIViewBridge.mm @@ -1137,6 +1137,22 @@ - (BOOL)_locked_insetsLayoutMarginsFromSafeArea @implementation ASDisplayNode (UIViewBridgeAccessibility) +// Walks up the view tree to nil out all the cached accsesibilityElements. This is required when changing +// accessibility properties like accessibilityViewIsModal. +- (void)invalidateAccessibilityElements +{ + // If we are not caching accessibilityElements we don't need to do anything here. + if (ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements)) { + return; + } + + // we want to check if we are on the main thread first, since _loaded checks the layer and can only be done on main + if (ASDisplayNodeThreadIsMain() && _loaded(self)) { + self.view.accessibilityElements = nil; + [self.supernode invalidateAccessibilityElements]; + } +} + - (BOOL)isAccessibilityElement { _bridge_prologue_read; @@ -1306,9 +1322,16 @@ - (BOOL)accessibilityViewIsModal - (void)setAccessibilityViewIsModal:(BOOL)accessibilityViewIsModal { _bridge_prologue_write; + BOOL oldAccessibilityViewIsModal = _getFromViewOnly(accessibilityViewIsModal); _setAccessibilityToViewAndProperty(_flags.accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal); + + // if we made a change, we need to clear the view's accessibilityElements cache. + if (!ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements) && self.isNodeLoaded && oldAccessibilityViewIsModal != accessibilityViewIsModal) { + [self invalidateAccessibilityElements]; + } } + - (BOOL)shouldGroupAccessibilityChildren { _bridge_prologue_read; diff --git a/Tests/ASDisplayViewAccessibilityTests.mm b/Tests/ASDisplayViewAccessibilityTests.mm index 4dc68e37d..02d99d790 100644 --- a/Tests/ASDisplayViewAccessibilityTests.mm +++ b/Tests/ASDisplayViewAccessibilityTests.mm @@ -247,7 +247,7 @@ - (void)testThatAccessibilityElementsWorks { // force load __unused UIView *view = containerNode.view; - NSArray *elements = [containerNode accessibilityElements]; + NSArray *elements = [containerNode.view accessibilityElements]; XCTAssertTrue(elements.count == 2); XCTAssertEqual([elements.firstObject asyncdisplaykit_node], label); XCTAssertEqual([elements.lastObject asyncdisplaykit_node], button); @@ -273,7 +273,7 @@ - (void)testThatAccessibilityElementsOverrideWorks { // force load __unused UIView *view = containerNode.view; - NSArray *elements = [containerNode accessibilityElements]; + NSArray *elements = [containerNode.view accessibilityElements]; XCTAssertTrue(elements.count == 1); XCTAssertEqual(elements.firstObject, label); } @@ -301,7 +301,7 @@ - (void)testHiddenAccessibilityElements { // force load __unused UIView *view = containerNode.view; - NSArray *elements = [containerNode accessibilityElements]; + NSArray *elements = [containerNode.view accessibilityElements]; XCTAssertTrue(elements.count == 1); XCTAssertEqual(elements.firstObject, label.view); } @@ -328,7 +328,7 @@ - (void)testTransparentAccessibilityElements { // force load __unused UIView *view = containerNode.view; - NSArray *elements = [containerNode accessibilityElements]; + NSArray *elements = [containerNode.view accessibilityElements]; XCTAssertTrue(elements.count == 1); XCTAssertEqual(elements.firstObject, label.view); } @@ -376,7 +376,7 @@ - (void)testAccessibilityElementsNotInAppWindow { [node addSubnode:offScreenNodeX]; [node addSubnode:offScreenNode]; - NSArray *elements = [node accessibilityElements]; + NSArray *elements = [node.view accessibilityElements]; XCTAssertTrue(elements.count == 3); XCTAssertTrue([elements containsObject:label.view]); XCTAssertTrue([elements containsObject:partiallyOnScreenNodeX.view]); @@ -427,7 +427,7 @@ - (void)testAccessibilityElementsNotInAppWindowButInScrollView { [node addSubnode:offScreenNodeX]; [node addSubnode:offScreenNode]; - NSArray *elements = [node accessibilityElements]; + NSArray *elements = [node.view accessibilityElements]; XCTAssertTrue(elements.count == 6); XCTAssertTrue([elements containsObject:label.view]); XCTAssertTrue([elements containsObject:partiallyOnScreenNodeX.view]); @@ -488,5 +488,108 @@ - (void)testCustomAccessibilitySort { XCTAssertEqual(elements[3], node4); } +- (void)testSubnodeIsModal { + + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 568)]; + ASDisplayNode *node = [[ASDisplayNode alloc] init]; + node.automaticallyManagesSubnodes = YES; + + ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + window.rootViewController = vc; + [window makeKeyAndVisible]; + [window layoutIfNeeded]; + + ASTextNode *label1 = [[ASTextNode alloc] init]; + label1.attributedText = [[NSAttributedString alloc] initWithString:@"label1"]; + label1.frame = CGRectMake(10, 80, 300, 20); + [node addSubnode:label1]; + + ASTextNode *label2 = [[ASTextNode alloc] init]; + label2.attributedText = [[NSAttributedString alloc] initWithString:@"label2"]; + label2.frame = CGRectMake(10, CGRectGetMaxY(label1.frame) + 8, 300, 20); + [node addSubnode:label2]; + + ASDisplayNode *modalNode = [[ASDisplayNode alloc] init]; + modalNode.frame = CGRectInset(CGRectUnion(label1.frame, label2.frame), -8, -8); + + // This is kind of cheating. When voice over is activated, the modal node will end up reporting that it + // has 1 accessibilityElement. But getting that to happen in a unit test doesn't seem possible. + id modalMock = OCMPartialMock(modalNode); + OCMStub([modalMock accessibilityElementCount]).andReturn(1); + [node addSubnode:modalMock]; + + ASTextNode *label3 = [[ASTextNode alloc] init]; + label3.attributedText = [[NSAttributedString alloc] initWithString:@"label6"]; + label3.frame = CGRectMake(8, 4, 200, 20); + + [modalNode addSubnode:label3]; + modalNode.accessibilityViewIsModal = YES; + NSArray *elements = [node.view accessibilityElements]; + XCTAssertTrue(elements.count == 1); + XCTAssertTrue([elements containsObject:modalNode.view]); +} + +- (void)testMultipleSubnodesAreModal { + + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 568)]; + ASDisplayNode *node = [[ASDisplayNode alloc] init]; + node.automaticallyManagesSubnodes = YES; + + ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + window.rootViewController = vc; + [window makeKeyAndVisible]; + [window layoutIfNeeded]; + + ASTextNode *label1 = [[ASTextNode alloc] init]; + label1.attributedText = [[NSAttributedString alloc] initWithString:@"label1"]; + label1.frame = CGRectMake(10, 80, 300, 20); + [node addSubnode:label1]; + + ASTextNode *label2 = [[ASTextNode alloc] init]; + label2.attributedText = [[NSAttributedString alloc] initWithString:@"label2"]; + label2.frame = CGRectMake(10, CGRectGetMaxY(label1.frame) + 8, 300, 20); + [node addSubnode:label2]; + + ASDisplayNode *modalNode1 = [[ASDisplayNode alloc] init]; + modalNode1.frame = CGRectInset(CGRectUnion(label1.frame, label2.frame), -8, -8); + + // This is kind of cheating. When voice over is activated, the modal node will end up reporting that it + // has 1 accessibilityElement. But getting that to happen in a unit test doesn't seem possible. + id modalMock1 = OCMPartialMock(modalNode1); + OCMStub([modalMock1 accessibilityElementCount]).andReturn(1); + + ASTextNode *label3 = [[ASTextNode alloc] init]; + label3.attributedText = [[NSAttributedString alloc] initWithString:@"label6"]; + label3.frame = CGRectMake(8, 4, 200, 20); + [modalNode1 addSubnode:label3]; + modalNode1.accessibilityViewIsModal = YES; + + ASDisplayNode *modalNode2 = [[ASDisplayNode alloc] init]; + modalNode2.frame = CGRectOffset(modalNode1.frame, 0, modalNode1.frame.size.height + 10); + id modalMock2 = OCMPartialMock(modalNode2); + OCMStub([modalMock2 accessibilityElementCount]).andReturn(1); + + ASTextNode *label4 = [[ASTextNode alloc] init]; + label4.attributedText = [[NSAttributedString alloc] initWithString:@"label6"]; + label4.frame = CGRectMake(8, 4, 200, 20); + [modalNode2 addSubnode:label4]; + modalNode2.accessibilityViewIsModal = YES; + + // add modalNode1 last, and assert that it is the one that appears in accessibilityElements + // (UIKit uses the last modal subview in subviews as the modal element). + [node addSubnode:modalMock2]; + [node addSubnode:modalMock1]; + + NSArray *elements = [node.view accessibilityElements]; + XCTAssertTrue(elements.count == 1); + XCTAssertTrue([elements containsObject:modalNode1.view]); + + // let's change which node is modal and make sure the elements get updated. + modalNode1.accessibilityViewIsModal = NO; + elements = [node.view accessibilityElements]; + XCTAssertTrue(elements.count == 1); + XCTAssertTrue([elements containsObject:modalNode2.view]); +} + @end From e56c047489369b445107545f4e7ab85c5b3e5b1e Mon Sep 17 00:00:00 2001 From: _ivanC Date: Tue, 2 Jun 2020 23:46:52 +0800 Subject: [PATCH 40/56] Add iOS13 UIContextMenu api to ASCommonCollectionDelegate (#1860) --- Source/ASCollectionViewProtocols.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/ASCollectionViewProtocols.h b/Source/ASCollectionViewProtocols.h index 3f0bd6116..ec1b8d577 100644 --- a/Source/ASCollectionViewProtocols.h +++ b/Source/ASCollectionViewProtocols.h @@ -95,6 +95,13 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender ASDISPLAYNODE_DEPRECATED_MSG("Implement collectionNode:canPerformAction:forItemAtIndexPath:withSender: instead."); - (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender ASDISPLAYNODE_DEPRECATED_MSG("Implement collectionNode:performAction:forItemAtIndexPath:withSender: instead."); +- (nullable UIContextMenuConfiguration *)collectionView:(UICollectionView *)collectionView contextMenuConfigurationForItemAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos); + +- (nullable UITargetedPreview *)collectionView:(UICollectionView *)collectionView previewForHighlightingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos); + +- (nullable UITargetedPreview *)collectionView:(UICollectionView *)collectionView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos); + +- (void)collectionView:(UICollectionView *)collectionView willPerformPreviewActionForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration animator:(id)animator API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos); @end NS_ASSUME_NONNULL_END From 8b9683d02cbefe7a9e6c83a3a8c2f07c87d52c7d Mon Sep 17 00:00:00 2001 From: Christos Gkekas Date: Tue, 2 Jun 2020 16:51:18 +0100 Subject: [PATCH 41/56] Fix documentation for ASCornerRoundingTypeClipping (#1863) --- Source/ASDisplayNode.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/ASDisplayNode.h b/Source/ASDisplayNode.h index 84ca49c59..7f506a03b 100644 --- a/Source/ASDisplayNode.h +++ b/Source/ASDisplayNode.h @@ -649,8 +649,8 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority; * thus works best for ASImageNodes or containers showing a background around their children. * * - ASCornerRoundingTypeClipping: overlays 4 separate opaque corners on top of the content that needs - * corner rounding. Requires .backgroundColor and .cornerRadius to be set. Use clip corners in situations - * in which is movement through the corner, with an opaque background (no movement underneath the corner). + * corner rounding. Requires .backgroundColor and .cornerRadius to be set. Use clip corners in situations + * where there is movement through the corner, with an opaque background (no movement underneath the corner). * Clipped corners are ideal for animating / resizing views, and still outperform CALayer. * * For more information and examples, see http://texturegroup.org/docs/corner-rounding.html From e16fdd67e127bd2418e6ac3042b3e621af43962d Mon Sep 17 00:00:00 2001 From: ricky Date: Wed, 3 Jun 2020 16:16:43 -0700 Subject: [PATCH 42/56] [ASDisplayNode] Implement accessibilityElementsHidden (#1859) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of this code comes from an old PR that @fruitcoder put up https://github.com/TextureGroup/Texture/pull/795 2 years ago. When creating our array of accessibilityElements, we need to respect the value of `accessibilityElementsHidden`. If the value of this property changes, we need to invalidate the cached accessibility elements (unless we are in the experiment that doesn’t cache `accessibilityElements`). I created a simple test app and made sure this matched UIKit’s implementation. I also added a test case that changes the value of `accessibilityElementsHidden` and makes sure the proper accessibilityElements are returned. --- Source/Details/_ASDisplayViewAccessiblity.mm | 12 ++++++- Source/Private/ASDisplayNode+UIViewBridge.mm | 6 ++++ Tests/ASDisplayViewAccessibilityTests.mm | 37 ++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index 7324c5c29..7fb79eaa2 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -89,6 +89,7 @@ + (ASAccessibilityElement *)accessibilityElementWithContainer:(UIView *)containe accessibilityElement.accessibilityHint = node.accessibilityHint; accessibilityElement.accessibilityValue = node.accessibilityValue; accessibilityElement.accessibilityTraits = node.accessibilityTraits; + accessibilityElement.accessibilityElementsHidden = node.accessibilityElementsHidden; if (AS_AVAILABLE_IOS_TVOS(11, 11)) { accessibilityElement.accessibilityAttributedLabel = node.accessibilityAttributedLabel; accessibilityElement.accessibilityAttributedHint = node.accessibilityAttributedHint; @@ -221,6 +222,11 @@ static BOOL recusivelyCheckSuperviewsForScrollView(UIView *view) { return recusivelyCheckSuperviewsForScrollView(view.superview); } +/// returns YES if this node should be considered "hidden" from the screen reader. +static BOOL nodeIsHiddenFromAcessibility(ASDisplayNode *node) { + return node.isHidden || node.alpha == 0.0 || node.accessibilityElementsHidden; +} + /// Collect all accessibliity elements for a given view and view node static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *elements) { @@ -254,6 +260,10 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el return; } + if (nodeIsHiddenFromAcessibility(node)) { + return; + } + // see if one of the subnodes is modal. If it is, then we only need to collect accessibilityElements from that // node. If more than one subnode is modal, UIKit uses the last view in subviews as the modal view (it appears to // be based on the index in the subviews array, not the location on screen). Let's do the same. @@ -270,7 +280,7 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el for (ASDisplayNode *subnode in subnodes) { // If a node is hidden or has an alpha of 0.0 we should not include it - if (subnode.hidden || subnode.alpha == 0.0) { + if (nodeIsHiddenFromAcessibility(subnode)) { continue; } diff --git a/Source/Private/ASDisplayNode+UIViewBridge.mm b/Source/Private/ASDisplayNode+UIViewBridge.mm index 94d8ace0a..50641d80d 100644 --- a/Source/Private/ASDisplayNode+UIViewBridge.mm +++ b/Source/Private/ASDisplayNode+UIViewBridge.mm @@ -1310,7 +1310,13 @@ - (BOOL)accessibilityElementsHidden - (void)setAccessibilityElementsHidden:(BOOL)accessibilityElementsHidden { _bridge_prologue_write; + BOOL oldHiddenValue = _getFromViewOnly(accessibilityElementsHidden); _setAccessibilityToViewAndProperty(_flags.accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden); + + // if we made a change, we need to clear the view's accessibilityElements cache. + if (!ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements) && self.isNodeLoaded && oldHiddenValue != accessibilityElementsHidden) { + [self invalidateAccessibilityElements]; + } } - (BOOL)accessibilityViewIsModal diff --git a/Tests/ASDisplayViewAccessibilityTests.mm b/Tests/ASDisplayViewAccessibilityTests.mm index 02d99d790..f1a7696cc 100644 --- a/Tests/ASDisplayViewAccessibilityTests.mm +++ b/Tests/ASDisplayViewAccessibilityTests.mm @@ -591,5 +591,42 @@ - (void)testMultipleSubnodesAreModal { XCTAssertTrue([elements containsObject:modalNode2.view]); } +- (void)testAccessibilityElementsHidden { + + UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 568)]; + ASDisplayNode *node = [[ASDisplayNode alloc] init]; + node.automaticallyManagesSubnodes = YES; + + ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + window.rootViewController = vc; + [window makeKeyAndVisible]; + [window layoutIfNeeded]; + + ASTextNode *label1 = [[ASTextNode alloc] init]; + label1.attributedText = [[NSAttributedString alloc] initWithString:@"on screen"]; + label1.frame = CGRectMake(0, 0, 100, 20); + + ASTextNode *label2 = [[ASTextNode alloc] init]; + label2.attributedText = [[NSAttributedString alloc] initWithString:@"partially on screen y"]; + label2.frame = CGRectMake(0, 20, 100, 20); + + [node addSubnode:label1]; + [node addSubnode:label2]; + + NSArray *elements = [node.view accessibilityElements]; + XCTAssertTrue(elements.count == 2); + XCTAssertTrue([elements containsObject:label1.view]); + XCTAssertTrue([elements containsObject:label2.view]); + + node.accessibilityElementsHidden = YES; + elements = [node.view accessibilityElements]; + XCTAssertTrue(elements.count == 0); + + node.accessibilityElementsHidden = NO; + elements = [node.view accessibilityElements]; + XCTAssertTrue(elements.count == 2); + XCTAssertTrue([elements containsObject:label1.view]); + XCTAssertTrue([elements containsObject:label2.view]); +} @end From 5651826c05ce8a06594ea965858f321e99fdc9ef Mon Sep 17 00:00:00 2001 From: _ivanC Date: Wed, 17 Jun 2020 05:07:27 +0800 Subject: [PATCH 43/56] -[ASNetworkImageNode setURL:resetToDefault:] forget to reset animatedImage (#1861) * Fix -[ASNetworkImageNode setURL:resetToDefault:] forget to reset animatedImage * add ASNetworkImageNodeTest for reset with animatedImage --- Source/ASNetworkImageNode.mm | 1 + Tests/ASNetworkImageNodeTests.mm | 73 ++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/Source/ASNetworkImageNode.mm b/Source/ASNetworkImageNode.mm index daf3a47c1..085fc063c 100644 --- a/Source/ASNetworkImageNode.mm +++ b/Source/ASNetworkImageNode.mm @@ -216,6 +216,7 @@ - (void)setURL:(NSURL *)URL resetToDefault:(BOOL)reset if (reset || hadURL) { [self _setCurrentImageQuality:(hadURL ? 0.0 : 1.0)]; [self _locked__setImage:_defaultImage]; + [self _locked_setAnimatedImage:nil]; } } diff --git a/Tests/ASNetworkImageNodeTests.mm b/Tests/ASNetworkImageNodeTests.mm index d0853c1c1..a707cd163 100644 --- a/Tests/ASNetworkImageNodeTests.mm +++ b/Tests/ASNetworkImageNodeTests.mm @@ -20,6 +20,9 @@ @interface ASTestImageDownloader : NSObject @interface ASTestImageCache : NSObject @end +@interface ASTestAnimatedImage : NSObject +@end + @implementation ASNetworkImageNodeTests { ASNetworkImageNode *node; id downloader; @@ -73,6 +76,18 @@ - (void)testThatProgressBlockIsSetAndClearedCorrectlyOnChangeURL [downloader verifyWithDelay:5]; } +- (void)testThatAnimatedImageClearedCorrectlyOnChangeURL +{ + [node layer]; + [node enterInterfaceState:ASInterfaceStateInHierarchy]; + + // Set URL while visible, should set progress block + node.animatedImage = [ASTestAnimatedImage new]; + [node setURL:[NSURL URLWithString:@"http://imageA"] resetToDefault:YES]; + + XCTAssertEqualObjects(nil, node.animatedImage); +} + - (void)testThatSettingAnImageWillStayForEnteringAndExitingPreloadState { UIImage *image = [[UIImage alloc] init]; @@ -133,3 +148,61 @@ - (void)setProgressImageBlock:(ASImageDownloaderProgressImage)progressBlock call // nop } @end + +@implementation ASTestAnimatedImage +@synthesize playbackReadyCallback; + +- (UIImage *)coverImage +{ + return [UIImage new]; +} + +- (BOOL)coverImageReady +{ + return YES; +} + +- (CFTimeInterval)totalDuration +{ + return 1; +} + +- (NSUInteger)frameInterval +{ + return 0.2; +} + +- (size_t)loopCount +{ + return 0; +} + +- (size_t)frameCount +{ + return 5; +} + +- (BOOL)playbackReady +{ + return YES; +} + +- (NSError *)error +{ + return nil; +} + +- (CGImageRef)imageAtIndex:(NSUInteger)index +{ + return [[UIImage new] CGImage]; +} + +- (CFTimeInterval)durationAtIndex:(NSUInteger)index +{ + return 0.2; +} + +- (void)clearAnimatedImageCache +{} + +@end From a9643e59cd370ed39e6196ae3179bf7c748e8a72 Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Wed, 24 Jun 2020 14:38:28 -0700 Subject: [PATCH 44/56] Prepare for 3.0.0-rc.1 release (#1870) --- .github_changelog_generator | 4 +- CHANGELOG.md | 264 ++++++++++++++++++++++++++++++++++++ RELEASE.md | 2 +- Texture.podspec | 2 +- 4 files changed, 268 insertions(+), 4 deletions(-) diff --git a/.github_changelog_generator b/.github_changelog_generator index d3df245b8..f01cfffa0 100644 --- a/.github_changelog_generator +++ b/.github_changelog_generator @@ -1,3 +1,3 @@ issues=false -since-tag=2.8.1 -future-release=2.9 +since-tag=3.0.0-rc.1 +future-release=3.0.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index cdf49081e..afbd14431 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,269 @@ # Change Log +## [3.0.0-rc.1](https://github.com/TextureGroup/Texture/tree/3.0.0-rc.1) (2020-06-19) + +[Full Changelog](https://github.com/TextureGroup/Texture/compare/sync-base-08-29-19...3.0.0-rc.1) + +**Merged pull requests:** + +- Fix documentation for ASCornerRoundingTypeClipping [\#1863](https://github.com/TextureGroup/Texture/pull/1863) ([chggr](https://github.com/chggr)) +- -\[ASNetworkImageNode setURL:resetToDefault:\] forget to reset animatedImage [\#1861](https://github.com/TextureGroup/Texture/pull/1861) ([IvanChan](https://github.com/IvanChan)) +- Add iOS13 UIContextMenu api to ASCommonCollectionDelegate [\#1860](https://github.com/TextureGroup/Texture/pull/1860) ([IvanChan](https://github.com/IvanChan)) +- \[ASDisplayNode\] Implement accessibilityElementsHidden [\#1859](https://github.com/TextureGroup/Texture/pull/1859) ([rcancro](https://github.com/rcancro)) +- \[ASDisplayNode\] Implement accessibilityViewIsModal [\#1858](https://github.com/TextureGroup/Texture/pull/1858) ([rcancro](https://github.com/rcancro)) +- Reference Image Updates in preparation for iOSSnapshotTestCase 6.2 [\#1857](https://github.com/TextureGroup/Texture/pull/1857) ([bolsinga](https://github.com/bolsinga)) +- Run the tests with iOS10 and as a framework in preparation of updating snapshot test case. [\#1856](https://github.com/TextureGroup/Texture/pull/1856) ([bolsinga](https://github.com/bolsinga)) +- Update FBSnapshotTestCase to iOSSnapshotTestCase \(=6.2\) [\#1855](https://github.com/TextureGroup/Texture/pull/1855) ([bolsinga](https://github.com/bolsinga)) +- Ship ASExperimentalTraitCollectionDidChangeWithPreviousCollection [\#1842](https://github.com/TextureGroup/Texture/pull/1842) ([bolsinga](https://github.com/bolsinga)) +- Ship ASExperimentalUnfairLock experiment [\#1841](https://github.com/TextureGroup/Texture/pull/1841) ([bolsinga](https://github.com/bolsinga)) +- Ship ASExperimentalOOMBackgroundDeallocDisable since it decreases OOMs [\#1840](https://github.com/TextureGroup/Texture/pull/1840) ([bolsinga](https://github.com/bolsinga)) +- Update Texture Xcode project to 11.4 and fix resulting warnings - 4 [\#1838](https://github.com/TextureGroup/Texture/pull/1838) ([bolsinga](https://github.com/bolsinga)) +- Update Swift collection view interop example [\#1837](https://github.com/TextureGroup/Texture/pull/1837) ([drinkius](https://github.com/drinkius)) +- deprecate ASGraphicsCreateImageWithTraitCollectionAndOptions [\#1836](https://github.com/TextureGroup/Texture/pull/1836) ([vovasty](https://github.com/vovasty)) +- Remove Danger from the development workflow [\#1835](https://github.com/TextureGroup/Texture/pull/1835) ([jparise](https://github.com/jparise)) +- Use ASReplaceMethodWithBlock instead of swizzling with a library [\#1832](https://github.com/TextureGroup/Texture/pull/1832) ([bolsinga](https://github.com/bolsinga)) +- use iOS 13.4.1 and Xcode 11.4.1 for CI [\#1831](https://github.com/TextureGroup/Texture/pull/1831) ([vovasty](https://github.com/vovasty)) +- Do not use xcpretty in builds so that CI errors are logged. [\#1830](https://github.com/TextureGroup/Texture/pull/1830) ([bolsinga](https://github.com/bolsinga)) +- Update to OCMock 3.6 [\#1829](https://github.com/TextureGroup/Texture/pull/1829) ([bolsinga](https://github.com/bolsinga)) +- Removes unnecessary `-tearDown` code. [\#1822](https://github.com/TextureGroup/Texture/pull/1822) ([dmaclach](https://github.com/dmaclach)) +- \[Accessibility\] Do not exclude elements outside the window’s rect that are subviews of UIScrollView [\#1821](https://github.com/TextureGroup/Texture/pull/1821) ([rcancro](https://github.com/rcancro)) +- support cancelation in ASGraphicsCreateImage [\#1814](https://github.com/TextureGroup/Texture/pull/1814) ([vovasty](https://github.com/vovasty)) +- \[ASDisplayViewAccessibility\] A few accessibility improvements [\#1812](https://github.com/TextureGroup/Texture/pull/1812) ([rcancro](https://github.com/rcancro)) +- \[ASDisplayNode\] Allow explicit setting of accessibilityElements [\#1807](https://github.com/TextureGroup/Texture/pull/1807) ([rcancro](https://github.com/rcancro)) +- Add `nullable` to new ASCommonTableViewDelegate methods [\#1796](https://github.com/TextureGroup/Texture/pull/1796) ([jparise](https://github.com/jparise)) +- Context menu iOS 13 API [\#1795](https://github.com/TextureGroup/Texture/pull/1795) ([uuttff8](https://github.com/uuttff8)) +- resolve background color using system trait collection [\#1777](https://github.com/TextureGroup/Texture/pull/1777) ([vovasty](https://github.com/vovasty)) +- Update PINRemoteImage to the latest stable [\#1773](https://github.com/TextureGroup/Texture/pull/1773) ([mackoj](https://github.com/mackoj)) +- Prevent crashing during non critical logging at rotation [\#1770](https://github.com/TextureGroup/Texture/pull/1770) ([foxware00](https://github.com/foxware00)) +- Pruning ASExperimentalRemoveTextKitInitialisingLock code. [\#1766](https://github.com/TextureGroup/Texture/pull/1766) ([trufflin](https://github.com/trufflin)) +- fix calling CALayer out of the main thread [\#1762](https://github.com/TextureGroup/Texture/pull/1762) ([vovasty](https://github.com/vovasty)) +- Fix typo [\#1759](https://github.com/TextureGroup/Texture/pull/1759) ([devxoul](https://github.com/devxoul)) +- Lint podspec on all pull requests [\#1758](https://github.com/TextureGroup/Texture/pull/1758) ([nguyenhuy](https://github.com/nguyenhuy)) +- Only include UIUserInterfaceLevel in iOS target [\#1757](https://github.com/TextureGroup/Texture/pull/1757) ([nguyenhuy](https://github.com/nguyenhuy)) +- Link to IGListDiffKit in our IGListKit subspec [\#1756](https://github.com/TextureGroup/Texture/pull/1756) ([nguyenhuy](https://github.com/nguyenhuy)) +- Remove references to xcpretty-travis-formatter [\#1755](https://github.com/TextureGroup/Texture/pull/1755) ([jparise](https://github.com/jparise)) +- Add empty ASViewController initializer to facilitate subclassing [\#1754](https://github.com/TextureGroup/Texture/pull/1754) ([christianselig](https://github.com/christianselig)) +- Bump up IGListKit version [\#1749](https://github.com/TextureGroup/Texture/pull/1749) ([ay8s](https://github.com/ay8s)) +- Improve recursive unfair lock [\#1742](https://github.com/TextureGroup/Texture/pull/1742) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Use `queue` in `ASMainSerialQueue` [\#1738](https://github.com/TextureGroup/Texture/pull/1738) ([hanton](https://github.com/hanton)) +- Delete unused header in `ASRunLoopQueue` [\#1737](https://github.com/TextureGroup/Texture/pull/1737) ([hanton](https://github.com/hanton)) +- Simplify push\_back `GroupNotify` [\#1736](https://github.com/TextureGroup/Texture/pull/1736) ([hanton](https://github.com/hanton)) +- \[Docs\] minor fixes in `Layout` [\#1735](https://github.com/TextureGroup/Texture/pull/1735) ([hanton](https://github.com/hanton)) +- Delete unused macro in `ASControlNode` [\#1734](https://github.com/TextureGroup/Texture/pull/1734) ([hanton](https://github.com/hanton)) +- Fix tint color dead lock \#1731 [\#1732](https://github.com/TextureGroup/Texture/pull/1732) ([lkzhao](https://github.com/lkzhao)) +- Fix for images retrieved from the memory cache being reported as disk cache hits. [\#1722](https://github.com/TextureGroup/Texture/pull/1722) ([darrengyles](https://github.com/darrengyles)) +- \[Docs\] Update to use `ASCornerLayoutSpec` for `Photo with Outset Icon Overlay` [\#1721](https://github.com/TextureGroup/Texture/pull/1721) ([hanton](https://github.com/hanton)) +- Add `copy` sematic to `userInfo` property in `ASTextRunDelegate` [\#1719](https://github.com/TextureGroup/Texture/pull/1719) ([hanton](https://github.com/hanton)) +- Change `layoutSizeDifferentFromBounds` macro to a BOOL [\#1718](https://github.com/TextureGroup/Texture/pull/1718) ([hanton](https://github.com/hanton)) +- Remove unused `sharedDeallocationQueue` property [\#1717](https://github.com/TextureGroup/Texture/pull/1717) ([hanton](https://github.com/hanton)) +- modify examples\_extra/Shop swift 4.2 Version [\#1709](https://github.com/TextureGroup/Texture/pull/1709) ([doulos76](https://github.com/doulos76)) +- Fix element lookup for supplementary attributes. [\#1707](https://github.com/TextureGroup/Texture/pull/1707) ([craighowarth](https://github.com/craighowarth)) +- Remove duplicate `ASPINRemoteImageDownloader` [\#1705](https://github.com/TextureGroup/Texture/pull/1705) ([hanton](https://github.com/hanton)) +- deprecate ASGraphicsCreateImageWithOptions [\#1704](https://github.com/TextureGroup/Texture/pull/1704) ([vovasty](https://github.com/vovasty)) +- fix typo in ASVideoNodeDelegate protocol [\#1695](https://github.com/TextureGroup/Texture/pull/1695) ([Eeyore741](https://github.com/Eeyore741)) +- Adds new delegate methods to ASCommonTableViewDelegate for swipes [\#1694](https://github.com/TextureGroup/Texture/pull/1694) ([SashaZolotarev](https://github.com/SashaZolotarev)) +- fix a node background color in non layer baked mode. [\#1693](https://github.com/TextureGroup/Texture/pull/1693) ([vovasty](https://github.com/vovasty)) +- use iOS 13.0 and Xcode 11 on CI [\#1691](https://github.com/TextureGroup/Texture/pull/1691) ([vovasty](https://github.com/vovasty)) +- Remove build warnings [\#1681](https://github.com/TextureGroup/Texture/pull/1681) ([hanton](https://github.com/hanton)) +- Use backgroundColor ivar instead of property access in traitCollectio… [\#1678](https://github.com/TextureGroup/Texture/pull/1678) ([rahul-malik](https://github.com/rahul-malik)) +- introduction of `ASGraphicsCreateImageWithTraitCollectionAndOptions` [\#1675](https://github.com/TextureGroup/Texture/pull/1675) ([vovasty](https://github.com/vovasty)) +- \#1673 - Re-render Clipping Corners when User Interface Style Changes [\#1674](https://github.com/TextureGroup/Texture/pull/1674) ([shamanskyh](https://github.com/shamanskyh)) +- Fix main thread assertion for tint color on text nodes, re-render tint-able nodes on hierarchy changes [\#1670](https://github.com/TextureGroup/Texture/pull/1670) ([rahul-malik](https://github.com/rahul-malik)) +- Fix CFRelease on null variable when using truncationAttributedText [\#1669](https://github.com/TextureGroup/Texture/pull/1669) ([MikeDonahue](https://github.com/MikeDonahue)) +- ASImageNode tintColor improvements. [\#1668](https://github.com/TextureGroup/Texture/pull/1668) ([bolsinga](https://github.com/bolsinga)) +- Use `CAEdgeAntialiasingMask` instead of `unsigned int` [\#1667](https://github.com/TextureGroup/Texture/pull/1667) ([hanton](https://github.com/hanton)) +- Node TintColor Tweaks [\#1666](https://github.com/TextureGroup/Texture/pull/1666) ([bolsinga](https://github.com/bolsinga)) +- Defer image asset regeneration to draw loop [\#1663](https://github.com/TextureGroup/Texture/pull/1663) ([mikezucc](https://github.com/mikezucc)) +- Use MutexLocker when ASImageNode traits change [\#1662](https://github.com/TextureGroup/Texture/pull/1662) ([bolsinga](https://github.com/bolsinga)) +- Use lock to access the image renderingMode when tint color changes [\#1661](https://github.com/TextureGroup/Texture/pull/1661) ([bolsinga](https://github.com/bolsinga)) +- Use standard ivar \_ prefix for userInterfaceStyle in ASImageNodeDrawParameters [\#1660](https://github.com/TextureGroup/Texture/pull/1660) ([bolsinga](https://github.com/bolsinga)) +- Using `emplace\_back` instead of `push\_back` for efficiency [\#1658](https://github.com/TextureGroup/Texture/pull/1658) ([hanton](https://github.com/hanton)) +- Fix `\_ASAsyncTransaction` initialization method [\#1656](https://github.com/TextureGroup/Texture/pull/1656) ([hanton](https://github.com/hanton)) +- use lock in asyncTraitCollectionDidChangeWithPreviousTraitCollection [\#1651](https://github.com/TextureGroup/Texture/pull/1651) ([vovasty](https://github.com/vovasty)) +- \[GitHub CI\] Revert back to Ruby Danger as Danger JS is not working properly [\#1650](https://github.com/TextureGroup/Texture/pull/1650) ([Kaspik](https://github.com/Kaspik)) +- \[Docs\] Fix broken link in `Layout-Quickstart` [\#1648](https://github.com/TextureGroup/Texture/pull/1648) ([hanton](https://github.com/hanton)) +- tests for `ASImageNode` dynamic tint color [\#1644](https://github.com/TextureGroup/Texture/pull/1644) ([vovasty](https://github.com/vovasty)) +- AS::Map function improvement [\#1642](https://github.com/TextureGroup/Texture/pull/1642) ([hanton](https://github.com/hanton)) +- Fix comment typo for `showsHorizontalScrollIndicator` in ASCollectionNode [\#1638](https://github.com/TextureGroup/Texture/pull/1638) ([innocarpe](https://github.com/innocarpe)) +- Adds support for new iOS 13 traits [\#1568](https://github.com/TextureGroup/Texture/pull/1568) ([ay8s](https://github.com/ay8s)) +- \[IGListKit\] Extended IGListKit support for displaying delegates [\#1011](https://github.com/TextureGroup/Texture/pull/1011) ([hebertialmeida](https://github.com/hebertialmeida)) + +## [sync-base-08-29-19](https://github.com/TextureGroup/Texture/tree/sync-base-08-29-19) (2019-08-28) + +[Full Changelog](https://github.com/TextureGroup/Texture/compare/sync-base-05-09-19...sync-base-08-29-19) + +**Merged pull requests:** + +- Cleanup from recent changes [\#1647](https://github.com/TextureGroup/Texture/pull/1647) ([rahul-malik](https://github.com/rahul-malik)) +- Propagate ASTraitCollection for snapshot testing [\#1646](https://github.com/TextureGroup/Texture/pull/1646) ([rahul-malik](https://github.com/rahul-malik)) +- Fix issue where UIGraphicsRendererFormat is mutated [\#1645](https://github.com/TextureGroup/Texture/pull/1645) ([rahul-malik](https://github.com/rahul-malik)) +- Store backgroundColor in ASDisplayNode [\#1640](https://github.com/TextureGroup/Texture/pull/1640) ([rahul-malik](https://github.com/rahul-malik)) +- Adding experiment to propagate older trait collections when trait [\#1637](https://github.com/TextureGroup/Texture/pull/1637) ([rahul-malik](https://github.com/rahul-malik)) +- Update Danger workflow [\#1636](https://github.com/TextureGroup/Texture/pull/1636) ([nguyenhuy](https://github.com/nguyenhuy)) +- Run Danger with GitHub Actions [\#1635](https://github.com/TextureGroup/Texture/pull/1635) ([nguyenhuy](https://github.com/nguyenhuy)) +- Remove Travis and Slather configs, as well as run\_tests\_update\_status.sh [\#1633](https://github.com/TextureGroup/Texture/pull/1633) ([nguyenhuy](https://github.com/nguyenhuy)) +- Remove BUCK support [\#1632](https://github.com/TextureGroup/Texture/pull/1632) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[GitHub CI\] Remove build approval step [\#1631](https://github.com/TextureGroup/Texture/pull/1631) ([nguyenhuy](https://github.com/nguyenhuy)) +- support dynamic images in iOS13 [\#1630](https://github.com/TextureGroup/Texture/pull/1630) ([vovasty](https://github.com/vovasty)) +- Allow full color tinting on grayscale template images. [\#1629](https://github.com/TextureGroup/Texture/pull/1629) ([jessietea](https://github.com/jessietea)) +- \[GitHub CI\] Add step to block PRs from forked repositories unless they have the right label [\#1627](https://github.com/TextureGroup/Texture/pull/1627) ([nguyenhuy](https://github.com/nguyenhuy)) +- Keep using `unowned` macro [\#1626](https://github.com/TextureGroup/Texture/pull/1626) ([hanton](https://github.com/hanton)) +- Set up GitHub Actions CI [\#1623](https://github.com/TextureGroup/Texture/pull/1623) ([nguyenhuy](https://github.com/nguyenhuy)) +- Minor code improvements [\#1622](https://github.com/TextureGroup/Texture/pull/1622) ([hanton](https://github.com/hanton)) +- Minor changes to tint color support [\#1620](https://github.com/TextureGroup/Texture/pull/1620) ([nguyenhuy](https://github.com/nguyenhuy)) +- Remove \_ASDisplayLayer's delegateDidChangeBounds flag [\#1618](https://github.com/TextureGroup/Texture/pull/1618) ([nguyenhuy](https://github.com/nguyenhuy)) +- Add support for tinting layer-backed ASDisplayNode [\#1617](https://github.com/TextureGroup/Texture/pull/1617) ([rahul-malik](https://github.com/rahul-malik)) +- Remove unused headers [\#1615](https://github.com/TextureGroup/Texture/pull/1615) ([hanton](https://github.com/hanton)) +- Avoid querying for NSAttributedString attributes on empty string [\#1614](https://github.com/TextureGroup/Texture/pull/1614) ([rahul-malik](https://github.com/rahul-malik)) +- Force `-\[\_ASDisplayLayer setDelegate:\]` to evaluate delegateFlags in iOS 13 [\#1609](https://github.com/TextureGroup/Texture/pull/1609) ([rahul-malik](https://github.com/rahul-malik)) +- Stop setting `frameInterval` for animated image optimization [\#1607](https://github.com/TextureGroup/Texture/pull/1607) ([raycsh017](https://github.com/raycsh017)) +- Fix a comment bug in `ASVideoNode` and `ASVideoPlayerNode` [\#1604](https://github.com/TextureGroup/Texture/pull/1604) ([hanton](https://github.com/hanton)) +- Add support for tintColor on ASImageNode and ASButtonNode [\#1603](https://github.com/TextureGroup/Texture/pull/1603) ([rahul-malik](https://github.com/rahul-malik)) +- \[Dev docs\] Fix previous and next page links [\#1601](https://github.com/TextureGroup/Texture/pull/1601) ([nguyenhuy](https://github.com/nguyenhuy)) +- Use AS\_ARRAY\_SIZE for array counting [\#1600](https://github.com/TextureGroup/Texture/pull/1600) ([hanton](https://github.com/hanton)) +- \[Dev docs\] Add page navigation [\#1599](https://github.com/TextureGroup/Texture/pull/1599) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Dev docs\] fix broken image links [\#1597](https://github.com/TextureGroup/Texture/pull/1597) ([hanton](https://github.com/hanton)) +- Migrate example projects to the recommended `-nodeBlock` data source method [\#1596](https://github.com/TextureGroup/Texture/pull/1596) ([hanton](https://github.com/hanton)) +- Update Pending state type for backgroundColor to UIColor [\#1593](https://github.com/TextureGroup/Texture/pull/1593) ([rahul-malik](https://github.com/rahul-malik)) +- add new networking image delegate method when image does not load from cache [\#1590](https://github.com/TextureGroup/Texture/pull/1590) ([ernestmama](https://github.com/ernestmama)) +- Set background color directly to view if not layer backed [\#1588](https://github.com/TextureGroup/Texture/pull/1588) ([rahul-malik](https://github.com/rahul-malik)) +- \[dev docs\] Add link to Getting Started to Overview page [\#1587](https://github.com/TextureGroup/Texture/pull/1587) ([mikezucc](https://github.com/mikezucc)) +- \[Dev docs\] Improve title of how-to-debug.md [\#1586](https://github.com/TextureGroup/Texture/pull/1586) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Dev docs\] Update navigation bar [\#1585](https://github.com/TextureGroup/Texture/pull/1585) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update docs navigation orders [\#1584](https://github.com/TextureGroup/Texture/pull/1584) ([hanton](https://github.com/hanton)) +- Fix all project coding warnings in `examples` folder [\#1582](https://github.com/TextureGroup/Texture/pull/1582) ([hanton](https://github.com/hanton)) +- Update .gitignore file \[Carthage\] [\#1581](https://github.com/TextureGroup/Texture/pull/1581) ([hanton](https://github.com/hanton)) +- Run Import Optimizer on Texture [\#1580](https://github.com/TextureGroup/Texture/pull/1580) ([bolsinga](https://github.com/bolsinga)) +- Bridge CTFontRef directly to UIFont when converting attributes on NSAttributedString [\#1579](https://github.com/TextureGroup/Texture/pull/1579) ([rahul-malik](https://github.com/rahul-malik)) +- \[Dev doc\] Add Carthage version [\#1578](https://github.com/TextureGroup/Texture/pull/1578) ([hanton](https://github.com/hanton)) +- Fix ASBasicImageDownloaderTests [\#1576](https://github.com/TextureGroup/Texture/pull/1576) ([hanton](https://github.com/hanton)) +- Fix the build warning in `ASRangeController.mm` [\#1575](https://github.com/TextureGroup/Texture/pull/1575) ([hanton](https://github.com/hanton)) +- Update CONTRIBUTING.md [\#1574](https://github.com/TextureGroup/Texture/pull/1574) ([hanton](https://github.com/hanton)) +- Fixes accessibilityLabel bug on ASButtonNode that has no title [\#1573](https://github.com/TextureGroup/Texture/pull/1573) ([SterlingWaves](https://github.com/SterlingWaves)) +- Cleanup for cgFloatForYogaFloat [\#1571](https://github.com/TextureGroup/Texture/pull/1571) ([maicki](https://github.com/maicki)) +- \[ASDataController\] Add an experiment that avoids flushing editing queue before starting the data pipeline pipeline [\#1564](https://github.com/TextureGroup/Texture/pull/1564) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[dev docs\] Remove redundant page [\#1563](https://github.com/TextureGroup/Texture/pull/1563) ([mikezucc](https://github.com/mikezucc)) +- \[Dev doc\] Add overview and explain repository structure [\#1562](https://github.com/TextureGroup/Texture/pull/1562) ([nguyenhuy](https://github.com/nguyenhuy)) +- Restore call pattern where UIView methods drive \_\_enterHierarchy and \_\_exitHierarchy for view-backed nodes [\#1561](https://github.com/TextureGroup/Texture/pull/1561) ([nguyenhuy](https://github.com/nguyenhuy)) +- Remove ivar of ASCellNode.owningNode [\#1559](https://github.com/TextureGroup/Texture/pull/1559) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Dev doc\] Collections and asynchronous updates [\#1558](https://github.com/TextureGroup/Texture/pull/1558) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[dev docs\] Created the first pass at demystifying the layout system for debuggers and developers [\#1557](https://github.com/TextureGroup/Texture/pull/1557) ([mikezucc](https://github.com/mikezucc)) +- included Longwalks [\#1556](https://github.com/TextureGroup/Texture/pull/1556) ([cgarg](https://github.com/cgarg)) +- Fix placeholder [\#1555](https://github.com/TextureGroup/Texture/pull/1555) ([strangeliu](https://github.com/strangeliu)) +- \#trivial fix development sidebar in docs [\#1554](https://github.com/TextureGroup/Texture/pull/1554) ([garrettmoon](https://github.com/garrettmoon)) +- Update how to contribute docs [\#1553](https://github.com/TextureGroup/Texture/pull/1553) ([garrettmoon](https://github.com/garrettmoon)) +- Upgrade Xcode and Cocoapods [\#1552](https://github.com/TextureGroup/Texture/pull/1552) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASTextNode2\] Fix truncation token is wrong after attributed string is changing with different foreground color [\#1550](https://github.com/TextureGroup/Texture/pull/1550) ([maicki](https://github.com/maicki)) +- Remove ASExperimentalTransactionOperationRetainCycle [\#1547](https://github.com/TextureGroup/Texture/pull/1547) ([bolsinga](https://github.com/bolsinga)) +- Adjust how AS\_ENABLE\_TEXT\_NODE is used to fix Xcode cmd+click & editor support [\#1546](https://github.com/TextureGroup/Texture/pull/1546) ([maicki](https://github.com/maicki)) +- Fix ASTextNode2 supportsLayerBacking [\#1545](https://github.com/TextureGroup/Texture/pull/1545) ([maicki](https://github.com/maicki)) +- \[Dev docs\] How to develop with Texture [\#1538](https://github.com/TextureGroup/Texture/pull/1538) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fix multiple issues around accessibility handlinig [\#1537](https://github.com/TextureGroup/Texture/pull/1537) ([maicki](https://github.com/maicki)) +- \[Dev docs\] Node Lifecycle [\#1536](https://github.com/TextureGroup/Texture/pull/1536) ([nguyenhuy](https://github.com/nguyenhuy)) +- Don't eagerly create arrays for attachments in ASTextNode2 [\#1535](https://github.com/TextureGroup/Texture/pull/1535) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove the text rendering experiment. [\#1531](https://github.com/TextureGroup/Texture/pull/1531) ([garrettmoon](https://github.com/garrettmoon)) +- Use flag for responder chain methods between view and node dispatching [\#1522](https://github.com/TextureGroup/Texture/pull/1522) ([maicki](https://github.com/maicki)) +- Fixes UIKit version of ASDKGram [\#1521](https://github.com/TextureGroup/Texture/pull/1521) ([maicki](https://github.com/maicki)) +- Add new property alwaysHandleTapTruncationAction to ASTextNode2 and ASTextNode. [\#1520](https://github.com/TextureGroup/Texture/pull/1520) ([dirtmelon](https://github.com/dirtmelon)) +- Fix Opting-Out of Linking with Photos Framework [\#1519](https://github.com/TextureGroup/Texture/pull/1519) ([b3ll](https://github.com/b3ll)) +- Add support for basic ASTextNode2 link highlighting [\#1518](https://github.com/TextureGroup/Texture/pull/1518) ([maicki](https://github.com/maicki)) +- Small cleanup to remove unnecessary internal import [\#1517](https://github.com/TextureGroup/Texture/pull/1517) ([maicki](https://github.com/maicki)) +- Assign accessibilityElements to \_accessibilityElements [\#1516](https://github.com/TextureGroup/Texture/pull/1516) ([maicki](https://github.com/maicki)) +- Remove ASExperimentalDisableAccessibilityCache [\#1515](https://github.com/TextureGroup/Texture/pull/1515) ([maicki](https://github.com/maicki)) +- Reclaim CALayer asyncTransactions, use pointer-based NSMutableSet instead [\#1510](https://github.com/TextureGroup/Texture/pull/1510) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Discard \_pendingDisplayNodes after subtree is rendered [\#1509](https://github.com/TextureGroup/Texture/pull/1509) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Cleanup whitespace \#trivial [\#1507](https://github.com/TextureGroup/Texture/pull/1507) ([wiseoldduck](https://github.com/wiseoldduck)) +- Shrink ASLayout [\#1503](https://github.com/TextureGroup/Texture/pull/1503) ([bolsinga](https://github.com/bolsinga)) +- Shrink LayoutSpec classes [\#1502](https://github.com/TextureGroup/Texture/pull/1502) ([bolsinga](https://github.com/bolsinga)) +- \[feat\] Added download progress for NetworkImageNode [\#1489](https://github.com/TextureGroup/Texture/pull/1489) ([zhongwuzw](https://github.com/zhongwuzw)) +- Ship ASExperimentalImageDownloaderPriority [\#1480](https://github.com/TextureGroup/Texture/pull/1480) ([nguyenhuy](https://github.com/nguyenhuy)) +- NetworkingImageNode: update URL if we found image in assets [\#1473](https://github.com/TextureGroup/Texture/pull/1473) ([zhongwuzw](https://github.com/zhongwuzw)) +- \[Dev docs\] Debugging documentation [\#1328](https://github.com/TextureGroup/Texture/pull/1328) ([mikezucc](https://github.com/mikezucc)) + +## [sync-base-05-09-19](https://github.com/TextureGroup/Texture/tree/sync-base-05-09-19) (2019-05-09) + +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.8.1...sync-base-05-09-19) + +**Merged pull requests:** + +- ASSignpost: Add support for the os\_signpost API, fixes [\#1501](https://github.com/TextureGroup/Texture/pull/1501) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Shrink ASEditableTextNode by 16 bytes [\#1500](https://github.com/TextureGroup/Texture/pull/1500) ([bolsinga](https://github.com/bolsinga)) +- Shrink ASCellNode by 8 bytes [\#1499](https://github.com/TextureGroup/Texture/pull/1499) ([bolsinga](https://github.com/bolsinga)) +- Keep the atomics - does not affect memory reduction work [\#1498](https://github.com/TextureGroup/Texture/pull/1498) ([bolsinga](https://github.com/bolsinga)) +- Remove unused declaration, missed in \#1460 [\#1497](https://github.com/TextureGroup/Texture/pull/1497) ([bolsinga](https://github.com/bolsinga)) +- Shrink Pager and Scroll Node [\#1496](https://github.com/TextureGroup/Texture/pull/1496) ([bolsinga](https://github.com/bolsinga)) +- Shrink TextNode\(2\) [\#1495](https://github.com/TextureGroup/Texture/pull/1495) ([bolsinga](https://github.com/bolsinga)) +- Shrink Button Node [\#1494](https://github.com/TextureGroup/Texture/pull/1494) ([bolsinga](https://github.com/bolsinga)) +- Minor update in change log \#changelog [\#1492](https://github.com/TextureGroup/Texture/pull/1492) ([nguyenhuy](https://github.com/nguyenhuy)) +- Cut version 2.8.1 \#changelog [\#1491](https://github.com/TextureGroup/Texture/pull/1491) ([nguyenhuy](https://github.com/nguyenhuy)) +- Clean up documentation issues around periods [\#1490](https://github.com/TextureGroup/Texture/pull/1490) ([amonshiz](https://github.com/amonshiz)) +- Shrink ASImageNode by .6% and ASNetworkImageNode by 2.2% [\#1487](https://github.com/TextureGroup/Texture/pull/1487) ([bolsinga](https://github.com/bolsinga)) +- Ship ASExperimentalFixRangeController [\#1486](https://github.com/TextureGroup/Texture/pull/1486) ([nguyenhuy](https://github.com/nguyenhuy)) +- Shrink \_ASCollectionPendingState from 144 to 128 bytes, a 12.5% reduction [\#1485](https://github.com/TextureGroup/Texture/pull/1485) ([bolsinga](https://github.com/bolsinga)) +- Shrink ASDisplayNode from 1072 to 968 bytes, reduction of 10.74% [\#1484](https://github.com/TextureGroup/Texture/pull/1484) ([bolsinga](https://github.com/bolsinga)) +- Shrink \_ASPendingState from 824 to 808 bytes, reduction of ~2% [\#1483](https://github.com/TextureGroup/Texture/pull/1483) ([bolsinga](https://github.com/bolsinga)) +- Ensure ASControlMode properties lock before accessing their ivars [\#1476](https://github.com/TextureGroup/Texture/pull/1476) ([bolsinga](https://github.com/bolsinga)) +- Make sure all ASDisplayNode properties have backing ivars for consistency. [\#1475](https://github.com/TextureGroup/Texture/pull/1475) ([bolsinga](https://github.com/bolsinga)) +- Add a new "global drawing" experiment to use UIGraphicsRenderer [\#1469](https://github.com/TextureGroup/Texture/pull/1469) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix open context bug introduced in \#1458 [\#1468](https://github.com/TextureGroup/Texture/pull/1468) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Passthrough pagingEnabled for ASCollectionNode / ASTableNode [\#1466](https://github.com/TextureGroup/Texture/pull/1466) ([maicki](https://github.com/maicki)) +- Cover the other background dealloc surfaces [\#1464](https://github.com/TextureGroup/Texture/pull/1464) ([mikezucc](https://github.com/mikezucc)) +- Drop support for Xcode 8 and fix some compiler warnings [\#1463](https://github.com/TextureGroup/Texture/pull/1463) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove iOS 8 logging support [\#1462](https://github.com/TextureGroup/Texture/pull/1462) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove ASEventLog [\#1460](https://github.com/TextureGroup/Texture/pull/1460) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Shut down graphics contexts experiment [\#1458](https://github.com/TextureGroup/Texture/pull/1458) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Make ASCollectionNode's pan gesture customizable [\#1457](https://github.com/TextureGroup/Texture/pull/1457) ([OskarZhang](https://github.com/OskarZhang)) +- Only create activities during debug [\#1456](https://github.com/TextureGroup/Texture/pull/1456) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Try to remove global lock when initialising TextKit components [\#1455](https://github.com/TextureGroup/Texture/pull/1455) ([zhongwuzw](https://github.com/zhongwuzw)) +- Remove lock of ASTextNodeRendererKey [\#1454](https://github.com/TextureGroup/Texture/pull/1454) ([zhongwuzw](https://github.com/zhongwuzw)) +- Fix wrongly formatted RELEASE link [\#1453](https://github.com/TextureGroup/Texture/pull/1453) ([BalestraPatrick](https://github.com/BalestraPatrick)) +- \[\#1451\] Add support for UIAccessibilityCustomAction [\#1452](https://github.com/TextureGroup/Texture/pull/1452) ([shamanskyh](https://github.com/shamanskyh)) +- Simplify ASTraitCollection propagation in ASViewController [\#1447](https://github.com/TextureGroup/Texture/pull/1447) ([maicki](https://github.com/maicki)) +- Use AS::Mutex in ASCollectionElement [\#1445](https://github.com/TextureGroup/Texture/pull/1445) ([maicki](https://github.com/maicki)) +- Add didEnterHierarchy/didExitHierarchy to ASNodeController. [\#1444](https://github.com/TextureGroup/Texture/pull/1444) ([tnorman42](https://github.com/tnorman42)) +- Revert "Have image nodes draw into opaque contexts automatically if possible" [\#1443](https://github.com/TextureGroup/Texture/pull/1443) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Use instance lock for ASPrimitiveTraitCollection [\#1442](https://github.com/TextureGroup/Texture/pull/1442) ([maicki](https://github.com/maicki)) +- Fix the stub for layerActionForKey: to let CA continue the search [\#1441](https://github.com/TextureGroup/Texture/pull/1441) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Wrap transaction operation retain cycle fix in an experiment [\#1438](https://github.com/TextureGroup/Texture/pull/1438) ([bolsinga](https://github.com/bolsinga)) +- Fix typo. [\#1437](https://github.com/TextureGroup/Texture/pull/1437) ([dirtmelon](https://github.com/dirtmelon)) +- Add a verbose log for locking operations. Has no effect in production [\#1436](https://github.com/TextureGroup/Texture/pull/1436) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix scroll node in yoga [\#1435](https://github.com/TextureGroup/Texture/pull/1435) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- \[ASDisplayNode\] Stop infinite layout in \_u\_measureNodeWithBoundsIfNecessary [\#1434](https://github.com/TextureGroup/Texture/pull/1434) ([rcancro](https://github.com/rcancro)) +- Have image nodes draw into opaque contexts automatically if possible [\#1432](https://github.com/TextureGroup/Texture/pull/1432) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix retain cycle with transaction operations [\#1429](https://github.com/TextureGroup/Texture/pull/1429) ([bolsinga](https://github.com/bolsinga)) +- Replace +load initializers with \_\_attribute\_\_\(\(constructor\)\) functions [\#1425](https://github.com/TextureGroup/Texture/pull/1425) ([farktronix](https://github.com/farktronix)) +- \[Experiment\] Dont forget about these collection view background deallocs [\#1424](https://github.com/TextureGroup/Texture/pull/1424) ([mikezucc](https://github.com/mikezucc)) +- showcase.md updated [\#1421](https://github.com/TextureGroup/Texture/pull/1421) ([plotkin](https://github.com/plotkin)) +- Experiment with disabling background dealloc for ASViewController [\#1420](https://github.com/TextureGroup/Texture/pull/1420) ([mikezucc](https://github.com/mikezucc)) +- Follow up on the ASRangeController fix in \#1418 [\#1419](https://github.com/TextureGroup/Texture/pull/1419) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fix a bug in ASRangeController that causes cell nodes to render unnecessarily [\#1418](https://github.com/TextureGroup/Texture/pull/1418) ([nguyenhuy](https://github.com/nguyenhuy)) +- Only set ASLayoutElementStyle delegate if Yoga is enabled [\#1417](https://github.com/TextureGroup/Texture/pull/1417) ([maicki](https://github.com/maicki)) +- Add support for clipping only specific corners, add unit tests [\#1415](https://github.com/TextureGroup/Texture/pull/1415) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add support for reverse direction to yoga layouts [\#1413](https://github.com/TextureGroup/Texture/pull/1413) ([wiseoldduck](https://github.com/wiseoldduck)) +- Disable ASAssertLocked and ASAssertUnlocked by default [\#1412](https://github.com/TextureGroup/Texture/pull/1412) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fix dealloc on bg [\#1410](https://github.com/TextureGroup/Texture/pull/1410) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Avoid an unnecessary lock & unlock pair in ASMainSerialQueue [\#1409](https://github.com/TextureGroup/Texture/pull/1409) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fix a bug with Yoga nodes whose position change and don't update. [\#1408](https://github.com/TextureGroup/Texture/pull/1408) ([tnorman42](https://github.com/tnorman42)) +- Fix GIF Caching [\#1405](https://github.com/TextureGroup/Texture/pull/1405) ([ay8s](https://github.com/ay8s)) +- Fix header typo [\#1402](https://github.com/TextureGroup/Texture/pull/1402) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Suppress documentation warnings when using external libraries [\#1401](https://github.com/TextureGroup/Texture/pull/1401) ([bolsinga](https://github.com/bolsinga)) +- Naming ivar context can conflict with subclasses [\#1399](https://github.com/TextureGroup/Texture/pull/1399) ([garrettmoon](https://github.com/garrettmoon)) +- Make shared CA transaction queue variable extern so it's actually shared [\#1397](https://github.com/TextureGroup/Texture/pull/1397) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add layer-action support to nodes [\#1396](https://github.com/TextureGroup/Texture/pull/1396) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Make experiment checks faster [\#1393](https://github.com/TextureGroup/Texture/pull/1393) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Update for 9.4.1 CI [\#1392](https://github.com/TextureGroup/Texture/pull/1392) ([garrettmoon](https://github.com/garrettmoon)) +- Need some more locks for working with calculated yoga layouts [\#1388](https://github.com/TextureGroup/Texture/pull/1388) ([wiseoldduck](https://github.com/wiseoldduck)) +- Clean up a clang analyzer cast error [\#1387](https://github.com/TextureGroup/Texture/pull/1387) ([bolsinga](https://github.com/bolsinga)) +- Adds support for using UIGraphicsImageRenderer in ASTextNode. [\#1384](https://github.com/TextureGroup/Texture/pull/1384) ([garrettmoon](https://github.com/garrettmoon)) +- Remove experimental features \(exp\_skip\_a11y\_wait && exp\_new\_default\_cell\_layout\_mode\) [\#1383](https://github.com/TextureGroup/Texture/pull/1383) ([ernestmama](https://github.com/ernestmama)) +- Rename ASDN C++ namespace to AS [\#1366](https://github.com/TextureGroup/Texture/pull/1366) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add clang-format for a common source code format [\#1365](https://github.com/TextureGroup/Texture/pull/1365) ([maicki](https://github.com/maicki)) +- Add UIDataSourceModelAssociation to ASTableView and ASCollectionView [\#1354](https://github.com/TextureGroup/Texture/pull/1354) ([farktronix](https://github.com/farktronix)) +- \[Text Nodes\] Maintain isAccessibilityElement setting on text nodes when updating text [\#1326](https://github.com/TextureGroup/Texture/pull/1326) ([smeis](https://github.com/smeis)) +- Removed locked jekyll version [\#1322](https://github.com/TextureGroup/Texture/pull/1322) ([mikezucc](https://github.com/mikezucc)) +- Dev docs for threading in Texture [\#1319](https://github.com/TextureGroup/Texture/pull/1319) ([mikezucc](https://github.com/mikezucc)) +- \[ASImageNode\]fix incorrect backing size calculation [\#1189](https://github.com/TextureGroup/Texture/pull/1189) ([junjielu](https://github.com/junjielu)) + ## [2.8.1](https://github.com/TextureGroup/Texture/tree/2.8.1) (2019-05-05) [Full Changelog](https://github.com/TextureGroup/Texture/compare/2.8...2.8.1) diff --git a/RELEASE.md b/RELEASE.md index b675fa492..a31073983 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -6,7 +6,7 @@ This document describes the process for a public Texture release. - Generate a GitHub Personal Access Token to prevent running into public GitHub API rate limits: https://github.com/github-changelog-generator/github-changelog-generator#github-token ### Process -- Run `github_changelog_generator` in Texture project directory: `github_changelog_generator --token TextureGroup/Texture`. To avoid hitting rate limit, the generator will replace the entire file with just the changes from this version – revert that giant deletion to get the entire new changelog. +- Run `github_changelog_generator` in Texture project directory: `github_changelog_generator --token --user TextureGroup --project Texture`. To avoid hitting rate limit, the generator will replace the entire file with just the changes from this version – revert that giant deletion to get the entire new changelog. - Update `spec.version` within `Texture.podspec` and the `since-tag` and `future-release` fields in `.github_changelog_generator`. - Create a new PR with the updated `Texture.podspec` and the newly generated changelog, add `#changelog` to the PR message so the CI will not prevent merging it. - After merging in the PR, [create a new GitHub release](https://github.com/TextureGroup/Texture/releases/new). Use the generated changelog for the new release. diff --git a/Texture.podspec b/Texture.podspec index 0ce226aff..51f637aab 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'Texture' - spec.version = '2.8.1' + spec.version = '3.0.0-rc.1' spec.license = { :type => 'Apache 2', } spec.homepage = 'http://texturegroup.org' spec.authors = { 'Huy Nguyen' => 'hi@huynguyen.dev', 'Garrett Moon' => 'garrett@excitedpixel.com', 'Scott Goodson' => 'scottgoodson@gmail.com', 'Michael Schneider' => 'mischneider1@gmail.com', 'Adlai Holler' => 'adlai@icloud.com' } From dbb06bf58ff60bdc773f4cabd9ea92e9a5e6d5c3 Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Thu, 25 Jun 2020 11:54:00 -0700 Subject: [PATCH 45/56] Fix all the warnings and re-enable on CI (#1872) --- Source/ASControlNode.mm | 3 +++ Source/ASDisplayNode.mm | 2 +- Source/ASViewController.mm | 4 ++-- Source/Details/ASGraphicsContext.mm | 2 +- Source/Details/ASRecursiveUnfairLock.mm | 3 +++ Source/Details/ASThread.h | 24 +++++++++++++++---- Source/Details/ASTraitCollection.mm | 20 +++++++++------- Source/Private/ASDisplayNode+UIViewBridge.mm | 6 ++--- .../Private/ASIGListAdapterBasedDataSource.mm | 4 ++-- Source/Private/_ASPendingState.mm | 2 +- Source/UIImage+ASConvenience.mm | 2 +- Texture.podspec | 2 +- build.sh | 4 ++-- 13 files changed, 51 insertions(+), 27 deletions(-) diff --git a/Source/ASControlNode.mm b/Source/ASControlNode.mm index 6336d9947..4bc0ae604 100644 --- a/Source/ASControlNode.mm +++ b/Source/ASControlNode.mm @@ -15,6 +15,9 @@ #import #import #import +#if TARGET_OS_TV +#import +#endif // UIControl allows dragging some distance outside of the control itself during // tracking. This value depends on the device idiom (25 or 70 points), so diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 45f3df870..20643f95b 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -436,7 +436,7 @@ - (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body - (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTraitCollection)previousTraitCollection { - if (@available(iOS 13.0, *)) { + if (@available(iOS 13.0, tvOS 10.0, *)) { // When changing between light and dark mode, often the entire node needs to re-render. // This change doesn't happen frequently so it's fairly safe to render nodes again __instanceLock__.lock(); diff --git a/Source/ASViewController.mm b/Source/ASViewController.mm index 672d90422..8b889dfc6 100644 --- a/Source/ASViewController.mm +++ b/Source/ASViewController.mm @@ -286,7 +286,7 @@ - (ASInterfaceState)interfaceState - (UIEdgeInsets)additionalSafeAreaInsets { - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { return super.additionalSafeAreaInsets; } @@ -295,7 +295,7 @@ - (UIEdgeInsets)additionalSafeAreaInsets - (void)setAdditionalSafeAreaInsets:(UIEdgeInsets)additionalSafeAreaInsets { - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { [super setAdditionalSafeAreaInsets:additionalSafeAreaInsets]; } else { _fallbackAdditionalSafeAreaInsets = additionalSafeAreaInsets; diff --git a/Source/Details/ASGraphicsContext.mm b/Source/Details/ASGraphicsContext.mm index fbd23ddc3..8f543e06f 100644 --- a/Source/Details/ASGraphicsContext.mm +++ b/Source/Details/ASGraphicsContext.mm @@ -15,7 +15,7 @@ #if AS_AT_LEAST_IOS13 #define ASPerformBlockWithTraitCollection(work, traitCollection) \ - if (@available(iOS 13.0, *)) { \ + if (@available(iOS 13.0, tvOS 13.0, *)) { \ UITraitCollection *uiTraitCollection = ASPrimitiveTraitCollectionToUITraitCollection(traitCollection); \ [uiTraitCollection performAsCurrentTraitCollection:^{ \ work(); \ diff --git a/Source/Details/ASRecursiveUnfairLock.mm b/Source/Details/ASRecursiveUnfairLock.mm index b32973335..d6eb1886b 100644 --- a/Source/Details/ASRecursiveUnfairLock.mm +++ b/Source/Details/ASRecursiveUnfairLock.mm @@ -18,16 +18,19 @@ #define rul_set_thread(l, t) atomic_store_explicit(&l->_thread, t, memory_order_relaxed) #define rul_get_thread(l) atomic_load_explicit(&l->_thread, memory_order_relaxed) +OS_UNFAIR_LOCK_AVAILABILITY NS_INLINE void ASRecursiveUnfairLockDidAcquire(ASRecursiveUnfairLock *l, pthread_t tid) { NSCAssert(pthread_equal(rul_get_thread(l), NULL) && l->_count == 0, @"Unfair lock error"); rul_set_thread(l, tid); } +OS_UNFAIR_LOCK_AVAILABILITY NS_INLINE void ASRecursiveUnfairLockWillRelease(ASRecursiveUnfairLock *l) { NSCAssert(pthread_equal(rul_get_thread(l), pthread_self()) && l->_count == 0, @"Unfair lock error"); rul_set_thread(l, NULL); } +OS_UNFAIR_LOCK_AVAILABILITY NS_INLINE void ASRecursiveUnfairLockAssertHeld(ASRecursiveUnfairLock *l) { NSCAssert(pthread_equal(rul_get_thread(l), pthread_self()) && l->_count > 0, @"Unfair lock error"); } diff --git a/Source/Details/ASThread.h b/Source/Details/ASThread.h index cb840e167..0ef3d325a 100644 --- a/Source/Details/ASThread.h +++ b/Source/Details/ASThread.h @@ -159,7 +159,11 @@ namespace AS { success = os_unfair_lock_trylock(&_unfair); break; case RecursiveUnfair: - success = ASRecursiveUnfairLockTryLock(&_runfair); + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + success = ASRecursiveUnfairLockTryLock(&_runfair); + } else { + success = _recursive.try_lock(); + } break; } if (success) { @@ -180,7 +184,11 @@ namespace AS { os_unfair_lock_lock(&_unfair); break; case RecursiveUnfair: - ASRecursiveUnfairLockLock(&_runfair); + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + ASRecursiveUnfairLockLock(&_runfair); + } else { + _recursive.lock(); + } break; } DidLock(); @@ -199,7 +207,11 @@ namespace AS { os_unfair_lock_unlock(&_unfair); break; case RecursiveUnfair: - ASRecursiveUnfairLockUnlock(&_runfair); + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + ASRecursiveUnfairLockUnlock(&_runfair); + } else { + _recursive.unlock(); + } break; } } @@ -225,7 +237,11 @@ namespace AS { if (recursive) { if (gMutex_unfair) { _type = RecursiveUnfair; - _runfair = AS_RECURSIVE_UNFAIR_LOCK_INIT; + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + _runfair = AS_RECURSIVE_UNFAIR_LOCK_INIT; + } else { + new (&_recursive) std::recursive_mutex(); + } } else { _type = Recursive; new (&_recursive) std::recursive_mutex(); diff --git a/Source/Details/ASTraitCollection.mm b/Source/Details/ASTraitCollection.mm index 39c1615d5..8a697eccd 100644 --- a/Source/Details/ASTraitCollection.mm +++ b/Source/Details/ASTraitCollection.mm @@ -33,7 +33,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() { tc.horizontalSizeClass = UIUserInterfaceSizeClassUnspecified; tc.verticalSizeClass = UIUserInterfaceSizeClassUnspecified; tc.containerSize = CGSizeZero; - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { tc.displayGamut = UIDisplayGamutUnspecified; tc.preferredContentSizeCategory = UIContentSizeCategoryUnspecified; tc.layoutDirection = UITraitEnvironmentLayoutDirectionUnspecified; @@ -48,7 +48,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() { } #endif - if (AS_AVAILABLE_IOS(13)) { + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { tc.accessibilityContrast = UIAccessibilityContrastUnspecified; tc.legibilityWeight = UILegibilityWeightUnspecified; } @@ -62,7 +62,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra environmentTraitCollection.displayScale = traitCollection.displayScale; environmentTraitCollection.userInterfaceIdiom = traitCollection.userInterfaceIdiom; environmentTraitCollection.forceTouchCapability = traitCollection.forceTouchCapability; - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { environmentTraitCollection.displayGamut = traitCollection.displayGamut; environmentTraitCollection.layoutDirection = traitCollection.layoutDirection; @@ -79,7 +79,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra } #endif - if (AS_AVAILABLE_IOS(13)) { + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { environmentTraitCollection.accessibilityContrast = traitCollection.accessibilityContrast; environmentTraitCollection.legibilityWeight = traitCollection.legibilityWeight; } @@ -95,7 +95,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra [UITraitCollection traitCollectionWithForceTouchCapability:traitCollection.forceTouchCapability], ]]; - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { [collections addObject:[UITraitCollection traitCollectionWithDisplayGamut:traitCollection.displayGamut]]; [collections addObject:[UITraitCollection traitCollectionWithLayoutDirection:traitCollection.layoutDirection]]; [collections addObject:[UITraitCollection traitCollectionWithPreferredContentSizeCategory:traitCollection.preferredContentSizeCategory]]; @@ -191,8 +191,9 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr } } +#if TARGET_OS_IOS // Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline -API_AVAILABLE(ios(13)) API_UNAVAILABLE(tvos) +API_AVAILABLE(ios(13)) ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentUserInterfaceLevel(UIUserInterfaceLevel userInterfaceLevel) { switch (userInterfaceLevel) { case UIUserInterfaceLevelBase: @@ -203,6 +204,7 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr return @"Unspecified"; } } +#endif // Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline API_AVAILABLE(ios(13)) @@ -242,7 +244,7 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr if (AS_AVAILABLE_IOS_TVOS(12, 10)) { [props addObject:@{ @"userInterfaceStyle": AS_NSStringFromUIUserInterfaceStyle(traits.userInterfaceStyle) }]; } - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { [props addObject:@{ @"layoutDirection": AS_NSStringFromUITraitEnvironmentLayoutDirection(traits.layoutDirection) }]; if (traits.preferredContentSizeCategory != nil) { [props addObject:@{ @"preferredContentSizeCategory": traits.preferredContentSizeCategory }]; @@ -256,7 +258,7 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr } #endif - if (AS_AVAILABLE_IOS(13)) { + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { [props addObject:@{ @"accessibilityContrast": AS_NSStringFromUITraitEnvironmentAccessibilityContrast(traits.accessibilityContrast) }]; [props addObject:@{ @"legibilityWeight": AS_NSStringFromUITraitEnvironmentLegibilityWeight(traits.legibilityWeight) }]; } @@ -272,7 +274,7 @@ @implementation ASTraitCollection { + (ASTraitCollection *)traitCollectionWithASPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traits NS_RETURNS_RETAINED { ASTraitCollection *tc = [[ASTraitCollection alloc] init]; - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { ASDisplayNodeCAssertPermanent(traits.preferredContentSizeCategory); } tc->_prim = traits; diff --git a/Source/Private/ASDisplayNode+UIViewBridge.mm b/Source/Private/ASDisplayNode+UIViewBridge.mm index 50641d80d..42dbbfcb6 100644 --- a/Source/Private/ASDisplayNode+UIViewBridge.mm +++ b/Source/Private/ASDisplayNode+UIViewBridge.mm @@ -1005,7 +1005,7 @@ - (UIEdgeInsets)safeAreaInsets { _bridge_prologue_read; - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (!_flags.layerBacked && _loaded(self)) { return self.view.safeAreaInsets; } @@ -1029,7 +1029,7 @@ - (void)setInsetsLayoutMarginsFromSafeArea:(BOOL)insetsLayoutMarginsFromSafeArea _flags.fallbackInsetsLayoutMarginsFromSafeArea = insetsLayoutMarginsFromSafeArea; - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (!_flags.layerBacked) { _setToViewOnly(insetsLayoutMarginsFromSafeArea, insetsLayoutMarginsFromSafeArea); } @@ -1106,7 +1106,7 @@ - (void)setLayerMaskedCorners:(CACornerMask)newLayerMaskedCorners - (BOOL)_locked_insetsLayoutMarginsFromSafeArea { DISABLED_ASAssertLocked(__instanceLock__); - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (!_flags.layerBacked) { return _getFromViewOnly(insetsLayoutMarginsFromSafeArea); } diff --git a/Source/Private/ASIGListAdapterBasedDataSource.mm b/Source/Private/ASIGListAdapterBasedDataSource.mm index 2f89b42cf..10f51f37d 100644 --- a/Source/Private/ASIGListAdapterBasedDataSource.mm +++ b/Source/Private/ASIGListAdapterBasedDataSource.mm @@ -166,7 +166,7 @@ - (void)collectionNode:(ASCollectionNode *)collectionNode willDisplayItemWithNod { NSIndexPath *indexPath = [collectionNode.view indexPathForNode:node]; UIView *contentView = node.view.superview; - UICollectionViewCell *cell = contentView.superview; + UICollectionViewCell *cell = (UICollectionViewCell *)contentView.superview; if (cell == nil || indexPath == nil) { return; @@ -179,7 +179,7 @@ - (void)collectionNode:(ASCollectionNode *)collectionNode didEndDisplayingItemWi { NSIndexPath *indexPath = [collectionNode.view indexPathForNode:node]; UIView *contentView = node.view.superview; - UICollectionViewCell *cell = contentView.superview; + UICollectionViewCell *cell = (UICollectionViewCell *)contentView.superview; if (cell == nil || indexPath == nil) { return; diff --git a/Source/Private/_ASPendingState.mm b/Source/Private/_ASPendingState.mm index 8593bd583..a9d760e9e 100644 --- a/Source/Private/_ASPendingState.mm +++ b/Source/Private/_ASPendingState.mm @@ -1182,7 +1182,7 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr if (flags.setPreservesSuperviewLayoutMargins) view.preservesSuperviewLayoutMargins = _flags.preservesSuperviewLayoutMargins; - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (flags.setInsetsLayoutMarginsFromSafeArea) { view.insetsLayoutMarginsFromSafeArea = _flags.insetsLayoutMarginsFromSafeArea; } diff --git a/Source/UIImage+ASConvenience.mm b/Source/UIImage+ASConvenience.mm index 567a377c6..cc5896b4f 100644 --- a/Source/UIImage+ASConvenience.mm +++ b/Source/UIImage+ASConvenience.mm @@ -30,7 +30,7 @@ @implementation UIImage (ASDKFastImageNamed) NSString *imageKey = imageName; if (traitCollection) { char imageKeyBuffer[256]; - if (@available(iOS 12.0, *)) { + if (@available(iOS 12.0, tvOS 10.0, *)) { snprintf(imageKeyBuffer, sizeof(imageKeyBuffer), "%s|%ld|%ld|%ld", imageName.UTF8String, (long)traitCollection.horizontalSizeClass, (long)traitCollection.verticalSizeClass, (long)traitCollection.userInterfaceStyle); } else { // Fallback on earlier versions diff --git a/Texture.podspec b/Texture.podspec index 51f637aab..d1df1c90c 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # Subspecs spec.subspec 'Core' do |core| - core.compiler_flags = '-fno-exceptions -Wno-implicit-retain-self' + core.compiler_flags = '-fno-exceptions' core.public_header_files = [ 'Source/*.h', 'Source/Details/**/*.h', diff --git a/build.sh b/build.sh index b2115aa5b..3f4fb2785 100755 --- a/build.sh +++ b/build.sh @@ -66,7 +66,7 @@ function build_example { # Lint subspec function lint_subspec { - set -o pipefail && pod env && pod lib lint --allow-warnings --subspec="$1" + set -o pipefail && pod env && pod lib lint --subspec="$1" } function cleanup { @@ -218,7 +218,7 @@ framework|all) cocoapods-lint|all) echo "Verifying that podspec lints." - set -o pipefail && pod env && pod lib lint --allow-warnings + set -o pipefail && pod env && pod lib lint success="1" ;; From f55ade187b1b1db74f6feb46a71c9ab140a3daf9 Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Thu, 25 Jun 2020 13:00:05 -0700 Subject: [PATCH 46/56] Update RELEASE.md (#1873) --- RELEASE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index a31073983..4826178a9 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -10,6 +10,7 @@ This document describes the process for a public Texture release. - Update `spec.version` within `Texture.podspec` and the `since-tag` and `future-release` fields in `.github_changelog_generator`. - Create a new PR with the updated `Texture.podspec` and the newly generated changelog, add `#changelog` to the PR message so the CI will not prevent merging it. - After merging in the PR, [create a new GitHub release](https://github.com/TextureGroup/Texture/releases/new). Use the generated changelog for the new release. +- Push to Cocoapods with `pod trunk push` ### Problems -- Sometimes we will still run into GitHub rate limit issues although using a personal token to generate the changelog. For now there is no solution for this. The issue to track is: [Triggering Github Rate limits #656](https://github.com/github-changelog-generator/github-changelog-generator/issues/656) \ No newline at end of file +- Sometimes we will still run into GitHub rate limit issues although using a personal token to generate the changelog. For now there is no solution for this. The issue to track is: [Triggering Github Rate limits #656](https://github.com/github-changelog-generator/github-changelog-generator/issues/656) From a7cc48293e35a293697a6a969e69e3fa5d8f980c Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Thu, 25 Jun 2020 15:19:15 -0700 Subject: [PATCH 47/56] Update for 3.0.0-rc.2 (#1874) --- .github_changelog_generator | 2 +- CHANGELOG.md | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github_changelog_generator b/.github_changelog_generator index f01cfffa0..4df42730a 100644 --- a/.github_changelog_generator +++ b/.github_changelog_generator @@ -1,3 +1,3 @@ issues=false -since-tag=3.0.0-rc.1 +since-tag=3.0.0-rc.2 future-release=3.0.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index afbd14431..f3fdb668f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ -# Change Log +# Changelog + +## [3.0.0-rc.2](https://github.com/TextureGroup/Texture/tree/3.0.0-rc.2) (2020-06-25) + +[Full Changelog](https://github.com/TextureGroup/Texture/compare/3.0.0-rc.1...3.0.0-rc.2) + +**Merged pull requests:** + +- Fix all the warnings and re-enable on CI [\#1872](https://github.com/TextureGroup/Texture/pull/1872) ([garrettmoon](https://github.com/garrettmoon)) +- Prepare for 3.0.0-rc.1 release [\#1870](https://github.com/TextureGroup/Texture/pull/1870) ([garrettmoon](https://github.com/garrettmoon)) +- -\[ASNetworkImageNode setURL:resetToDefault:\] forget to reset animatedImage [\#1861](https://github.com/TextureGroup/Texture/pull/1861) ([IvanChan](https://github.com/IvanChan)) ## [3.0.0-rc.1](https://github.com/TextureGroup/Texture/tree/3.0.0-rc.1) (2020-06-19) From 92598f5fb7e6238e9f9964365bef1a8d6d3a2bcf Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Thu, 25 Jun 2020 15:21:57 -0700 Subject: [PATCH 48/56] I forgot this in the last PR and I'm pushing to master, I'm a bad person. --- Texture.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Texture.podspec b/Texture.podspec index d1df1c90c..1b2d153e2 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'Texture' - spec.version = '3.0.0-rc.1' + spec.version = '3.0.0-rc.2' spec.license = { :type => 'Apache 2', } spec.homepage = 'http://texturegroup.org' spec.authors = { 'Huy Nguyen' => 'hi@huynguyen.dev', 'Garrett Moon' => 'garrett@excitedpixel.com', 'Scott Goodson' => 'scottgoodson@gmail.com', 'Michael Schneider' => 'mischneider1@gmail.com', 'Adlai Holler' => 'adlai@icloud.com' } From 6a3a24707eae7a4e9b05e19f8988400245fbe3f0 Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Thu, 25 Jun 2020 15:57:11 -0700 Subject: [PATCH 49/56] Add a 3.0 migration guide (#1875) --- ThreeMigrationGuide.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ThreeMigrationGuide.md diff --git a/ThreeMigrationGuide.md b/ThreeMigrationGuide.md new file mode 100644 index 000000000..afd30d22a --- /dev/null +++ b/ThreeMigrationGuide.md @@ -0,0 +1,3 @@ +### Texture 3.0 Migration Guide ### + +Got a tip for upgrading? Please open a PR to this document! \ No newline at end of file From 8e91008b8e03d329bb890f90d11ad297a2c5c6e0 Mon Sep 17 00:00:00 2001 From: Roger Oba Date: Mon, 29 Jun 2020 12:49:08 -0300 Subject: [PATCH 50/56] Improve ThreeMigrationGuide.md (#1878) * Add `ASImageCacherCompletion` breaking API change. * Remove unnecessary trailing pounds. --- ThreeMigrationGuide.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/ThreeMigrationGuide.md b/ThreeMigrationGuide.md index afd30d22a..eafc3e572 100644 --- a/ThreeMigrationGuide.md +++ b/ThreeMigrationGuide.md @@ -1,3 +1,23 @@ -### Texture 3.0 Migration Guide ### +## Texture 3.0 Migration Guide -Got a tip for upgrading? Please open a PR to this document! \ No newline at end of file +Got a tip for upgrading? Please open a PR to this document! + + +### Breaking API Changes + +`ASImageCacherCompletion` typedef has a new parameter: `ASImageCacheType cacheType`. Example: + + +```swift +ASPINRemoteImageDownloader.shared().cachedImage(with: url, callbackQueue: .main) { result in + … +} +``` + +Becomes + +```swift +ASPINRemoteImageDownloader.shared().cachedImage(with: url, callbackQueue: .main) { result, cacheType in + … +} +``` From c5f69f0b01fc52ea2059366368c095fd842d23bb Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Mon, 29 Jun 2020 12:49:59 -0700 Subject: [PATCH 51/56] Renames AS_EXTERN and ASViewController (#1876) * Renames AS_EXTERN and ASViewController To ASDK_EXTERN and ASDKViewController. This is to avoid conflicting with AuthenticationServices in Xcode 12 * Fix up examples and docs * Add bit about updating ASViewController rename --- AsyncDisplayKit.xcodeproj/project.pbxproj | 24 +++++----- Source/ASCellNode.mm | 6 +-- Source/ASConfigurationInternal.h | 4 +- Source/ASContextTransitioning.h | 4 +- ...SViewController.h => ASDKViewController.h} | 16 +++---- ...iewController.mm => ASDKViewController.mm} | 12 ++--- Source/ASDisplayNode+Beta.h | 4 +- Source/ASDisplayNode+InterfaceState.h | 2 +- Source/ASDisplayNode+Layout.mm | 2 +- Source/ASDisplayNode+Yoga.h | 2 +- Source/ASDisplayNode.h | 2 +- Source/ASDisplayNode.mm | 2 +- Source/ASDisplayNodeExtras.h | 48 +++++++++---------- Source/ASExperimentalFeatures.h | 4 +- Source/ASImageNode.h | 4 +- Source/ASMultiplexImageNode.h | 2 +- Source/ASNavigationController.h | 2 +- Source/ASVisibilityProtocols.h | 8 ++-- Source/AsyncDisplayKit.h | 2 +- Source/Base/ASAssert.h | 6 +-- Source/Base/ASBaseDefines.h | 2 +- Source/Base/ASLog.h | 20 ++++---- Source/Details/ASAbstractLayoutController.h | 6 +-- .../Details/ASCollectionViewLayoutInspector.h | 2 +- Source/Details/ASDataController.h | 4 +- Source/Details/ASGraphicsContext.h | 6 +-- Source/Details/ASHashing.h | 2 +- Source/Details/ASLayoutRangeType.h | 4 +- Source/Details/ASObjectDescriptionHelpers.h | 10 ++-- Source/Details/ASPageTable.h | 12 ++--- .../Details/ASPhotosFrameworkImageRequest.h | 2 +- Source/Details/ASRecursiveUnfairLock.h | 6 +-- Source/Details/ASScrollDirection.h | 18 +++---- Source/Details/ASTraitCollection.h | 14 +++--- Source/Details/ASTraitCollection.mm | 2 +- .../Transactions/_ASAsyncTransaction.h | 2 +- .../Transactions/_ASAsyncTransaction.mm | 2 +- Source/Details/_ASDisplayView.mm | 4 +- Source/Layout/ASDimension.h | 20 ++++---- Source/Layout/ASDimensionInternal.h | 4 +- Source/Layout/ASLayout.h | 10 ++-- Source/Layout/ASLayoutElement.h | 34 ++++++------- Source/Layout/ASLayoutElementPrivate.h | 10 ++-- Source/Layout/ASYogaUtilities.h | 26 +++++----- Source/Private/ASBatchFetching.h | 4 +- Source/Private/ASCollectionLayoutDefines.h | 2 +- Source/Private/ASDispatch.h | 4 +- .../Private/ASDisplayNode+FrameworkPrivate.h | 8 ++-- Source/Private/ASDisplayNodeInternal.h | 4 +- Source/Private/ASImageNode+CGExtras.h | 2 +- Source/Private/ASInternalHelpers.h | 36 +++++++------- Source/Private/ASTipsWindow.h | 2 +- Source/Private/ASTwoDimensionalArrayUtils.h | 10 ++-- .../Layout/ASStackUnpositionedLayout.h | 2 +- .../TextExperiment/Component/ASTextLayout.h | 2 +- .../TextExperiment/String/ASTextAttribute.h | 2 +- Source/Private/_ASCoreAnimationExtras.h | 16 +++---- Source/TextKit/ASTextKitAttributes.h | 4 +- Source/TextKit/ASTextKitCoreTextAdditions.h | 6 +-- ...lerTests.mm => ASDKViewControllerTests.mm} | 10 ++-- Tests/ASDisplayNodeTests.mm | 4 +- Tests/ASDisplayNodeTestsHelper.h | 8 ++-- Tests/ASDisplayViewAccessibilityTests.mm | 12 ++--- Tests/ASNavigationControllerTests.mm | 12 ++--- Tests/ASPagerNodeTests.mm | 2 +- Tests/ASTabBarControllerTests.mm | 10 ++-- Tests/ASTableViewTests.mm | 2 +- ThreeMigrationGuide.md | 1 + ...iewcontroller.md => asdkviewcontroller.md} | 10 ++-- docs/_docs/development/layout-specs.md | 2 +- docs/_docs/development/node-lifecycle.md | 2 +- docs/_docs/subclassing.md | 18 +++---- docs/_docs/synchronous-concurrency.md | 4 +- .../Controller/VideoFeedNodeController.h | 2 +- examples/ASDKTube/Sample/ViewController.h | 2 +- .../ASDKgram/Sample/PhotoFeedBaseController.h | 2 +- .../Sample/PhotoFeedListKitViewController.h | 2 +- examples/ASMapNode/Sample/ViewController.h | 4 +- .../Sample/DetailViewController.h | 4 +- .../ASViewController/Sample/ViewController.h | 4 +- .../Sample/OverviewComponentsViewController.h | 2 +- .../Sample/ViewController.h | 2 +- .../Sample/ViewController.swift | 2 +- .../Sample/ViewController.h | 2 +- .../Sample/ViewController.h | 2 +- examples/Kittens/Sample/ViewController.h | 2 +- .../Sample/LayoutExampleViewController.swift | 2 +- .../Sample/OverviewViewController.swift | 2 +- .../Sample/LayoutExampleViewController.h | 2 +- .../Sample/OverviewViewController.h | 2 +- examples/PagerNode/Sample/ViewController.h | 2 +- examples/README.md | 12 ++--- .../Sample/ViewController.h | 2 +- .../SocialAppLayout/Sample/ViewController.h | 2 +- examples/Swift/Sample/ViewController.swift | 2 +- .../PhotoFeedTableNodeController.swift | 2 +- .../Sample/CollectionViewController.h | 2 +- .../ASTraitCollection/Sample/KittenNode.h | 2 +- .../ASTraitCollection/Sample/KittenNode.m | 2 +- .../Sample/OverrideViewController.h | 2 +- .../Sample/TableViewController.h | 2 +- .../ASTraitCollection/Sample/ViewController.h | 2 +- .../Sample/ViewController.swift | 2 +- .../Multiplex/Sample/ViewController.h | 4 +- .../RepoSearcher/SearchViewController.swift | 2 +- .../Product/ProductViewController.swift | 2 +- .../ProductsCollectionViewController.swift | 2 +- .../ProductsTableViewController.swift | 2 +- .../Shop/Scenes/Shop/ShopViewController.swift | 2 +- .../Sample/AsyncViewController.h | 4 +- .../Sample/CollectionViewController.h | 2 +- 111 files changed, 338 insertions(+), 337 deletions(-) rename Source/{ASViewController.h => ASDKViewController.h} (83%) rename Source/{ASViewController.mm => ASDKViewController.mm} (96%) rename Tests/{ASViewControllerTests.mm => ASDKViewControllerTests.mm} (93%) rename docs/_docs/{asviewcontroller.md => asdkviewcontroller.md} (73%) diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 4f8b9a3c9..e96599067 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -65,7 +65,7 @@ 254C6B8C1BF94F8A003EC431 /* ASTextKitTailTruncater.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754A21BEE44CD00737CA5 /* ASTextKitTailTruncater.mm */; }; 25E327571C16819500A2170C /* ASPagerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 25E327541C16819500A2170C /* ASPagerNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25E327591C16819500A2170C /* ASPagerNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 25E327551C16819500A2170C /* ASPagerNode.mm */; }; - 2767E9411BB19BD600EA9B77 /* ASViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2767E9411BB19BD600EA9B77 /* ASDKViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = ACC945A81BA9E7A0005E1FB8 /* ASDKViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2911485C1A77147A005D0878 /* ASControlNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2911485B1A77147A005D0878 /* ASControlNodeTests.mm */; }; 296A0A351A951ABF005ACEAA /* ASBatchFetchingTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.mm */; }; 29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29CDC2E11AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.mm */; }; @@ -198,7 +198,7 @@ 9C6BB3B31B8CC9C200F13F52 /* ASAbsoluteLayoutElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASAbsoluteLayoutElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9C70F2051CDA4F06007D6C76 /* ASTraitCollection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C70F2021CDA4EFA007D6C76 /* ASTraitCollection.mm */; }; 9C70F2061CDA4F0C007D6C76 /* ASTraitCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C70F2011CDA4EFA007D6C76 /* ASTraitCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9C70F2091CDABA36007D6C76 /* ASViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFFC6BF1CCAC73C006A6476 /* ASViewController.mm */; }; + 9C70F2091CDABA36007D6C76 /* ASDKViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFFC6BF1CCAC73C006A6476 /* ASDKViewController.mm */; }; 9C70F20A1CDBE949007D6C76 /* ASTableNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFFC6C11CCAC768006A6476 /* ASTableNode.mm */; }; 9C70F20D1CDBE9CB007D6C76 /* ASDefaultPlayButton.h in Headers */ = {isa = PBXBuildFile; fileRef = AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */; settings = {ATTRIBUTES = (Private, ); }; }; 9C70F20E1CDBE9E5007D6C76 /* NSArray+Diffing.h in Headers */ = {isa = PBXBuildFile; fileRef = DBC452D91C5BF64600B16017 /* NSArray+Diffing.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -390,7 +390,7 @@ CC8B05D61D73836400F54286 /* ASPerformanceTestContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC8B05D51D73836400F54286 /* ASPerformanceTestContext.mm */; }; CC8B05D81D73979700F54286 /* ASTextNodePerformanceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.mm */; }; CC90E1F41E383C0400FED591 /* AsyncDisplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B35061DA1B010EDF0018CF92 /* AsyncDisplayKit.framework */; }; - CCA221D31D6FA7EF00AF6A0F /* ASViewControllerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.mm */; }; + CCA221D31D6FA7EF00AF6A0F /* ASDKViewControllerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA221D21D6FA7EF00AF6A0F /* ASDKViewControllerTests.mm */; }; CCA282B41E9EA7310037E8B7 /* ASTipsController.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282B21E9EA7310037E8B7 /* ASTipsController.h */; }; CCA282B51E9EA7310037E8B7 /* ASTipsController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA282B31E9EA7310037E8B7 /* ASTipsController.mm */; }; CCA282B81E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282B61E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -779,7 +779,7 @@ 9C70F2021CDA4EFA007D6C76 /* ASTraitCollection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTraitCollection.mm; sourceTree = ""; }; 9C8898BA1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitFontSizeAdjuster.mm; path = TextKit/ASTextKitFontSizeAdjuster.mm; sourceTree = ""; }; 9CDC18CB1B910E12004965E2 /* ASLayoutElementPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutElementPrivate.h; sourceTree = ""; }; - 9CFFC6BF1CCAC73C006A6476 /* ASViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASViewController.mm; sourceTree = ""; }; + 9CFFC6BF1CCAC73C006A6476 /* ASDKViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDKViewController.mm; sourceTree = ""; }; 9CFFC6C11CCAC768006A6476 /* ASTableNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTableNode.mm; sourceTree = ""; }; 9D302F9A2231B07E005739C3 /* ASButtonNode+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASButtonNode+Private.h"; sourceTree = ""; }; 9D302F9C2231B373005739C3 /* ASButtonNode+Yoga.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASButtonNode+Yoga.h"; sourceTree = ""; }; @@ -803,7 +803,7 @@ AC6145421D8AFD4F003D62A2 /* ASSection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASSection.mm; path = ../Private/ASSection.mm; sourceTree = ""; }; AC6456071B0A335000CF11B8 /* ASCellNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCellNode.mm; sourceTree = ""; }; AC7A2C161BDE11DF0093FE1A /* ASTableViewInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTableViewInternal.h; sourceTree = ""; }; - ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASViewController.h; sourceTree = ""; }; + ACC945A81BA9E7A0005E1FB8 /* ASDKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDKViewController.h; sourceTree = ""; }; ACE87A2B1D73696800D7FF06 /* ASSectionContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASSectionContext.h; path = Details/ASSectionContext.h; sourceTree = ""; }; ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBackgroundLayoutSpec.h; sourceTree = ""; }; ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASBackgroundLayoutSpec.mm; sourceTree = ""; }; @@ -923,7 +923,7 @@ CC8B05D41D73836400F54286 /* ASPerformanceTestContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPerformanceTestContext.h; sourceTree = ""; }; CC8B05D51D73836400F54286 /* ASPerformanceTestContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPerformanceTestContext.mm; sourceTree = ""; }; CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextNodePerformanceTests.mm; sourceTree = ""; }; - CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASViewControllerTests.mm; sourceTree = ""; }; + CCA221D21D6FA7EF00AF6A0F /* ASDKViewControllerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDKViewControllerTests.mm; sourceTree = ""; }; CCA282B21E9EA7310037E8B7 /* ASTipsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTipsController.h; sourceTree = ""; }; CCA282B31E9EA7310037E8B7 /* ASTipsController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTipsController.mm; sourceTree = ""; }; CCA282B61E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit+Tips.h"; sourceTree = ""; }; @@ -1275,8 +1275,8 @@ AEEC47E01C20C2DD00EC1693 /* ASVideoNode.mm */, 8BDA5FC31CDBDDE1007D13B2 /* ASVideoPlayerNode.h */, 8BDA5FC41CDBDDE1007D13B2 /* ASVideoPlayerNode.mm */, - ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */, - 9CFFC6BF1CCAC73C006A6476 /* ASViewController.mm */, + ACC945A81BA9E7A0005E1FB8 /* ASDKViewController.h */, + 9CFFC6BF1CCAC73C006A6476 /* ASDKViewController.mm */, 68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */, 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.mm */, 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */, @@ -1386,7 +1386,7 @@ D933F040224AD17F00FF495E /* ASTransactionTests.mm */, CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.mm */, AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.mm */, - CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.mm */, + CCA221D21D6FA7EF00AF6A0F /* ASDKViewControllerTests.mm */, 83A7D95D1D446A6E00BF333E /* ASWeakMapTests.mm */, CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.mm */, 695BE2541DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm */, @@ -2107,7 +2107,7 @@ CCA282B41E9EA7310037E8B7 /* ASTipsController.h in Headers */, 34EFC7711B701CFF00AD841F /* ASStackLayoutSpec.h in Headers */, CCA282C01E9EAE010037E8B7 /* ASTip.h in Headers */, - 2767E9411BB19BD600EA9B77 /* ASViewController.h in Headers */, + 2767E9411BB19BD600EA9B77 /* ASDKViewController.h in Headers */, 92DD2FE81BF4D0A80074C9DD /* ASMapNode.h in Headers */, 9C6BB3B31B8CC9C200F13F52 /* ASAbsoluteLayoutElement.h in Headers */, 34EFC7731B701D0700AD841F /* ASAbsoluteLayoutSpec.h in Headers */, @@ -2330,7 +2330,7 @@ ACF6ED5D1B178DC700DA7C62 /* ASDimensionTests.mm in Sources */, BB5FC3D11F9C9389007F191E /* ASTabBarControllerTests.mm in Sources */, 695BE2551DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm in Sources */, - CCA221D31D6FA7EF00AF6A0F /* ASViewControllerTests.mm in Sources */, + CCA221D31D6FA7EF00AF6A0F /* ASDKViewControllerTests.mm in Sources */, 058D0A38195D057000B7D73C /* ASDisplayLayerTests.mm in Sources */, 2538B6F31BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.mm in Sources */, CC583AD61EF9BDBE00134156 /* ASTestCase.mm in Sources */, @@ -2405,7 +2405,7 @@ DEB8ED7C1DD003D300DBDE55 /* ASLayoutTransition.mm in Sources */, CCA5F62E1EECC2A80060C137 /* ASAssert.mm in Sources */, 9F98C0261DBE29E000476D92 /* ASControlTargetAction.mm in Sources */, - 9C70F2091CDABA36007D6C76 /* ASViewController.mm in Sources */, + 9C70F2091CDABA36007D6C76 /* ASDKViewController.mm in Sources */, 3917EBD51E9C2FC400D04A01 /* _ASCollectionReusableView.mm in Sources */, CCA282D11E9EBF6C0037E8B7 /* ASTipsWindow.mm in Sources */, CCCCCCE41EC3EF060087FE10 /* NSParagraphStyle+ASText.mm in Sources */, diff --git a/Source/ASCellNode.mm b/Source/ASCellNode.mm index 5bf648cad..208eb5f05 100644 --- a/Source/ASCellNode.mm +++ b/Source/ASCellNode.mm @@ -20,7 +20,7 @@ #import #import -#import +#import #import #import @@ -79,8 +79,8 @@ - (void)didLoad _viewController = _viewControllerBlock(); _viewControllerBlock = nil; - if ([_viewController isKindOfClass:[ASViewController class]]) { - ASViewController *asViewController = (ASViewController *)_viewController; + if ([_viewController isKindOfClass:[ASDKViewController class]]) { + ASDKViewController *asViewController = (ASDKViewController *)_viewController; _viewControllerNode = asViewController.node; [_viewController loadViewIfNeeded]; } else { diff --git a/Source/ASConfigurationInternal.h b/Source/ASConfigurationInternal.h index eb639c224..fa6949622 100644 --- a/Source/ASConfigurationInternal.h +++ b/Source/ASConfigurationInternal.h @@ -34,12 +34,12 @@ NS_ASSUME_NONNULL_BEGIN /** * Internal function. Use the macro without the underbar. */ -AS_EXTERN BOOL _ASActivateExperimentalFeature(ASExperimentalFeatures option); +ASDK_EXTERN BOOL _ASActivateExperimentalFeature(ASExperimentalFeatures option); /** * Notify the configuration delegate that the framework initialized, if needed. */ -AS_EXTERN void ASNotifyInitialized(void); +ASDK_EXTERN void ASNotifyInitialized(void); AS_SUBCLASSING_RESTRICTED @interface ASConfigurationManager : NSObject diff --git a/Source/ASContextTransitioning.h b/Source/ASContextTransitioning.h index 9802ecefc..aea3501b2 100644 --- a/Source/ASContextTransitioning.h +++ b/Source/ASContextTransitioning.h @@ -14,8 +14,8 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN NSString * const ASTransitionContextFromLayoutKey; -AS_EXTERN NSString * const ASTransitionContextToLayoutKey; +ASDK_EXTERN NSString * const ASTransitionContextFromLayoutKey; +ASDK_EXTERN NSString * const ASTransitionContextToLayoutKey; @protocol ASContextTransitioning diff --git a/Source/ASViewController.h b/Source/ASDKViewController.h similarity index 83% rename from Source/ASViewController.h rename to Source/ASDKViewController.h index 89c02d6f9..035b09e1d 100644 --- a/Source/ASViewController.h +++ b/Source/ASDKViewController.h @@ -1,5 +1,5 @@ // -// ASViewController.h +// ASDKViewController.h // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -19,29 +19,29 @@ typedef ASTraitCollection * _Nonnull (^ASDisplayTraitsForTraitCollectionBlock)(U typedef ASTraitCollection * _Nonnull (^ASDisplayTraitsForTraitWindowSizeBlock)(CGSize windowSize); /** - * ASViewController allows you to have a completely node backed hierarchy. It automatically + * ASDKViewController allows you to have a completely node backed hierarchy. It automatically * handles @c ASVisibilityDepth, automatic range mode and propogating @c ASDisplayTraits to contained nodes. * * You can opt-out of node backed hierarchy and use it like a normal UIViewController. * More importantly, you can use it as a base class for all of your view controllers among which some use a node hierarchy and some don't. * See examples/ASDKgram project for actual implementation. */ -@interface ASViewController<__covariant DisplayNodeType : ASDisplayNode *> : UIViewController +@interface ASDKViewController<__covariant DisplayNodeType : ASDisplayNode *> : UIViewController /** - * ASViewController initializer. + * ASDKViewController initializer. * * @param node An ASDisplayNode which will provide the root view (self.view) - * @return An ASViewController instance whose root view will be backed by the provided ASDisplayNode. + * @return An ASDKViewController instance whose root view will be backed by the provided ASDisplayNode. * * @see ASVisibilityDepth */ - (instancetype)initWithNode:(DisplayNodeType)node NS_DESIGNATED_INITIALIZER; /** -* ASViewController initializer. Useful for interoperability with normal UIViewControllers. +* ASDKViewController initializer. Useful for interoperability with normal UIViewControllers. * -* @return An ASViewController instance with a nil node whose root view will be backed by a standard UIView as with a normal UIViewController. +* @return An ASDKViewController instance with a nil node whose root view will be backed by a standard UIView as with a normal UIViewController. * * @see ASVisibilityDepth */ @@ -86,7 +86,7 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface ASViewController (ASRangeControllerUpdateRangeProtocol) +@interface ASDKViewController (ASRangeControllerUpdateRangeProtocol) /** * Automatically adjust range mode based on view events. If you set this to YES, the view controller or its node diff --git a/Source/ASViewController.mm b/Source/ASDKViewController.mm similarity index 96% rename from Source/ASViewController.mm rename to Source/ASDKViewController.mm index 8b889dfc6..da4a19e82 100644 --- a/Source/ASViewController.mm +++ b/Source/ASDKViewController.mm @@ -1,5 +1,5 @@ // -// ASViewController.mm +// ASDKViewController.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,14 +7,14 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import +#import #import #import #import #import #import -@implementation ASViewController +@implementation ASDKViewController { BOOL _ensureDisplayed; BOOL _automaticallyAdjustRangeModeBasedOnViewEvents; @@ -185,7 +185,7 @@ - (void)_updateNodeFallbackSafeArea - (void)viewWillAppear:(BOOL)animated { - as_activity_create_for_scope("ASViewController will appear"); + as_activity_create_for_scope("ASDKViewController will appear"); os_log_debug(ASNodeLog(), "View controller %@ will appear", self); [super viewWillAppear:animated]; @@ -323,13 +323,13 @@ - (void)propagateNewTraitCollection:(ASPrimitiveTraitCollection)traitCollection ASPrimitiveTraitCollection oldTraitCollection = self.node.primitiveTraitCollection; if (ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(traitCollection, oldTraitCollection) == NO) { - as_activity_scope_verbose(as_activity_create("Propagate ASViewController trait collection", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); + as_activity_scope_verbose(as_activity_create("Propagate ASDKViewController trait collection", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); os_log_debug(ASNodeLog(), "Propagating new traits for %@: %@", self, NSStringFromASPrimitiveTraitCollection(traitCollection)); ASTraitCollectionPropagateDown(self.node, traitCollection); // Once we've propagated all the traits, layout this node. // Remeasure the node with the latest constrained size – old constrained size may be incorrect. - as_activity_scope_verbose(as_activity_create("Layout ASViewController node with new traits", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); + as_activity_scope_verbose(as_activity_create("Layout ASDKViewController node with new traits", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); [_node layoutThatFits:[self nodeConstrainedSize]]; } } diff --git a/Source/ASDisplayNode+Beta.h b/Source/ASDisplayNode+Beta.h index 4a8f4f451..882042a97 100644 --- a/Source/ASDisplayNode+Beta.h +++ b/Source/ASDisplayNode+Beta.h @@ -19,8 +19,8 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN void ASPerformBlockOnMainThread(void (^block)(void)); -AS_EXTERN void ASPerformBlockOnBackgroundThread(void (^block)(void)); // DISPATCH_QUEUE_PRIORITY_DEFAULT +ASDK_EXTERN void ASPerformBlockOnMainThread(void (^block)(void)); +ASDK_EXTERN void ASPerformBlockOnBackgroundThread(void (^block)(void)); // DISPATCH_QUEUE_PRIORITY_DEFAULT /** * Bitmask to indicate what performance measurements the cell should record. diff --git a/Source/ASDisplayNode+InterfaceState.h b/Source/ASDisplayNode+InterfaceState.h index 273cf6cb7..96ff70322 100644 --- a/Source/ASDisplayNode+InterfaceState.h +++ b/Source/ASDisplayNode+InterfaceState.h @@ -9,7 +9,7 @@ #import /** - * Interface state is available on ASDisplayNode and ASViewController, and + * Interface state is available on ASDisplayNode and ASDKViewController, and * allows checking whether a node is in an interface situation where it is prudent to trigger certain * actions: measurement, data loading, display, and visibility (the latter for animations or other onscreen-only effects). * diff --git a/Source/ASDisplayNode+Layout.mm b/Source/ASDisplayNode+Layout.mm index 25d44b87b..ab99d3ae1 100644 --- a/Source/ASDisplayNode+Layout.mm +++ b/Source/ASDisplayNode+Layout.mm @@ -298,7 +298,7 @@ - (void)_rootNodeDidInvalidateSize // TODO // We should remove this logic, which is relatively new, and instead // rely on the parent / host of the root node to do this size change. That's always been the -// expectation with other node containers like ASTableView, ASCollectionView, ASViewController, etc. +// expectation with other node containers like ASTableView, ASCollectionView, ASDKViewController, etc. // E.g. in ASCellNode the _interactionDelegate is a Table or Collection that will resize in this // case. By resizing without participating with the parent, we could get cases where our parent size // does not match, especially if there is a size constraint that is applied at that level. diff --git a/Source/ASDisplayNode+Yoga.h b/Source/ASDisplayNode+Yoga.h index ac6b92175..000bb90e0 100644 --- a/Source/ASDisplayNode+Yoga.h +++ b/Source/ASDisplayNode+Yoga.h @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @class ASLayout; -AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullable node, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullable node, void(^block)(ASDisplayNode *node)); @interface ASDisplayNode (Yoga) diff --git a/Source/ASDisplayNode.h b/Source/ASDisplayNode.h index 7f506a03b..eff930ccf 100644 --- a/Source/ASDisplayNode.h +++ b/Source/ASDisplayNode.h @@ -76,7 +76,7 @@ typedef NS_ENUM(unsigned char, ASCornerRoundingType) { /** * Default drawing priority for display node */ -AS_EXTERN NSInteger const ASDefaultDrawingPriority; +ASDK_EXTERN NSInteger const ASDefaultDrawingPriority; /** * An `ASDisplayNode` is an abstraction over `UIView` and `CALayer` that allows you to perform calculations about a view diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 20643f95b..abb339bdd 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -1377,7 +1377,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) { // This recursion must handle layers in various states: // 1. Just added to hierarchy, CA hasn't yet called -display - // 2. Previously in a hierarchy (such as a working window owned by an Intelligent Preloading class, like ASTableView / ASCollectionView / ASViewController) + // 2. Previously in a hierarchy (such as a working window owned by an Intelligent Preloading class, like ASTableView / ASCollectionView / ASDKViewController) // 3. Has no content to display at all // Specifically for case 1), we need to explicitly trigger a -display call now. // Otherwise, there is no opportunity to block the main thread after CoreAnimation's transaction commit diff --git a/Source/ASDisplayNodeExtras.h b/Source/ASDisplayNodeExtras.h index 09512ead9..03f294043 100644 --- a/Source/ASDisplayNodeExtras.h +++ b/Source/ASDisplayNodeExtras.h @@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN /// For deallocation of objects on the main thread across multiple run loops. -AS_EXTERN void ASPerformMainThreadDeallocation(id _Nullable __strong * _Nonnull objectPtr); +ASDK_EXTERN void ASPerformMainThreadDeallocation(id _Nullable __strong * _Nonnull objectPtr); // Because inline methods can't be extern'd and need to be part of the translation unit of code // that compiles with them to actually inline, we both declare and define these in the header. @@ -101,22 +101,22 @@ __unused static NSString *NSStringFromASInterfaceStateChange(ASInterfaceState ol /** Returns the appropriate interface state for a given ASDisplayNode and window */ -AS_EXTERN ASInterfaceState ASInterfaceStateForDisplayNode(ASDisplayNode *displayNode, UIWindow *window) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASInterfaceState ASInterfaceStateForDisplayNode(ASDisplayNode *displayNode, UIWindow *window) AS_WARN_UNUSED_RESULT; /** Given a layer, returns the associated display node, if any. */ -AS_EXTERN ASDisplayNode * _Nullable ASLayerToDisplayNode(CALayer * _Nullable layer) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASDisplayNode * _Nullable ASLayerToDisplayNode(CALayer * _Nullable layer) AS_WARN_UNUSED_RESULT; /** Given a view, returns the associated display node, if any. */ -AS_EXTERN ASDisplayNode * _Nullable ASViewToDisplayNode(UIView * _Nullable view) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASDisplayNode * _Nullable ASViewToDisplayNode(UIView * _Nullable view) AS_WARN_UNUSED_RESULT; /** Given a node, returns the root of the node hierarchy (where supernode == nil) */ -AS_EXTERN ASDisplayNode *ASDisplayNodeUltimateParentOfNode(ASDisplayNode *node) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASDisplayNode *ASDisplayNodeUltimateParentOfNode(ASDisplayNode *node) AS_WARN_UNUSED_RESULT; /** If traverseSublayers == YES, this function will walk the layer hierarchy, spanning discontinuous sections of the node hierarchy\ @@ -124,39 +124,39 @@ AS_EXTERN ASDisplayNode *ASDisplayNodeUltimateParentOfNode(ASDisplayNode *node) In the event that a node's backing layer is not created yet, the function will only walk the direct subnodes instead of forcing the layer hierarchy to be created. */ -AS_EXTERN void ASDisplayNodePerformBlockOnEveryNode(CALayer * _Nullable layer, ASDisplayNode * _Nullable node, BOOL traverseSublayers, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEveryNode(CALayer * _Nullable layer, ASDisplayNode * _Nullable node, BOOL traverseSublayers, void(^block)(ASDisplayNode *node)); /** This function will walk the node hierarchy in a breadth first fashion. It does run the block on the node provided directly to the function call. It does NOT traverse sublayers. */ -AS_EXTERN void ASDisplayNodePerformBlockOnEveryNodeBFS(ASDisplayNode *node, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEveryNodeBFS(ASDisplayNode *node, void(^block)(ASDisplayNode *node)); /** Identical to ASDisplayNodePerformBlockOnEveryNode, except it does not run the block on the node provided directly to the function call - only on all descendants. */ -AS_EXTERN void ASDisplayNodePerformBlockOnEverySubnode(ASDisplayNode *node, BOOL traverseSublayers, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEverySubnode(ASDisplayNode *node, BOOL traverseSublayers, void(^block)(ASDisplayNode *node)); /** Given a display node, traverses up the layer tree hierarchy, returning the first display node that passes block. */ -AS_EXTERN ASDisplayNode * _Nullable ASDisplayNodeFindFirstSupernode(ASDisplayNode * _Nullable node, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use the `supernodes` property instead."); +ASDK_EXTERN ASDisplayNode * _Nullable ASDisplayNodeFindFirstSupernode(ASDisplayNode * _Nullable node, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use the `supernodes` property instead."); /** Given a display node, traverses up the layer tree hierarchy, returning the first display node of kind class. */ -AS_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSupernodeOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use the `supernodeOfClass:includingSelf:` method instead."); +ASDK_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSupernodeOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use the `supernodeOfClass:includingSelf:` method instead."); /** * Given a layer, find the window it lives in, if any. */ -AS_EXTERN UIWindow * _Nullable ASFindWindowOfLayer(CALayer *layer) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN UIWindow * _Nullable ASFindWindowOfLayer(CALayer *layer) AS_WARN_UNUSED_RESULT; /** * Given a layer, find the closest view it lives in, if any. */ -AS_EXTERN UIView * _Nullable ASFindClosestViewOfLayer(CALayer *layer) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN UIView * _Nullable ASFindClosestViewOfLayer(CALayer *layer) AS_WARN_UNUSED_RESULT; /** * Given two nodes, finds their most immediate common parent. Used for geometry conversion methods. @@ -166,48 +166,48 @@ AS_EXTERN UIView * _Nullable ASFindClosestViewOfLayer(CALayer *layer) AS_WARN_UN * undefined and undocumented behavior of UIKit in ASDisplayNode, this operation is defined to be incorrect in all * circumstances and must be fixed wherever encountered. */ -AS_EXTERN ASDisplayNode * _Nullable ASDisplayNodeFindClosestCommonAncestor(ASDisplayNode *node1, ASDisplayNode *node2) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASDisplayNode * _Nullable ASDisplayNodeFindClosestCommonAncestor(ASDisplayNode *node1, ASDisplayNode *node2) AS_WARN_UNUSED_RESULT; /** Given a display node, collects all descendants. This is a specialization of ASCollectContainer() that walks the Core Animation layer tree as opposed to the display node tree, thus supporting non-continues display node hierarchies. */ -AS_EXTERN NSArray *ASCollectDisplayNodes(ASDisplayNode *node) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray *ASCollectDisplayNodes(ASDisplayNode *node) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning all the display nodes that pass the block. */ -AS_EXTERN NSArray *ASDisplayNodeFindAllSubnodes(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray *ASDisplayNodeFindAllSubnodes(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning all the display nodes of kind class. */ -AS_EXTERN NSArray<__kindof ASDisplayNode *> *ASDisplayNodeFindAllSubnodesOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray<__kindof ASDisplayNode *> *ASDisplayNodeFindAllSubnodesOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning the depth-first display node, including the start node that pass the block. */ -AS_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstNode(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstNode(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning the depth-first display node, excluding the start node, that pass the block */ -AS_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSubnode(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSubnode(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning the depth-first display node of kind class. */ -AS_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSubnodeOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSubnodeOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT; -AS_EXTERN UIColor *ASDisplayNodeDefaultPlaceholderColor(void) AS_WARN_UNUSED_RESULT; -AS_EXTERN UIColor *ASDisplayNodeDefaultTintColor(void) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN UIColor *ASDisplayNodeDefaultPlaceholderColor(void) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN UIColor *ASDisplayNodeDefaultTintColor(void) AS_WARN_UNUSED_RESULT; /** Disable willAppear / didAppear / didDisappear notifications for a sub-hierarchy, then re-enable when done. Nested calls are supported. */ -AS_EXTERN void ASDisplayNodeDisableHierarchyNotifications(ASDisplayNode *node); -AS_EXTERN void ASDisplayNodeEnableHierarchyNotifications(ASDisplayNode *node); +ASDK_EXTERN void ASDisplayNodeDisableHierarchyNotifications(ASDisplayNode *node); +ASDK_EXTERN void ASDisplayNodeEnableHierarchyNotifications(ASDisplayNode *node); // Not to be called directly. -AS_EXTERN void _ASSetDebugNames(Class owningClass, NSString *names, ASDisplayNode * _Nullable object, ...); +ASDK_EXTERN void _ASSetDebugNames(Class owningClass, NSString *names, ASDisplayNode * _Nullable object, ...); NS_ASSUME_NONNULL_END diff --git a/Source/ASExperimentalFeatures.h b/Source/ASExperimentalFeatures.h index 306c57d41..7729e2e34 100644 --- a/Source/ASExperimentalFeatures.h +++ b/Source/ASExperimentalFeatures.h @@ -33,9 +33,9 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { }; /// Convert flags -> name array. -AS_EXTERN NSArray *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags); +ASDK_EXTERN NSArray *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags); /// Convert name array -> flags. -AS_EXTERN ASExperimentalFeatures ASExperimentalFeaturesFromArray(NSArray *array); +ASDK_EXTERN ASExperimentalFeatures ASExperimentalFeaturesFromArray(NSArray *array); NS_ASSUME_NONNULL_END diff --git a/Source/ASImageNode.h b/Source/ASImageNode.h index 6c71eaa0a..dcdb11069 100644 --- a/Source/ASImageNode.h +++ b/Source/ASImageNode.h @@ -195,7 +195,7 @@ typedef UIImage * _Nullable (^asimagenode_modification_block_t)(UIImage *image, * * @return An ASImageNode image modification block. */ -AS_EXTERN asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor * _Nullable borderColor); +ASDK_EXTERN asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor * _Nullable borderColor); /** * @abstract Image modification block that applies a tint color à la UIImage configured with @@ -207,6 +207,6 @@ AS_EXTERN asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlo * * @return An ASImageNode image modification block. */ -AS_EXTERN asimagenode_modification_block_t ASImageNodeTintColorModificationBlock(UIColor *color); +ASDK_EXTERN asimagenode_modification_block_t ASImageNodeTintColorModificationBlock(UIColor *color); NS_ASSUME_NONNULL_END diff --git a/Source/ASMultiplexImageNode.h b/Source/ASMultiplexImageNode.h index aad731ddd..72a913a90 100644 --- a/Source/ASMultiplexImageNode.h +++ b/Source/ASMultiplexImageNode.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN typedef id ASImageIdentifier; -AS_EXTERN NSString *const ASMultiplexImageNodeErrorDomain; +ASDK_EXTERN NSString *const ASMultiplexImageNodeErrorDomain; /** * ASMultiplexImageNode error codes. diff --git a/Source/ASNavigationController.h b/Source/ASNavigationController.h index cd6e417d4..0d259b24a 100644 --- a/Source/ASNavigationController.h +++ b/Source/ASNavigationController.h @@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN * * @discussion ASNavigationController is a drop in replacement for UINavigationController * which improves memory efficiency by implementing the @c ASManagesChildVisibilityDepth protocol. - * You can use ASNavigationController with regular UIViewControllers, as well as ASViewControllers. + * You can use ASNavigationController with regular UIViewControllers, as well as ASDKViewControllers. * It is safe to subclass or use even where AsyncDisplayKit is not adopted. * * @see ASManagesChildVisibilityDepth diff --git a/Source/ASVisibilityProtocols.h b/Source/ASVisibilityProtocols.h index f350a3444..b9f5c7ba3 100644 --- a/Source/ASVisibilityProtocols.h +++ b/Source/ASVisibilityProtocols.h @@ -14,13 +14,13 @@ NS_ASSUME_NONNULL_BEGIN @class UIViewController; -AS_EXTERN ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visibilityDepth); +ASDK_EXTERN ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visibilityDepth); /** * ASVisibilityDepth * * @discussion "Visibility Depth" represents the number of user actions required to make an ASDisplayNode or - * ASViewController visibile. AsyncDisplayKit uses this information to intelligently manage memory and focus + * ASDKViewController visibile. AsyncDisplayKit uses this information to intelligently manage memory and focus * resources where they are most visible to the user. * * The ASVisibilityDepth protocol describes how custom view controllers can integrate with this system. @@ -55,11 +55,11 @@ AS_EXTERN ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visib * If implemented by a view controller container, use this method to notify child view controllers that their view * depth has changed @see ASNavigationController.m * - * If implemented on an ASViewController, use this method to reduce or increase the resources that your + * If implemented on an ASDKViewController, use this method to reduce or increase the resources that your * view controller uses. A higher visibility depth view controller should decrease it's resource usage, a lower * visibility depth controller should pre-warm resources in preperation for a display at 0 depth. * - * ASViewController implements this method and reduces / increases range mode of supporting nodes (such as ASCollectionNode + * ASDKViewController implements this method and reduces / increases range mode of supporting nodes (such as ASCollectionNode * and ASTableNode). * * @see visibilityDepth diff --git a/Source/AsyncDisplayKit.h b/Source/AsyncDisplayKit.h index 59e9aeeca..2ac6e9b00 100644 --- a/Source/AsyncDisplayKit.h +++ b/Source/AsyncDisplayKit.h @@ -64,7 +64,7 @@ #import #import -#import +#import #import #import #import diff --git a/Source/Base/ASAssert.h b/Source/Base/ASAssert.h index f00ce967d..4445b2443 100644 --- a/Source/Base/ASAssert.h +++ b/Source/Base/ASAssert.h @@ -74,11 +74,11 @@ */ #pragma mark - Main Thread Assertions Disabling -AS_EXTERN BOOL ASMainThreadAssertionsAreDisabled(void); +ASDK_EXTERN BOOL ASMainThreadAssertionsAreDisabled(void); -AS_EXTERN void ASPushMainThreadAssertionsDisabled(void); +ASDK_EXTERN void ASPushMainThreadAssertionsDisabled(void); -AS_EXTERN void ASPopMainThreadAssertionsDisabled(void); +ASDK_EXTERN void ASPopMainThreadAssertionsDisabled(void); #pragma mark - Non-Fatal Assertions diff --git a/Source/Base/ASBaseDefines.h b/Source/Base/ASBaseDefines.h index 92b6d8fac..53ea66a03 100644 --- a/Source/Base/ASBaseDefines.h +++ b/Source/Base/ASBaseDefines.h @@ -9,7 +9,7 @@ #import -#define AS_EXTERN FOUNDATION_EXTERN +#define ASDK_EXTERN FOUNDATION_EXTERN #define unowned __unsafe_unretained /** diff --git a/Source/Base/ASLog.h b/Source/Base/ASLog.h index e21f8519b..fb0eb574a 100644 --- a/Source/Base/ASLog.h +++ b/Source/Base/ASLog.h @@ -30,7 +30,7 @@ * are at the `debug` log level, which the system * disables in production. */ -AS_EXTERN void ASDisableLogging(void); +ASDK_EXTERN void ASDisableLogging(void); /** * Restore logging that has been runtime-disabled via ASDisableLogging(). @@ -40,38 +40,38 @@ AS_EXTERN void ASDisableLogging(void); * configuration. This can be used in conjunction with ASDisableLogging() * to allow logging to be toggled off and back on at runtime. */ -AS_EXTERN void ASEnableLogging(void); +ASDK_EXTERN void ASEnableLogging(void); /// Log for general node events e.g. interfaceState, didLoad. #define ASNodeLogEnabled 1 -AS_EXTERN os_log_t ASNodeLog(void); +ASDK_EXTERN os_log_t ASNodeLog(void); /// Log for layout-specific events e.g. calculateLayout. #define ASLayoutLogEnabled 1 -AS_EXTERN os_log_t ASLayoutLog(void); +ASDK_EXTERN os_log_t ASLayoutLog(void); /// Log for display-specific events e.g. display queue batches. #define ASDisplayLogEnabled 1 -AS_EXTERN os_log_t ASDisplayLog(void); +ASDK_EXTERN os_log_t ASDisplayLog(void); /// Log for collection events e.g. reloadData, performBatchUpdates. #define ASCollectionLogEnabled 1 -AS_EXTERN os_log_t ASCollectionLog(void); +ASDK_EXTERN os_log_t ASCollectionLog(void); /// Log for ASNetworkImageNode and ASMultiplexImageNode events. #define ASImageLoadingLogEnabled 1 -AS_EXTERN os_log_t ASImageLoadingLog(void); +ASDK_EXTERN os_log_t ASImageLoadingLog(void); /// Specialized log for our main thread deallocation trampoline. #define ASMainThreadDeallocationLogEnabled 0 -AS_EXTERN os_log_t ASMainThreadDeallocationLog(void); +ASDK_EXTERN os_log_t ASMainThreadDeallocationLog(void); #define ASLockingLogEnabled 0 -AS_EXTERN os_log_t ASLockingLog(void); +ASDK_EXTERN os_log_t ASLockingLog(void); #if AS_HAS_OS_SIGNPOST /// Uses the special POI category for Instruments. Used by ASSignpost.h. -AS_EXTERN os_log_t ASPointsOfInterestLog(void); +ASDK_EXTERN os_log_t ASPointsOfInterestLog(void); #endif /** diff --git a/Source/Details/ASAbstractLayoutController.h b/Source/Details/ASAbstractLayoutController.h index 6de7801fb..4cc7b3ae4 100644 --- a/Source/Details/ASAbstractLayoutController.h +++ b/Source/Details/ASAbstractLayoutController.h @@ -12,11 +12,11 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDirection scrollDirection, ASRangeTuningParameters rangeTuningParameters); +ASDK_EXTERN ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDirection scrollDirection, ASRangeTuningParameters rangeTuningParameters); -AS_EXTERN ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferVertical(ASScrollDirection scrollDirection, ASRangeTuningParameters rangeTuningParameters); +ASDK_EXTERN ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferVertical(ASScrollDirection scrollDirection, ASRangeTuningParameters rangeTuningParameters); -AS_EXTERN CGRect CGRectExpandToRangeWithScrollableDirections(CGRect rect, ASRangeTuningParameters tuningParameters, ASScrollDirection scrollableDirections, ASScrollDirection scrollDirection); +ASDK_EXTERN CGRect CGRectExpandToRangeWithScrollableDirections(CGRect rect, ASRangeTuningParameters tuningParameters, ASScrollDirection scrollableDirections, ASScrollDirection scrollDirection); @interface ASAbstractLayoutController : NSObject diff --git a/Source/Details/ASCollectionViewLayoutInspector.h b/Source/Details/ASCollectionViewLayoutInspector.h index a1ddb3474..4e58890f2 100644 --- a/Source/Details/ASCollectionViewLayoutInspector.h +++ b/Source/Details/ASCollectionViewLayoutInspector.h @@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView); +ASDK_EXTERN ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView); @protocol ASCollectionViewLayoutInspecting diff --git a/Source/Details/ASDataController.h b/Source/Details/ASDataController.h index 099137ad7..88150cba0 100644 --- a/Source/Details/ASDataController.h +++ b/Source/Details/ASDataController.h @@ -32,8 +32,8 @@ NS_ASSUME_NONNULL_BEGIN typedef NSUInteger ASDataControllerAnimationOptions; -AS_EXTERN NSString * const ASDataControllerRowNodeKind; -AS_EXTERN NSString * const ASCollectionInvalidUpdateException; +ASDK_EXTERN NSString * const ASDataControllerRowNodeKind; +ASDK_EXTERN NSString * const ASCollectionInvalidUpdateException; /** Data source for data controller diff --git a/Source/Details/ASGraphicsContext.h b/Source/Details/ASGraphicsContext.h index 02c18f1a5..5bd153764 100644 --- a/Source/Details/ASGraphicsContext.h +++ b/Source/Details/ASGraphicsContext.h @@ -28,7 +28,7 @@ NS_ASSUME_NONNULL_BEGIN * * @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext. */ -AS_EXTERN UIImage *ASGraphicsCreateImageWithOptions(CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t NS_NOESCAPE _Nullable isCancelled, void (NS_NOESCAPE ^work)(void)) ASDISPLAYNODE_DEPRECATED_MSG("Use ASGraphicsCreateImageWithTraitCollectionAndOptions instead"); +ASDK_EXTERN UIImage *ASGraphicsCreateImageWithOptions(CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t NS_NOESCAPE _Nullable isCancelled, void (NS_NOESCAPE ^work)(void)) ASDISPLAYNODE_DEPRECATED_MSG("Use ASGraphicsCreateImageWithTraitCollectionAndOptions instead"); /** * A wrapper for the UIKit drawing APIs. If you are in ASExperimentalDrawingGlobal, and you have iOS >= 10, we will create @@ -45,7 +45,7 @@ AS_EXTERN UIImage *ASGraphicsCreateImageWithOptions(CGSize size, BOOL opaque, CG * * @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext. */ -AS_EXTERN UIImage *ASGraphicsCreateImage(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t _Nullable NS_NOESCAPE isCancelled, void (NS_NOESCAPE ^work)(void)); +ASDK_EXTERN UIImage *ASGraphicsCreateImage(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t _Nullable NS_NOESCAPE isCancelled, void (NS_NOESCAPE ^work)(void)); /** * A wrapper for the UIKit drawing APIs. @@ -60,6 +60,6 @@ AS_EXTERN UIImage *ASGraphicsCreateImage(ASPrimitiveTraitCollection traitCollect * * @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext. */ -AS_EXTERN UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, void (NS_NOESCAPE ^work)(void)) ASDISPLAYNODE_DEPRECATED_MSG("Use ASGraphicsCreateImage instead"); +ASDK_EXTERN UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, void (NS_NOESCAPE ^work)(void)) ASDISPLAYNODE_DEPRECATED_MSG("Use ASGraphicsCreateImage instead"); NS_ASSUME_NONNULL_END diff --git a/Source/Details/ASHashing.h b/Source/Details/ASHashing.h index 084d74078..42a4a98be 100644 --- a/Source/Details/ASHashing.h +++ b/Source/Details/ASHashing.h @@ -35,6 +35,6 @@ NS_ASSUME_NONNULL_BEGIN * use `pragma clang diagnostic warning "-Wpadded"` around your struct definition * or manually initialize the fields of your struct (`myStruct.x = 7;` etc). */ -AS_EXTERN NSUInteger ASHashBytes(void *bytes, size_t length); +ASDK_EXTERN NSUInteger ASHashBytes(void *bytes, size_t length); NS_ASSUME_NONNULL_END diff --git a/Source/Details/ASLayoutRangeType.h b/Source/Details/ASLayoutRangeType.h index 7361b2063..1a60e29d8 100644 --- a/Source/Details/ASLayoutRangeType.h +++ b/Source/Details/ASLayoutRangeType.h @@ -15,9 +15,9 @@ typedef struct { CGFloat trailingBufferScreenfuls; } ASRangeTuningParameters; -AS_EXTERN ASRangeTuningParameters const ASRangeTuningParametersZero; +ASDK_EXTERN ASRangeTuningParameters const ASRangeTuningParametersZero; -AS_EXTERN BOOL ASRangeTuningParametersEqualToRangeTuningParameters(ASRangeTuningParameters lhs, ASRangeTuningParameters rhs); +ASDK_EXTERN BOOL ASRangeTuningParametersEqualToRangeTuningParameters(ASRangeTuningParameters lhs, ASRangeTuningParameters rhs); /** * Each mode has a complete set of tuning parameters for range types. diff --git a/Source/Details/ASObjectDescriptionHelpers.h b/Source/Details/ASObjectDescriptionHelpers.h index 5a2823bd9..beaf889a2 100644 --- a/Source/Details/ASObjectDescriptionHelpers.h +++ b/Source/Details/ASObjectDescriptionHelpers.h @@ -44,13 +44,13 @@ NS_ASSUME_NONNULL_BEGIN - (NSMutableArray *)propertiesForDescription; @end -AS_EXTERN NSString *ASGetDescriptionValueString(id object); +ASDK_EXTERN NSString *ASGetDescriptionValueString(id object); /// Useful for structs etc. Returns e.g. { position = (0 0); frame = (0 0; 50 50) } -AS_EXTERN NSString *ASObjectDescriptionMakeWithoutObject(NSArray * _Nullable propertyGroups); +ASDK_EXTERN NSString *ASObjectDescriptionMakeWithoutObject(NSArray * _Nullable propertyGroups); /// Returns e.g. -AS_EXTERN NSString *ASObjectDescriptionMake(__autoreleasing id object, NSArray * _Nullable propertyGroups); +ASDK_EXTERN NSString *ASObjectDescriptionMake(__autoreleasing id object, NSArray * _Nullable propertyGroups); /** * Returns e.g. @@ -58,8 +58,8 @@ AS_EXTERN NSString *ASObjectDescriptionMake(__autoreleasing id object, NSArray element, ASPrimitiveTraitCollection traitCollection); +ASDK_EXTERN void ASTraitCollectionPropagateDown(id element, ASPrimitiveTraitCollection traitCollection); /** * Abstraction on top of UITraitCollection for propagation within AsyncDisplayKit-Layout @@ -105,7 +105,7 @@ AS_EXTERN void ASTraitCollectionPropagateDown(id element, ASPri * @abstract Sets a trait collection on this environment state. * * @discussion This only exists as an internal convenience method. Users should not override trait collection using it. - * Use [ASViewController overrideDisplayTraitsWithTraitCollection] block instead. + * Use [ASDKViewController overrideDisplayTraitsWithTraitCollection] block instead. */ - (void)setPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traitCollection; diff --git a/Source/Details/ASTraitCollection.mm b/Source/Details/ASTraitCollection.mm index 8a697eccd..f26a2beae 100644 --- a/Source/Details/ASTraitCollection.mm +++ b/Source/Details/ASTraitCollection.mm @@ -86,7 +86,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra return environmentTraitCollection; } -AS_EXTERN UITraitCollection * ASPrimitiveTraitCollectionToUITraitCollection(ASPrimitiveTraitCollection traitCollection) { +ASDK_EXTERN UITraitCollection * ASPrimitiveTraitCollectionToUITraitCollection(ASPrimitiveTraitCollection traitCollection) { NSMutableArray *collections = [[NSMutableArray alloc] initWithArray:@[ [UITraitCollection traitCollectionWithHorizontalSizeClass:traitCollection.horizontalSizeClass], [UITraitCollection traitCollectionWithVerticalSizeClass:traitCollection.verticalSizeClass], diff --git a/Source/Details/Transactions/_ASAsyncTransaction.h b/Source/Details/Transactions/_ASAsyncTransaction.h index 245c62b29..e3d0f211b 100644 --- a/Source/Details/Transactions/_ASAsyncTransaction.h +++ b/Source/Details/Transactions/_ASAsyncTransaction.h @@ -32,7 +32,7 @@ typedef NS_ENUM(NSUInteger, ASAsyncTransactionState) { ASAsyncTransactionStateComplete }; -AS_EXTERN NSInteger const ASDefaultTransactionPriority; +ASDK_EXTERN NSInteger const ASDefaultTransactionPriority; /** @summary ASAsyncTransaction provides lightweight transaction semantics for asynchronous operations. diff --git a/Source/Details/Transactions/_ASAsyncTransaction.mm b/Source/Details/Transactions/_ASAsyncTransaction.mm index c23cad341..35d9a43c5 100644 --- a/Source/Details/Transactions/_ASAsyncTransaction.mm +++ b/Source/Details/Transactions/_ASAsyncTransaction.mm @@ -19,7 +19,7 @@ #warning "Texture must be compiled with std=c++11 to prevent layout issues. gnu++ is not supported. This is hopefully temporary." #endif -AS_EXTERN NSRunLoopMode const UITrackingRunLoopMode; +ASDK_EXTERN NSRunLoopMode const UITrackingRunLoopMode; NSInteger const ASDefaultTransactionPriority = 0; diff --git a/Source/Details/_ASDisplayView.mm b/Source/Details/_ASDisplayView.mm index 12863e053..7741e4447 100644 --- a/Source/Details/_ASDisplayView.mm +++ b/Source/Details/_ASDisplayView.mm @@ -15,7 +15,7 @@ #import #import #import -#import +#import #pragma mark - _ASDisplayView @@ -176,7 +176,7 @@ - (void)didMoveToSuperview if (superview && node.viewControllerRoot) { UIViewController *vc = [node closestViewController]; - ASDisplayNodeAssert(vc != nil && [vc isKindOfClass:[ASViewController class]] && ((ASViewController*)vc).node == node, @"This node was once used as a view controller's node. You should not reuse it without its view controller."); + ASDisplayNodeAssert(vc != nil && [vc isKindOfClass:[ASDKViewController class]] && ((ASDKViewController*)vc).node == node, @"This node was once used as a view controller's node. You should not reuse it without its view controller."); } #endif diff --git a/Source/Layout/ASDimension.h b/Source/Layout/ASDimension.h index 0b3c6b7be..ab0717bad 100644 --- a/Source/Layout/ASDimension.h +++ b/Source/Layout/ASDimension.h @@ -83,7 +83,7 @@ typedef struct { /** * Represents auto as ASDimension */ -AS_EXTERN ASDimension const ASDimensionAuto; +ASDK_EXTERN ASDimension const ASDimensionAuto; /** * Returns a dimension with the specified type and value. @@ -116,7 +116,7 @@ ASOVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASDimension ASDimensio * Examples: ASDimensionMake(@"50%") = ASDimensionMake(ASDimensionUnitFraction, 0.5) * ASDimensionMake(@"0.5pt") = ASDimensionMake(ASDimensionUnitPoints, 0.5) */ -ASOVERLOADABLE AS_WARN_UNUSED_RESULT AS_EXTERN ASDimension ASDimensionMake(NSString *dimension); +ASOVERLOADABLE AS_WARN_UNUSED_RESULT ASDK_EXTERN ASDimension ASDimensionMake(NSString *dimension); /** * Returns a dimension with the specified points value. @@ -147,7 +147,7 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASDimensionEqualToDimension(ASDi /** * Returns a NSString representation of a dimension. */ -AS_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASDimension(ASDimension dimension); +ASDK_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASDimension(ASDimension dimension); /** * Resolve this dimension to a parent size. @@ -174,7 +174,7 @@ typedef struct { ASDimension height; } ASLayoutSize; -AS_EXTERN ASLayoutSize const ASLayoutSizeAuto; +ASDK_EXTERN ASLayoutSize const ASLayoutSizeAuto; /* * Creates an ASLayoutSize with provided min and max dimensions. @@ -219,12 +219,12 @@ typedef struct { /** * A size range with all dimensions zero. */ -AS_EXTERN ASSizeRange const ASSizeRangeZero; +ASDK_EXTERN ASSizeRange const ASSizeRangeZero; /** * A size range from zero to infinity in both directions. */ -AS_EXTERN ASSizeRange const ASSizeRangeUnconstrained; +ASDK_EXTERN ASSizeRange const ASSizeRangeUnconstrained; /** * Returns whether a size range has > 0.1 max width and max height. @@ -275,7 +275,7 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT CGSize ASSizeRangeClamp(ASSizeRange s * Intersects another size range. If the other size range does not overlap in either dimension, this size range * "wins" by returning a single point within its own range that is closest to the non-overlapping range. */ -AS_EXTERN AS_WARN_UNUSED_RESULT ASSizeRange ASSizeRangeIntersect(ASSizeRange sizeRange, ASSizeRange otherSizeRange); +ASDK_EXTERN AS_WARN_UNUSED_RESULT ASSizeRange ASSizeRangeIntersect(ASSizeRange sizeRange, ASSizeRange otherSizeRange); /** * Returns whether two size ranges are equal in min and max size. @@ -288,7 +288,7 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASSizeRangeEqualToSizeRange(ASSi /** * Returns a string representation of a size range */ -AS_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASSizeRange(ASSizeRange sizeRange); +ASDK_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASSizeRange(ASSizeRange sizeRange); #if YOGA @@ -306,9 +306,9 @@ typedef struct { ASDimension all; } ASEdgeInsets; -AS_EXTERN ASEdgeInsets const ASEdgeInsetsZero; +ASDK_EXTERN ASEdgeInsets const ASEdgeInsetsZero; -AS_EXTERN ASEdgeInsets ASEdgeInsetsMake(UIEdgeInsets edgeInsets); +ASDK_EXTERN ASEdgeInsets ASEdgeInsetsMake(UIEdgeInsets edgeInsets); #endif diff --git a/Source/Layout/ASDimensionInternal.h b/Source/Layout/ASDimensionInternal.h index df8f05600..dced2ffae 100644 --- a/Source/Layout/ASDimensionInternal.h +++ b/Source/Layout/ASDimensionInternal.h @@ -77,7 +77,7 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASLayoutElementSizeEqualToLayout /** * Returns a string formatted to contain the data from an ASLayoutElementSize. */ -AS_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASLayoutElementSize(ASLayoutElementSize size); +ASDK_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASLayoutElementSize(ASLayoutElementSize size); /** * Resolve the given size relative to a parent size and an auto size. @@ -86,7 +86,7 @@ AS_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASLayoutElementSize(ASLayo * dimension with unit ASDimensionUnitAuto the given autoASSizeRange value will be used. * Based on the calculated exact, min and max size constraints the final size range will be calculated. */ -AS_EXTERN AS_WARN_UNUSED_RESULT ASSizeRange ASLayoutElementSizeResolveAutoSize(ASLayoutElementSize size, const CGSize parentSize, ASSizeRange autoASSizeRange); +ASDK_EXTERN AS_WARN_UNUSED_RESULT ASSizeRange ASLayoutElementSizeResolveAutoSize(ASLayoutElementSize size, const CGSize parentSize, ASSizeRange autoASSizeRange); /** * Resolve the given size to a parent size. Uses internally ASLayoutElementSizeResolveAutoSize with {INFINITY, INFINITY} as diff --git a/Source/Layout/ASLayout.h b/Source/Layout/ASLayout.h index 0e40574d0..44b7de087 100644 --- a/Source/Layout/ASLayout.h +++ b/Source/Layout/ASLayout.h @@ -14,18 +14,18 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN CGPoint const ASPointNull; // {NAN, NAN} +ASDK_EXTERN CGPoint const ASPointNull; // {NAN, NAN} -AS_EXTERN BOOL ASPointIsNull(CGPoint point); +ASDK_EXTERN BOOL ASPointIsNull(CGPoint point); -AS_EXTERN NSString *const ASThreadDictMaxConstraintSizeKey; +ASDK_EXTERN NSString *const ASThreadDictMaxConstraintSizeKey; /** * Safely calculates the layout of the given root layoutElement by guarding against nil nodes. * @param rootLayoutElement The root node to calculate the layout for. * @param sizeRange The size range to calculate the root layout within. */ -AS_EXTERN ASLayout *ASCalculateRootLayout(id rootLayoutElement, const ASSizeRange sizeRange); +ASDK_EXTERN ASLayout *ASCalculateRootLayout(id rootLayoutElement, const ASSizeRange sizeRange); /** * Safely computes the layout of the given node by guarding against nil nodes. @@ -33,7 +33,7 @@ AS_EXTERN ASLayout *ASCalculateRootLayout(id rootLayoutElement, * @param sizeRange The size range to calculate the node layout within. * @param parentSize The parent size of the node to calculate the layout for. */ -AS_EXTERN ASLayout *ASCalculateLayout(idlayoutElement, const ASSizeRange sizeRange, const CGSize parentSize); +ASDK_EXTERN ASLayout *ASCalculateLayout(idlayoutElement, const ASSizeRange sizeRange, const CGSize parentSize); /** * A node in the layout tree that represents the size and position of the object that created it (ASLayoutElement). diff --git a/Source/Layout/ASLayoutElement.h b/Source/Layout/ASLayoutElement.h index df8deecee..000f96551 100644 --- a/Source/Layout/ASLayoutElement.h +++ b/Source/Layout/ASLayoutElement.h @@ -25,10 +25,10 @@ NS_ASSUME_NONNULL_BEGIN /** A constant that indicates that the parent's size is not yet determined in a given dimension. */ -AS_EXTERN CGFloat const ASLayoutElementParentDimensionUndefined; +ASDK_EXTERN CGFloat const ASLayoutElementParentDimensionUndefined; /** A constant that indicates that the parent's size is not yet determined in either dimension. */ -AS_EXTERN CGSize const ASLayoutElementParentSizeUndefined; +ASDK_EXTERN CGSize const ASLayoutElementParentSizeUndefined; /** Type of ASLayoutElement */ typedef NS_ENUM(unsigned char, ASLayoutElementType) { @@ -144,24 +144,24 @@ typedef NS_ENUM(unsigned char, ASLayoutElementType) { #pragma mark - ASLayoutElementStyle -AS_EXTERN NSString * const ASLayoutElementStyleWidthProperty; -AS_EXTERN NSString * const ASLayoutElementStyleMinWidthProperty; -AS_EXTERN NSString * const ASLayoutElementStyleMaxWidthProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleWidthProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleMinWidthProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleMaxWidthProperty; -AS_EXTERN NSString * const ASLayoutElementStyleHeightProperty; -AS_EXTERN NSString * const ASLayoutElementStyleMinHeightProperty; -AS_EXTERN NSString * const ASLayoutElementStyleMaxHeightProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleHeightProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleMinHeightProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleMaxHeightProperty; -AS_EXTERN NSString * const ASLayoutElementStyleSpacingBeforeProperty; -AS_EXTERN NSString * const ASLayoutElementStyleSpacingAfterProperty; -AS_EXTERN NSString * const ASLayoutElementStyleFlexGrowProperty; -AS_EXTERN NSString * const ASLayoutElementStyleFlexShrinkProperty; -AS_EXTERN NSString * const ASLayoutElementStyleFlexBasisProperty; -AS_EXTERN NSString * const ASLayoutElementStyleAlignSelfProperty; -AS_EXTERN NSString * const ASLayoutElementStyleAscenderProperty; -AS_EXTERN NSString * const ASLayoutElementStyleDescenderProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleSpacingBeforeProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleSpacingAfterProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleFlexGrowProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleFlexShrinkProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleFlexBasisProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleAlignSelfProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleAscenderProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleDescenderProperty; -AS_EXTERN NSString * const ASLayoutElementStyleLayoutPositionProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleLayoutPositionProperty; @protocol ASLayoutElementStyleDelegate - (void)style:(__kindof ASLayoutElementStyle *)style propertyDidChange:(NSString *)propertyName; diff --git a/Source/Layout/ASLayoutElementPrivate.h b/Source/Layout/ASLayoutElementPrivate.h index cf699f42a..bf8c05bfa 100644 --- a/Source/Layout/ASLayoutElementPrivate.h +++ b/Source/Layout/ASLayoutElementPrivate.h @@ -22,16 +22,16 @@ AS_SUBCLASSING_RESTRICTED @property (nonatomic) int32_t transitionID; @end -AS_EXTERN int32_t const ASLayoutElementContextInvalidTransitionID; +ASDK_EXTERN int32_t const ASLayoutElementContextInvalidTransitionID; -AS_EXTERN int32_t const ASLayoutElementContextDefaultTransitionID; +ASDK_EXTERN int32_t const ASLayoutElementContextDefaultTransitionID; // Does not currently support nesting – there must be no current context. -AS_EXTERN void ASLayoutElementPushContext(ASLayoutElementContext * context); +ASDK_EXTERN void ASLayoutElementPushContext(ASLayoutElementContext * context); -AS_EXTERN ASLayoutElementContext * _Nullable ASLayoutElementGetCurrentContext(void); +ASDK_EXTERN ASLayoutElementContext * _Nullable ASLayoutElementGetCurrentContext(void); -AS_EXTERN void ASLayoutElementPopContext(void); +ASDK_EXTERN void ASLayoutElementPopContext(void); NS_ASSUME_NONNULL_END diff --git a/Source/Layout/ASYogaUtilities.h b/Source/Layout/ASYogaUtilities.h index c3d1d8233..d5529fc45 100644 --- a/Source/Layout/ASYogaUtilities.h +++ b/Source/Layout/ASYogaUtilities.h @@ -27,22 +27,22 @@ @end // pre-order, depth-first -AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode *node, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode *node, void(^block)(ASDisplayNode *node)); #pragma mark - Yoga Type Conversion Helpers -AS_EXTERN YGAlign yogaAlignItems(ASStackLayoutAlignItems alignItems); -AS_EXTERN YGJustify yogaJustifyContent(ASStackLayoutJustifyContent justifyContent); -AS_EXTERN YGAlign yogaAlignSelf(ASStackLayoutAlignSelf alignSelf); -AS_EXTERN YGFlexDirection yogaFlexDirection(ASStackLayoutDirection direction); -AS_EXTERN float yogaFloatForCGFloat(CGFloat value); -AS_EXTERN float yogaDimensionToPoints(ASDimension dimension); -AS_EXTERN float yogaDimensionToPercent(ASDimension dimension); -AS_EXTERN ASDimension dimensionForEdgeWithEdgeInsets(YGEdge edge, ASEdgeInsets insets); - -AS_EXTERN void ASLayoutElementYogaUpdateMeasureFunc(YGNodeRef yogaNode, id layoutElement); -AS_EXTERN float ASLayoutElementYogaBaselineFunc(YGNodeRef yogaNode, const float width, const float height); -AS_EXTERN YGSize ASLayoutElementYogaMeasureFunc(YGNodeRef yogaNode, +ASDK_EXTERN YGAlign yogaAlignItems(ASStackLayoutAlignItems alignItems); +ASDK_EXTERN YGJustify yogaJustifyContent(ASStackLayoutJustifyContent justifyContent); +ASDK_EXTERN YGAlign yogaAlignSelf(ASStackLayoutAlignSelf alignSelf); +ASDK_EXTERN YGFlexDirection yogaFlexDirection(ASStackLayoutDirection direction); +ASDK_EXTERN float yogaFloatForCGFloat(CGFloat value); +ASDK_EXTERN float yogaDimensionToPoints(ASDimension dimension); +ASDK_EXTERN float yogaDimensionToPercent(ASDimension dimension); +ASDK_EXTERN ASDimension dimensionForEdgeWithEdgeInsets(YGEdge edge, ASEdgeInsets insets); + +ASDK_EXTERN void ASLayoutElementYogaUpdateMeasureFunc(YGNodeRef yogaNode, id layoutElement); +ASDK_EXTERN float ASLayoutElementYogaBaselineFunc(YGNodeRef yogaNode, const float width, const float height); +ASDK_EXTERN YGSize ASLayoutElementYogaMeasureFunc(YGNodeRef yogaNode, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode); diff --git a/Source/Private/ASBatchFetching.h b/Source/Private/ASBatchFetching.h index 15d5a98c3..fec0c6764 100644 --- a/Source/Private/ASBatchFetching.h +++ b/Source/Private/ASBatchFetching.h @@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN @param velocity The velocity of the scroll view (in points) at the moment the touch was released. @return Whether or not the current state should proceed with batch fetching. */ -AS_EXTERN BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView *scrollView, +ASDK_EXTERN BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView *scrollView, ASScrollDirection scrollDirection, ASScrollDirection scrollableDirections, CGPoint contentOffset, @@ -59,7 +59,7 @@ AS_EXTERN BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView +#import #import #if AS_ENABLE_TIPS diff --git a/Source/Private/ASTwoDimensionalArrayUtils.h b/Source/Private/ASTwoDimensionalArrayUtils.h index 6a3c9bb5c..8bddf29e5 100644 --- a/Source/Private/ASTwoDimensionalArrayUtils.h +++ b/Source/Private/ASTwoDimensionalArrayUtils.h @@ -21,26 +21,26 @@ NS_ASSUME_NONNULL_BEGIN * Deep mutable copy of an array that contains arrays, which contain objects. It will go one level deep into the array to copy. * This method is substantially faster than the generalized version, e.g. about 10x faster, so use it whenever it fits the need. */ -AS_EXTERN NSMutableArray *ASTwoDimensionalArrayDeepMutableCopy(NSArray *array) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSMutableArray *ASTwoDimensionalArrayDeepMutableCopy(NSArray *array) AS_WARN_UNUSED_RESULT; /** * Delete the elements of the mutable two-dimensional array at given index paths – sorted in descending order! */ -AS_EXTERN void ASDeleteElementsInTwoDimensionalArrayAtIndexPaths(NSMutableArray *mutableArray, NSArray *indexPaths); +ASDK_EXTERN void ASDeleteElementsInTwoDimensionalArrayAtIndexPaths(NSMutableArray *mutableArray, NSArray *indexPaths); /** * Return all the index paths of a two-dimensional array, in ascending order. */ -AS_EXTERN NSArray *ASIndexPathsForTwoDimensionalArray(NSArray* twoDimensionalArray) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray *ASIndexPathsForTwoDimensionalArray(NSArray* twoDimensionalArray) AS_WARN_UNUSED_RESULT; /** * Return all the elements of a two-dimensional array, in ascending order. */ -AS_EXTERN NSArray *ASElementsInTwoDimensionalArray(NSArray* twoDimensionalArray) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray *ASElementsInTwoDimensionalArray(NSArray* twoDimensionalArray) AS_WARN_UNUSED_RESULT; /** * Attempt to get the object at the given index path. Returns @c nil if the index path is out of bounds. */ -AS_EXTERN id _Nullable ASGetElementInTwoDimensionalArray(NSArray *array, NSIndexPath *indexPath) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN id _Nullable ASGetElementInTwoDimensionalArray(NSArray *array, NSIndexPath *indexPath) AS_WARN_UNUSED_RESULT; NS_ASSUME_NONNULL_END diff --git a/Source/Private/Layout/ASStackUnpositionedLayout.h b/Source/Private/Layout/ASStackUnpositionedLayout.h index 989b4c2f1..68f9421d5 100644 --- a/Source/Private/Layout/ASStackUnpositionedLayout.h +++ b/Source/Private/Layout/ASStackUnpositionedLayout.h @@ -14,7 +14,7 @@ #import /** The threshold that determines if a violation has actually occurred. */ -AS_EXTERN CGFloat const kViolationEpsilon; +ASDK_EXTERN CGFloat const kViolationEpsilon; struct ASStackLayoutSpecChild { /** The original source child. */ diff --git a/Source/Private/TextExperiment/Component/ASTextLayout.h b/Source/Private/TextExperiment/Component/ASTextLayout.h index 46bc8ccf5..55ac417f1 100644 --- a/Source/Private/TextExperiment/Component/ASTextLayout.h +++ b/Source/Private/TextExperiment/Component/ASTextLayout.h @@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN /** The max text container size in layout. */ -AS_EXTERN const CGSize ASTextContainerMaxSize; +ASDK_EXTERN const CGSize ASTextContainerMaxSize; /** The ASTextContainer class defines a region in which text is laid out. diff --git a/Source/Private/TextExperiment/String/ASTextAttribute.h b/Source/Private/TextExperiment/String/ASTextAttribute.h index 2d9e3771a..571334ed3 100644 --- a/Source/Private/TextExperiment/String/ASTextAttribute.h +++ b/Source/Private/TextExperiment/String/ASTextAttribute.h @@ -23,7 +23,7 @@ typedef NS_OPTIONS(NSInteger, ASTextAttributeType) { }; /// Get the attribute type from an attribute name. -AS_EXTERN ASTextAttributeType ASTextAttributeGetType(NSString *attributeName); +ASDK_EXTERN ASTextAttributeType ASTextAttributeGetType(NSString *attributeName); /** Line style in ASText (similar to NSUnderlineStyle). diff --git a/Source/Private/_ASCoreAnimationExtras.h b/Source/Private/_ASCoreAnimationExtras.h index 5937f3012..182bc3532 100644 --- a/Source/Private/_ASCoreAnimationExtras.h +++ b/Source/Private/_ASCoreAnimationExtras.h @@ -34,21 +34,21 @@ @param obj ASDisplayNode, CALayer or object that conforms to `ASResizableContents` protocol @param image Image you would like to resize */ -AS_EXTERN void ASDisplayNodeSetResizableContents(id obj, UIImage *image); +ASDK_EXTERN void ASDisplayNodeSetResizableContents(id obj, UIImage *image); /** Turns a value of UIViewContentMode to a string for debugging or serialization @param contentMode Any of the UIViewContentMode constants @return A human-readable representation of the constant, or the integer value of the constant if not recognized. */ -AS_EXTERN NSString *ASDisplayNodeNSStringFromUIContentMode(UIViewContentMode contentMode); +ASDK_EXTERN NSString *ASDisplayNodeNSStringFromUIContentMode(UIViewContentMode contentMode); /** Turns a string representing a contentMode into a contentMode @param string Any of the strings in UIContentModeDescriptionLUT @return Any of the UIViewContentMode constants, or an int if the string is a number. If the string is not recognized, UIViewContentModeScaleToFill is returned. */ -AS_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *string); +ASDK_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *string); /** Maps a value of UIViewContentMode to a corresponding contentsGravity @@ -56,7 +56,7 @@ AS_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *str @param contentMode A content mode except for UIViewContentModeRedraw, which has no corresponding contentsGravity (it corresponds to needsDisplayOnBoundsChange = YES) @return An NSString constant from the documentation, eg kCAGravityCenter... or nil if there is no corresponding contentsGravity. Will assert if contentMode is unknown. */ -AS_EXTERN NSString *const ASDisplayNodeCAContentsGravityFromUIContentMode(UIViewContentMode contentMode); +ASDK_EXTERN NSString *const ASDisplayNodeCAContentsGravityFromUIContentMode(UIViewContentMode contentMode); /** Maps a value of contentsGravity to a corresponding UIViewContentMode @@ -64,21 +64,21 @@ AS_EXTERN NSString *const ASDisplayNodeCAContentsGravityFromUIContentMode(UIView @param contentsGravity A contents gravity @return A UIViewContentMode constant from UIView.h, eg UIViewContentModeCenter..., or UIViewContentModeScaleToFill if contentsGravity is not one of the CA constants. Will assert if the contentsGravity is unknown. */ -AS_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromCAContentsGravity(NSString *const contentsGravity); +ASDK_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromCAContentsGravity(NSString *const contentsGravity); /** Use this to create a stretchable appropriate to approximate a filled rectangle, but with antialiasing on the edges when not pixel-aligned. It's best to keep the layer this image is added to with contentsScale equal to the scale of the final transform to screen space so it is able to antialias appropriately even when you shrink or grow the layer. @param color the fill color to use in the center of the image @param innerSize Unfortunately, 4 seems to be the smallest inner size that works if you're applying this stretchable to a larger box, whereas it does not display correctly for larger boxes. Thus some adjustment is necessary for the size of box you're displaying. If you're showing a 1px horizontal line, pass 1 height and at least 4 width. 2px vertical line: 2px wide, 4px high. Passing an innerSize greater that you desire is wasteful */ -AS_EXTERN UIImage *ASDisplayNodeStretchableBoxContentsWithColor(UIColor *color, CGSize innerSize); +ASDK_EXTERN UIImage *ASDisplayNodeStretchableBoxContentsWithColor(UIColor *color, CGSize innerSize); /** Checks whether a layer has ongoing animations @param layer A layer to check if animations are ongoing @return YES if the layer has ongoing animations, otherwise NO */ -AS_EXTERN BOOL ASDisplayNodeLayerHasAnimations(CALayer *layer); +ASDK_EXTERN BOOL ASDisplayNodeLayerHasAnimations(CALayer *layer); // This function is a less generalized version of ASDisplayNodeSetResizableContents. -AS_EXTERN void ASDisplayNodeSetupLayerContentsWithResizableImage(CALayer *layer, UIImage *image) ASDISPLAYNODE_DEPRECATED; +ASDK_EXTERN void ASDisplayNodeSetupLayerContentsWithResizableImage(CALayer *layer, UIImage *image) ASDISPLAYNODE_DEPRECATED; diff --git a/Source/TextKit/ASTextKitAttributes.h b/Source/TextKit/ASTextKitAttributes.h index bf9017a59..cf09ad668 100644 --- a/Source/TextKit/ASTextKitAttributes.h +++ b/Source/TextKit/ASTextKitAttributes.h @@ -17,12 +17,12 @@ #import -AS_EXTERN NSString *const ASTextKitTruncationAttributeName; +ASDK_EXTERN NSString *const ASTextKitTruncationAttributeName; /** Use ASTextKitEntityAttribute as the value of this attribute to embed a link or other interactable content inside the text. */ -AS_EXTERN NSString *const ASTextKitEntityAttributeName; +ASDK_EXTERN NSString *const ASTextKitEntityAttributeName; /** All NSObject values in this struct should be copied when passed into the TextComponent. diff --git a/Source/TextKit/ASTextKitCoreTextAdditions.h b/Source/TextKit/ASTextKitCoreTextAdditions.h index 9a8f48050..0da484d08 100644 --- a/Source/TextKit/ASTextKitCoreTextAdditions.h +++ b/Source/TextKit/ASTextKitCoreTextAdditions.h @@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN - kCTUnderlineColorAttributeName @result Whether attributeName is an unsupported Core Text attribute. */ -AS_EXTERN BOOL ASAttributeWithNameIsUnsupportedCoreTextAttribute(NSString *attributeName); +ASDK_EXTERN BOOL ASAttributeWithNameIsUnsupportedCoreTextAttribute(NSString *attributeName); /** @@ -54,14 +54,14 @@ AS_EXTERN BOOL ASAttributeWithNameIsUnsupportedCoreTextAttribute(NSString *attri - kCTUnderlineColorAttributeName @result An NSDictionary of attributes for use by NSAttributedString. */ -AS_EXTERN NSDictionary *NSAttributedStringAttributesForCoreTextAttributes(NSDictionary *coreTextAttributes); +ASDK_EXTERN NSDictionary *NSAttributedStringAttributesForCoreTextAttributes(NSDictionary *coreTextAttributes); /** @abstract Returns an NSAttributedString whose Core Text attributes have been converted, where possible, to NSAttributedString attributes. @param dirtyAttributedString An NSAttributedString that may contain Core Text attributes. @result An NSAttributedString that's preserved as many CFAttributedString attributes as possible. */ -AS_EXTERN NSAttributedString *ASCleanseAttributedStringOfCoreTextAttributes(NSAttributedString *dirtyAttributedString); +ASDK_EXTERN NSAttributedString *ASCleanseAttributedStringOfCoreTextAttributes(NSAttributedString *dirtyAttributedString); #pragma mark - #pragma mark - diff --git a/Tests/ASViewControllerTests.mm b/Tests/ASDKViewControllerTests.mm similarity index 93% rename from Tests/ASViewControllerTests.mm rename to Tests/ASDKViewControllerTests.mm index 929ee67b3..1f7af48c1 100644 --- a/Tests/ASViewControllerTests.mm +++ b/Tests/ASDKViewControllerTests.mm @@ -1,5 +1,5 @@ // -// ASViewControllerTests.mm +// ASDKViewControllerTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -15,11 +15,11 @@ #import "NSInvocation+ASTestHelpers.h" -@interface ASViewControllerTests : XCTestCase +@interface ASDKViewControllerTests : XCTestCase @end -@implementation ASViewControllerTests +@implementation ASDKViewControllerTests - (void)testThatAutomaticSubnodeManagementScrollViewInsetsAreApplied { @@ -32,7 +32,7 @@ - (void)testThatAutomaticSubnodeManagementScrollViewInsetsAreApplied node.layoutSpecBlock = ^(ASDisplayNode *node, ASSizeRange constrainedSize){ return [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsZero child:scrollNode]; }; - ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + ASDKViewController *vc = [[ASDKViewController alloc] initWithNode:node]; window.rootViewController = [[UINavigationController alloc] initWithRootViewController:vc]; [window makeKeyAndVisible]; [window layoutIfNeeded]; @@ -48,7 +48,7 @@ - (void)testThatViewControllerFrameIsRightAfterCustomTransitionWithNonextendedEd ASDisplayNode *node = [[ASDisplayNode alloc] init]; - ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + ASDKViewController *vc = [[ASDKViewController alloc] initWithNode:node]; vc.node.backgroundColor = [UIColor greenColor]; vc.edgesForExtendedLayout = UIRectEdgeNone; diff --git a/Tests/ASDisplayNodeTests.mm b/Tests/ASDisplayNodeTests.mm index e6ef1be31..edf622c71 100644 --- a/Tests/ASDisplayNodeTests.mm +++ b/Tests/ASDisplayNodeTests.mm @@ -29,7 +29,7 @@ #import #import #import -#import +#import #import "ASXCTExtensions.h" #import "ASDisplayNodeTestsHelper.h" @@ -274,7 +274,7 @@ - (BOOL)canBecomeFirstResponder { } @end -@interface ASTestViewController: ASViewController +@interface ASTestViewController: ASDKViewController @end @implementation ASTestViewController - (BOOL)prefersStatusBarHidden { return YES; } diff --git a/Tests/ASDisplayNodeTestsHelper.h b/Tests/ASDisplayNodeTestsHelper.h index 4e884f442..07c8d617a 100644 --- a/Tests/ASDisplayNodeTestsHelper.h +++ b/Tests/ASDisplayNodeTestsHelper.h @@ -14,8 +14,8 @@ typedef BOOL (^as_condition_block_t)(void); -AS_EXTERN BOOL ASDisplayNodeRunRunLoopUntilBlockIsTrue(as_condition_block_t block); +ASDK_EXTERN BOOL ASDisplayNodeRunRunLoopUntilBlockIsTrue(as_condition_block_t block); -AS_EXTERN void ASDisplayNodeSizeToFitSize(ASDisplayNode *node, CGSize size); -AS_EXTERN void ASDisplayNodeSizeToFitSizeRange(ASDisplayNode *node, ASSizeRange sizeRange); -AS_EXTERN void ASCATransactionQueueWait(ASCATransactionQueue *q); // nil means shared queue +ASDK_EXTERN void ASDisplayNodeSizeToFitSize(ASDisplayNode *node, CGSize size); +ASDK_EXTERN void ASDisplayNodeSizeToFitSizeRange(ASDisplayNode *node, ASSizeRange sizeRange); +ASDK_EXTERN void ASCATransactionQueueWait(ASCATransactionQueue *q); // nil means shared queue diff --git a/Tests/ASDisplayViewAccessibilityTests.mm b/Tests/ASDisplayViewAccessibilityTests.mm index f1a7696cc..2b8a848b1 100644 --- a/Tests/ASDisplayViewAccessibilityTests.mm +++ b/Tests/ASDisplayViewAccessibilityTests.mm @@ -21,7 +21,7 @@ #import #import #import -#import +#import #import #import "ASDisplayNodeTestsHelper.h" @@ -339,7 +339,7 @@ - (void)testAccessibilityElementsNotInAppWindow { ASDisplayNode *node = [[ASDisplayNode alloc] init]; node.automaticallyManagesSubnodes = YES; - ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + ASDKViewController *vc = [[ASDKViewController alloc] initWithNode:node]; window.rootViewController = vc; [window makeKeyAndVisible]; [window layoutIfNeeded]; @@ -389,7 +389,7 @@ - (void)testAccessibilityElementsNotInAppWindowButInScrollView { ASScrollNode *node = [[ASScrollNode alloc] init]; node.automaticallyManagesSubnodes = YES; - ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + ASDKViewController *vc = [[ASDKViewController alloc] initWithNode:node]; window.rootViewController = vc; [window makeKeyAndVisible]; [window layoutIfNeeded]; @@ -494,7 +494,7 @@ - (void)testSubnodeIsModal { ASDisplayNode *node = [[ASDisplayNode alloc] init]; node.automaticallyManagesSubnodes = YES; - ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + ASDKViewController *vc = [[ASDKViewController alloc] initWithNode:node]; window.rootViewController = vc; [window makeKeyAndVisible]; [window layoutIfNeeded]; @@ -535,7 +535,7 @@ - (void)testMultipleSubnodesAreModal { ASDisplayNode *node = [[ASDisplayNode alloc] init]; node.automaticallyManagesSubnodes = YES; - ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + ASDKViewController *vc = [[ASDKViewController alloc] initWithNode:node]; window.rootViewController = vc; [window makeKeyAndVisible]; [window layoutIfNeeded]; @@ -597,7 +597,7 @@ - (void)testAccessibilityElementsHidden { ASDisplayNode *node = [[ASDisplayNode alloc] init]; node.automaticallyManagesSubnodes = YES; - ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + ASDKViewController *vc = [[ASDKViewController alloc] initWithNode:node]; window.rootViewController = vc; [window makeKeyAndVisible]; [window layoutIfNeeded]; diff --git a/Tests/ASNavigationControllerTests.mm b/Tests/ASNavigationControllerTests.mm index d9ed2464c..379905a4b 100644 --- a/Tests/ASNavigationControllerTests.mm +++ b/Tests/ASNavigationControllerTests.mm @@ -16,8 +16,8 @@ @interface ASNavigationControllerTests : XCTestCase @implementation ASNavigationControllerTests - (void)testSetViewControllers { - ASViewController *firstController = [ASViewController new]; - ASViewController *secondController = [ASViewController new]; + ASDKViewController *firstController = [ASDKViewController new]; + ASDKViewController *secondController = [ASDKViewController new]; NSArray *expectedViewControllerStack = @[firstController, secondController]; ASNavigationController *navigationController = [ASNavigationController new]; [navigationController setViewControllers:@[firstController, secondController]]; @@ -27,8 +27,8 @@ - (void)testSetViewControllers { } - (void)testPopViewController { - ASViewController *firstController = [ASViewController new]; - ASViewController *secondController = [ASViewController new]; + ASDKViewController *firstController = [ASDKViewController new]; + ASDKViewController *secondController = [ASDKViewController new]; NSArray *expectedViewControllerStack = @[firstController]; ASNavigationController *navigationController = [ASNavigationController new]; [navigationController setViewControllers:@[firstController, secondController]]; @@ -39,8 +39,8 @@ - (void)testPopViewController { } - (void)testPushViewController { - ASViewController *firstController = [ASViewController new]; - ASViewController *secondController = [ASViewController new]; + ASDKViewController *firstController = [ASDKViewController new]; + ASDKViewController *secondController = [ASDKViewController new]; NSArray *expectedViewControllerStack = @[firstController, secondController]; ASNavigationController *navigationController = [[ASNavigationController new] initWithRootViewController:firstController]; [navigationController pushViewController:secondController animated:false]; diff --git a/Tests/ASPagerNodeTests.mm b/Tests/ASPagerNodeTests.mm index 416efaae3..835de4d4d 100644 --- a/Tests/ASPagerNodeTests.mm +++ b/Tests/ASPagerNodeTests.mm @@ -122,7 +122,7 @@ - (void)DISABLED_testThatRootPagerNodeDoesGetTheRightInsetWhilePoppingBack node.layoutSpecBlock = ^(ASDisplayNode *node, ASSizeRange constrainedSize){ return [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsZero child:pagerNode]; }; - ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + ASDKViewController *vc = [[ASDKViewController alloc] initWithNode:node]; UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; window.rootViewController = nav; [window makeKeyAndVisible]; diff --git a/Tests/ASTabBarControllerTests.mm b/Tests/ASTabBarControllerTests.mm index 764ab9b54..b20c7a984 100644 --- a/Tests/ASTabBarControllerTests.mm +++ b/Tests/ASTabBarControllerTests.mm @@ -8,7 +8,7 @@ #import #import -#import +#import @interface ASTabBarControllerTests: XCTestCase @@ -17,8 +17,8 @@ @interface ASTabBarControllerTests: XCTestCase @implementation ASTabBarControllerTests - (void)testTabBarControllerSelectIndex { - ASViewController *firstViewController = [ASViewController new]; - ASViewController *secondViewController = [ASViewController new]; + ASDKViewController *firstViewController = [ASDKViewController new]; + ASDKViewController *secondViewController = [ASDKViewController new]; NSArray *viewControllers = @[firstViewController, secondViewController]; ASTabBarController *tabBarController = [ASTabBarController new]; [tabBarController setViewControllers:viewControllers]; @@ -28,8 +28,8 @@ - (void)testTabBarControllerSelectIndex { } - (void)testTabBarControllerSelectViewController { - ASViewController *firstViewController = [ASViewController new]; - ASViewController *secondViewController = [ASViewController new]; + ASDKViewController *firstViewController = [ASDKViewController new]; + ASDKViewController *secondViewController = [ASDKViewController new]; NSArray *viewControllers = @[firstViewController, secondViewController]; ASTabBarController *tabBarController = [ASTabBarController new]; [tabBarController setViewControllers:viewControllers]; diff --git a/Tests/ASTableViewTests.mm b/Tests/ASTableViewTests.mm index 29bb72c81..0d07d129b 100644 --- a/Tests/ASTableViewTests.mm +++ b/Tests/ASTableViewTests.mm @@ -776,7 +776,7 @@ - (void)testIssue2252 ASTableViewFilledDataSource *ds = [[ASTableViewFilledDataSource alloc] init]; ds.rowsPerSection = 1; node.dataSource = ds; - ASViewController *vc = [[ASViewController alloc] initWithNode:node]; + ASDKViewController *vc = [[ASDKViewController alloc] initWithNode:node]; UITabBarController *tabCtrl = [[UITabBarController alloc] init]; tabCtrl.viewControllers = @[ vc ]; tabCtrl.tabBar.translucent = NO; diff --git a/ThreeMigrationGuide.md b/ThreeMigrationGuide.md index eafc3e572..4ea5bf372 100644 --- a/ThreeMigrationGuide.md +++ b/ThreeMigrationGuide.md @@ -2,6 +2,7 @@ Got a tip for upgrading? Please open a PR to this document! +- Rename all instances of ASViewController to ASDKViewController ### Breaking API Changes diff --git a/docs/_docs/asviewcontroller.md b/docs/_docs/asdkviewcontroller.md similarity index 73% rename from docs/_docs/asviewcontroller.md rename to docs/_docs/asdkviewcontroller.md index 9cba5be9e..09cca2451 100755 --- a/docs/_docs/asviewcontroller.md +++ b/docs/_docs/asdkviewcontroller.md @@ -1,16 +1,16 @@ --- -title: ASViewController +title: ASDKViewController layout: docs -permalink: /docs/asviewcontroller.html +permalink: /docs/ASDKViewController.html prevPage: nextPage: aspagernode.html --- -`ASViewController` is a direct subclass of `UIViewController`. For the most part, it can be used in place of any `UIViewController` relatively easily. +`ASDKViewController` is a direct subclass of `UIViewController`. For the most part, it can be used in place of any `UIViewController` relatively easily. The main difference is that you construct and return the node you'd like managed as opposed to the way `UIViewController` provides a view of its own. -Consider the following `ASViewController` subclass that would like to use a custom table node as its managed node. +Consider the following `ASDKViewController` subclass that would like to use a custom table node as its managed node.
SwiftObjective-C @@ -52,4 +52,4 @@ The most important line is: `if (!(self = [super initWithNode:tableNode])) { return nil; }` -As you can see, `ASViewController`'s are initialized with a node of your choosing. +As you can see, `ASDKViewController`'s are initialized with a node of your choosing. diff --git a/docs/_docs/development/layout-specs.md b/docs/_docs/development/layout-specs.md index 771d4ca05..9fec11694 100644 --- a/docs/_docs/development/layout-specs.md +++ b/docs/_docs/development/layout-specs.md @@ -71,7 +71,7 @@ This is the function that will recursively call through its underlying tree of n ![layoutcallstack1](/static/images/development/layoutspecs1.png) -This is what a typical call stack will look like for the layout of an `ASViewController` with a simple view hierarchy. Here we clicked on the "Photo with outset icon overlay" in the Layout Specs Examples project. Breakpointing on the `-[PhotoWithOutsetIconOverlay layoutSpecThatFits:]` reveals that call stack. +This is what a typical call stack will look like for the layout of an `ASDKViewController` with a simple view hierarchy. Here we clicked on the "Photo with outset icon overlay" in the Layout Specs Examples project. Breakpointing on the `-[PhotoWithOutsetIconOverlay layoutSpecThatFits:]` reveals that call stack. The first significant branch of logic is the top level `-[ASDisplayNode calculateLayoutThatFits]` where it will choose between the Texture Layout and the Yoga engine. diff --git a/docs/_docs/development/node-lifecycle.md b/docs/_docs/development/node-lifecycle.md index dabb07579..6484eeed5 100644 --- a/docs/_docs/development/node-lifecycle.md +++ b/docs/_docs/development/node-lifecycle.md @@ -39,7 +39,7 @@ As mentioned above, ASDeallocQueue helps to defer the deallocation of objects gi # Nodes that are not managed by containers -These are nodes that are often directly created by client code, such as direct and indirect subnodes of cell nodes. When a node is added to a parent node, the parent node retains it until it's removed from the parent node, or until the parent node is deallocated. As a result, if the subnode is not retained by client code in any other way or if it's not removed from the parent node, the subnode's lifecycle is tied to the parent node's lifecycle. In addition, since nodes often live in a hierarchy, the entire node hierarchy has the same lifecycle as the root node's. Lastly, if the root node is managed by a node container -- directly in the case of ASViewController and the like, or indirectly as a cell node of a collection or table node --, then the entire node hierarchy is managed by the node container. +These are nodes that are often directly created by client code, such as direct and indirect subnodes of cell nodes. When a node is added to a parent node, the parent node retains it until it's removed from the parent node, or until the parent node is deallocated. As a result, if the subnode is not retained by client code in any other way or if it's not removed from the parent node, the subnode's lifecycle is tied to the parent node's lifecycle. In addition, since nodes often live in a hierarchy, the entire node hierarchy has the same lifecycle as the root node's. Lastly, if the root node is managed by a node container -- directly in the case of ASDKViewController and the like, or indirectly as a cell node of a collection or table node --, then the entire node hierarchy is managed by the node container. ## Node lifecycle under [Automatic Subnode Management (ASM)](/docs/automatic-subnode-mgmt.html) diff --git a/docs/_docs/subclassing.md b/docs/_docs/subclassing.md index 0bedc55ac..57af53f80 100755 --- a/docs/_docs/subclassing.md +++ b/docs/_docs/subclassing.md @@ -5,7 +5,7 @@ permalink: /docs/subclassing.html prevPage: node-overview.html nextPage: faq.html --- -The most important distinction when creating a subclass is whether you writing an ASViewController or an ASDisplayNode. This sounds obvious, but because some of these differences are subtle, it is important to keep this top of mind. +The most important distinction when creating a subclass is whether you writing an ASDKViewController or an ASDisplayNode. This sounds obvious, but because some of these differences are subtle, it is important to keep this top of mind. ## ASDisplayNode
@@ -43,17 +43,17 @@ One great use of `-layout` is for the specific case in which you want a subnode subnode.frame = self.bounds; ``` -If you desire the same effect in a ASViewController, you can do the same thing in -viewWillLayoutSubviews, unless your node is the node in initWithNode: and in that case it will do this automatically. +If you desire the same effect in a ASDKViewController, you can do the same thing in -viewWillLayoutSubviews, unless your node is the node in initWithNode: and in that case it will do this automatically. -## ASViewController +## ASDKViewController
-An `ASViewController` is a regular `UIViewController` subclass that has special features to manage nodes. Since it is a UIViewController subclass, all methods are called on the **main thread** (and you should always create an ASViewController on the main thread). +An `ASDKViewController` is a regular `UIViewController` subclass that has special features to manage nodes. Since it is a UIViewController subclass, all methods are called on the **main thread** (and you should always create an ASDKViewController on the main thread). ### `-init` -This method is called once, at the very beginning of an ASViewController's lifecycle. As with UIViewController initialization, it is best practice to **never access** `self.view` or `self.node.view` in this method as it will force the view to be created early. Instead, do any view access in -viewDidLoad. +This method is called once, at the very beginning of an ASDKViewController's lifecycle. As with UIViewController initialization, it is best practice to **never access** `self.view` or `self.node.view` in this method as it will force the view to be created early. Instead, do any view access in -viewDidLoad. -ASViewController's designated initializer is `initWithNode:`. A typical initializer will look something like the code below. Note how the ASViewController's node is created _before_ calling super. An ASViewController manages a node similarly to how a UIViewController manages a view, but the initialization is slightly different. +ASDKViewController's designated initializer is `initWithNode:`. A typical initializer will look something like the code below. Note how the ASDKViewController's node is created _before_ calling super. An ASDKViewController manages a node similarly to how a UIViewController manages a view, but the initialization is slightly different.
@@ -93,18 +93,18 @@ We recommend that you do not use this method because it is has no particular adv ### `-viewDidLoad` -This method is called once in a ASViewController's lifecycle, immediately after `-loadView`. This is the earliest time at which you should access the node's view. It is a great spot to put any **setup code that should only be run once and requires access to the view/layer**, such as adding a gesture recognizer. +This method is called once in a ASDKViewController's lifecycle, immediately after `-loadView`. This is the earliest time at which you should access the node's view. It is a great spot to put any **setup code that should only be run once and requires access to the view/layer**, such as adding a gesture recognizer. Layout code should never be put in this method, because it will not be called again when geometry changes. Note this is equally true for UIViewController; it is bad practice to put layout code in this method even if you don't currently expect geometry changes. ### `-viewWillLayoutSubviews` -This method is called at the exact same time as a node's `-layout` method and it may be called multiple times in a ASViewController's lifecycle; it will be called whenever the bounds of the ASViewController's node are changed (including rotation, split screen, keyboard presentation) as well as when there are changes to the hierarchy (children being added, removed, or changed in size). +This method is called at the exact same time as a node's `-layout` method and it may be called multiple times in a ASDKViewController's lifecycle; it will be called whenever the bounds of the ASDKViewController's node are changed (including rotation, split screen, keyboard presentation) as well as when there are changes to the hierarchy (children being added, removed, or changed in size). For consistency, it is best practice to put all layout code in this method. Because it is not called very frequently, even code that does not directly depend on the size belongs here. ### `-viewWillAppear:` / `-viewDidDisappear:` -These methods are called just before the ASViewController's node appears on screen (the earliest time that it is visible) and just after it is removed from the view hierarchy (the earliest time that it is no longer visible). These methods provide a good opportunity to start or stop animations related to the presentation or dismissal of your controller. This is also a good place to make a log of a user action. +These methods are called just before the ASDKViewController's node appears on screen (the earliest time that it is visible) and just after it is removed from the view hierarchy (the earliest time that it is no longer visible). These methods provide a good opportunity to start or stop animations related to the presentation or dismissal of your controller. This is also a good place to make a log of a user action. Although these methods may be called multiple times and geometry information is available, they are not called for all geometry changes and so should not be used for core layout code (beyond setup required for specific animations). diff --git a/docs/_docs/synchronous-concurrency.md b/docs/_docs/synchronous-concurrency.md index d4430b751..158407ecd 100755 --- a/docs/_docs/synchronous-concurrency.md +++ b/docs/_docs/synchronous-concurrency.md @@ -6,7 +6,7 @@ prevPage: subtree-rasterization.html nextPage: corner-rounding.html --- -Both `ASViewController` and `ASCellNode` have a property called `neverShowPlaceholders`. +Both `ASDKViewController` and `ASCellNode` have a property called `neverShowPlaceholders`. By setting this property to YES, the main thread will be blocked until display has completed for the cell or view controller's view. @@ -27,6 +27,6 @@ node.neverShowPlaceholders = true

-Usually, if a cell hasn't finished its display pass before it has reached the screen it will show placeholders until it has drawing its content. Setting this option to YES makes your scrolling node or ASViewController act more like UIKit, and in fact makes Texture scrolling visually indistinguishable from UIKit's, except that it's faster. +Usually, if a cell hasn't finished its display pass before it has reached the screen it will show placeholders until it has drawing its content. Setting this option to YES makes your scrolling node or ASDKViewController act more like UIKit, and in fact makes Texture scrolling visually indistinguishable from UIKit's, except that it's faster. diff --git a/examples/ASDKTube/Sample/Controller/VideoFeedNodeController.h b/examples/ASDKTube/Sample/Controller/VideoFeedNodeController.h index 131bb38ef..f6100ac90 100644 --- a/examples/ASDKTube/Sample/Controller/VideoFeedNodeController.h +++ b/examples/ASDKTube/Sample/Controller/VideoFeedNodeController.h @@ -9,6 +9,6 @@ #import -@interface VideoFeedNodeController : ASViewController +@interface VideoFeedNodeController : ASDKViewController @end diff --git a/examples/ASDKTube/Sample/ViewController.h b/examples/ASDKTube/Sample/ViewController.h index 560b6a2d0..8e8bc18bf 100644 --- a/examples/ASDKTube/Sample/ViewController.h +++ b/examples/ASDKTube/Sample/ViewController.h @@ -9,6 +9,6 @@ #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/ASDKgram/Sample/PhotoFeedBaseController.h b/examples/ASDKgram/Sample/PhotoFeedBaseController.h index b40a5946c..82aea4d46 100644 --- a/examples/ASDKgram/Sample/PhotoFeedBaseController.h +++ b/examples/ASDKgram/Sample/PhotoFeedBaseController.h @@ -13,7 +13,7 @@ @protocol PhotoFeedControllerProtocol; @class PhotoFeedModel; -@interface PhotoFeedBaseController : ASViewController +@interface PhotoFeedBaseController : ASDKViewController @property (nonatomic, strong, readonly) PhotoFeedModel *photoFeed; @property (nonatomic, strong, readonly) UITableView *tableView; diff --git a/examples/ASDKgram/Sample/PhotoFeedListKitViewController.h b/examples/ASDKgram/Sample/PhotoFeedListKitViewController.h index a1e3e6a33..b84f3621e 100644 --- a/examples/ASDKgram/Sample/PhotoFeedListKitViewController.h +++ b/examples/ASDKgram/Sample/PhotoFeedListKitViewController.h @@ -9,6 +9,6 @@ #import #import "PhotoFeedControllerProtocol.h" -@interface PhotoFeedListKitViewController : ASViewController +@interface PhotoFeedListKitViewController : ASDKViewController @end diff --git a/examples/ASMapNode/Sample/ViewController.h b/examples/ASMapNode/Sample/ViewController.h index 7054e2d89..c5228722c 100644 --- a/examples/ASMapNode/Sample/ViewController.h +++ b/examples/ASMapNode/Sample/ViewController.h @@ -7,9 +7,9 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import +#import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/ASViewController/Sample/DetailViewController.h b/examples/ASViewController/Sample/DetailViewController.h index 0c5eb8589..cc78cf170 100644 --- a/examples/ASViewController/Sample/DetailViewController.h +++ b/examples/ASViewController/Sample/DetailViewController.h @@ -7,9 +7,9 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import +#import #import "DetailRootNode.h" -@interface DetailViewController : ASViewController +@interface DetailViewController : ASDKViewController @end diff --git a/examples/ASViewController/Sample/ViewController.h b/examples/ASViewController/Sample/ViewController.h index f1700621f..70421044e 100644 --- a/examples/ASViewController/Sample/ViewController.h +++ b/examples/ASViewController/Sample/ViewController.h @@ -7,10 +7,10 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import +#import #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.h b/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.h index cae34ad20..c439021d0 100644 --- a/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.h +++ b/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.h @@ -17,7 +17,7 @@ @end -@interface OverviewComponentsViewController : ASViewController +@interface OverviewComponentsViewController : ASDKViewController @end diff --git a/examples/CatDealsCollectionView/Sample/ViewController.h b/examples/CatDealsCollectionView/Sample/ViewController.h index 560b6a2d0..8e8bc18bf 100644 --- a/examples/CatDealsCollectionView/Sample/ViewController.h +++ b/examples/CatDealsCollectionView/Sample/ViewController.h @@ -9,6 +9,6 @@ #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/CustomCollectionView-Swift/Sample/ViewController.swift b/examples/CustomCollectionView-Swift/Sample/ViewController.swift index 1e33a06f3..3625b4c68 100644 --- a/examples/CustomCollectionView-Swift/Sample/ViewController.swift +++ b/examples/CustomCollectionView-Swift/Sample/ViewController.swift @@ -10,7 +10,7 @@ import UIKit import AsyncDisplayKit -class ViewController: ASViewController, MosaicCollectionViewLayoutDelegate, ASCollectionDataSource, ASCollectionDelegate { +class ViewController: ASDKViewController, MosaicCollectionViewLayoutDelegate, ASCollectionDataSource, ASCollectionDelegate { var _sections = [[UIImage]]() let _collectionNode: ASCollectionNode diff --git a/examples/CustomCollectionView/Sample/ViewController.h b/examples/CustomCollectionView/Sample/ViewController.h index da850f744..b9629ecde 100644 --- a/examples/CustomCollectionView/Sample/ViewController.h +++ b/examples/CustomCollectionView/Sample/ViewController.h @@ -10,6 +10,6 @@ #import #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/HorizontalWithinVerticalScrolling/Sample/ViewController.h b/examples/HorizontalWithinVerticalScrolling/Sample/ViewController.h index 560b6a2d0..8e8bc18bf 100644 --- a/examples/HorizontalWithinVerticalScrolling/Sample/ViewController.h +++ b/examples/HorizontalWithinVerticalScrolling/Sample/ViewController.h @@ -9,6 +9,6 @@ #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/Kittens/Sample/ViewController.h b/examples/Kittens/Sample/ViewController.h index 560b6a2d0..8e8bc18bf 100644 --- a/examples/Kittens/Sample/ViewController.h +++ b/examples/Kittens/Sample/ViewController.h @@ -9,6 +9,6 @@ #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/LayoutSpecExamples-Swift/Sample/LayoutExampleViewController.swift b/examples/LayoutSpecExamples-Swift/Sample/LayoutExampleViewController.swift index 25a391694..09bea303b 100644 --- a/examples/LayoutSpecExamples-Swift/Sample/LayoutExampleViewController.swift +++ b/examples/LayoutSpecExamples-Swift/Sample/LayoutExampleViewController.swift @@ -9,7 +9,7 @@ import AsyncDisplayKit -class LayoutExampleViewController: ASViewController { +class LayoutExampleViewController: ASDKViewController { let customNode: LayoutExampleNode diff --git a/examples/LayoutSpecExamples-Swift/Sample/OverviewViewController.swift b/examples/LayoutSpecExamples-Swift/Sample/OverviewViewController.swift index 0c9110a3b..553d9eb1e 100644 --- a/examples/LayoutSpecExamples-Swift/Sample/OverviewViewController.swift +++ b/examples/LayoutSpecExamples-Swift/Sample/OverviewViewController.swift @@ -9,7 +9,7 @@ import AsyncDisplayKit -class OverviewViewController: ASViewController { +class OverviewViewController: ASDKViewController { let tableNode = ASTableNode() let layoutExamples: [LayoutExampleNode.Type] diff --git a/examples/LayoutSpecExamples/Sample/LayoutExampleViewController.h b/examples/LayoutSpecExamples/Sample/LayoutExampleViewController.h index d087bcc77..184032dd5 100644 --- a/examples/LayoutSpecExamples/Sample/LayoutExampleViewController.h +++ b/examples/LayoutSpecExamples/Sample/LayoutExampleViewController.h @@ -9,7 +9,7 @@ #import -@interface LayoutExampleViewController : ASViewController +@interface LayoutExampleViewController : ASDKViewController - (instancetype)initWithLayoutExampleClass:(Class)layoutExampleClass NS_DESIGNATED_INITIALIZER; - (instancetype)initWithNode:(ASDisplayNode *)node NS_UNAVAILABLE; @end diff --git a/examples/LayoutSpecExamples/Sample/OverviewViewController.h b/examples/LayoutSpecExamples/Sample/OverviewViewController.h index 83381429a..a012b402d 100644 --- a/examples/LayoutSpecExamples/Sample/OverviewViewController.h +++ b/examples/LayoutSpecExamples/Sample/OverviewViewController.h @@ -10,6 +10,6 @@ #import -@interface OverviewViewController : ASViewController +@interface OverviewViewController : ASDKViewController @end diff --git a/examples/PagerNode/Sample/ViewController.h b/examples/PagerNode/Sample/ViewController.h index 3af731c84..a474218c0 100644 --- a/examples/PagerNode/Sample/ViewController.h +++ b/examples/PagerNode/Sample/ViewController.h @@ -9,6 +9,6 @@ #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/README.md b/examples/README.md index 39fac1c1c..f35f5d0b7 100644 --- a/examples/README.md +++ b/examples/README.md @@ -36,12 +36,12 @@ Featuring: ![ASTableViewStressTest Example App Screenshot](https://github.com/AsyncDisplayKit/Documentation/raw/master/docs/static/images/example-app-screenshots/ASTableViewStressTest.png) -### ASViewController [ObjC] +### ASDKViewController [ObjC] -![ASViewController Example App Screenshot](https://github.com/AsyncDisplayKit/Documentation/raw/master/docs/static/images/example-app-screenshots/ASViewController.png) +![ASDKViewController Example App Screenshot](https://github.com/AsyncDisplayKit/Documentation/raw/master/docs/static/images/example-app-screenshots/ASDKViewController.png) Featuring: -- ASViewController +- ASDKViewController - ASTableView - ASMultiplexImageNode - ASLayoutSpec @@ -56,7 +56,7 @@ Featuring: Featuring: - ASDK Swift compatibility -- ASViewController +- ASDKViewController - ASCollectionView - thread affinity - ASLayoutSpec @@ -150,7 +150,7 @@ Featuring: ![Swift Example App Screenshot](https://github.com/AsyncDisplayKit/Documentation/raw/master/docs/static/images/example-app-screenshots/Swift.png) Featuring: -- ASViewController with ASTableNode +- ASDKViewController with ASTableNode ### SynchronousConcurrency [ObjC] @@ -169,7 +169,7 @@ The internal features are: Also provided are two such implementations: -[ASCellNode setNeverShowPlaceholders:], which integrates with both Tables and Collections --[ASViewController setNeverShowPlaceholders:], which should work with Nav and Tab controllers. +-[ASDKViewController setNeverShowPlaceholders:], which should work with Nav and Tab controllers. Lastly, on ASDisplayNode, a new property .shouldBypassEnsureDisplay allows individual node types to exempt themselves from blocking the main thread on their display. diff --git a/examples/SocialAppLayout-Inverted/Sample/ViewController.h b/examples/SocialAppLayout-Inverted/Sample/ViewController.h index 641624224..f3c06cc37 100644 --- a/examples/SocialAppLayout-Inverted/Sample/ViewController.h +++ b/examples/SocialAppLayout-Inverted/Sample/ViewController.h @@ -9,5 +9,5 @@ #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/SocialAppLayout/Sample/ViewController.h b/examples/SocialAppLayout/Sample/ViewController.h index 641624224..f3c06cc37 100644 --- a/examples/SocialAppLayout/Sample/ViewController.h +++ b/examples/SocialAppLayout/Sample/ViewController.h @@ -9,5 +9,5 @@ #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples/Swift/Sample/ViewController.swift b/examples/Swift/Sample/ViewController.swift index 8384906cb..7a7c2d3ec 100644 --- a/examples/Swift/Sample/ViewController.swift +++ b/examples/Swift/Sample/ViewController.swift @@ -10,7 +10,7 @@ import UIKit import AsyncDisplayKit -final class ViewController: ASViewController, ASTableDataSource, ASTableDelegate { +final class ViewController: ASDKViewController, ASTableDataSource, ASTableDelegate { struct State { var itemCount: Int diff --git a/examples_extra/ASDKgram-Swift/ASDKgram-Swift/PhotoFeedTableNodeController.swift b/examples_extra/ASDKgram-Swift/ASDKgram-Swift/PhotoFeedTableNodeController.swift index 6c2fe39f1..4cade0c93 100644 --- a/examples_extra/ASDKgram-Swift/ASDKgram-Swift/PhotoFeedTableNodeController.swift +++ b/examples_extra/ASDKgram-Swift/ASDKgram-Swift/PhotoFeedTableNodeController.swift @@ -9,7 +9,7 @@ import AsyncDisplayKit -class PhotoFeedTableNodeController: ASViewController { +class PhotoFeedTableNodeController: ASDKViewController { // MARK: Lifecycle diff --git a/examples_extra/ASTraitCollection/Sample/CollectionViewController.h b/examples_extra/ASTraitCollection/Sample/CollectionViewController.h index 0528310b7..2cb388136 100644 --- a/examples_extra/ASTraitCollection/Sample/CollectionViewController.h +++ b/examples_extra/ASTraitCollection/Sample/CollectionViewController.h @@ -9,5 +9,5 @@ #import -@interface CollectionViewController : ASViewController +@interface CollectionViewController : ASDKViewController @end diff --git a/examples_extra/ASTraitCollection/Sample/KittenNode.h b/examples_extra/ASTraitCollection/Sample/KittenNode.h index 17655e076..47f5ee44a 100644 --- a/examples_extra/ASTraitCollection/Sample/KittenNode.h +++ b/examples_extra/ASTraitCollection/Sample/KittenNode.h @@ -17,5 +17,5 @@ // The default action when an image node is tapped. This action will create an // OverrideVC and override its display traits to always be compact. -+ (void)defaultImageTappedAction:(ASViewController *)sourceViewController; ++ (void)defaultImageTappedAction:(ASDKViewController *)sourceViewController; @end diff --git a/examples_extra/ASTraitCollection/Sample/KittenNode.m b/examples_extra/ASTraitCollection/Sample/KittenNode.m index 1526563e0..f0d32ac0f 100644 --- a/examples_extra/ASTraitCollection/Sample/KittenNode.m +++ b/examples_extra/ASTraitCollection/Sample/KittenNode.m @@ -143,7 +143,7 @@ - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize return [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(kOuterPadding, kOuterPadding, kOuterPadding, kOuterPadding) child:stackSpec]; } -+ (void)defaultImageTappedAction:(ASViewController *)sourceViewController ++ (void)defaultImageTappedAction:(ASDKViewController *)sourceViewController { OverrideViewController *overrideVC = [[OverrideViewController alloc] init]; diff --git a/examples_extra/ASTraitCollection/Sample/OverrideViewController.h b/examples_extra/ASTraitCollection/Sample/OverrideViewController.h index f5de270ae..6cef2af9b 100644 --- a/examples_extra/ASTraitCollection/Sample/OverrideViewController.h +++ b/examples_extra/ASTraitCollection/Sample/OverrideViewController.h @@ -22,6 +22,6 @@ * This is a fairly stupid VC that's main purpose is to show how to override ASDisplayTraits. * Take a look at `defaultImageTappedAction` in KittenNode to see how this is accomplished. */ -@interface OverrideViewController : ASViewController +@interface OverrideViewController : ASDKViewController @property (nonatomic, copy) dispatch_block_t closeBlock; @end diff --git a/examples_extra/ASTraitCollection/Sample/TableViewController.h b/examples_extra/ASTraitCollection/Sample/TableViewController.h index bfb5fad61..4bb66b388 100644 --- a/examples_extra/ASTraitCollection/Sample/TableViewController.h +++ b/examples_extra/ASTraitCollection/Sample/TableViewController.h @@ -9,6 +9,6 @@ #import -@interface TableViewController : ASViewController +@interface TableViewController : ASDKViewController @end diff --git a/examples_extra/ASTraitCollection/Sample/ViewController.h b/examples_extra/ASTraitCollection/Sample/ViewController.h index 4499f93ba..dd2097b3f 100644 --- a/examples_extra/ASTraitCollection/Sample/ViewController.h +++ b/examples_extra/ASTraitCollection/Sample/ViewController.h @@ -9,6 +9,6 @@ #import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples_extra/BackgroundPropertySetting/Sample/ViewController.swift b/examples_extra/BackgroundPropertySetting/Sample/ViewController.swift index 47faf4384..6024611a8 100644 --- a/examples_extra/BackgroundPropertySetting/Sample/ViewController.swift +++ b/examples_extra/BackgroundPropertySetting/Sample/ViewController.swift @@ -10,7 +10,7 @@ import UIKit import AsyncDisplayKit -final class ViewController: ASViewController, ASCollectionDelegate, ASCollectionDataSource { +final class ViewController: ASDKViewController, ASCollectionDelegate, ASCollectionDataSource { let itemCount = 1000 let itemSize: CGSize diff --git a/examples_extra/Multiplex/Sample/ViewController.h b/examples_extra/Multiplex/Sample/ViewController.h index 27738fcbe..bf9612326 100644 --- a/examples_extra/Multiplex/Sample/ViewController.h +++ b/examples_extra/Multiplex/Sample/ViewController.h @@ -7,8 +7,8 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import +#import -@interface ViewController : ASViewController +@interface ViewController : ASDKViewController @end diff --git a/examples_extra/RepoSearcher/RepoSearcher/SearchViewController.swift b/examples_extra/RepoSearcher/RepoSearcher/SearchViewController.swift index 59556d4b3..ec108c2a7 100644 --- a/examples_extra/RepoSearcher/RepoSearcher/SearchViewController.swift +++ b/examples_extra/RepoSearcher/RepoSearcher/SearchViewController.swift @@ -12,7 +12,7 @@ import IGListKit class SearchToken: NSObject {} -final class SearchViewController: ASViewController { +final class SearchViewController: ASDKViewController { lazy var adapter: ListAdapter = { return ListAdapter(updater: ListAdapterUpdater(), viewController: self, workingRangeSize: 0) diff --git a/examples_extra/Shop/Shop/Scenes/Product/ProductViewController.swift b/examples_extra/Shop/Shop/Scenes/Product/ProductViewController.swift index 9d36298e1..0d406b57a 100644 --- a/examples_extra/Shop/Shop/Scenes/Product/ProductViewController.swift +++ b/examples_extra/Shop/Shop/Scenes/Product/ProductViewController.swift @@ -8,7 +8,7 @@ import UIKit -class ProductViewController: ASViewController { +class ProductViewController: ASDKViewController { // MARK: - Variables diff --git a/examples_extra/Shop/Shop/Scenes/Products/ProductsCollectionViewController.swift b/examples_extra/Shop/Shop/Scenes/Products/ProductsCollectionViewController.swift index caa5278f0..f96834a08 100644 --- a/examples_extra/Shop/Shop/Scenes/Products/ProductsCollectionViewController.swift +++ b/examples_extra/Shop/Shop/Scenes/Products/ProductsCollectionViewController.swift @@ -8,7 +8,7 @@ import UIKit -class ProductsCollectionViewController: ASViewController { +class ProductsCollectionViewController: ASDKViewController { // MARK: - Variables diff --git a/examples_extra/Shop/Shop/Scenes/Products/ProductsTableViewController.swift b/examples_extra/Shop/Shop/Scenes/Products/ProductsTableViewController.swift index bfb851a3f..533afe2c7 100644 --- a/examples_extra/Shop/Shop/Scenes/Products/ProductsTableViewController.swift +++ b/examples_extra/Shop/Shop/Scenes/Products/ProductsTableViewController.swift @@ -8,7 +8,7 @@ import UIKit -class ProductsTableViewController: ASViewController { +class ProductsTableViewController: ASDKViewController { // MARK: - Variables diff --git a/examples_extra/Shop/Shop/Scenes/Shop/ShopViewController.swift b/examples_extra/Shop/Shop/Scenes/Shop/ShopViewController.swift index 8feefa3f2..bea9f86ac 100644 --- a/examples_extra/Shop/Shop/Scenes/Shop/ShopViewController.swift +++ b/examples_extra/Shop/Shop/Scenes/Shop/ShopViewController.swift @@ -8,7 +8,7 @@ import UIKit -class ShopViewController: ASViewController { +class ShopViewController: ASDKViewController { // MARK: - Variables diff --git a/examples_extra/SynchronousConcurrency/Sample/AsyncViewController.h b/examples_extra/SynchronousConcurrency/Sample/AsyncViewController.h index 2c20ade6e..0df528387 100644 --- a/examples_extra/SynchronousConcurrency/Sample/AsyncViewController.h +++ b/examples_extra/SynchronousConcurrency/Sample/AsyncViewController.h @@ -7,8 +7,8 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import +#import -@interface AsyncViewController : ASViewController +@interface AsyncViewController : ASDKViewController @end diff --git a/examples_extra/TextStressTest/Sample/CollectionViewController.h b/examples_extra/TextStressTest/Sample/CollectionViewController.h index d9329bdb0..419f634d0 100644 --- a/examples_extra/TextStressTest/Sample/CollectionViewController.h +++ b/examples_extra/TextStressTest/Sample/CollectionViewController.h @@ -9,5 +9,5 @@ #import #import -@interface CollectionViewController : ASViewController +@interface CollectionViewController : ASDKViewController @end From 1552c2e3865b1a872e30f647e7300fcccbf87d00 Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Mon, 29 Jun 2020 15:05:17 -0700 Subject: [PATCH 52/56] Upgrade to Xcode 11.5 (#1877) --- .github/workflows/ci-master-only.yml | 2 +- .github/workflows/ci-pull-requests-only.yml | 2 +- .github/workflows/ci.yml | 2 +- build.sh | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-master-only.yml b/.github/workflows/ci-master-only.yml index 9f6a4a8bd..a58671d5c 100644 --- a/.github/workflows/ci-master-only.yml +++ b/.github/workflows/ci-master-only.yml @@ -8,7 +8,7 @@ on: jobs: cocoapods-lint: env: - DEVELOPER_DIR: /Applications/Xcode_11.4.1.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_11.5.app/Contents/Developer name: Verify that podspec lints runs-on: macOS-latest steps: diff --git a/.github/workflows/ci-pull-requests-only.yml b/.github/workflows/ci-pull-requests-only.yml index 6dbf42b00..859b525c7 100644 --- a/.github/workflows/ci-pull-requests-only.yml +++ b/.github/workflows/ci-pull-requests-only.yml @@ -8,7 +8,7 @@ on: jobs: buildsh: env: - DEVELOPER_DIR: /Applications/Xcode_11.4.1.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_11.5.app/Contents/Developer strategy: matrix: mode: [cocoapods-lint-default-subspecs, cocoapods-lint-other-subspecs] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72b78d44b..bb2212d03 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,7 @@ on: [push, pull_request] jobs: buildsh: env: - DEVELOPER_DIR: /Applications/Xcode_11.4.1.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_11.5.app/Contents/Developer strategy: matrix: mode: [tests, framework, life-without-cocoapods, carthage, examples-pt1, examples-pt2, examples-pt3, examples-pt4] diff --git a/build.sh b/build.sh index 3f4fb2785..547194124 100755 --- a/build.sh +++ b/build.sh @@ -8,8 +8,8 @@ # ls -ld /Applications/Xcode* # echo ************* diagnostics end -PLATFORM="${TEXTURE_BUILD_PLATFORM:-platform=iOS Simulator,OS=13.4.1,name=iPhone 8}" -SDK="${TEXTURE_BUILD_SDK:-iphonesimulator13.4}" +PLATFORM="${TEXTURE_BUILD_PLATFORM:-platform=iOS Simulator,OS=13.5,name=iPhone 8}" +SDK="${TEXTURE_BUILD_SDK:-iphonesimulator13.5}" DERIVED_DATA_PATH="~/ASDKDerivedData" # It is pitch black. From 81ecdc903236d9c88e2ad16ae9672759bbe71431 Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Wed, 15 Jul 2020 10:37:03 -0700 Subject: [PATCH 53/56] =?UTF-8?q?=F0=9F=8E=89=203.0.0=20(#1883)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 11 +++++++++++ RELEASE.md | 2 +- Texture.podspec | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3fdb668f..128b49a7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [3.0.0](https://github.com/TextureGroup/Texture/tree/3.0.0) (2020-07-15) + +[Full Changelog](https://github.com/TextureGroup/Texture/compare/3.0.0-rc.2...3.0.0) + +**Merged pull requests:** + +- Improve ThreeMigrationGuide.md [\#1878](https://github.com/TextureGroup/Texture/pull/1878) ([rogerluan](https://github.com/rogerluan)) +- Upgrade to Xcode 11.5 [\#1877](https://github.com/TextureGroup/Texture/pull/1877) ([garrettmoon](https://github.com/garrettmoon)) +- Renames AS\_EXTERN and ASViewController [\#1876](https://github.com/TextureGroup/Texture/pull/1876) ([garrettmoon](https://github.com/garrettmoon)) +- Add a 3.0 migration guide [\#1875](https://github.com/TextureGroup/Texture/pull/1875) ([garrettmoon](https://github.com/garrettmoon)) + ## [3.0.0-rc.2](https://github.com/TextureGroup/Texture/tree/3.0.0-rc.2) (2020-06-25) [Full Changelog](https://github.com/TextureGroup/Texture/compare/3.0.0-rc.1...3.0.0-rc.2) diff --git a/RELEASE.md b/RELEASE.md index 4826178a9..f7ea00e92 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -8,7 +8,7 @@ This document describes the process for a public Texture release. ### Process - Run `github_changelog_generator` in Texture project directory: `github_changelog_generator --token --user TextureGroup --project Texture`. To avoid hitting rate limit, the generator will replace the entire file with just the changes from this version – revert that giant deletion to get the entire new changelog. - Update `spec.version` within `Texture.podspec` and the `since-tag` and `future-release` fields in `.github_changelog_generator`. -- Create a new PR with the updated `Texture.podspec` and the newly generated changelog, add `#changelog` to the PR message so the CI will not prevent merging it. +- Create a new PR with the updated `Texture.podspec` and the newly generated changelog. - After merging in the PR, [create a new GitHub release](https://github.com/TextureGroup/Texture/releases/new). Use the generated changelog for the new release. - Push to Cocoapods with `pod trunk push` diff --git a/Texture.podspec b/Texture.podspec index 1b2d153e2..2df851974 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'Texture' - spec.version = '3.0.0-rc.2' + spec.version = '3.0.0' spec.license = { :type => 'Apache 2', } spec.homepage = 'http://texturegroup.org' spec.authors = { 'Huy Nguyen' => 'hi@huynguyen.dev', 'Garrett Moon' => 'garrett@excitedpixel.com', 'Scott Goodson' => 'scottgoodson@gmail.com', 'Michael Schneider' => 'mischneider1@gmail.com', 'Adlai Holler' => 'adlai@icloud.com' } From f56a4dd1ddab09718b94fd3d9e1b1458c5221b2a Mon Sep 17 00:00:00 2001 From: ricky Date: Thu, 23 Jul 2020 15:21:07 -0700 Subject: [PATCH 54/56] [Accessibility] Ship ASExperimentalDoNotCacheAccessibilityElements (#1888) We did not notice any effect on performance of the Pinterest app by not caching `accessibilityElements` in `_ASDisplayView`. By not caching the elements, we can be sure that the elements will be correct even when nodes change visibility state. There will be a performance impact when voice over is enabled, but providing the correct elements for the current state of a view is more important than performance in this case. https://github.com/TextureGroup/Texture/issues/1853 --- Source/ASExperimentalFeatures.h | 1 - Source/ASExperimentalFeatures.mm | 3 +- Source/Details/_ASDisplayViewAccessiblity.mm | 27 ++++++------------ Source/Private/ASDisplayNode+UIViewBridge.mm | 29 -------------------- Tests/ASConfigurationTests.mm | 2 -- 5 files changed, 10 insertions(+), 52 deletions(-) diff --git a/Source/ASExperimentalFeatures.h b/Source/ASExperimentalFeatures.h index 7729e2e34..6545c6875 100644 --- a/Source/ASExperimentalFeatures.h +++ b/Source/ASExperimentalFeatures.h @@ -28,7 +28,6 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { ASExperimentalDispatchApply = 1 << 7, // exp_dispatch_apply ASExperimentalDrawingGlobal = 1 << 8, // exp_drawing_global ASExperimentalOptimizeDataControllerPipeline = 1 << 9, // exp_optimize_data_controller_pipeline - ASExperimentalDoNotCacheAccessibilityElements = 1 << 10, // exp_do_not_cache_accessibility_elements ASExperimentalFeatureAll = 0xFFFFFFFF }; diff --git a/Source/ASExperimentalFeatures.mm b/Source/ASExperimentalFeatures.mm index fef124b45..fd35bfaf2 100644 --- a/Source/ASExperimentalFeatures.mm +++ b/Source/ASExperimentalFeatures.mm @@ -21,8 +21,7 @@ @"exp_did_enter_preload_skip_asm_layout", @"exp_dispatch_apply", @"exp_drawing_global", - @"exp_optimize_data_controller_pipeline", - @"exp_do_not_cache_accessibility_elements"])); + @"exp_optimize_data_controller_pipeline"])); if (flags == ASExperimentalFeatureAll) { return allNames; } diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index 7fb79eaa2..bdbd7dcc4 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -311,24 +311,15 @@ static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *el } } -@interface _ASDisplayView () { - NSArray *_accessibilityElements; -} - -@end - @implementation _ASDisplayView (UIAccessibilityContainer) #pragma mark - UIAccessibility - (void)setAccessibilityElements:(NSArray *)accessibilityElements { - ASDisplayNodeAssertMainThread(); - // While it looks very strange to ignore the accessibilyElements param and set _accessibilityElements to nil, it is actually on purpose. - // _ASDisplayView's accessibilityElements method will always defer to the node for accessibilityElements when _accessibilityElements is - // nil. Calling setAccessibilityElements on _ASDisplayView is basically clearing the cache and forcing _ASDisplayView to ask the node - // for its accessibilityElements the next time they are requested. - _accessibilityElements = nil; + // this is a no-op. You should not be setting accessibilityElements directly on _ASDisplayView. + // if you wish to set accessibilityElements, do so in your node. UIKit will call _ASDisplayView's + // accessibilityElements which will in turn ask its node for its elements. } - (NSArray *)accessibilityElements @@ -340,12 +331,12 @@ - (NSArray *)accessibilityElements return @[]; } - // when items become hidden/visible we have to manually clear the _accessibilityElements in order to get an updated version - // Instead, let's try computing the elements every time and see how badly it affects performance. - if (_accessibilityElements == nil || ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements)) { - _accessibilityElements = [viewNode accessibilityElements]; - } - return _accessibilityElements; + // we no longer cache accessibilityElements. When caching, in order to provide correct element when items become hidden/visible + // we had to manually clear _accessibilityElements. This seemed like a heavy burden to place on a user, and one that is also + // not immediately obvious. While recomputing accessibilityElements may be expensive, this will only affect users that have + // voice over enabled (we checked to ensure performance did not suffer by not caching for an overall user base). For those + // users with voice over on, being correct is almost certainly more important than being performant. + return [viewNode accessibilityElements]; } @end diff --git a/Source/Private/ASDisplayNode+UIViewBridge.mm b/Source/Private/ASDisplayNode+UIViewBridge.mm index 42dbbfcb6..8be28957f 100644 --- a/Source/Private/ASDisplayNode+UIViewBridge.mm +++ b/Source/Private/ASDisplayNode+UIViewBridge.mm @@ -1137,22 +1137,6 @@ - (BOOL)_locked_insetsLayoutMarginsFromSafeArea @implementation ASDisplayNode (UIViewBridgeAccessibility) -// Walks up the view tree to nil out all the cached accsesibilityElements. This is required when changing -// accessibility properties like accessibilityViewIsModal. -- (void)invalidateAccessibilityElements -{ - // If we are not caching accessibilityElements we don't need to do anything here. - if (ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements)) { - return; - } - - // we want to check if we are on the main thread first, since _loaded checks the layer and can only be done on main - if (ASDisplayNodeThreadIsMain() && _loaded(self)) { - self.view.accessibilityElements = nil; - [self.supernode invalidateAccessibilityElements]; - } -} - - (BOOL)isAccessibilityElement { _bridge_prologue_read; @@ -1310,13 +1294,7 @@ - (BOOL)accessibilityElementsHidden - (void)setAccessibilityElementsHidden:(BOOL)accessibilityElementsHidden { _bridge_prologue_write; - BOOL oldHiddenValue = _getFromViewOnly(accessibilityElementsHidden); _setAccessibilityToViewAndProperty(_flags.accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden); - - // if we made a change, we need to clear the view's accessibilityElements cache. - if (!ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements) && self.isNodeLoaded && oldHiddenValue != accessibilityElementsHidden) { - [self invalidateAccessibilityElements]; - } } - (BOOL)accessibilityViewIsModal @@ -1328,16 +1306,9 @@ - (BOOL)accessibilityViewIsModal - (void)setAccessibilityViewIsModal:(BOOL)accessibilityViewIsModal { _bridge_prologue_write; - BOOL oldAccessibilityViewIsModal = _getFromViewOnly(accessibilityViewIsModal); _setAccessibilityToViewAndProperty(_flags.accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal); - - // if we made a change, we need to clear the view's accessibilityElements cache. - if (!ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements) && self.isNodeLoaded && oldAccessibilityViewIsModal != accessibilityViewIsModal) { - [self invalidateAccessibilityElements]; - } } - - (BOOL)shouldGroupAccessibilityChildren { _bridge_prologue_read; diff --git a/Tests/ASConfigurationTests.mm b/Tests/ASConfigurationTests.mm index 755375af8..b3287fc31 100644 --- a/Tests/ASConfigurationTests.mm +++ b/Tests/ASConfigurationTests.mm @@ -28,7 +28,6 @@ ASExperimentalDispatchApply, ASExperimentalDrawingGlobal, ASExperimentalOptimizeDataControllerPipeline, - ASExperimentalDoNotCacheAccessibilityElements, }; @interface ASConfigurationTests : ASTestCase @@ -51,7 +50,6 @@ + (NSArray *)names { @"exp_dispatch_apply", @"exp_drawing_global", @"exp_optimize_data_controller_pipeline", - @"exp_do_not_cache_accessibility_elements", ]; } From 9ef97f49657e6e690bb222ef4634bbdcc453c3c2 Mon Sep 17 00:00:00 2001 From: Greg Bolsinga Date: Thu, 30 Jul 2020 12:02:46 -0700 Subject: [PATCH 55/56] Remove background deallocation helper code (#1890) * Remove background deallocation helper code Last use removed in Texture with #1840, now PINS no longer uses it either. Less OOMs is so nice. * remove methods from docs --- Source/ASRunLoopQueue.h | 13 +---- Source/ASRunLoopQueue.mm | 61 ------------------------ Source/Private/ASInternalHelpers.h | 3 -- Source/Private/ASInternalHelpers.mm | 5 -- Tests/Common/ASTestCase.mm | 3 -- docs/_docs/development/how-to-debug.md | 4 -- docs/_docs/development/node-lifecycle.md | 6 --- docs/_docs/development/threading.md | 20 -------- 8 files changed, 1 insertion(+), 114 deletions(-) diff --git a/Source/ASRunLoopQueue.h b/Source/ASRunLoopQueue.h index 298fe76ca..c66a5dbfb 100644 --- a/Source/ASRunLoopQueue.h +++ b/Source/ASRunLoopQueue.h @@ -32,8 +32,7 @@ AS_SUBCLASSING_RESTRICTED * * @discussion You may pass @c nil for the handler if you simply want the objects to * be retained at enqueue time, and released during the run loop step. This is useful - * for creating a "main deallocation queue", as @c ASDeallocQueue creates its own - * worker thread with its own run loop. + * for creating a "main deallocation queue". */ - (instancetype)initWithRunLoop:(CFRunLoopRef)runloop retainObjects:(BOOL)retainsObjects @@ -78,14 +77,4 @@ NS_INLINE ASCATransactionQueue *ASCATransactionQueueGet(void) { return _ASSharedCATransactionQueue; } -@interface ASDeallocQueue : NSObject - -+ (ASDeallocQueue *)sharedDeallocationQueue NS_RETURNS_RETAINED; - -- (void)drain; - -- (void)releaseObjectInBackground:(id __strong _Nullable * _Nonnull)objectPtr; - -@end - NS_ASSUME_NONNULL_END diff --git a/Source/ASRunLoopQueue.mm b/Source/ASRunLoopQueue.mm index fd896af89..8c917b07a 100644 --- a/Source/ASRunLoopQueue.mm +++ b/Source/ASRunLoopQueue.mm @@ -27,67 +27,6 @@ static void runLoopSourceCallback(void *info) { #endif } -#pragma mark - ASDeallocQueue - -@implementation ASDeallocQueue { - std::vector _queue; - AS::Mutex _lock; -} - -+ (ASDeallocQueue *)sharedDeallocationQueue NS_RETURNS_RETAINED -{ - static ASDeallocQueue *deallocQueue = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - deallocQueue = [[ASDeallocQueue alloc] init]; - }); - return deallocQueue; -} - -- (void)dealloc -{ - ASDisplayNodeFailAssert(@"Singleton should not dealloc."); -} - -- (void)releaseObjectInBackground:(id _Nullable __strong *)objectPtr -{ - NSParameterAssert(objectPtr != NULL); - - // Cast to CFType so we can manipulate retain count manually. - const auto cfPtr = (CFTypeRef *)(void *)objectPtr; - if (!cfPtr || !*cfPtr) { - return; - } - - _lock.lock(); - const auto isFirstEntry = _queue.empty(); - // Push the pointer into our queue and clear their pointer. - // This "steals" the +1 from ARC and nils their pointer so they can't - // access or release the object. - _queue.push_back(*cfPtr); - *cfPtr = NULL; - _lock.unlock(); - - if (isFirstEntry) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.100 * NSEC_PER_SEC)), dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ - [self drain]; - }); - } -} - -- (void)drain -{ - _lock.lock(); - const auto q = std::move(_queue); - _lock.unlock(); - for (CFTypeRef ref : q) { - // NOTE: Could check that retain count is 1 and retry later if not. - CFRelease(ref); - } -} - -@end - @implementation ASAbstractRunLoopQueue - (instancetype)init diff --git a/Source/Private/ASInternalHelpers.h b/Source/Private/ASInternalHelpers.h index 69a8eabc2..29fa26897 100644 --- a/Source/Private/ASInternalHelpers.h +++ b/Source/Private/ASInternalHelpers.h @@ -34,9 +34,6 @@ ASDK_EXTERN void ASPerformBlockOnMainThread(void (^block)(void)); /// Dispatches the given block to a background queue with priority of DISPATCH_QUEUE_PRIORITY_DEFAULT if not already run on a background queue ASDK_EXTERN void ASPerformBlockOnBackgroundThread(void (^block)(void)); // DISPATCH_QUEUE_PRIORITY_DEFAULT -/// For deallocation of objects on a background thread without GCD overhead / thread explosion -ASDK_EXTERN void ASPerformBackgroundDeallocation(id __strong _Nullable * _Nonnull object); - ASDK_EXTERN CGFloat ASScreenScale(void); ASDK_EXTERN CGSize ASFloorSizeValues(CGSize s); diff --git a/Source/Private/ASInternalHelpers.mm b/Source/Private/ASInternalHelpers.mm index 7811c3b6b..4d6e1fde8 100644 --- a/Source/Private/ASInternalHelpers.mm +++ b/Source/Private/ASInternalHelpers.mm @@ -140,11 +140,6 @@ void ASPerformBlockOnBackgroundThread(void (^block)(void)) } } -void ASPerformBackgroundDeallocation(id __strong _Nullable * _Nonnull object) -{ - [[ASDeallocQueue sharedDeallocationQueue] releaseObjectInBackground:object]; -} - Class _Nullable ASGetClassFromType(const char * _Nullable type) { // Class types all start with @" diff --git a/Tests/Common/ASTestCase.mm b/Tests/Common/ASTestCase.mm index 30b42bde4..81236d271 100644 --- a/Tests/Common/ASTestCase.mm +++ b/Tests/Common/ASTestCase.mm @@ -85,9 +85,6 @@ - (void)invokeTest @autoreleasepool { [super invokeTest]; } - - // Now that the autorelease pool is drained, drain the dealloc queue also. - [[ASDeallocQueue sharedDeallocationQueue] drain]; } + (ASTestCase *)currentTestCase diff --git a/docs/_docs/development/how-to-debug.md b/docs/_docs/development/how-to-debug.md index 8098cd4a8..75f8c2ec7 100644 --- a/docs/_docs/development/how-to-debug.md +++ b/docs/_docs/development/how-to-debug.md @@ -75,10 +75,6 @@ Here is the collection view's `dealloc` [self setAsyncDelegate:nil]; [self setAsyncDataSource:nil]; } - - // Data controller & range controller may own a ton of nodes, let's deallocate those off-main. - ASPerformBackgroundDeallocation(&_dataController); - ASPerformBackgroundDeallocation(&_rangeController); } ``` diff --git a/docs/_docs/development/node-lifecycle.md b/docs/_docs/development/node-lifecycle.md index 6484eeed5..3725b8770 100644 --- a/docs/_docs/development/node-lifecycle.md +++ b/docs/_docs/development/node-lifecycle.md @@ -31,12 +31,6 @@ For more details, look into ASCollectionLayout, ASCollectionGalleryLayoutDelegat As mentioned above, since ASCellNodes are not meant to be reused, they have a longer lifecycle compared to the view or layer that they encapsulate or their corresponding UICollectionViewCell or UITableViewCell. ASCellNodes are deallocated when they are no longer used and removed from the container node. This can occur after a batch update that includes a reload data or deletion, or after the container node is no longer used and thus released. -For the latter case in which the container node is no longer used and thus released, their cell nodes are not released immediately. That is because collection and table nodes might hold a large number of cell nodes and releasing all of them (and their subnodes, more on this later) at the same time can cause a noticeable delay. To avoid that, ASCollectionNode and ASTableNode release their instance variables, most noticeably an ASDataController instance, on a background thread using a helper called ASDeallocQueue. Since the ASDataController instance is the true owner of all cell nodes -- it has a strong reference to all of them --, all of those cell nodes are deallocated off the main thread as well. As a result, you can expect a delay from which a collection or table view is released until all the cell nodes are fully released and their memory reclaimed. It's important to remember this when debugging memory leaks: objects referenced by the data controller may take a bit to show as dealloced by Instruments. - -## ASDeallocQueue - -As mentioned above, ASDeallocQueue helps to defer the deallocation of objects given to it by increasing the reference count of each object -- essentially retaining them and acting as their sole owner -- and then release them later on a background thread. - # Nodes that are not managed by containers These are nodes that are often directly created by client code, such as direct and indirect subnodes of cell nodes. When a node is added to a parent node, the parent node retains it until it's removed from the parent node, or until the parent node is deallocated. As a result, if the subnode is not retained by client code in any other way or if it's not removed from the parent node, the subnode's lifecycle is tied to the parent node's lifecycle. In addition, since nodes often live in a hierarchy, the entire node hierarchy has the same lifecycle as the root node's. Lastly, if the root node is managed by a node container -- directly in the case of ASDKViewController and the like, or indirectly as a cell node of a collection or table node --, then the entire node hierarchy is managed by the node container. diff --git a/docs/_docs/development/threading.md b/docs/_docs/development/threading.md index fad2e994c..06ea796cd 100644 --- a/docs/_docs/development/threading.md +++ b/docs/_docs/development/threading.md @@ -250,25 +250,6 @@ Since this lock is also shared, it will prevent other routines from entering unt __Method 2__ -An alternative method is to manage the duration of the lock hold manually rather than using the runtime and scope. You must remember to unlock. - -``` -@implementation ASDeallocQueue { - ASDN::Mutex _lock; -} - -- (void)releaseObjectInBackground:(id _Nullable __strong *)objectPtr -{ - NSParameterAssert(objectPtr != NULL); // do I actually need to lock ? - // other conditions or non-shared tasks - _lock.lock(); - sharedObject.modify(newData); - _lock.unlock(); -} -``` - -__Method 3__ - `ASThread` provides `ASLockScopeSelf()`. This is a convenience over `ASLockScopeUnowned()`. This will unlock itself once the scope in which the lock was created is released. Only use this when you are confident that the lock should remain until scope is complete. You can only have one lock defined for `self`, thus it will block all other branches. ``` @@ -311,7 +292,6 @@ API | Description | `ASDisplayNodeAssertMainThread();` | Place this at the start of the every function definition that performs work synchronously on the main thread. `ASPerformBlockOnMainThread(block)` | If on main thread already, run block synchronously, otherwise use `dispatch_async(dispatch_get_main_queue(block))` `ASPerformMainThreadDeallocation(&object)` | Schedule async deallocation of UIKit components -`ASPerformBackgroundDeallocation(&object)` | Schedule async deallocation of __non-UIKit__ objects `ASPerformBlockOnBackgroundThread(block)` | Perform work on background From d608bb982924aafec0d76d88072578ee1bbfe530 Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Fri, 14 Aug 2020 11:37:44 -0700 Subject: [PATCH 56/56] Call will / did display node for ASTextNode. Fixes #1680 (#1893) --- Source/ASTextNode.mm | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index afffba507..8df442667 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -141,6 +141,8 @@ @interface ASTextNodeDrawParameter : NSObject { BOOL _opaque; CGRect _bounds; ASPrimitiveTraitCollection _traitCollection; + ASDisplayNodeContextModifier _willDisplayNodeContentWithRenderingContext; + ASDisplayNodeContextModifier _didDisplayNodeContentWithRenderingContext; } @end @@ -152,7 +154,9 @@ - (instancetype)initWithRendererAttributes:(ASTextKitAttributes)rendererAttribut contentScale:(CGFloat)contentScale opaque:(BOOL)opaque bounds:(CGRect)bounds - traitCollection: (ASPrimitiveTraitCollection)traitCollection + traitCollection:(ASPrimitiveTraitCollection)traitCollection +willDisplayNodeContentWithRenderingContext:(ASDisplayNodeContextModifier)willDisplayNodeContentWithRenderingContext + didDisplayNodeContentWithRenderingContext:(ASDisplayNodeContextModifier)didDisplayNodeContentWithRenderingContext { self = [super init]; if (self != nil) { @@ -163,6 +167,8 @@ - (instancetype)initWithRendererAttributes:(ASTextKitAttributes)rendererAttribut _opaque = opaque; _bounds = bounds; _traitCollection = traitCollection; + _willDisplayNodeContentWithRenderingContext = willDisplayNodeContentWithRenderingContext; + _didDisplayNodeContentWithRenderingContext = didDisplayNodeContentWithRenderingContext; } return self; } @@ -560,7 +566,9 @@ - (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer contentScale:_contentsScaleForDisplay opaque:self.isOpaque bounds:[self threadSafeBounds] - traitCollection:self.primitiveTraitCollection]; + traitCollection:self.primitiveTraitCollection + willDisplayNodeContentWithRenderingContext:self.willDisplayNodeContentWithRenderingContext + didDisplayNodeContentWithRenderingContext:self.didDisplayNodeContentWithRenderingContext]; } + (UIImage *)displayWithParameters:(id)parameters isCancelled:(NS_NOESCAPE asdisplaynode_iscancelled_block_t)isCancelled @@ -574,12 +582,19 @@ + (UIImage *)displayWithParameters:(id)parameters isCancelled:(NS_NOES UIColor *backgroundColor = drawParameter->_backgroundColor; UIEdgeInsets textContainerInsets = drawParameter ? drawParameter->_textContainerInsets : UIEdgeInsetsZero; ASTextKitRenderer *renderer = [drawParameter rendererForBounds:drawParameter->_bounds]; + ASDisplayNodeContextModifier willDisplayNodeContentWithRenderingContext = drawParameter->_willDisplayNodeContentWithRenderingContext; + ASDisplayNodeContextModifier didDisplayNodeContentWithRenderingContext = drawParameter->_didDisplayNodeContentWithRenderingContext; UIImage *result = ASGraphicsCreateImage(drawParameter->_traitCollection, CGSizeMake(drawParameter->_bounds.size.width, drawParameter->_bounds.size.height), drawParameter->_opaque, drawParameter->_contentScale, nil, nil, ^{ CGContextRef context = UIGraphicsGetCurrentContext(); ASDisplayNodeAssert(context, @"This is no good without a context."); CGContextSaveGState(context); + + if (context && willDisplayNodeContentWithRenderingContext) { + willDisplayNodeContentWithRenderingContext(context, drawParameter); + } + CGContextTranslateCTM(context, textContainerInsets.left, textContainerInsets.top); // Fill background @@ -591,6 +606,11 @@ + (UIImage *)displayWithParameters:(id)parameters isCancelled:(NS_NOES // Draw text [renderer drawInContext:context bounds:drawParameter->_bounds]; + + if (context && didDisplayNodeContentWithRenderingContext) { + didDisplayNodeContentWithRenderingContext(context, drawParameter); + } + CGContextRestoreGState(context); });