From a3763c9c910d8ffaca53975d23af14127a720963 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Tue, 9 Oct 2018 07:39:38 -0700 Subject: [PATCH 01/60] Fix crash if setting attributed text on multiple threads (#1141) --- CHANGELOG.md | 1 + Source/ASDisplayNode+Layout.mm | 5 +++ Source/ASTextNode.mm | 58 +++++++++++++++----------- Source/ASTextNode2.mm | 16 ++++--- Source/Private/ASDisplayNodeInternal.h | 9 ++++ 5 files changed, 60 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85b2f08433..6503a5085f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ - Remove display node's reliance on shared_ptr. [Adlai Holler](https://github.com/Adlai-Holler) - [ASCollectionView] Fix a crash that is caused by clearing a collection view's data while it's still being used. [Huy Nguyen](https://github.com/nguyenhuy) [#1154](https://github.com/TextureGroup/Texture/pull/1154) - Clean up timing of layout tree flattening/ copying of unflattened tree for Weaver. [Michael Zuccarino](https://github.com/mikezucc) [#1157](https://github.com/TextureGroup/Texture/pull/1157) +- Fix crash setting attributed text on multiple threads [Michael Schneider](https://github.com/maicki) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASDisplayNode+Layout.mm b/Source/ASDisplayNode+Layout.mm index 866f661875..bf85800aba 100644 --- a/Source/ASDisplayNode+Layout.mm +++ b/Source/ASDisplayNode+Layout.mm @@ -34,6 +34,11 @@ - (ASLayoutElementStyle *)style { ASDN::MutexLocker l(__instanceLock__); + return [self _locked_style]; +} + +- (ASLayoutElementStyle *)_locked_style +{ if (_style == nil) { _style = [[ASLayoutElementStyle alloc] init]; } diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index 1de1117dd9..7f0cc3f1a3 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -440,39 +440,46 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; if (attributedText == nil) { attributedText = [[NSAttributedString alloc] initWithString:@"" attributes:nil]; } - - // Don't hold textLock for too long. + { ASLockScopeSelf(); if (ASObjectIsEqual(attributedText, _attributedText)) { return; } - _attributedText = ASCleanseAttributedStringOfCoreTextAttributes(attributedText); -#if AS_TEXTNODE_RECORD_ATTRIBUTED_STRINGS - [ASTextNode _registerAttributedText:_attributedText]; -#endif - } - - // Since truncation text matches style of attributedText, invalidate it now. - [self _invalidateTruncationText]; - - NSUInteger length = _attributedText.length; - if (length > 0) { - self.style.ascender = [[self class] ascenderWithAttributedString:_attributedText]; - self.style.descender = [[_attributedText attribute:NSFontAttributeName atIndex:length - 1 effectiveRange:NULL] descender]; - } + NSAttributedString *cleanedAttributedString = ASCleanseAttributedStringOfCoreTextAttributes(attributedText); + // Invalidating the truncation text must be done while we still hold the lock. Because after we release it, + // another thread may set a new truncation text that will then be cleared by this thread, other may draw + // this soon-to-be-invalidated text. + [self _locked_invalidateTruncationText]; + + NSUInteger length = cleanedAttributedString.length; + if (length > 0) { + // Updating ascender and descender in one transaction while holding the lock. + ASLayoutElementStyle *style = [self _locked_style]; + style.ascender = [[self class] ascenderWithAttributedString:cleanedAttributedString]; + style.descender = [[attributedText attribute:NSFontAttributeName atIndex:cleanedAttributedString.length - 1 effectiveRange:NULL] descender]; + } + + // Update attributed text with cleaned attributed string + _attributedText = cleanedAttributedString; + } + // Tell the display node superclasses that the cached layout is incorrect now [self setNeedsLayout]; // Force display to create renderer with new size and redisplay with new string [self setNeedsDisplay]; - // Accessiblity - self.accessibilityLabel = _attributedText.string; - self.isAccessibilityElement = (length != 0); // We're an accessibility element by default if there is a string. + let currentAttributedText = self.attributedText; // Grab attributed string again in case it changed in the meantime + self.accessibilityLabel = currentAttributedText.string; + self.isAccessibilityElement = (currentAttributedText.length != 0); // We're an accessibility element by default if there is a string. + +#if AS_TEXTNODE_RECORD_ATTRIBUTED_STRINGS + [ASTextNode _registerAttributedText:_attributedText]; +#endif } #pragma mark - Text Layout @@ -1166,6 +1173,7 @@ static NSAttributedString *DefaultTruncationAttributedString() { if (ASLockedSelfCompareAssignCopy(_truncationAttributedText, truncationAttributedText)) { [self _invalidateTruncationText]; + [self setNeedsDisplay]; } } @@ -1173,6 +1181,7 @@ static NSAttributedString *DefaultTruncationAttributedString() { if (ASLockedSelfCompareAssignCopy(_additionalTruncationMessage, additionalTruncationMessage)) { [self _invalidateTruncationText]; + [self setNeedsDisplay]; } } @@ -1231,12 +1240,13 @@ static NSAttributedString *DefaultTruncationAttributedString() - (void)_invalidateTruncationText { - { - ASLockScopeSelf(); - _composedTruncationText = nil; - } + ASLockScopeSelf(); + [self _locked_invalidateTruncationText]; +} - [self setNeedsDisplay]; +- (void)_locked_invalidateTruncationText +{ + _composedTruncationText = nil; } /** diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index aaa215e672..1cd9444c4e 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -280,12 +280,13 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; } // Since truncation text matches style of attributedText, invalidate it now. - [self _invalidateTruncationText]; - + [self _locked_invalidateTruncationText]; + NSUInteger length = attributedText.length; if (length > 0) { - self.style.ascender = [[self class] ascenderWithAttributedString:attributedText]; - self.style.descender = [[attributedText attribute:NSFontAttributeName atIndex:attributedText.length - 1 effectiveRange:NULL] descender]; + ASLayoutElementStyle *style = [self _locked_style]; + style.ascender = [[self class] ascenderWithAttributedString:attributedText]; + style.descender = [[attributedText attribute:NSFontAttributeName atIndex:attributedText.length - 1 effectiveRange:NULL] descender]; } // Tell the display node superclasses that the cached layout is incorrect now @@ -1061,10 +1062,15 @@ static NSAttributedString *DefaultTruncationAttributedString() - (void)_invalidateTruncationText { ASLockScopeSelf(); - _textContainer.truncationToken = nil; + [self _locked_invalidateTruncationText]; [self setNeedsDisplay]; } +- (void)_locked_invalidateTruncationText +{ + _textContainer.truncationToken = nil; +} + /** * @return the additional truncation message range within the as-rendered text. * Must be called from main thread diff --git a/Source/Private/ASDisplayNodeInternal.h b/Source/Private/ASDisplayNodeInternal.h index 5f9092ffaa..1e907d3e7f 100644 --- a/Source/Private/ASDisplayNodeInternal.h +++ b/Source/Private/ASDisplayNodeInternal.h @@ -386,4 +386,13 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest @end +@interface ASDisplayNode (ASLayoutElementPrivate) + +/** + * Returns the internal style object or creates a new if no exists. Need to be called with lock held. + */ +- (ASLayoutElementStyle *)_locked_style; + +@end + NS_ASSUME_NONNULL_END From affddb0e968b17d0cb3a206e7ddde7ad94ecc46b Mon Sep 17 00:00:00 2001 From: Max Wang Date: Wed, 10 Oct 2018 10:46:33 -0700 Subject: [PATCH 02/60] Set default tuning params (#1158) * 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. * Only test when photo library is enabled. It will fail to build if photo library is disabled cause the test is depending on it. * Add ChangeLog. * set default tuning parameters for collection/table node * add change log * Move to framework private. * Apply to tableNode * trigger ci * fix directory * fix file link --- AsyncDisplayKit.xcodeproj/project.pbxproj | 36 +------- CHANGELOG.md | 1 + Source/ASCollectionNode.mm | 11 +-- Source/ASTableNode.mm | 11 +-- Source/Details/ASAbstractLayoutController.mm | 91 ++++++++++--------- .../ASCollectionViewLayoutController.m | 1 - ...bstractLayoutController+FrameworkPrivate.h | 21 +++++ 7 files changed, 84 insertions(+), 88 deletions(-) create mode 100644 Source/Private/ASAbstractLayoutController+FrameworkPrivate.h diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 305b392e1c..5d2280c29e 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -314,6 +314,7 @@ B350625E1B0111780018CF92 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943121A1575630030A7D0 /* AssetsLibrary.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; BB5FC3CE1F9BA689007F191E /* ASNavigationControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BB5FC3CD1F9BA688007F191E /* ASNavigationControllerTests.m */; }; BB5FC3D11F9C9389007F191E /* ASTabBarControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BB5FC3D01F9C9389007F191E /* ASTabBarControllerTests.m */; }; + C018DF21216BF26700181FDA /* ASAbstractLayoutController+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = C018DF20216BF26600181FDA /* ASAbstractLayoutController+FrameworkPrivate.h */; }; C057D9BD20B5453D00FC9112 /* ASTextNode2SnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.m */; }; C78F7E2B1BF7809800CDEAFC /* ASTableNode.h in Headers */ = {isa = PBXBuildFile; fileRef = B0F880581BEAEC7500D17647 /* ASTableNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; CC034A091E60BEB400626263 /* ASDisplayNode+Convenience.h in Headers */ = {isa = PBXBuildFile; fileRef = CC034A071E60BEB400626263 /* ASDisplayNode+Convenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -827,6 +828,7 @@ BB5FC3CD1F9BA688007F191E /* ASNavigationControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASNavigationControllerTests.m; sourceTree = ""; }; BB5FC3D01F9C9389007F191E /* ASTabBarControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASTabBarControllerTests.m; sourceTree = ""; }; BDC2D162BD55A807C1475DA5 /* Pods-AsyncDisplayKitTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.profile.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.profile.xcconfig"; sourceTree = ""; }; + C018DF20216BF26600181FDA /* ASAbstractLayoutController+FrameworkPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASAbstractLayoutController+FrameworkPrivate.h"; sourceTree = ""; }; C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASTextNode2SnapshotTests.m; sourceTree = ""; }; CC034A071E60BEB400626263 /* ASDisplayNode+Convenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+Convenience.h"; sourceTree = ""; }; CC034A081E60BEB400626263 /* ASDisplayNode+Convenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASDisplayNode+Convenience.m"; sourceTree = ""; }; @@ -1457,6 +1459,7 @@ 058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */, 058D0A04195D050800B7D73C /* _ASCoreAnimationExtras.mm */, AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */, + C018DF20216BF26600181FDA /* ASAbstractLayoutController+FrameworkPrivate.h */, AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.mm */, 058D0A05195D050800B7D73C /* _ASPendingState.h */, 058D0A06195D050800B7D73C /* _ASPendingState.mm */, @@ -1878,6 +1881,7 @@ CC0F88621E4281E200576FED /* ASSectionController.h in Headers */, CCB1F95C1EFB6350009C7475 /* ASSignpost.h in Headers */, A2763D7A1CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.h in Headers */, + C018DF21216BF26700181FDA /* ASAbstractLayoutController+FrameworkPrivate.h in Headers */, 34EFC7611B701C9C00AD841F /* ASBackgroundLayoutSpec.h in Headers */, B35062591B010F070018CF92 /* ASBaseDefines.h in Headers */, B35062131B010EFD0018CF92 /* ASBasicImageDownloader.h in Headers */, @@ -2090,8 +2094,6 @@ 058D09B8195D04C000B7D73C /* Sources */, 058D09B9195D04C000B7D73C /* Frameworks */, 058D09BA195D04C000B7D73C /* Resources */, - 3B9D88CDF51B429C8409E4B6 /* [CP] Copy Pods Resources */, - B130AB1AC0A1E5162E211C19 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -2211,36 +2213,6 @@ 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; }; - 3B9D88CDF51B429C8409E4B6 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - B130AB1AC0A1E5162E211C19 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/CHANGELOG.md b/CHANGELOG.md index 6503a5085f..629b9c1c44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master * Add your own contributions to the next release on the line below this with your name. +- [ASCollectionViewLayoutController] Set default tuning parameters before view is loaded. [Max Wang](https://github.com/wsdwsd0829). [#1158](https://github.com/TextureGroup/Texture/pull/1158) - [ASPhotosFrameworkImageRequestTests] Guard photo library with macro for tests. [Max Wang](https://github.com/wsdwsd0829). [#1147](https://github.com/TextureGroup/Texture/pull/1147) - [ASDisplayNode] Do not cancel display when in exit hierarchy but let interface state changing to handle it. [Max Wang](https://github.com/wsdwsd0829). [#1110](https://github.com/TextureGroup/Texture/pull/1110) - [Breaking][ASDisplayNode] Make interface state delegate protocol required. [Max Wang](https://github.com/wsdwsd0829). [#1112](https://github.com/TextureGroup/Texture/pull/1112) diff --git a/Source/ASCollectionNode.mm b/Source/ASCollectionNode.mm index ba31b41ca2..a28e0adeae 100644 --- a/Source/ASCollectionNode.mm +++ b/Source/ASCollectionNode.mm @@ -27,6 +27,7 @@ #import #import #import +#import #pragma mark - _ASCollectionPendingState @@ -62,7 +63,7 @@ self = [super init]; if (self) { _rangeMode = ASLayoutRangeModeUnspecified; - _tuningParameters = std::vector> (ASLayoutRangeModeCount, std::vector (ASLayoutRangeTypeCount, ASRangeTuningParametersZero)); + _tuningParameters = [ASAbstractLayoutController defaultTuningParameters]; _allowsSelection = YES; _allowsMultipleSelection = NO; _inverted = NO; @@ -220,11 +221,9 @@ let tuningParametersVectorRangeModeSize = tuningparametersRangeModeVector.size(); for (NSInteger rangeType = 0; rangeType < tuningParametersVectorRangeModeSize; rangeType++) { ASRangeTuningParameters tuningParameters = tuningparametersRangeModeVector[rangeType]; - if (!ASRangeTuningParametersEqualToRangeTuningParameters(tuningParameters, ASRangeTuningParametersZero)) { - [_rangeController setTuningParameters:tuningParameters - forRangeMode:(ASLayoutRangeMode)rangeMode - rangeType:(ASLayoutRangeType)rangeType]; - } + [_rangeController setTuningParameters:tuningParameters + forRangeMode:(ASLayoutRangeMode)rangeMode + rangeType:(ASLayoutRangeType)rangeType]; } } diff --git a/Source/ASTableNode.mm b/Source/ASTableNode.mm index 4ac85989c6..24f7ddf112 100644 --- a/Source/ASTableNode.mm +++ b/Source/ASTableNode.mm @@ -22,6 +22,7 @@ #import #import #import +#import #pragma mark - _ASTablePendingState @@ -54,7 +55,7 @@ self = [super init]; if (self) { _rangeMode = ASLayoutRangeModeUnspecified; - _tuningParameters = std::vector> (ASLayoutRangeModeCount, std::vector (ASLayoutRangeTypeCount, ASRangeTuningParametersZero)); + _tuningParameters = [ASAbstractLayoutController defaultTuningParameters]; _allowsSelection = YES; _allowsSelectionDuringEditing = NO; _allowsMultipleSelection = NO; @@ -171,11 +172,9 @@ let tuningParametersVectorRangeModeSize = tuningparametersRangeModeVector.size(); for (NSInteger rangeType = 0; rangeType < tuningParametersVectorRangeModeSize; rangeType++) { ASRangeTuningParameters tuningParameters = tuningparametersRangeModeVector[rangeType]; - if (!ASRangeTuningParametersEqualToRangeTuningParameters(tuningParameters, ASRangeTuningParametersZero)) { - [_rangeController setTuningParameters:tuningParameters - forRangeMode:(ASLayoutRangeMode)rangeMode - rangeType:(ASLayoutRangeType)rangeType]; - } + [_rangeController setTuningParameters:tuningParameters + forRangeMode:(ASLayoutRangeMode)rangeMode + rangeType:(ASLayoutRangeType)rangeType]; } } diff --git a/Source/Details/ASAbstractLayoutController.mm b/Source/Details/ASAbstractLayoutController.mm index f63a3ca86c..b8947ae49b 100644 --- a/Source/Details/ASAbstractLayoutController.mm +++ b/Source/Details/ASAbstractLayoutController.mm @@ -8,11 +8,9 @@ // #import - +#import #import -#include - ASRangeTuningParameters const ASRangeTuningParametersZero = {}; BOOL ASRangeTuningParametersEqualToRangeTuningParameters(ASRangeTuningParameters lhs, ASRangeTuningParameters rhs) @@ -89,6 +87,52 @@ CGRect CGRectExpandToRangeWithScrollableDirections(CGRect rect, ASRangeTuningPar @implementation ASAbstractLayoutController ++ (std::vector>)defaultTuningParameters +{ + var tuningParameters = std::vector> (ASLayoutRangeModeCount, std::vector (ASLayoutRangeTypeCount)); + + tuningParameters[ASLayoutRangeModeFull][ASLayoutRangeTypeDisplay] = { + .leadingBufferScreenfuls = 1.0, + .trailingBufferScreenfuls = 0.5 + }; + + tuningParameters[ASLayoutRangeModeFull][ASLayoutRangeTypePreload] = { + .leadingBufferScreenfuls = 2.5, + .trailingBufferScreenfuls = 1.5 + }; + + tuningParameters[ASLayoutRangeModeMinimum][ASLayoutRangeTypeDisplay] = { + .leadingBufferScreenfuls = 0.25, + .trailingBufferScreenfuls = 0.25 + }; + tuningParameters[ASLayoutRangeModeMinimum][ASLayoutRangeTypePreload] = { + .leadingBufferScreenfuls = 0.5, + .trailingBufferScreenfuls = 0.25 + }; + + tuningParameters[ASLayoutRangeModeVisibleOnly][ASLayoutRangeTypeDisplay] = { + .leadingBufferScreenfuls = 0, + .trailingBufferScreenfuls = 0 + }; + tuningParameters[ASLayoutRangeModeVisibleOnly][ASLayoutRangeTypePreload] = { + .leadingBufferScreenfuls = 0, + .trailingBufferScreenfuls = 0 + }; + + // The Low Memory range mode has special handling. Because a zero range still includes the visible area / bounds, + // in order to implement the behavior of releasing all graphics memory (backing stores), ASRangeController must check + // for this range mode and use an empty set for displayIndexPaths rather than querying the ASLayoutController for the indexPaths. + tuningParameters[ASLayoutRangeModeLowMemory][ASLayoutRangeTypeDisplay] = { + .leadingBufferScreenfuls = 0, + .trailingBufferScreenfuls = 0 + }; + tuningParameters[ASLayoutRangeModeLowMemory][ASLayoutRangeTypePreload] = { + .leadingBufferScreenfuls = 0, + .trailingBufferScreenfuls = 0 + }; + return tuningParameters; +} + - (instancetype)init { if (!(self = [super init])) { @@ -96,46 +140,7 @@ CGRect CGRectExpandToRangeWithScrollableDirections(CGRect rect, ASRangeTuningPar } ASDisplayNodeAssert(self.class != [ASAbstractLayoutController class], @"Should never create instances of abstract class ASAbstractLayoutController."); - _tuningParameters = std::vector> (ASLayoutRangeModeCount, std::vector (ASLayoutRangeTypeCount)); - - _tuningParameters[ASLayoutRangeModeFull][ASLayoutRangeTypeDisplay] = { - .leadingBufferScreenfuls = 1.0, - .trailingBufferScreenfuls = 0.5 - }; - _tuningParameters[ASLayoutRangeModeFull][ASLayoutRangeTypePreload] = { - .leadingBufferScreenfuls = 2.5, - .trailingBufferScreenfuls = 1.5 - }; - - _tuningParameters[ASLayoutRangeModeMinimum][ASLayoutRangeTypeDisplay] = { - .leadingBufferScreenfuls = 0.25, - .trailingBufferScreenfuls = 0.25 - }; - _tuningParameters[ASLayoutRangeModeMinimum][ASLayoutRangeTypePreload] = { - .leadingBufferScreenfuls = 0.5, - .trailingBufferScreenfuls = 0.25 - }; - - _tuningParameters[ASLayoutRangeModeVisibleOnly][ASLayoutRangeTypeDisplay] = { - .leadingBufferScreenfuls = 0, - .trailingBufferScreenfuls = 0 - }; - _tuningParameters[ASLayoutRangeModeVisibleOnly][ASLayoutRangeTypePreload] = { - .leadingBufferScreenfuls = 0, - .trailingBufferScreenfuls = 0 - }; - - // The Low Memory range mode has special handling. Because a zero range still includes the visible area / bounds, - // in order to implement the behavior of releasing all graphics memory (backing stores), ASRangeController must check - // for this range mode and use an empty set for displayIndexPaths rather than querying the ASLayoutController for the indexPaths. - _tuningParameters[ASLayoutRangeModeLowMemory][ASLayoutRangeTypeDisplay] = { - .leadingBufferScreenfuls = 0, - .trailingBufferScreenfuls = 0 - }; - _tuningParameters[ASLayoutRangeModeLowMemory][ASLayoutRangeTypePreload] = { - .leadingBufferScreenfuls = 0, - .trailingBufferScreenfuls = 0 - }; + _tuningParameters = [[self class] defaultTuningParameters]; return self; } diff --git a/Source/Details/ASCollectionViewLayoutController.m b/Source/Details/ASCollectionViewLayoutController.m index 46c869b8a9..275fd23f6b 100644 --- a/Source/Details/ASCollectionViewLayoutController.m +++ b/Source/Details/ASCollectionViewLayoutController.m @@ -21,7 +21,6 @@ struct ASRangeGeometry { }; typedef struct ASRangeGeometry ASRangeGeometry; - #pragma mark - #pragma mark ASCollectionViewLayoutController diff --git a/Source/Private/ASAbstractLayoutController+FrameworkPrivate.h b/Source/Private/ASAbstractLayoutController+FrameworkPrivate.h new file mode 100644 index 0000000000..f836fa0b84 --- /dev/null +++ b/Source/Private/ASAbstractLayoutController+FrameworkPrivate.h @@ -0,0 +1,21 @@ +// +// ASAbstractLayoutController+FrameworkPrivate.h +// Texture +// +// 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 +// + +// +// The following methods are ONLY for use by _ASDisplayLayer, _ASDisplayView, and ASDisplayNode. +// These methods must never be called or overridden by other classes. +// + +#include + +@interface ASAbstractLayoutController (FrameworkPrivate) + ++ (std::vector>)defaultTuningParameters; + +@end From 70329f5730cda13ad5b01388b881dad28646c478 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Wed, 10 Oct 2018 21:40:22 -0700 Subject: [PATCH 03/60] ASTextNode2 to ignore certain text alignments while calculating intrinsic size (#1166) ASTextNode2 uses ASTextLayout to calculate its layout and bounding rect. When the constrained width that is used for layout calculation is inf/max (e.g when the node is inside a horizontal stack), ASTextLayout doesn't ignore its right/center/natural text alignment but takes it into account. That results in an unreasonable size (and position). Fix by detecting when the node is calculating intrinsic size and force its layout alignment to be left. Other alignments should still work when the max width is finite/reasonable. --- CHANGELOG.md | 1 + Source/ASTextNode2.mm | 43 ++++++++++++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 629b9c1c44..0ecb119f48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ - [ASCollectionView] Fix a crash that is caused by clearing a collection view's data while it's still being used. [Huy Nguyen](https://github.com/nguyenhuy) [#1154](https://github.com/TextureGroup/Texture/pull/1154) - Clean up timing of layout tree flattening/ copying of unflattened tree for Weaver. [Michael Zuccarino](https://github.com/mikezucc) [#1157](https://github.com/TextureGroup/Texture/pull/1157) - Fix crash setting attributed text on multiple threads [Michael Schneider](https://github.com/maicki) +- [ASTextNode2] Ignore certain text alignments while calculating intrinsic size [Huy Nguyen](https://github.com/nguyenhuy) [#1166](https://github.com/TextureGroup/Texture/pull/1166) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 1cd9444c4e..194921bbe7 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -234,9 +234,17 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; _textContainer.size = constrainedSize; [self _ensureTruncationText]; - + + // If the constrained size has a max/inf value on the text's forward direction, the text node is calculating its intrinsic size. + BOOL isCalculatingIntrinsicSize; + if (_textContainer.isVerticalForm) { + isCalculatingIntrinsicSize = (_textContainer.size.height >= ASTextContainerMaxSize.height); + } else { + isCalculatingIntrinsicSize = (_textContainer.size.width >= ASTextContainerMaxSize.width); + } + NSMutableAttributedString *mutableText = [_attributedText mutableCopy]; - [self prepareAttributedString:mutableText]; + [self prepareAttributedString:mutableText isForIntrinsicSize:isCalculatingIntrinsicSize]; ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:_textContainer text:mutableText]; return layout.textBoundingSize; @@ -321,18 +329,31 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; return _textContainer.exclusionPaths; } -- (void)prepareAttributedString:(NSMutableAttributedString *)attributedString +- (void)prepareAttributedString:(NSMutableAttributedString *)attributedString isForIntrinsicSize:(BOOL)isForIntrinsicSize { ASLockScopeSelf(); - - // Apply paragraph style if needed + + // Apply/Fix paragraph style if needed [attributedString enumerateAttribute:NSParagraphStyleAttributeName inRange:NSMakeRange(0, attributedString.length) options:kNilOptions usingBlock:^(NSParagraphStyle *style, NSRange range, BOOL * _Nonnull stop) { - if (style == nil || style.lineBreakMode == _truncationMode) { + + const BOOL applyTruncationMode = (style != nil && style.lineBreakMode != _truncationMode); + // Only "left" and "justified" alignments are supported while calculating intrinsic size. + // Other alignments like "right", "center" and "natural" cause the size to be bigger than needed and thus should be ignored/overridden. + const BOOL forceLeftAlignment = (style != nil + && isForIntrinsicSize + && style.alignment != NSTextAlignmentLeft + && style.alignment != NSTextAlignmentJustified); + if (!applyTruncationMode && !forceLeftAlignment) { return; } - - NSMutableParagraphStyle *paragraphStyle = [style mutableCopy] ?: [[NSMutableParagraphStyle alloc] init]; - paragraphStyle.lineBreakMode = _truncationMode; + + NSMutableParagraphStyle *paragraphStyle = [style mutableCopy]; + if (applyTruncationMode) { + paragraphStyle.lineBreakMode = _truncationMode; + } + if (forceLeftAlignment) { + paragraphStyle.alignment = NSTextAlignmentLeft; + } [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range]; }]; @@ -364,8 +385,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; copiedContainer.size = self.bounds.size; [copiedContainer makeImmutable]; NSMutableAttributedString *mutableText = [_attributedText mutableCopy] ?: [[NSMutableAttributedString alloc] init]; - - [self prepareAttributedString:mutableText]; + + [self prepareAttributedString:mutableText isForIntrinsicSize:NO]; return @{ @"container": copiedContainer, From 17f24aad3d348f84250af2345eac99d73e698253 Mon Sep 17 00:00:00 2001 From: Max Wang Date: Thu, 11 Oct 2018 12:01:37 -0700 Subject: [PATCH 04/60] Mismatch name experimental features (#1159) * 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 mismatch of name array and experimental features * add more tests * remove nslog * add change log * fix tests --- CHANGELOG.md | 1 + Source/ASExperimentalFeatures.m | 1 - Tests/ASConfigurationTests.m | 63 +++++++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ecb119f48..b7e0430498 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master * Add your own contributions to the next release on the line below this with your name. +- [ASExperimentalFeatures.m] Fix mismatch name in experimental features. [Max Wang](https://github.com/wsdwsd0829). [#1159](https://github.com/TextureGroup/Texture/pull/1159) - [ASCollectionViewLayoutController] Set default tuning parameters before view is loaded. [Max Wang](https://github.com/wsdwsd0829). [#1158](https://github.com/TextureGroup/Texture/pull/1158) - [ASPhotosFrameworkImageRequestTests] Guard photo library with macro for tests. [Max Wang](https://github.com/wsdwsd0829). [#1147](https://github.com/TextureGroup/Texture/pull/1147) - [ASDisplayNode] Do not cancel display when in exit hierarchy but let interface state changing to handle it. [Max Wang](https://github.com/wsdwsd0829). [#1110](https://github.com/TextureGroup/Texture/pull/1110) diff --git a/Source/ASExperimentalFeatures.m b/Source/ASExperimentalFeatures.m index 73abea48b6..01eaad0e84 100644 --- a/Source/ASExperimentalFeatures.m +++ b/Source/ASExperimentalFeatures.m @@ -18,7 +18,6 @@ NSArray *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags @"exp_unfair_lock", @"exp_infer_layer_defaults", @"exp_network_image_queue", - @"exp_dealloc_queue_v2", @"exp_collection_teardown", @"exp_framesetter_cache", @"exp_clear_data_during_deallocation"])); diff --git a/Tests/ASConfigurationTests.m b/Tests/ASConfigurationTests.m index c16cb79e0f..d2f2b5a6cd 100644 --- a/Tests/ASConfigurationTests.m +++ b/Tests/ASConfigurationTests.m @@ -12,6 +12,18 @@ #import "ASConfigurationDelegate.h" #import "ASConfigurationInternal.h" +static ASExperimentalFeatures features[] = { + ASExperimentalGraphicsContexts, + ASExperimentalTextNode, + ASExperimentalInterfaceStateCoalescing, + ASExperimentalUnfairLock, + ASExperimentalLayerDefaults, + ASExperimentalNetworkImageQueue, + ASExperimentalCollectionTeardown, + ASExperimentalFramesetterCache, + ASExperimentalClearDataDuringDeallocation +}; + @interface ASConfigurationTests : ASTestCase @end @@ -20,6 +32,28 @@ void (^onActivate)(ASConfigurationTests *self, ASExperimentalFeatures feature); } ++ (NSArray *)names { + return @[ + @"exp_graphics_contexts", + @"exp_text_node", + @"exp_interface_state_coalesce", + @"exp_unfair_lock", + @"exp_infer_layer_defaults", + @"exp_network_image_queue", + @"exp_collection_teardown", + @"exp_framesetter_cache", + @"exp_clear_data_during_deallocation" + ]; +} + +- (ASExperimentalFeatures)allFeatures { + ASExperimentalFeatures allFeatures = 0; + for (int i = 0; i < sizeof(features)/sizeof(ASExperimentalFeatures); i++) { + allFeatures |= features[i]; + } + return allFeatures; +} + - (void)testExperimentalFeatureConfig { // Set the config @@ -55,17 +89,34 @@ - (void)testMappingNamesToFlags { // Throw in a bad bit. - ASExperimentalFeatures features = ASExperimentalTextNode | ASExperimentalGraphicsContexts | (1 << 22); - NSArray *expectedNames = @[ @"exp_graphics_contexts", @"exp_text_node" ]; - XCTAssertEqualObjects(expectedNames, ASExperimentalFeaturesGetNames(features)); + ASExperimentalFeatures allFeatures = [self allFeatures]; + ASExperimentalFeatures featuresWithBadBit = allFeatures | (1 << 22); + NSArray *expectedNames = [ASConfigurationTests names]; + XCTAssertEqualObjects(expectedNames, ASExperimentalFeaturesGetNames(featuresWithBadBit)); } - (void)testMappingFlagsFromNames { // Throw in a bad name. - NSArray *names = @[ @"exp_text_node", @"exp_graphics_contexts", @"__invalid_name" ]; - ASExperimentalFeatures expected = ASExperimentalGraphicsContexts | ASExperimentalTextNode; - XCTAssertEqual(expected, ASExperimentalFeaturesFromArray(names)); + NSMutableArray *allNames = [[NSMutableArray alloc] initWithArray:[ASConfigurationTests names]]; + [allNames addObject:@"__invalid_name"]; + ASExperimentalFeatures expected = [self allFeatures]; + XCTAssertEqual(expected, ASExperimentalFeaturesFromArray(allNames)); +} + +- (void)testFlagMatchName +{ + NSArray *names = [ASConfigurationTests names]; + for (NSInteger i = 0; i < names.count; i++) { + XCTAssertEqual(features[i], ASExperimentalFeaturesFromArray(@[names[i]])); + } +} + +- (void)testNameMatchFlag { + NSArray *names = [ASConfigurationTests names]; + for (NSInteger i = 0; i < names.count; i++) { + XCTAssertEqualObjects(@[names[i]], ASExperimentalFeaturesGetNames(features[i])); + } } @end From 7cdfacca4a989e795bd2019e0825b819cf8b74a7 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Sun, 14 Oct 2018 09:16:47 -0700 Subject: [PATCH 05/60] Update documentation of ASNetworkImageNodeDelegate #trivial (#1163) `-imageNodeDidStartFetchingData:` and `-imageNodeDidFinishDecoding:` are always called on main thread, and the documentation should reflect that. --- Source/ASNetworkImageNode.h | 20 +++++++++++--------- Source/ASNetworkImageNode.mm | 2 ++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Source/ASNetworkImageNode.h b/Source/ASNetworkImageNode.h index f77a9a59d1..576cbb94b8 100644 --- a/Source/ASNetworkImageNode.h +++ b/Source/ASNetworkImageNode.h @@ -145,6 +145,15 @@ NS_ASSUME_NONNULL_BEGIN @protocol ASNetworkImageNodeDelegate @optional +/** + * Notification that the image node started to load + * + * @param imageNode The sender. + * + * @discussion Called on the main thread. + */ +- (void)imageNodeDidStartFetchingData:(ASNetworkImageNode *)imageNode; + /** * Notification that the image node finished downloading an image, with additional info. * If implemented, this method will be called instead of `imageNode:didLoadImage:`. @@ -167,15 +176,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)imageNode:(ASNetworkImageNode *)imageNode didLoadImage:(UIImage *)image; -/** - * Notification that the image node started to load - * - * @param imageNode The sender. - * - * @discussion Called on a background queue. - */ -- (void)imageNodeDidStartFetchingData:(ASNetworkImageNode *)imageNode; - /** * Notification that the image node failed to download the image. * @@ -190,6 +190,8 @@ NS_ASSUME_NONNULL_BEGIN * Notification that the image node finished decoding an image. * * @param imageNode The sender. + * + * @discussion Called on the main thread. */ - (void)imageNodeDidFinishDecoding:(ASNetworkImageNode *)imageNode; diff --git a/Source/ASNetworkImageNode.mm b/Source/ASNetworkImageNode.mm index ce864647af..ea863c1ee1 100644 --- a/Source/ASNetworkImageNode.mm +++ b/Source/ASNetworkImageNode.mm @@ -614,6 +614,8 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); - (void)_lazilyLoadImageIfNecessary { + ASDisplayNodeAssertMainThread(); + [self lock]; __weak id delegate = _delegate; BOOL delegateDidStartFetchingData = _delegateFlags.delegateDidStartFetchingData; From 393ca818b0f101492a81492d0cf10cd167fb6ec4 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Tue, 16 Oct 2018 10:04:58 -0700 Subject: [PATCH 06/60] Update Jekyll to 3.6.3 (#1165) Seeing a warning from GitHub that suggests to update Jekyll because of this vulnerability: > Jekyll through 3.6.2, 3.7.x through 3.7.3, and 3.8.x through 3.8.3 allows attackers to access arbitrary files by specifying a symlink in the "include" key in the "_config.yml" file. [CVE-2018-17567](https://nvd.nist.gov/vuln/detail/CVE-2018-17567) --- docs/Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Gemfile b/docs/Gemfile index 99e72d8322..dec8af5008 100755 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -2,4 +2,4 @@ source 'https://rubygems.org' gem 'github-pages' gem 'rouge', '~>1.7' -gem 'jekyll', '~>3.2.0' +gem 'jekyll', '~>3.6.3' From 072df8962c8a92bdd37a381f51dda3eb6cd9ed86 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Wed, 17 Oct 2018 08:02:10 -0700 Subject: [PATCH 07/60] Fix mismatch in UIAccessibilityAction selector method (#1169) * Fix mismatch in UIAccessibilityAction selector method * Update changelog --- CHANGELOG.md | 1 + Source/ASDisplayNode+Beta.h | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7e0430498..d85256b12b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ - Clean up timing of layout tree flattening/ copying of unflattened tree for Weaver. [Michael Zuccarino](https://github.com/mikezucc) [#1157](https://github.com/TextureGroup/Texture/pull/1157) - Fix crash setting attributed text on multiple threads [Michael Schneider](https://github.com/maicki) - [ASTextNode2] Ignore certain text alignments while calculating intrinsic size [Huy Nguyen](https://github.com/nguyenhuy) [#1166](https://github.com/TextureGroup/Texture/pull/1166) +- Fix mismatch in UIAccessibilityAction selector method [Michael Schneider](https://github.com/maicki) [#1169](https://github.com/TextureGroup/Texture/pull/1169) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASDisplayNode+Beta.h b/Source/ASDisplayNode+Beta.h index e140721cc6..b288372792 100644 --- a/Source/ASDisplayNode+Beta.h +++ b/Source/ASDisplayNode+Beta.h @@ -99,8 +99,11 @@ typedef struct { /** * @abstract Invoked when a user performs a custom action on an accessible node. Nodes that are children of accessibility containers, have * an accessibity label and have an interactive UIAccessibilityTrait will automatically receive custom-action handling. + * + * @return Return a boolean value that determine whether to propagate through the responder chain. + * To halt propagation, return YES; otherwise, return NO. */ -- (void)performAccessibilityCustomAction:(UIAccessibilityCustomAction *)action; +- (BOOL)performAccessibilityCustomAction:(UIAccessibilityCustomAction *)action; /** * @abstract Currently used by ASNetworkImageNode and ASMultiplexImageNode to allow their placeholders to stay if they are loading an image from the network. From eab0fc200bf9c4188fd6442a82dc5f5dcce7a643 Mon Sep 17 00:00:00 2001 From: Andrew Yates Date: Wed, 17 Oct 2018 08:02:47 -0700 Subject: [PATCH 08/60] Migrate placeholder example project from 1.0 to 2.x (#1164) --- examples_extra/Placeholders/Sample/PostNode.m | 4 ++-- examples_extra/Placeholders/Sample/ViewController.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples_extra/Placeholders/Sample/PostNode.m b/examples_extra/Placeholders/Sample/PostNode.m index 27809b471d..5c8bbd6dad 100644 --- a/examples_extra/Placeholders/Sample/PostNode.m +++ b/examples_extra/Placeholders/Sample/PostNode.m @@ -72,8 +72,8 @@ - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize { - CGSize textSize = [_textNode measure:constrainedSize]; - CGSize shareSize = [_needyChildNode measure:constrainedSize]; + CGSize textSize = [_textNode layoutThatFits:ASSizeRangeMake(CGSizeZero, constrainedSize)].size; + CGSize shareSize = [_needyChildNode layoutThatFits:ASSizeRangeMake(CGSizeZero, constrainedSize)].size; return CGSizeMake(constrainedSize.width, textSize.height + 10.0 + shareSize.height); } diff --git a/examples_extra/Placeholders/Sample/ViewController.m b/examples_extra/Placeholders/Sample/ViewController.m index f1177963bb..d10f83c55d 100644 --- a/examples_extra/Placeholders/Sample/ViewController.m +++ b/examples_extra/Placeholders/Sample/ViewController.m @@ -61,8 +61,8 @@ CGFloat constrainedWidth = CGRectGetWidth(bounds); CGSize constrainedSize = CGSizeMake(constrainedWidth - 2 * padding, CGFLOAT_MAX); - CGSize postSize = [_postNode measure:constrainedSize]; - CGSize imageSize = [_imageNode measure:constrainedSize]; + CGSize postSize = [_postNode layoutThatFits:ASSizeRangeMake(CGSizeZero, constrainedSize)].size; + CGSize imageSize = [_imageNode layoutThatFits:ASSizeRangeMake(CGSizeZero, constrainedSize)].size; _imageNode.frame = (CGRect){padding, padding, imageSize}; _postNode.frame = (CGRect){padding, CGRectGetMaxY(_imageNode.frame) + 10.0, postSize}; From bfb22988f79fd007f2b012054da7ad3583c32ded Mon Sep 17 00:00:00 2001 From: Kevin Date: Wed, 17 Oct 2018 13:26:45 -0700 Subject: [PATCH 09/60] [ASTextNode2] Add improved support for all line-break modes in experimental text node. (#1150) * ASTextNode2 rendering corrections. ASTextNode2 was only setting truncationMode (lineBreakMode) on existing paragraph styles in attributedString (thus having no effect for the two non-truncating modes if there were not any existing paragraph style runs). ASTextLayout (essentially YYTextLayout) was not rendering the two non-tail truncation lineBreakModes correctly. There's not much history on github but it appears to me that it was set up correctly at one time and then some additional code was added for unclear reasons that assumed any truncation was at the end of the string. This commit corrects both issues. * Update CHANGELOG.md --- CHANGELOG.md | 1 + Source/ASTextNode2.mm | 28 +- .../TextExperiment/Component/ASTextLayout.m | 359 ++++++++++-------- 3 files changed, 223 insertions(+), 165 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d85256b12b..e1898e1eb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master * Add your own contributions to the next release on the line below this with your name. +- [ASTextNode2] Add improved support for all line-break modes in experimental text node. [Kevin Smith](https://github.com/wiseoldduck). [#1150](https://github.com/TextureGroup/Texture/pull/1150) - [ASExperimentalFeatures.m] Fix mismatch name in experimental features. [Max Wang](https://github.com/wsdwsd0829). [#1159](https://github.com/TextureGroup/Texture/pull/1159) - [ASCollectionViewLayoutController] Set default tuning parameters before view is loaded. [Max Wang](https://github.com/wsdwsd0829). [#1158](https://github.com/TextureGroup/Texture/pull/1158) - [ASPhotosFrameworkImageRequestTests] Guard photo library with macro for tests. [Max Wang](https://github.com/wsdwsd0829). [#1147](https://github.com/TextureGroup/Texture/pull/1147) diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 194921bbe7..f3d5487b82 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -332,22 +332,44 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (void)prepareAttributedString:(NSMutableAttributedString *)attributedString isForIntrinsicSize:(BOOL)isForIntrinsicSize { ASLockScopeSelf(); + NSLineBreakMode innerMode; + switch (_truncationMode) { + case NSLineBreakByWordWrapping: + case NSLineBreakByCharWrapping: + case NSLineBreakByClipping: + innerMode = _truncationMode; + break; + default: + innerMode = NSLineBreakByWordWrapping; + } // Apply/Fix paragraph style if needed [attributedString enumerateAttribute:NSParagraphStyleAttributeName inRange:NSMakeRange(0, attributedString.length) options:kNilOptions usingBlock:^(NSParagraphStyle *style, NSRange range, BOOL * _Nonnull stop) { - const BOOL applyTruncationMode = (style != nil && style.lineBreakMode != _truncationMode); + BOOL applyTruncationMode = YES; + NSMutableParagraphStyle *paragraphStyle = nil; // Only "left" and "justified" alignments are supported while calculating intrinsic size. // Other alignments like "right", "center" and "natural" cause the size to be bigger than needed and thus should be ignored/overridden. const BOOL forceLeftAlignment = (style != nil && isForIntrinsicSize && style.alignment != NSTextAlignmentLeft && style.alignment != NSTextAlignmentJustified); + if (style != nil) { + if (innerMode == style.lineBreakMode) { + applyTruncationMode = NO; + } + paragraphStyle = [style mutableCopy]; + } else { + if (innerMode == NSLineBreakByWordWrapping) { + applyTruncationMode = NO; + } + paragraphStyle = [NSMutableParagraphStyle new]; + } if (!applyTruncationMode && !forceLeftAlignment) { return; } + paragraphStyle.lineBreakMode = innerMode; - NSMutableParagraphStyle *paragraphStyle = [style mutableCopy]; if (applyTruncationMode) { paragraphStyle.lineBreakMode = _truncationMode; } @@ -356,7 +378,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; } [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range]; }]; - + // Apply shadow if needed if (_shadowOpacity > 0 && (_shadowRadius != 0 || !CGSizeEqualToSize(_shadowOffset, CGSizeZero)) && CGColorGetAlpha(_shadowColor) > 0) { NSShadow *shadow = [[NSShadow alloc] init]; diff --git a/Source/Private/TextExperiment/Component/ASTextLayout.m b/Source/Private/TextExperiment/Component/ASTextLayout.m index 5c0b0cda53..b1d9fee59c 100644 --- a/Source/Private/TextExperiment/Component/ASTextLayout.m +++ b/Source/Private/TextExperiment/Component/ASTextLayout.m @@ -584,6 +584,7 @@ dispatch_semaphore_signal(_lock); // calculate line frame NSUInteger lineCurrentIdx = 0; + BOOL measuringBeyondConstraints = NO; for (NSUInteger i = 0; i < lineCount; i++) { CTLineRef ctLine = (CTLineRef)CFArrayGetValueAtIndex(ctLines, i); CFArrayRef ctRuns = CTLineGetGlyphRuns(ctLine); @@ -599,21 +600,25 @@ dispatch_semaphore_signal(_lock); ASTextLine *line = [ASTextLine lineWithCTLine:ctLine position:position vertical:isVerticalForm]; CGRect rect = line.bounds; - + if (constraintSizeIsExtended) { if (isVerticalForm) { if (rect.origin.x + rect.size.width > constraintRectBeforeExtended.origin.x + - constraintRectBeforeExtended.size.width) break; + constraintRectBeforeExtended.size.width) { + measuringBeyondConstraints = YES; + }; } else { if (rect.origin.y + rect.size.height > constraintRectBeforeExtended.origin.y + - constraintRectBeforeExtended.size.height) break; + constraintRectBeforeExtended.size.height) { + measuringBeyondConstraints = YES; + } } } - - BOOL newRow = YES; - if (rowMaySeparated && position.x != lastPosition.x) { + + BOOL newRow = !measuringBeyondConstraints; + if (newRow && rowMaySeparated && position.x != lastPosition.x) { if (isVerticalForm) { if (rect.size.width > lastRect.size.width) { if (rect.origin.x > lastPosition.x && lastPosition.x > rect.origin.x - rect.size.width) newRow = NO; @@ -638,185 +643,215 @@ dispatch_semaphore_signal(_lock); [lines addObject:line]; rowCount = rowIdx + 1; lineCurrentIdx ++; - - if (i == 0) textBoundingRect = rect; - else { + + if (i == 0) { + textBoundingRect = rect; + } else if (!measuringBeyondConstraints) { if (maximumNumberOfRows == 0 || rowIdx < maximumNumberOfRows) { textBoundingRect = CGRectUnion(textBoundingRect, rect); } } } - - if (rowCount > 0) { - if (maximumNumberOfRows > 0) { - if (rowCount > maximumNumberOfRows) { - needTruncation = YES; - rowCount = maximumNumberOfRows; - do { - ASTextLine *line = lines.lastObject; - if (!line) break; - if (line.row < rowCount) break; - [lines removeLastObject]; - } while (1); + + { + NSMutableArray *removedLines = [NSMutableArray new]; + if (rowCount > 0) { + if (maximumNumberOfRows > 0) { + if (rowCount > maximumNumberOfRows) { + needTruncation = YES; + rowCount = maximumNumberOfRows; + do { + ASTextLine *line = lines.lastObject; + if (!line) break; + if (line.row < rowCount) break; // we have removed down to an allowed # of lines now + [lines removeLastObject]; + [removedLines addObject:line]; + } while (1); + } } - } - ASTextLine *lastLine = lines.lastObject; - if (!needTruncation && lastLine.range.location + lastLine.range.length < text.length) { - needTruncation = YES; - } - - // Give user a chance to modify the line's position. - if (container.linePositionModifier) { - [container.linePositionModifier modifyLines:lines fromText:text inContainer:container]; - textBoundingRect = CGRectZero; + ASTextLine *lastLine = rowCount < lines.count ? lines[rowCount - 1] : lines.lastObject; + if (!needTruncation && lastLine.range.location + lastLine.range.length < text.length) { + needTruncation = YES; + while (lines.count > rowCount) { + ASTextLine *line = lines.lastObject; + [lines removeLastObject]; + [removedLines addObject:line]; + } + } + + // Give user a chance to modify the line's position. + if (container.linePositionModifier) { + [container.linePositionModifier modifyLines:lines fromText:text inContainer:container]; + textBoundingRect = CGRectZero; + for (NSUInteger i = 0, max = lines.count; i < max; i++) { + ASTextLine *line = lines[i]; + if (i == 0) textBoundingRect = line.bounds; + else textBoundingRect = CGRectUnion(textBoundingRect, line.bounds); + } + } + + lineRowsEdge = (ASRowEdge *) calloc(rowCount, sizeof(ASRowEdge)); + if (lineRowsEdge == NULL) FAIL_AND_RETURN + lineRowsIndex = (NSUInteger *) calloc(rowCount, sizeof(NSUInteger)); + if (lineRowsIndex == NULL) FAIL_AND_RETURN + NSInteger lastRowIdx = -1; + CGFloat lastHead = 0; + CGFloat lastFoot = 0; for (NSUInteger i = 0, max = lines.count; i < max; i++) { ASTextLine *line = lines[i]; - if (i == 0) textBoundingRect = line.bounds; - else textBoundingRect = CGRectUnion(textBoundingRect, line.bounds); - } - } - - lineRowsEdge = (ASRowEdge *)calloc(rowCount, sizeof(ASRowEdge)); - if (lineRowsEdge == NULL) FAIL_AND_RETURN - lineRowsIndex = (NSUInteger *)calloc(rowCount, sizeof(NSUInteger)); - if (lineRowsIndex == NULL) FAIL_AND_RETURN - NSInteger lastRowIdx = -1; - CGFloat lastHead = 0; - CGFloat lastFoot = 0; - for (NSUInteger i = 0, max = lines.count; i < max; i++) { - ASTextLine *line = lines[i]; - CGRect rect = line.bounds; - if ((NSInteger)line.row != lastRowIdx) { - if (lastRowIdx >= 0) { - lineRowsEdge[lastRowIdx] = (ASRowEdge) {.head = lastHead, .foot = lastFoot }; - } - lastRowIdx = line.row; - lineRowsIndex[lastRowIdx] = i; - if (isVerticalForm) { - lastHead = rect.origin.x + rect.size.width; - lastFoot = lastHead - rect.size.width; - } else { - lastHead = rect.origin.y; - lastFoot = lastHead + rect.size.height; - } - } else { - if (isVerticalForm) { - lastHead = MAX(lastHead, rect.origin.x + rect.size.width); - lastFoot = MIN(lastFoot, rect.origin.x); - } else { - lastHead = MIN(lastHead, rect.origin.y); - lastFoot = MAX(lastFoot, rect.origin.y + rect.size.height); - } - } - } - lineRowsEdge[lastRowIdx] = (ASRowEdge) {.head = lastHead, .foot = lastFoot }; - - for (NSUInteger i = 1; i < rowCount; i++) { - ASRowEdge v0 = lineRowsEdge[i - 1]; - ASRowEdge v1 = lineRowsEdge[i]; - lineRowsEdge[i - 1].foot = lineRowsEdge[i].head = (v0.foot + v1.head) * 0.5; - } - } - - { // calculate bounding size - CGRect rect = textBoundingRect; - if (container.path) { - if (container.pathLineWidth > 0) { - CGFloat inset = container.pathLineWidth / 2; - rect = CGRectInset(rect, -inset, -inset); - } - } else { - rect = UIEdgeInsetsInsetRect(rect,ASTextUIEdgeInsetsInvert(container.insets)); - } - rect = CGRectStandardize(rect); - CGSize size = rect.size; - if (container.verticalForm) { - size.width += container.size.width - (rect.origin.x + rect.size.width); - } else { - size.width += rect.origin.x; - } - size.height += rect.origin.y; - if (size.width < 0) size.width = 0; - if (size.height < 0) size.height = 0; - size.width = ceil(size.width); - size.height = ceil(size.height); - textBoundingSize = size; - } - - visibleRange = ASTextNSRangeFromCFRange(CTFrameGetVisibleStringRange(ctFrame)); - if (needTruncation) { - ASTextLine *lastLine = lines.lastObject; - NSRange lastRange = lastLine.range; - visibleRange.length = lastRange.location + lastRange.length - visibleRange.location; - - // create truncated line - if (container.truncationType != ASTextTruncationTypeNone) { - CTLineRef truncationTokenLine = NULL; - if (container.truncationToken) { - truncationToken = container.truncationToken; - truncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)truncationToken); - } else { - CFArrayRef runs = CTLineGetGlyphRuns(lastLine.CTLine); - NSUInteger runCount = CFArrayGetCount(runs); - NSMutableDictionary *attrs = nil; - if (runCount > 0) { - CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, runCount - 1); - attrs = (id)CTRunGetAttributes(run); - attrs = attrs ? attrs.mutableCopy : [NSMutableArray new]; - [attrs removeObjectsForKeys:[NSMutableAttributedString as_allDiscontinuousAttributeKeys]]; - CTFontRef font = (__bridge CTFontRef)attrs[(id)kCTFontAttributeName]; - CGFloat fontSize = font ? CTFontGetSize(font) : 12.0; - UIFont *uiFont = [UIFont systemFontOfSize:fontSize * 0.9]; - if (uiFont) { - font = CTFontCreateWithName((__bridge CFStringRef)uiFont.fontName, uiFont.pointSize, NULL); + CGRect rect = line.bounds; + if ((NSInteger) line.row != lastRowIdx) { + if (lastRowIdx >= 0) { + lineRowsEdge[lastRowIdx] = (ASRowEdge) {.head = lastHead, .foot = lastFoot}; + } + lastRowIdx = line.row; + lineRowsIndex[lastRowIdx] = i; + if (isVerticalForm) { + lastHead = rect.origin.x + rect.size.width; + lastFoot = lastHead - rect.size.width; } else { - font = NULL; + lastHead = rect.origin.y; + lastFoot = lastHead + rect.size.height; } - if (font) { - attrs[(id)kCTFontAttributeName] = (__bridge id)(font); - uiFont = nil; - CFRelease(font); + } else { + if (isVerticalForm) { + lastHead = MAX(lastHead, rect.origin.x + rect.size.width); + lastFoot = MIN(lastFoot, rect.origin.x); + } else { + lastHead = MIN(lastHead, rect.origin.y); + lastFoot = MAX(lastFoot, rect.origin.y + rect.size.height); } - CGColorRef color = (__bridge CGColorRef)(attrs[(id)kCTForegroundColorAttributeName]); - if (color && CFGetTypeID(color) == CGColorGetTypeID() && CGColorGetAlpha(color) == 0) { - // ignore clear color - [attrs removeObjectForKey:(id)kCTForegroundColorAttributeName]; - } - if (!attrs) attrs = [NSMutableDictionary new]; } - truncationToken = [[NSAttributedString alloc] initWithString:ASTextTruncationToken attributes:attrs]; - truncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)truncationToken); } - if (truncationTokenLine) { - CTLineTruncationType type = kCTLineTruncationEnd; - if (container.truncationType == ASTextTruncationTypeStart) { - type = kCTLineTruncationStart; - } else if (container.truncationType == ASTextTruncationTypeMiddle) { - type = kCTLineTruncationMiddle; + lineRowsEdge[lastRowIdx] = (ASRowEdge) {.head = lastHead, .foot = lastFoot}; + + for (NSUInteger i = 1; i < rowCount; i++) { + ASRowEdge v0 = lineRowsEdge[i - 1]; + ASRowEdge v1 = lineRowsEdge[i]; + lineRowsEdge[i - 1].foot = lineRowsEdge[i].head = (v0.foot + v1.head) * 0.5; + } + } + + { // calculate bounding size + CGRect rect = textBoundingRect; + if (container.path) { + if (container.pathLineWidth > 0) { + CGFloat inset = container.pathLineWidth / 2; + rect = CGRectInset(rect, -inset, -inset); } - NSMutableAttributedString *lastLineText = [text attributedSubstringFromRange:lastLine.range].mutableCopy; - [lastLineText appendAttributedString:truncationToken]; - CTLineRef ctLastLineExtend = CTLineCreateWithAttributedString((CFAttributedStringRef)lastLineText); - if (ctLastLineExtend) { + } else { + rect = UIEdgeInsetsInsetRect(rect, ASTextUIEdgeInsetsInvert(container.insets)); + } + rect = CGRectStandardize(rect); + CGSize size = rect.size; + if (container.verticalForm) { + size.width += container.size.width - (rect.origin.x + rect.size.width); + } else { + size.width += rect.origin.x; + } + size.height += rect.origin.y; + if (size.width < 0) size.width = 0; + if (size.height < 0) size.height = 0; + size.width = ceil(size.width); + size.height = ceil(size.height); + textBoundingSize = size; + } + + visibleRange = ASTextNSRangeFromCFRange(CTFrameGetVisibleStringRange(ctFrame)); + if (needTruncation) { + ASTextLine *lastLine = lines.lastObject; + NSRange lastRange = lastLine.range; + visibleRange.length = lastRange.location + lastRange.length - visibleRange.location; + + // create truncated line + if (container.truncationType != ASTextTruncationTypeNone) { + CTLineRef truncationTokenLine = NULL; + if (container.truncationToken) { + truncationToken = container.truncationToken; + truncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef) truncationToken); + } else { + CFArrayRef runs = CTLineGetGlyphRuns(lastLine.CTLine); + NSUInteger runCount = CFArrayGetCount(runs); + NSMutableDictionary *attrs = nil; + if (runCount > 0) { + CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex(runs, runCount - 1); + attrs = (id) CTRunGetAttributes(run); + attrs = attrs ? attrs.mutableCopy : [NSMutableArray new]; + [attrs removeObjectsForKeys:[NSMutableAttributedString as_allDiscontinuousAttributeKeys]]; + CTFontRef font = (__bridge CTFontRef) attrs[(id) kCTFontAttributeName]; + CGFloat fontSize = font ? CTFontGetSize(font) : 12.0; + UIFont *uiFont = [UIFont systemFontOfSize:fontSize * 0.9]; + if (uiFont) { + font = CTFontCreateWithName((__bridge CFStringRef) uiFont.fontName, uiFont.pointSize, NULL); + } else { + font = NULL; + } + if (font) { + attrs[(id) kCTFontAttributeName] = (__bridge id) (font); + uiFont = nil; + CFRelease(font); + } + CGColorRef color = (__bridge CGColorRef) (attrs[(id) kCTForegroundColorAttributeName]); + if (color && CFGetTypeID(color) == CGColorGetTypeID() && CGColorGetAlpha(color) == 0) { + // ignore clear color + [attrs removeObjectForKey:(id) kCTForegroundColorAttributeName]; + } + if (!attrs) attrs = [NSMutableDictionary new]; + } + truncationToken = [[NSAttributedString alloc] initWithString:ASTextTruncationToken attributes:attrs]; + truncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef) truncationToken); + } + if (truncationTokenLine) { + CTLineTruncationType type = kCTLineTruncationEnd; + if (container.truncationType == ASTextTruncationTypeStart) { + type = kCTLineTruncationStart; + } else if (container.truncationType == ASTextTruncationTypeMiddle) { + type = kCTLineTruncationMiddle; + } + NSMutableAttributedString *lastLineText = [text attributedSubstringFromRange:lastLine.range].mutableCopy; CGFloat truncatedWidth = lastLine.width; + CGFloat atLeastOneLine = lastLine.width; CGRect cgPathRect = CGRectZero; if (CGPathIsRect(cgPath, &cgPathRect)) { if (isVerticalForm) { truncatedWidth = cgPathRect.size.height; - } else { + } else { truncatedWidth = cgPathRect.size.width; } } - CTLineRef ctTruncatedLine = CTLineCreateTruncatedLine(ctLastLineExtend, truncatedWidth, type, truncationTokenLine); - CFRelease(ctLastLineExtend); - if (ctTruncatedLine) { - truncatedLine = [ASTextLine lineWithCTLine:ctTruncatedLine position:lastLine.position vertical:isVerticalForm]; - truncatedLine.index = lastLine.index; - truncatedLine.row = lastLine.row; - CFRelease(ctTruncatedLine); + int i = 0; + if (type != kCTLineTruncationStart) { // Middle or End/Tail wants text preceding truncated content + i = removedLines.count - 1; + while (atLeastOneLine < truncatedWidth && i >= 0) { + [lastLineText appendAttributedString:[text attributedSubstringFromRange:removedLines[i].range]]; + atLeastOneLine += removedLines[i--].width; + } + [lastLineText appendAttributedString:truncationToken]; } + if (type != kCTLineTruncationEnd && removedLines.count > 0) { // Middle or Start/Head wants text following truncated content + i = 0; + atLeastOneLine = removedLines[i].width; + while (atLeastOneLine < truncatedWidth && i < removedLines.count) { + atLeastOneLine += removedLines[i++].width; + } + for (i--; i >= 0; i--) { + [lastLineText appendAttributedString:[text attributedSubstringFromRange:removedLines[i].range]]; + } + } + + CTLineRef ctLastLineExtend = CTLineCreateWithAttributedString((CFAttributedStringRef) lastLineText); + if (ctLastLineExtend) { + CTLineRef ctTruncatedLine = CTLineCreateTruncatedLine(ctLastLineExtend, truncatedWidth, type, truncationTokenLine); + CFRelease(ctLastLineExtend); + if (ctTruncatedLine) { + truncatedLine = [ASTextLine lineWithCTLine:ctTruncatedLine position:lastLine.position vertical:isVerticalForm]; + truncatedLine.index = lastLine.index; + truncatedLine.row = lastLine.row; + CFRelease(ctTruncatedLine); + } + } + CFRelease(truncationTokenLine); } - CFRelease(truncationTokenLine); } } } @@ -824,7 +859,7 @@ dispatch_semaphore_signal(_lock); if (isVerticalForm) { NSCharacterSet *rotateCharset = ASTextVerticalFormRotateCharacterSet(); NSCharacterSet *rotateMoveCharset = ASTextVerticalFormRotateAndMoveCharacterSet(); - + void (^lineBlock)(ASTextLine *) = ^(ASTextLine *line){ CFArrayRef runs = CTLineGetGlyphRuns(line.CTLine); if (!runs) return; From d669be035ba73ea140dc154bdd6105cf901646d0 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 18 Oct 2018 09:34:00 -0700 Subject: [PATCH 10/60] Set the default values for showsVerticalScrollIndicator and showsHorizontalScrollIndicator (#1181) The default values of showsVerticalScrollIndicator and showsHorizontalScrollIndicator should be YES to correspond with the UIKit flags. --- Source/ASCollectionNode.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/ASCollectionNode.mm b/Source/ASCollectionNode.mm index a28e0adeae..11fe678fb2 100644 --- a/Source/ASCollectionNode.mm +++ b/Source/ASCollectionNode.mm @@ -70,6 +70,8 @@ _contentInset = UIEdgeInsetsZero; _contentOffset = CGPointZero; _animatesContentOffset = NO; + _showsVerticalScrollIndicator = YES; + _showsHorizontalScrollIndicator = YES; } return self; } From 27d50b03d881c60af9006c53e696e798322ac640 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 18 Oct 2018 09:34:29 -0700 Subject: [PATCH 11/60] Only initialize framework once, avoid multiple across tests (#1178) --- Source/Private/ASInternalHelpers.m | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Source/Private/ASInternalHelpers.m b/Source/Private/ASInternalHelpers.m index 484560aa89..81d1aa9971 100644 --- a/Source/Private/ASInternalHelpers.m +++ b/Source/Private/ASInternalHelpers.m @@ -45,16 +45,19 @@ BOOL ASDefaultAllowsEdgeAntialiasing() void ASInitializeFrameworkMainThread(void) { - ASDisplayNodeCAssertMainThread(); - // Ensure these values are cached on the main thread before needed in the background. - if (ASActivateExperimentalFeature(ASExperimentalLayerDefaults)) { - // Nop. We will gather default values on-demand in ASDefaultAllowsGroupOpacity and ASDefaultAllowsEdgeAntialiasing - } else { - CALayer *layer = [[[UIView alloc] init] layer]; - allowsGroupOpacityFromUIKitOrNil = @(layer.allowsGroupOpacity); - allowsEdgeAntialiasingFromUIKitOrNil = @(layer.allowsEdgeAntialiasing); - } - ASNotifyInitialized(); + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + ASDisplayNodeCAssertMainThread(); + // Ensure these values are cached on the main thread before needed in the background. + if (ASActivateExperimentalFeature(ASExperimentalLayerDefaults)) { + // Nop. We will gather default values on-demand in ASDefaultAllowsGroupOpacity and ASDefaultAllowsEdgeAntialiasing + } else { + CALayer *layer = [[[UIView alloc] init] layer]; + allowsGroupOpacityFromUIKitOrNil = @(layer.allowsGroupOpacity); + allowsEdgeAntialiasingFromUIKitOrNil = @(layer.allowsEdgeAntialiasing); + } + ASNotifyInitialized(); + }); } BOOL ASSubclassOverridesSelector(Class superclass, Class subclass, SEL selector) From 7ee2092dc34665014445f42c853c096f5735e173 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 18 Oct 2018 09:34:54 -0700 Subject: [PATCH 12/60] Use interface state to manage image loading. (#1172) --- Source/ASNetworkImageNode.mm | 3 --- 1 file changed, 3 deletions(-) diff --git a/Source/ASNetworkImageNode.mm b/Source/ASNetworkImageNode.mm index ea863c1ee1..1f5d907326 100644 --- a/Source/ASNetworkImageNode.mm +++ b/Source/ASNetworkImageNode.mm @@ -359,9 +359,6 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); } } - // TODO: Consider removing this; it predates ASInterfaceState, which now ensures that even non-range-managed nodes get a -preload call. - [self didEnterPreloadState]; - if (self.image == nil && _downloaderFlags.downloaderImplementsSetPriority) { id downloadIdentifier = ASLockedSelf(_downloadIdentifier); if (downloadIdentifier != nil) { From aa44d3175a918f748bd9242d2ae9edaa175f81a6 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 18 Oct 2018 09:35:04 -0700 Subject: [PATCH 13/60] Fix define spaces (#1176) Defines needs to right at the # --- Source/Base/ASAvailability.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Base/ASAvailability.h b/Source/Base/ASAvailability.h index 88e9e3fbe0..f420ccfbbf 100644 --- a/Source/Base/ASAvailability.h +++ b/Source/Base/ASAvailability.h @@ -18,15 +18,15 @@ #endif #ifndef AS_USE_PHOTOS -# define AS_USE_PHOTOS 0 + #define AS_USE_PHOTOS 0 #endif #ifndef AS_USE_MAPKIT -# define AS_USE_MAPKIT 0 + #define AS_USE_MAPKIT 0 #endif #ifndef AS_USE_ASSETS_LIBRARY -# define AS_USE_ASSETS_LIBRARY 0 + #define AS_USE_ASSETS_LIBRARY 0 #endif #ifndef kCFCoreFoundationVersionNumber_iOS_10_0 From b11ce52e9c2caff99c0749542914102a78e6a7a2 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 18 Oct 2018 09:35:36 -0700 Subject: [PATCH 14/60] Add way to suppress invalid CollectionUpdateExceptions (#1173) --- Source/ASDisplayNode+Beta.h | 13 +++++++++++++ Source/ASDisplayNode.mm | 11 +++++++++++ Source/Private/_ASHierarchyChangeSet.mm | 14 +++++++++++--- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/Source/ASDisplayNode+Beta.h b/Source/ASDisplayNode+Beta.h index b288372792..5907ac9b1c 100644 --- a/Source/ASDisplayNode+Beta.h +++ b/Source/ASDisplayNode+Beta.h @@ -51,6 +51,19 @@ typedef struct { @interface ASDisplayNode (Beta) +/** + * ASTableView and ASCollectionView now throw exceptions on invalid updates + * like their UIKit counterparts. If YES, these classes will log messages + * on invalid updates rather than throwing exceptions. + * + * Note that even if AsyncDisplayKit's exception is suppressed, the app may still crash + * as it proceeds with an invalid update. + * + * This property defaults to NO. It will be removed in a future release. + */ ++ (BOOL)suppressesInvalidCollectionUpdateExceptions AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Collection update exceptions are thrown if assertions are enabled."); ++ (void)setSuppressesInvalidCollectionUpdateExceptions:(BOOL)suppresses; + /** * @abstract Recursively ensures node and all subnodes are displayed. * @see Full documentation in ASDisplayNode+FrameworkPrivate.h diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index d9d6a66b51..52e389b2e3 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -78,6 +78,7 @@ NSInteger const ASDefaultDrawingPriority = ASDefaultTransactionPriority; @synthesize threadSafeBounds = _threadSafeBounds; +static std::atomic_bool suppressesInvalidCollectionUpdateExceptions = ATOMIC_VAR_INIT(NO); static std::atomic_bool storesUnflattenedLayouts = ATOMIC_VAR_INIT(NO); BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector) @@ -3792,6 +3793,16 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { return _unflattenedLayout; } ++ (void)setSuppressesInvalidCollectionUpdateExceptions:(BOOL)suppresses +{ + suppressesInvalidCollectionUpdateExceptions.store(suppresses); +} + ++ (BOOL)suppressesInvalidCollectionUpdateExceptions +{ + return suppressesInvalidCollectionUpdateExceptions.load(); +} + - (NSString *)displayNodeRecursiveDescription { return [self _recursiveDescriptionHelperWithIndent:@""]; diff --git a/Source/Private/_ASHierarchyChangeSet.mm b/Source/Private/_ASHierarchyChangeSet.mm index 57f70c461d..5ff4838178 100644 --- a/Source/Private/_ASHierarchyChangeSet.mm +++ b/Source/Private/_ASHierarchyChangeSet.mm @@ -18,11 +18,19 @@ #import #import -// If assertions are enabled, throw. Otherwise log. +// If assertions are enabled and they haven't forced us to suppress the exception, +// then throw, otherwise log. #if ASDISPLAYNODE_ASSERTIONS_ENABLED #define ASFailUpdateValidation(...)\ - NSLog(__VA_ARGS__);\ - [NSException raise:ASCollectionInvalidUpdateException format:__VA_ARGS__]; + _Pragma("clang diagnostic push")\ + _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")\ + if ([ASDisplayNode suppressesInvalidCollectionUpdateExceptions]) {\ + NSLog(__VA_ARGS__);\ + } else {\ + NSLog(__VA_ARGS__);\ + [NSException raise:ASCollectionInvalidUpdateException format:__VA_ARGS__];\ + }\ + _Pragma("clang diagnostic pop") #else #define ASFailUpdateValidation(...) NSLog(__VA_ARGS__); #endif From e6964d1ade0d16d1d247d675f768647e2d2034fa Mon Sep 17 00:00:00 2001 From: Jia Wern Lim <42153084+jiawernlim@users.noreply.github.com> Date: Fri, 19 Oct 2018 07:39:21 -0700 Subject: [PATCH 15/60] [ASDisplayNode] Expose default Texture-set accessibility values as properties (#1170) * Expose default Texture-set accessibility values as properties in ASDisplayNode. Added relevant overrides and tests. * Quick style fixes & add default a11y overrides to ASTextNode too. --- AsyncDisplayKit.xcodeproj/project.pbxproj | 8 +++ CHANGELOG.md | 1 + Source/ASButtonNode.mm | 22 ++++-- Source/ASDisplayNode+Beta.h | 11 +++ Source/ASDisplayNode.mm | 25 +++++++ Source/ASTextNode.mm | 15 +++- Source/ASTextNode2.mm | 15 +++- Tests/ASButtonNodeTests.m | 55 +++++++++++++++ Tests/ASTextNode2Tests.m | 85 +++++++++++++++++++++++ 9 files changed, 226 insertions(+), 11 deletions(-) create mode 100644 Tests/ASButtonNodeTests.m create mode 100644 Tests/ASTextNode2Tests.m diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 5d2280c29e..27d49fc5a8 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -494,6 +494,8 @@ E5E281761E71C845006B67C2 /* ASCollectionLayoutState.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5E281751E71C845006B67C2 /* ASCollectionLayoutState.mm */; }; E5E2D72E1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E5E2D72D1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; E5E2D7301EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5E2D72F1EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm */; }; + F325E48C21745F9E00AC93A4 /* ASButtonNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F325E48B21745F9E00AC93A4 /* ASButtonNodeTests.m */; }; + F325E490217460B100AC93A4 /* ASTextNode2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = F325E48F217460B000AC93A4 /* ASTextNode2Tests.m */; }; F3F698D2211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */; }; F711994E1D20C21100568860 /* ASDisplayNodeExtrasTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */; }; FA4FAF15200A850200E735BD /* ASControlNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4FAF14200A850200E735BD /* ASControlNode+Private.h */; }; @@ -1023,6 +1025,8 @@ 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.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASButtonNodeTests.m; sourceTree = ""; }; + F325E48F217460B000AC93A4 /* ASTextNode2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASTextNode2Tests.m; sourceTree = ""; }; F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayViewAccessibilityTests.mm; sourceTree = ""; }; F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeExtrasTests.m; sourceTree = ""; }; FA4FAF14200A850200E735BD /* ASControlNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+Private.h"; sourceTree = ""; }; @@ -1251,6 +1255,8 @@ 058D09C5195D04C000B7D73C /* Tests */ = { isa = PBXGroup; children = ( + F325E48F217460B000AC93A4 /* ASTextNode2Tests.m */, + F325E48B21745F9E00AC93A4 /* ASButtonNodeTests.m */, F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */, DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.m */, AC026B571BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.m */, @@ -2272,6 +2278,7 @@ CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */, 052EE0661A159FEF002C6279 /* ASMultiplexImageNodeTests.m in Sources */, 058D0A3C195D057000B7D73C /* ASMutableAttributedStringBuilderTests.m in Sources */, + F325E48C21745F9E00AC93A4 /* ASButtonNodeTests.m in Sources */, E586F96C1F9F9E2900ECE00E /* ASScrollNodeTests.m in Sources */, CC8B05D81D73979700F54286 /* ASTextNodePerformanceTests.m in Sources */, CC583AD91EF9BDC600134156 /* ASDisplayNode+OCMock.m in Sources */, @@ -2296,6 +2303,7 @@ 3C9C128519E616EF00E942A0 /* ASTableViewTests.mm in Sources */, AEEC47E41C21D3D200EC1693 /* ASVideoNodeTests.m in Sources */, 254C6B521BF8FE6D003EC431 /* ASTextKitTruncationTests.mm in Sources */, + F325E490217460B100AC93A4 /* ASTextNode2Tests.m in Sources */, 058D0A3D195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.m in Sources */, CC3B20901C3F892D00798563 /* ASBridgedPropertiesTests.mm in Sources */, CCE4F9BE1F0ECE5200062E4E /* ASTLayoutFixture.mm in Sources */, diff --git a/CHANGELOG.md b/CHANGELOG.md index e1898e1eb5..5b94c817ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ - Fix crash setting attributed text on multiple threads [Michael Schneider](https://github.com/maicki) - [ASTextNode2] Ignore certain text alignments while calculating intrinsic size [Huy Nguyen](https://github.com/nguyenhuy) [#1166](https://github.com/TextureGroup/Texture/pull/1166) - Fix mismatch in UIAccessibilityAction selector method [Michael Schneider](https://github.com/maicki) [#1169](https://github.com/TextureGroup/Texture/pull/1169) +- [ASDisplayNode] Expose default Texture-set accessibility values as properties. [Jia Wern Lim](https://github.com/jiawernlim) [#1170](https://github.com/TextureGroup/Texture/pull/1170) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASButtonNode.mm b/Source/ASButtonNode.mm index f0ca75eed2..e4bbb88633 100644 --- a/Source/ASButtonNode.mm +++ b/Source/ASButtonNode.mm @@ -63,7 +63,7 @@ _contentVerticalAlignment = ASVerticalAlignmentCenter; _contentEdgeInsets = UIEdgeInsetsZero; _imageAlignment = ASButtonNodeImageAlignmentBeginning; - self.accessibilityTraits = UIAccessibilityTraitButton; + self.accessibilityTraits = self.defaultAccessibilityTraits;; } return self; } @@ -114,11 +114,7 @@ { if (self.enabled != enabled) { [super setEnabled:enabled]; - if (enabled) { - self.accessibilityTraits = UIAccessibilityTraitButton; - } else { - self.accessibilityTraits = UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled; - } + self.accessibilityTraits = self.defaultAccessibilityTraits; [self updateButtonContent]; } } @@ -204,7 +200,7 @@ _titleNode.attributedText = newTitle; [self unlock]; - self.accessibilityLabel = _titleNode.accessibilityLabel; + self.accessibilityLabel = self.defaultAccessibilityLabel; [self setNeedsLayout]; return; } @@ -544,6 +540,18 @@ return spec; } +- (NSString *)defaultAccessibilityLabel +{ + ASLockScopeSelf(); + return _titleNode.accessibilityLabel; +} + +- (UIAccessibilityTraits)defaultAccessibilityTraits +{ + return self.enabled ? UIAccessibilityTraitButton + : (UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled); +} + - (void)layout { [super layout]; diff --git a/Source/ASDisplayNode+Beta.h b/Source/ASDisplayNode+Beta.h index 5907ac9b1c..affe99cb25 100644 --- a/Source/ASDisplayNode+Beta.h +++ b/Source/ASDisplayNode+Beta.h @@ -109,6 +109,17 @@ typedef struct { */ @property BOOL isAccessibilityContainer; +/** + * @abstract Returns the default accessibility property values set by Texture on this node. For + * example, the default accessibility label for a text node may be its text content, while most + * other nodes would have nil default labels. + */ +@property (nullable, readonly, copy) NSString *defaultAccessibilityLabel; +@property (nullable, readonly, copy) NSString *defaultAccessibilityHint; +@property (nullable, readonly, copy) NSString *defaultAccessibilityValue; +@property (nullable, readonly, copy) NSString *defaultAccessibilityIdentifier; +@property (readonly) UIAccessibilityTraits defaultAccessibilityTraits; + /** * @abstract Invoked when a user performs a custom action on an accessible node. Nodes that are children of accessibility containers, have * an accessibity label and have an interactive UIAccessibilityTrait will automatically receive custom-action handling. diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 52e389b2e3..7dd5c7d79c 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -3632,6 +3632,31 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { return _isAccessibilityContainer; } +- (NSString *)defaultAccessibilityLabel +{ + return nil; +} + +- (NSString *)defaultAccessibilityHint +{ + return nil; +} + +- (NSString *)defaultAccessibilityValue +{ + return nil; +} + +- (NSString *)defaultAccessibilityIdentifier +{ + return nil; +} + +- (UIAccessibilityTraits)defaultAccessibilityTraits +{ + return UIAccessibilityTraitNone; +} + #pragma mark - Debugging (Private) #if ASEVENTLOG_ENABLE diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index 7f0cc3f1a3..c29d03312c 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -226,7 +226,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // Accessibility self.isAccessibilityElement = YES; - self.accessibilityTraits = UIAccessibilityTraitStaticText; + self.accessibilityTraits = self.defaultAccessibilityTraits; // Placeholders // Disabled by default in ASDisplayNode, but add a few options for those who toggle @@ -365,6 +365,17 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; }; } +- (NSString *)defaultAccessibilityLabel +{ + ASLockScopeSelf(); + return _attributedText.string; +} + +- (UIAccessibilityTraits)defaultAccessibilityTraits +{ + return UIAccessibilityTraitStaticText; +} + #pragma mark - Layout and Sizing - (void)setTextContainerInset:(UIEdgeInsets)textContainerInset @@ -474,7 +485,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // Accessiblity let currentAttributedText = self.attributedText; // Grab attributed string again in case it changed in the meantime - self.accessibilityLabel = currentAttributedText.string; + self.accessibilityLabel = self.defaultAccessibilityLabel; self.isAccessibilityElement = (currentAttributedText.length != 0); // We're an accessibility element by default if there is a string. #if AS_TEXTNODE_RECORD_ATTRIBUTED_STRINGS diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index f3d5487b82..cca660f136 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -115,7 +115,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // Accessibility self.isAccessibilityElement = YES; - self.accessibilityTraits = UIAccessibilityTraitStaticText; + self.accessibilityTraits = self.defaultAccessibilityTraits; // Placeholders // Disabled by default in ASDisplayNode, but add a few options for those who toggle @@ -209,6 +209,17 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; return YES; } +- (NSString *)defaultAccessibilityLabel +{ + ASLockScopeSelf(); + return _attributedText.string; +} + +- (UIAccessibilityTraits)defaultAccessibilityTraits +{ + return UIAccessibilityTraitStaticText; +} + #pragma mark - Layout and Sizing - (void)setTextContainerInset:(UIEdgeInsets)textContainerInset @@ -304,7 +315,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; [self setNeedsDisplay]; // Accessiblity - self.accessibilityLabel = attributedText.string; + self.accessibilityLabel = self.defaultAccessibilityLabel; self.isAccessibilityElement = (length != 0); // We're an accessibility element by default if there is a string. #if AS_TEXTNODE2_RECORD_ATTRIBUTED_STRINGS diff --git a/Tests/ASButtonNodeTests.m b/Tests/ASButtonNodeTests.m new file mode 100644 index 0000000000..1c0c0adb61 --- /dev/null +++ b/Tests/ASButtonNodeTests.m @@ -0,0 +1,55 @@ +// +// ASButtonNodeTests.m +// Texture +// +// Copyright (c) Pinterest, Inc. All rights reserved. +// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 +// + +#import + +#import +#import + +@interface ASButtonNodeTests : XCTestCase +@end + +@implementation ASButtonNodeTests + +- (void)testAccessibility +{ + // Setup a button with some title. + ASButtonNode *buttonNode = nil; + buttonNode = [[ASButtonNode alloc] init]; + NSString *title = @"foo"; + [buttonNode setTitle:title withFont:nil withColor:nil forState:UIControlStateNormal]; + + // Verify accessibility properties. + XCTAssertTrue(buttonNode.accessibilityTraits == UIAccessibilityTraitButton, + @"Should have button accessibility trait, instead has %llu", + buttonNode.accessibilityTraits); + XCTAssertTrue(buttonNode.defaultAccessibilityTraits == UIAccessibilityTraitButton, + @"Default accessibility traits should return button accessibility trait, instead " + @"returns %llu", + buttonNode.defaultAccessibilityTraits); + XCTAssertTrue([buttonNode.accessibilityLabel isEqualToString:title], + @"Accessibility label is incorrectly set to \n%@\n when it should be \n%@\n", + buttonNode.accessibilityLabel, title); + XCTAssertTrue([buttonNode.defaultAccessibilityLabel isEqualToString:title], + @"Default accessibility label incorrectly returns \n%@\n when it should be \n%@\n", + buttonNode.defaultAccessibilityLabel, title); + + // Disable the button and verify that accessibility traits has been updated correctly. + buttonNode.enabled = NO; + UIAccessibilityTraits disabledButtonTrait = + UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled; + XCTAssertTrue(buttonNode.accessibilityTraits == disabledButtonTrait, + @"Should have disabled button accessibility trait, instead has %llu", + buttonNode.accessibilityTraits); + XCTAssertTrue(buttonNode.defaultAccessibilityTraits == disabledButtonTrait, + @"Default accessibility traits should return disabled button accessibility trait, " + @"instead returns %llu", + buttonNode.defaultAccessibilityTraits); +} + +@end diff --git a/Tests/ASTextNode2Tests.m b/Tests/ASTextNode2Tests.m new file mode 100644 index 0000000000..74e9399dd2 --- /dev/null +++ b/Tests/ASTextNode2Tests.m @@ -0,0 +1,85 @@ +// +// ASTextNode2Tests.m +// TextureTests +// +// Copyright (c) Pinterest, Inc. All rights reserved. +// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 +// + +#import + +#import "ASTestCase.h" + +#import +#import + +#import + +@interface ASTextNode2Tests : XCTestCase + +@property(nonatomic) ASTextNode2 *textNode; +@property(nonatomic, copy) NSAttributedString *attributedText; + +@end + +@implementation ASTextNode2Tests + +- (void)setUp +{ + [super setUp]; + _textNode = [[ASTextNode2 alloc] init]; + + UIFontDescriptor *desc = [UIFontDescriptor fontDescriptorWithName:@"Didot" size:18]; + NSArray *arr = @[ @{ + UIFontFeatureTypeIdentifierKey : @(kLetterCaseType), + UIFontFeatureSelectorIdentifierKey : @(kSmallCapsSelector) + } ]; + desc = [desc fontDescriptorByAddingAttributes:@{UIFontDescriptorFeatureSettingsAttribute : arr}]; + UIFont *f = [UIFont fontWithDescriptor:desc size:0]; + NSDictionary *d = @{NSFontAttributeName : f}; + NSMutableAttributedString *mas = [[NSMutableAttributedString alloc] + initWithString: + @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " + @"incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " + @"exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " + @"dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " + @"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @"mollit anim id est laborum." + attributes:d]; + NSMutableParagraphStyle *para = [NSMutableParagraphStyle new]; + para.alignment = NSTextAlignmentCenter; + para.lineSpacing = 1.0; + [mas addAttribute:NSParagraphStyleAttributeName value:para range:NSMakeRange(0, mas.length - 1)]; + + // Vary the linespacing on the last line + NSMutableParagraphStyle *lastLinePara = [NSMutableParagraphStyle new]; + lastLinePara.alignment = para.alignment; + lastLinePara.lineSpacing = 5.0; + [mas addAttribute:NSParagraphStyleAttributeName + value:lastLinePara + range:NSMakeRange(mas.length - 1, 1)]; + + _attributedText = mas; + _textNode.attributedText = _attributedText; +} + +- (void)testAccessibility +{ + XCTAssertTrue(_textNode.isAccessibilityElement, @"Should be an accessibility element"); + XCTAssertTrue(_textNode.accessibilityTraits == UIAccessibilityTraitStaticText, + @"Should have static text accessibility trait, instead has %llu", + _textNode.accessibilityTraits); + XCTAssertTrue(_textNode.defaultAccessibilityTraits == UIAccessibilityTraitStaticText, + @"Default accessibility traits should return static text accessibility trait, " + @"instead returns %llu", + _textNode.defaultAccessibilityTraits); + + XCTAssertTrue([_textNode.accessibilityLabel isEqualToString:_attributedText.string], + @"Accessibility label is incorrectly set to \n%@\n when it should be \n%@\n", + _textNode.accessibilityLabel, _attributedText.string); + XCTAssertTrue([_textNode.defaultAccessibilityLabel isEqualToString:_attributedText.string], + @"Default accessibility label incorrectly returns \n%@\n when it should be \n%@\n", + _textNode.defaultAccessibilityLabel, _attributedText.string); +} + +@end From 2f3c0b42e3f5451077d85c7026944e7b2e6cd773 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Fri, 19 Oct 2018 07:39:45 -0700 Subject: [PATCH 16/60] Expose test_resetWithConfiguration: for testing purposes (#1175) This makes it easier to write tests for specific configurations. --- Source/ASConfigurationInternal.h | 3 +++ Tests/Common/ASTestCase.h | 6 ------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Source/ASConfigurationInternal.h b/Source/ASConfigurationInternal.h index 8e744e65cd..3bad3fd575 100644 --- a/Source/ASConfigurationInternal.h +++ b/Source/ASConfigurationInternal.h @@ -35,6 +35,9 @@ AS_SUBCLASSING_RESTRICTED * Just use ASActivateExperimentalFeature to access this efficiently. */ +/* Exposed for testing purposes only */ ++ (void)test_resetWithConfiguration:(nullable ASConfiguration *)configuration; + @end NS_ASSUME_NONNULL_END diff --git a/Tests/Common/ASTestCase.h b/Tests/Common/ASTestCase.h index 4e8850c247..ed3f5ca55b 100644 --- a/Tests/Common/ASTestCase.h +++ b/Tests/Common/ASTestCase.h @@ -23,10 +23,4 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface ASConfigurationManager (Testing) - -+ (void)test_resetWithConfiguration:(nullable ASConfiguration *)configuration; - -@end - NS_ASSUME_NONNULL_END From dc49ce061530efc72ba6bea12a9bb8897e2399ba Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Fri, 19 Oct 2018 10:41:17 -0700 Subject: [PATCH 17/60] Move import of stdatomic to ASRecursiveUnfairLock implementation file (#1180) --- Source/Details/ASRecursiveUnfairLock.h | 5 ----- Source/Details/ASRecursiveUnfairLock.m | 2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/Details/ASRecursiveUnfairLock.h b/Source/Details/ASRecursiveUnfairLock.h index 48aab7f307..22ab5c703c 100644 --- a/Source/Details/ASRecursiveUnfairLock.h +++ b/Source/Details/ASRecursiveUnfairLock.h @@ -11,11 +11,6 @@ #import #import -// Don't import C-only header if we're in a C++ file -#ifndef __cplusplus -#import -#endif - // Note: We don't use ATOMIC_VAR_INIT here because C++ compilers don't like it, // and it literally does absolutely nothing. #define AS_RECURSIVE_UNFAIR_LOCK_INIT ((ASRecursiveUnfairLock){ OS_UNFAIR_LOCK_INIT, NULL, 0}) diff --git a/Source/Details/ASRecursiveUnfairLock.m b/Source/Details/ASRecursiveUnfairLock.m index 7e5cac3681..1013095ae3 100644 --- a/Source/Details/ASRecursiveUnfairLock.m +++ b/Source/Details/ASRecursiveUnfairLock.m @@ -8,6 +8,8 @@ #import "ASRecursiveUnfairLock.h" +#import + /** * For our atomic _thread, we use acquire/release memory order so that we can have * the minimum possible constraint on the hardware. The default, `memory_order_seq_cst` From c958812ed6acc37d8ad7607f14ece00eb0870894 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Sat, 20 Oct 2018 09:45:19 -0700 Subject: [PATCH 18/60] ASTableNode init method match checks from ASCollectionNode (#1171) --- CHANGELOG.md | 1 + Source/ASTableNode.mm | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b94c817ce..4e7d47f9fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ - [ASTextNode2] Ignore certain text alignments while calculating intrinsic size [Huy Nguyen](https://github.com/nguyenhuy) [#1166](https://github.com/TextureGroup/Texture/pull/1166) - Fix mismatch in UIAccessibilityAction selector method [Michael Schneider](https://github.com/maicki) [#1169](https://github.com/TextureGroup/Texture/pull/1169) - [ASDisplayNode] Expose default Texture-set accessibility values as properties. [Jia Wern Lim](https://github.com/jiawernlim) [#1170](https://github.com/TextureGroup/Texture/pull/1170) +- ASTableNode init method match checks from ASCollectionNode [Michael Schneider](https://github.com/maicki) [#1171] ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASTableNode.mm b/Source/ASTableNode.mm index 24f7ddf112..a916a4b075 100644 --- a/Source/ASTableNode.mm +++ b/Source/ASTableNode.mm @@ -155,6 +155,7 @@ if (_pendingState) { _ASTablePendingState *pendingState = _pendingState; + self.pendingState = nil; view.asyncDelegate = pendingState.delegate; view.asyncDataSource = pendingState.dataSource; view.inverted = pendingState.inverted; @@ -162,9 +163,17 @@ view.allowsSelectionDuringEditing = pendingState.allowsSelectionDuringEditing; view.allowsMultipleSelection = pendingState.allowsMultipleSelection; view.allowsMultipleSelectionDuringEditing = pendingState.allowsMultipleSelectionDuringEditing; - view.contentInset = pendingState.contentInset; - self.pendingState = nil; - + + UIEdgeInsets contentInset = pendingState.contentInset; + if (!UIEdgeInsetsEqualToEdgeInsets(contentInset, UIEdgeInsetsZero)) { + view.contentInset = contentInset; + } + + CGPoint contentOffset = pendingState.contentOffset; + if (!CGPointEqualToPoint(contentOffset, CGPointZero)) { + [view setContentOffset:contentOffset animated:pendingState.animatesContentOffset]; + } + let tuningParametersVector = pendingState->_tuningParameters; let tuningParametersVectorSize = tuningParametersVector.size(); for (NSInteger rangeMode = 0; rangeMode < tuningParametersVectorSize; rangeMode++) { @@ -181,8 +190,6 @@ if (pendingState.rangeMode != ASLayoutRangeModeUnspecified) { [_rangeController updateCurrentRangeWithMode:pendingState.rangeMode]; } - - [view setContentOffset:pendingState.contentOffset animated:pendingState.animatesContentOffset]; } } From 776e4755586116f3abb1e241dd74753d944c824c Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Sun, 21 Oct 2018 09:33:26 -0700 Subject: [PATCH 19/60] Expose a way to determine if a text node will truncate for a given constrained size #trivial (#1177) * Expose textLayoutForConstraint: - Expose textLayoutForConstraint:, but make unavailable on ASTextNode - Refactor compatibleLayoutWithContainer:text: into a static method * Instead of textLayoutForConstraint: expose shouldTruncateForConstrainedSize: in ASTextNode --- Source/ASTextNode+Beta.h | 5 + Source/ASTextNode.mm | 5 + Source/ASTextNode2.mm | 204 ++++++++++++++++++++------------------- 3 files changed, 116 insertions(+), 98 deletions(-) diff --git a/Source/ASTextNode+Beta.h b/Source/ASTextNode+Beta.h index 09259bd7f4..ad897c5f0e 100644 --- a/Source/ASTextNode+Beta.h +++ b/Source/ASTextNode+Beta.h @@ -35,6 +35,11 @@ NS_ASSUME_NONNULL_BEGIN */ @property (readonly) BOOL usingExperiment; +/** + * Returns a Boolean indicating if the text node will truncate for the given constrained size + */ +- (BOOL)shouldTruncateForConstrainedSize:(ASSizeRange)constrainedSize; + @end NS_ASSUME_NONNULL_END diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index c29d03312c..accbea3ad5 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -1218,6 +1218,11 @@ static NSAttributedString *DefaultTruncationAttributedString() return ASLockedSelf([[self _locked_renderer] isTruncated]); } +- (BOOL)shouldTruncateForConstrainedSize:(ASSizeRange)constrainedSize +{ + return ASLockedSelf([[self _locked_rendererWithBounds:{.size = constrainedSize.max}] isTruncated]); +} + - (void)setPointSizeScaleFactors:(NSArray *)pointSizeScaleFactors { if (ASLockedSelfCompareAssignCopy(_pointSizeScaleFactors, pointSizeScaleFactors)) { diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index cca660f136..6d894be82d 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -55,6 +55,95 @@ });\ } +/** + * If it can't find a compatible layout, this method creates one. + * + * NOTE: Be careful to copy `text` if needed. + */ +static NS_RETURNS_RETAINED ASTextLayout *ASTextNodeCompatibleLayoutWithContainerAndText(ASTextContainer *container, NSAttributedString *text) { + // Allocate layoutCacheLock on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) + static ASDN::StaticMutex& layoutCacheLock = *new ASDN::StaticMutex; + static NSCache *textLayoutCache; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + textLayoutCache = [[NSCache alloc] init]; + }); + + layoutCacheLock.lock(); + + ASTextCacheValue *cacheValue = [textLayoutCache objectForKey:text]; + if (cacheValue == nil) { + cacheValue = [[ASTextCacheValue alloc] init]; + [textLayoutCache setObject:cacheValue forKey:[text copy]]; + } + + // Lock the cache item for the rest of the method. Only after acquiring can we release the NSCache. + ASDN::MutexLocker lock(cacheValue->_m); + layoutCacheLock.unlock(); + + CGRect containerBounds = (CGRect){ .size = container.size }; + { + for (let &t : cacheValue->_layouts) { + CGSize constrainedSize = std::get<0>(t); + ASTextLayout *layout = std::get<1>(t); + + CGSize layoutSize = layout.textBoundingSize; + // 1. CoreText can return frames that are narrower than the constrained width, for obvious reasons. + // 2. CoreText can return frames that are slightly wider than the constrained width, for some reason. + // We have to trust that somehow it's OK to try and draw within our size constraint, despite the return value. + // 3. Thus, those two values (constrained width & returned width) form a range, where + // intermediate values in that range will be snapped. Thus, we can use a given layout as long as our + // width is in that range, between the min and max of those two values. + CGRect minRect = CGRectMake(0, 0, MIN(layoutSize.width, constrainedSize.width), MIN(layoutSize.height, constrainedSize.height)); + if (!CGRectContainsRect(containerBounds, minRect)) { + continue; + } + CGRect maxRect = CGRectMake(0, 0, MAX(layoutSize.width, constrainedSize.width), MAX(layoutSize.height, constrainedSize.height)); + if (!CGRectContainsRect(maxRect, containerBounds)) { + continue; + } + if (!CGSizeEqualToSize(container.size, constrainedSize)) { + continue; + } + + // Now check container params. + ASTextContainer *otherContainer = layout.container; + if (!UIEdgeInsetsEqualToEdgeInsets(container.insets, otherContainer.insets)) { + continue; + } + if (!ASObjectIsEqual(container.exclusionPaths, otherContainer.exclusionPaths)) { + continue; + } + if (container.maximumNumberOfRows != otherContainer.maximumNumberOfRows) { + continue; + } + if (container.truncationType != otherContainer.truncationType) { + continue; + } + if (!ASObjectIsEqual(container.truncationToken, otherContainer.truncationToken)) { + continue; + } + // TODO: When we get a cache hit, move this entry to the front (LRU). + return layout; + } + } + + // Cache Miss. Compute the text layout. + ASTextLayout *layout = [ASTextLayout layoutWithContainer:container text:text]; + + // Store the result in the cache. + { + // This is a critical section. However we also must hold the lock until this point, in case + // another thread requests this cache item while a layout is being calculated, so they don't race. + cacheValue->_layouts.push_front(std::make_tuple(container.size, layout)); + if (cacheValue->_layouts.size() > 3) { + cacheValue->_layouts.pop_back(); + } + } + + return layout; +} + static const CGFloat ASTextNodeHighlightLightOpacity = 0.11; static const CGFloat ASTextNodeHighlightDarkOpacity = 0.22; static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncationAttribute"; @@ -256,7 +345,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; NSMutableAttributedString *mutableText = [_attributedText mutableCopy]; [self prepareAttributedString:mutableText isForIntrinsicSize:isCalculatingIntrinsicSize]; - ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:_textContainer text:mutableText]; + ASTextLayout *layout = ASTextNodeCompatibleLayoutWithContainerAndText(_textContainer, mutableText); return layout.textBoundingSize; } @@ -428,104 +517,12 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; }; } -/** - * If it can't find a compatible layout, this method creates one. - * - * NOTE: Be careful to copy `text` if needed. - */ -+ (ASTextLayout *)compatibleLayoutWithContainer:(ASTextContainer *)container - text:(NSAttributedString *)text NS_RETURNS_RETAINED - -{ - // Allocate layoutCacheLock on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) - static ASDN::StaticMutex& layoutCacheLock = *new ASDN::StaticMutex; - static NSCache *textLayoutCache; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - textLayoutCache = [[NSCache alloc] init]; - }); - - layoutCacheLock.lock(); - - ASTextCacheValue *cacheValue = [textLayoutCache objectForKey:text]; - if (cacheValue == nil) { - cacheValue = [[ASTextCacheValue alloc] init]; - [textLayoutCache setObject:cacheValue forKey:[text copy]]; - } - - // Lock the cache item for the rest of the method. Only after acquiring can we release the NSCache. - ASDN::MutexLocker lock(cacheValue->_m); - layoutCacheLock.unlock(); - - CGRect containerBounds = (CGRect){ .size = container.size }; - { - for (let &t : cacheValue->_layouts) { - CGSize constrainedSize = std::get<0>(t); - ASTextLayout *layout = std::get<1>(t); - - CGSize layoutSize = layout.textBoundingSize; - // 1. CoreText can return frames that are narrower than the constrained width, for obvious reasons. - // 2. CoreText can return frames that are slightly wider than the constrained width, for some reason. - // We have to trust that somehow it's OK to try and draw within our size constraint, despite the return value. - // 3. Thus, those two values (constrained width & returned width) form a range, where - // intermediate values in that range will be snapped. Thus, we can use a given layout as long as our - // width is in that range, between the min and max of those two values. - CGRect minRect = CGRectMake(0, 0, MIN(layoutSize.width, constrainedSize.width), MIN(layoutSize.height, constrainedSize.height)); - if (!CGRectContainsRect(containerBounds, minRect)) { - continue; - } - CGRect maxRect = CGRectMake(0, 0, MAX(layoutSize.width, constrainedSize.width), MAX(layoutSize.height, constrainedSize.height)); - if (!CGRectContainsRect(maxRect, containerBounds)) { - continue; - } - if (!CGSizeEqualToSize(container.size, constrainedSize)) { - continue; - } - - // Now check container params. - ASTextContainer *otherContainer = layout.container; - if (!UIEdgeInsetsEqualToEdgeInsets(container.insets, otherContainer.insets)) { - continue; - } - if (!ASObjectIsEqual(container.exclusionPaths, otherContainer.exclusionPaths)) { - continue; - } - if (container.maximumNumberOfRows != otherContainer.maximumNumberOfRows) { - continue; - } - if (container.truncationType != otherContainer.truncationType) { - continue; - } - if (!ASObjectIsEqual(container.truncationToken, otherContainer.truncationToken)) { - continue; - } - // TODO: When we get a cache hit, move this entry to the front (LRU). - return layout; - } - } - - // Cache Miss. Compute the text layout. - ASTextLayout *layout = [ASTextLayout layoutWithContainer:container text:text]; - - // Store the result in the cache. - { - // This is a critical section. However we also must hold the lock until this point, in case - // another thread requests this cache item while a layout is being calculated, so they don't race. - cacheValue->_layouts.push_front(std::make_tuple(container.size, layout)); - if (cacheValue->_layouts.size() > 3) { - cacheValue->_layouts.pop_back(); - } - } - - return layout; -} - + (void)drawRect:(CGRect)bounds withParameters:(NSDictionary *)layoutDict isCancelled:(NS_NOESCAPE asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing { ASTextContainer *container = layoutDict[@"container"]; NSAttributedString *text = layoutDict[@"text"]; UIColor *bgColor = layoutDict[@"bgColor"]; - ASTextLayout *layout = [self compatibleLayoutWithContainer:container text:text]; + ASTextLayout *layout = ASTextNodeCompatibleLayoutWithContainerAndText(container, text); if (isCancelledBlock()) { return; @@ -574,7 +571,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // See discussion in https://github.com/TextureGroup/Texture/pull/396 ASTextContainer *containerCopy = [_textContainer copy]; containerCopy.size = self.calculatedSize; - ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:containerCopy text:_attributedText]; + ASTextLayout *layout = ASTextNodeCompatibleLayoutWithContainerAndText(containerCopy, _attributedText); NSRange visibleRange = layout.visibleRange; NSRange clampedRange = NSIntersectionRange(visibleRange, NSMakeRange(0, _attributedText.length)); @@ -830,7 +827,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // See discussion in https://github.com/TextureGroup/Texture/pull/396 ASTextContainer *containerCopy = [_textContainer copy]; containerCopy.size = self.calculatedSize; - ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:containerCopy text:_attributedText]; + ASTextLayout *layout = ASTextNodeCompatibleLayoutWithContainerAndText(containerCopy, _attributedText); visibleRange = layout.visibleRange; } NSRange truncationMessageRange = [self _additionalTruncationMessageRangeWithVisibleRange:visibleRange]; @@ -1086,8 +1083,19 @@ static NSAttributedString *DefaultTruncationAttributedString() - (BOOL)isTruncated { - AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE(); - return NO; + return ASLockedSelf([self locked_textLayoutForSize:[self _locked_threadSafeBounds].size].truncatedLine == nil); +} + +- (BOOL)shouldTruncateForConstrainedSize:(ASSizeRange)constrainedSize +{ + return ASLockedSelf([self locked_textLayoutForSize:constrainedSize.max].truncatedLine == nil); +} + +- (ASTextLayout *)locked_textLayoutForSize:(CGSize)size +{ + ASTextContainer *container = [_textContainer copy]; + container.size = size; + return ASTextNodeCompatibleLayoutWithContainerAndText(container, _attributedText); } - (NSUInteger)maximumNumberOfLines From cb154f1471482bd80c9b128403ddcca63e9fedb7 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Sun, 21 Oct 2018 11:49:02 -0700 Subject: [PATCH 20/60] Let ASNodeController conform to NSLocking (#1179) --- CHANGELOG.md | 1 + Source/ASNodeController+Beta.h | 3 ++- Source/ASNodeController+Beta.mm | 24 ++++++++++++++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e7d47f9fc..1e60016913 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ - Fix mismatch in UIAccessibilityAction selector method [Michael Schneider](https://github.com/maicki) [#1169](https://github.com/TextureGroup/Texture/pull/1169) - [ASDisplayNode] Expose default Texture-set accessibility values as properties. [Jia Wern Lim](https://github.com/jiawernlim) [#1170](https://github.com/TextureGroup/Texture/pull/1170) - ASTableNode init method match checks from ASCollectionNode [Michael Schneider](https://github.com/maicki) [#1171] +- Add NSLocking conformance to ASNodeController [Michael Schneider](https://github.com/maicki)[#1179] (https://github.com/TextureGroup/Texture/pull/1179) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASNodeController+Beta.h b/Source/ASNodeController+Beta.h index e5bcc29622..65150b0e59 100644 --- a/Source/ASNodeController+Beta.h +++ b/Source/ASNodeController+Beta.h @@ -11,7 +11,8 @@ #import // for ASInterfaceState protocol /* ASNodeController is currently beta and open to change in the future */ -@interface ASNodeController<__covariant DisplayNodeType : ASDisplayNode *> : NSObject +@interface ASNodeController<__covariant DisplayNodeType : ASDisplayNode *> + : NSObject @property (nonatomic, strong /* may be weak! */) DisplayNodeType node; diff --git a/Source/ASNodeController+Beta.mm b/Source/ASNodeController+Beta.mm index 201b3cfb93..05d0ba14ee 100644 --- a/Source/ASNodeController+Beta.mm +++ b/Source/ASNodeController+Beta.mm @@ -7,10 +7,11 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import #import #import #import +#import +#import #define _node (_shouldInvertStrongReference ? _weakNode : _strongNode) @@ -18,15 +19,18 @@ { ASDisplayNode *_strongNode; __weak ASDisplayNode *_weakNode; + ASDN::RecursiveMutex __instanceLock__; } - (void)loadNode { + ASLockScopeSelf(); self.node = [[ASDisplayNode alloc] init]; } - (ASDisplayNode *)node { + ASLockScopeSelf(); if (_node == nil) { [self loadNode]; } @@ -35,6 +39,7 @@ - (void)setupReferencesWithNode:(ASDisplayNode *)node { + ASLockScopeSelf(); if (_shouldInvertStrongReference) { // The node should own the controller; weak reference from controller to node. _weakNode = node; @@ -51,11 +56,13 @@ - (void)setNode:(ASDisplayNode *)node { + ASLockScopeSelf(); [self setupReferencesWithNode:node]; } - (void)setShouldInvertStrongReference:(BOOL)shouldInvertStrongReference { + ASLockScopeSelf(); if (_shouldInvertStrongReference != shouldInvertStrongReference) { // Because the BOOL controls which ivar we access, get the node before toggling. ASDisplayNode *node = _node; @@ -82,11 +89,24 @@ - (void)hierarchyDisplayDidFinish {} +#pragma mark NSLocking + +- (void)lock +{ + __instanceLock__.lock(); +} + +- (void)unlock +{ + __instanceLock__.unlock(); +} + @end @implementation ASDisplayNode (ASNodeController) -- (ASNodeController *)nodeController { +- (ASNodeController *)nodeController +{ return _weakNodeController ?: _strongNodeController; } From 9664364e4bcb72378f2a6cb823c16e53aa0cfaf8 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Sun, 21 Oct 2018 08:50:16 -1000 Subject: [PATCH 21/60] Small fix in ASTextKitRenderer #trivial (#1167) --- Source/TextKit/ASTextKitRenderer.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/TextKit/ASTextKitRenderer.mm b/Source/TextKit/ASTextKitRenderer.mm index a11283bd86..c7efb1d10e 100644 --- a/Source/TextKit/ASTextKitRenderer.mm +++ b/Source/TextKit/ASTextKitRenderer.mm @@ -111,11 +111,13 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet() _currentScaleFactor = [[self fontSizeAdjuster] scaleFactor]; } + const CGRect constrainedRect = {CGPointZero, _constrainedSize}; + // If we do not scale, do exclusion, or do custom truncation, we should just use NSAttributedString drawing for a fast-path. if (self.canUseFastPath) { CGRect rect = [_attributes.attributedString boundingRectWithSize:_constrainedSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine context:self.stringDrawingContext]; // Intersect with constrained rect, in case text kit goes out-of-bounds. - rect = CGRectIntersection(rect, {CGPointZero, _constrainedSize}); + rect = CGRectIntersection(rect, constrainedRect); _calculatedSize = [self.shadower outsetSizeWithInsetSize:rect.size]; return; } @@ -136,7 +138,6 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet() [[self truncater] truncate]; - CGRect constrainedRect = {CGPointZero, _constrainedSize}; __block CGRect boundingRect; // Force glyph generation and layout, which may not have happened yet (and isn't triggered by @@ -153,7 +154,7 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet() // TextKit often returns incorrect glyph bounding rects in the horizontal direction, so we clip to our bounding rect // to make sure our width calculations aren't being offset by glyphs going beyond the constrained rect. - boundingRect = CGRectIntersection(boundingRect, {.size = constrainedRect.size}); + boundingRect = CGRectIntersection(boundingRect, constrainedRect); _calculatedSize = [_shadower outsetSizeWithInsetSize:boundingRect.size]; } From 3d2a612487266812ded33188f9723edfae859228 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Tue, 23 Oct 2018 08:25:03 -0700 Subject: [PATCH 22/60] Remove unnecessary ASWeakProxy import (#1186) --- Source/ASNodeController+Beta.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/ASNodeController+Beta.mm b/Source/ASNodeController+Beta.mm index 05d0ba14ee..faaf8565da 100644 --- a/Source/ASNodeController+Beta.mm +++ b/Source/ASNodeController+Beta.mm @@ -11,7 +11,6 @@ #import #import #import -#import #define _node (_shouldInvertStrongReference ? _weakNode : _strongNode) From 1d78a3d07ffdd5d570b8f51aa9b997ff19c93413 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Tue, 23 Oct 2018 08:30:54 -0700 Subject: [PATCH 23/60] Directly use __instanceLock__ to lock / unlock without having to create and destroy a MutextUnlocker (#1185) --- Source/ASDisplayNode+Layout.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/ASDisplayNode+Layout.mm b/Source/ASDisplayNode+Layout.mm index bf85800aba..979db6ca39 100644 --- a/Source/ASDisplayNode+Layout.mm +++ b/Source/ASDisplayNode+Layout.mm @@ -395,8 +395,9 @@ ASLayoutElementStyleExtensibilityForwarding nextLayout.requestedLayoutFromAbove = YES; { - ASDN::MutexUnlocker u(__instanceLock__); + __instanceLock__.unlock(); [self _u_setNeedsLayoutFromAbove]; + __instanceLock__.lock(); } // Update the layout's version here because _u_setNeedsLayoutFromAbove calls __setNeedsLayout which in turn increases _layoutVersion From dab3281afa1eb93838b5dcad4af8908de69360c7 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Wed, 24 Oct 2018 07:49:58 -0700 Subject: [PATCH 24/60] =?UTF-8?q?=20Don=E2=80=99t=20handle=20touches=20on?= =?UTF-8?q?=20additional=20attributed=20message=20if=20passthrough=20is=20?= =?UTF-8?q?enabled=20(#1184)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Don’t handle touches on additional attributed message if passthrough is enabled * Cleanup * Don't handle extra inAdditionalTruncationMessage within pointInside:withEvent: * Update changelog * Address comments --- CHANGELOG.md | 1 + Source/ASTextNode.mm | 6 +-- Source/ASTextNode2.mm | 72 +++++++++++++++++++++++---- examples/Kittens/Sample/AppDelegate.m | 11 ++++ 4 files changed, 75 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e60016913..9a3e684671 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,7 @@ - [ASDisplayNode] Expose default Texture-set accessibility values as properties. [Jia Wern Lim](https://github.com/jiawernlim) [#1170](https://github.com/TextureGroup/Texture/pull/1170) - ASTableNode init method match checks from ASCollectionNode [Michael Schneider](https://github.com/maicki) [#1171] - Add NSLocking conformance to ASNodeController [Michael Schneider](https://github.com/maicki)[#1179] (https://github.com/TextureGroup/Texture/pull/1179) +- Don’t handle touches on additional attributed message if passthrough is enabled [Michael Schneider](https://github.com/maicki)[#1184] (https://github.com/TextureGroup/Texture/pull/1184) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index accbea3ad5..c6a8ca10ad 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -973,9 +973,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI NSUInteger lastCharIndex = NSIntegerMax; BOOL linkCrossesVisibleRange = (lastCharIndex > range.location) && (lastCharIndex < NSMaxRange(range) - 1); - if (inAdditionalTruncationMessage) { - return YES; - } else if (range.length && !linkCrossesVisibleRange && linkAttributeValue != nil && linkAttributeName != nil) { + if (range.length > 0 && !linkCrossesVisibleRange && linkAttributeValue != nil && linkAttributeName != nil) { return YES; } else { return NO; @@ -1011,7 +1009,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI } NSRange truncationMessageRange = [self _additionalTruncationMessageRangeWithVisibleRange:visibleRange]; [self _setHighlightRange:truncationMessageRange forAttributeName:ASTextNodeTruncationTokenAttributeName value:nil animated:YES]; - } else if (range.length && !linkCrossesVisibleRange && linkAttributeValue != nil && linkAttributeName != nil) { + } else if (range.length > 0 && !linkCrossesVisibleRange && linkAttributeValue != nil && linkAttributeName != nil) { [self _setHighlightRange:range forAttributeName:linkAttributeName value:linkAttributeValue animated:YES]; } } diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 6d894be82d..4a43278da9 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -572,20 +572,17 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; ASTextContainer *containerCopy = [_textContainer copy]; containerCopy.size = self.calculatedSize; ASTextLayout *layout = ASTextNodeCompatibleLayoutWithContainerAndText(containerCopy, _attributedText); - NSRange visibleRange = layout.visibleRange; - NSRange clampedRange = NSIntersectionRange(visibleRange, NSMakeRange(0, _attributedText.length)); - ASTextRange *range = [layout closestTextRangeAtPoint:point]; - - // For now, assume that a tap inside this text, but outside the text range is a tap on the - // truncation token. - if (![layout textRangeAtPoint:point]) { + if ([self _locked_pointInsideAdditionalTruncationMessage:point withLayout:layout]) { if (inAdditionalTruncationMessageOut != NULL) { *inAdditionalTruncationMessageOut = YES; } return nil; } + NSRange visibleRange = layout.visibleRange; + NSRange clampedRange = NSIntersectionRange(visibleRange, NSMakeRange(0, _attributedText.length)); + ASTextRange *range = [layout closestTextRangeAtPoint:point]; NSRange effectiveRange = NSMakeRange(0, 0); for (__strong NSString *attributeName in self.linkAttributeNames) { id value = [self.attributedText attribute:attributeName atIndex:range.start.offset longestEffectiveRange:&effectiveRange inRange:clampedRange]; @@ -617,6 +614,61 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; return nil; } +- (BOOL)_locked_pointInsideAdditionalTruncationMessage:(CGPoint)point withLayout:(ASTextLayout *)layout +{ + // Check if the range is within the additional truncation range + BOOL inAdditionalTruncationMessage = NO; + + CTLineRef truncatedCTLine = layout.truncatedLine.CTLine; + if (truncatedCTLine != NULL && _additionalTruncationMessage != nil) { + CFIndex stringIndexForPosition = CTLineGetStringIndexForPosition(truncatedCTLine, point); + if (stringIndexForPosition != kCFNotFound) { + CFIndex truncatedCTLineGlyphCount = CTLineGetGlyphCount(truncatedCTLine); + + CTLineRef truncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)_truncationAttributedText); + CFIndex truncationTokenLineGlyphCount = truncationTokenLine ? CTLineGetGlyphCount(truncationTokenLine) : 0; + + CTLineRef additionalTruncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)_additionalTruncationMessage); + CFIndex additionalTruncationTokenLineGlyphCount = additionalTruncationTokenLine ? CTLineGetGlyphCount(additionalTruncationTokenLine) : 0; + + switch (_textContainer.truncationType) { + case ASTextTruncationTypeStart: { + CFIndex composedTruncationTextLineGlyphCount = truncationTokenLineGlyphCount + additionalTruncationTokenLineGlyphCount; + if (stringIndexForPosition > truncationTokenLineGlyphCount && + stringIndexForPosition < composedTruncationTextLineGlyphCount) { + inAdditionalTruncationMessage = YES; + } + break; + } + case ASTextTruncationTypeMiddle: { + CFIndex composedTruncationTextLineGlyphCount = truncationTokenLineGlyphCount + additionalTruncationTokenLineGlyphCount; + CFIndex firstTruncatedTokenIndex = (truncatedCTLineGlyphCount - composedTruncationTextLineGlyphCount) / 2.0; + if ((firstTruncatedTokenIndex + truncationTokenLineGlyphCount) < stringIndexForPosition && + stringIndexForPosition < (firstTruncatedTokenIndex + composedTruncationTextLineGlyphCount)) { + inAdditionalTruncationMessage = YES; + } + break; + } + case ASTextTruncationTypeEnd: { + if (stringIndexForPosition > (truncatedCTLineGlyphCount - additionalTruncationTokenLineGlyphCount)) { + inAdditionalTruncationMessage = YES; + } + break; + } + default: + // For now, assume that a tap inside this text, but outside the text range is a tap on the + // truncation token. + if (![layout textRangeAtPoint:point]) { + inAdditionalTruncationMessage = YES; + } + break; + } + } + } + + return inAdditionalTruncationMessage; +} + #pragma mark - UIGestureRecognizerDelegate - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer @@ -789,9 +841,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; NSUInteger lastCharIndex = NSIntegerMax; BOOL linkCrossesVisibleRange = (lastCharIndex > range.location) && (lastCharIndex < NSMaxRange(range) - 1); - if (inAdditionalTruncationMessage) { - return YES; - } else if (range.length && !linkCrossesVisibleRange && linkAttributeValue != nil && linkAttributeName != nil) { + if (range.length > 0 && !linkCrossesVisibleRange && linkAttributeValue != nil && linkAttributeName != nil) { return YES; } else { return NO; @@ -832,7 +882,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; } NSRange truncationMessageRange = [self _additionalTruncationMessageRangeWithVisibleRange:visibleRange]; [self _setHighlightRange:truncationMessageRange forAttributeName:ASTextNodeTruncationTokenAttributeName value:nil animated:YES]; - } else if (range.length && !linkCrossesVisibleRange && linkAttributeValue != nil && linkAttributeName != nil) { + } else if (range.length > 0 && !linkCrossesVisibleRange && linkAttributeValue != nil && linkAttributeName != nil) { [self _setHighlightRange:range forAttributeName:linkAttributeName value:linkAttributeValue animated:YES]; } diff --git a/examples/Kittens/Sample/AppDelegate.m b/examples/Kittens/Sample/AppDelegate.m index d9465e0de7..2395642bd1 100644 --- a/examples/Kittens/Sample/AppDelegate.m +++ b/examples/Kittens/Sample/AppDelegate.m @@ -24,3 +24,14 @@ } @end + +@implementation ASConfiguration (UserProvided) + ++ (ASConfiguration *)textureConfiguration +{ + ASConfiguration *configuration = [ASConfiguration new]; + return configuration; + +} + +@end From 097790317ee7835173027ded3eeda05edc3546ad Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Wed, 24 Oct 2018 10:27:58 -0700 Subject: [PATCH 25/60] Yoga integration improvements (#1187) * Thread safety for Yoga layout * Support baseline alignments for ASYogaLayout * Refactor ASLayoutElementYogaBaselineFunc to not require yogaParent (its parent style is set into a private var on ASLayoutElementStyle before layout instead) * Only set the accessibility element if the view is loaded * Add nodeWillCalculateLayout to ASNodeController * Update Changelog * Address first comments --- CHANGELOG.md | 1 + Source/ASDisplayNode+Beta.h | 3 ++ Source/ASDisplayNode+InterfaceState.h | 11 +++++ Source/ASDisplayNode+Layout.mm | 6 +++ Source/ASDisplayNode+Yoga.mm | 34 ++++++++++++++- Source/ASNodeController+Beta.h | 3 ++ Source/ASNodeController+Beta.mm | 1 + Source/Layout/ASLayoutElement.mm | 14 ++++++- Source/Layout/ASYogaUtilities.h | 6 ++- Source/Layout/ASYogaUtilities.mm | 42 +++++++++++++++---- .../Layout/ASLayoutElementStylePrivate.h | 3 ++ 11 files changed, 112 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a3e684671..23b3e097a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ - ASTableNode init method match checks from ASCollectionNode [Michael Schneider](https://github.com/maicki) [#1171] - Add NSLocking conformance to ASNodeController [Michael Schneider](https://github.com/maicki)[#1179] (https://github.com/TextureGroup/Texture/pull/1179) - Don’t handle touches on additional attributed message if passthrough is enabled [Michael Schneider](https://github.com/maicki)[#1184] (https://github.com/TextureGroup/Texture/pull/1184) +- Yoga integration improvements [Michael Schneider](https://github.com/maicki)[#1187] (https://github.com/TextureGroup/Texture/pull/1187) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASDisplayNode+Beta.h b/Source/ASDisplayNode+Beta.h index affe99cb25..01c08609e0 100644 --- a/Source/ASDisplayNode+Beta.h +++ b/Source/ASDisplayNode+Beta.h @@ -200,6 +200,9 @@ AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullab @property BOOL yogaLayoutInProgress; @property (nullable, nonatomic) ASLayout *yogaCalculatedLayout; +// Will walk up the Yoga tree and returns the root node +- (ASDisplayNode *)yogaRoot; + // These methods are intended to be used internally to Texture, and should not be called directly. - (BOOL)shouldHaveYogaMeasureFunc; - (void)invalidateCalculatedYogaLayout; diff --git a/Source/ASDisplayNode+InterfaceState.h b/Source/ASDisplayNode+InterfaceState.h index ec4414bb77..1de83700ac 100644 --- a/Source/ASDisplayNode+InterfaceState.h +++ b/Source/ASDisplayNode+InterfaceState.h @@ -116,4 +116,15 @@ typedef NS_OPTIONS(NSUInteger, ASInterfaceState) */ - (void)hierarchyDisplayDidFinish; +@optional +/** + * @abstract Called when the node is about to calculate layout. This is only called before + * Yoga-driven layouts. + * @discussion Can be used for operations that are performed after the node's view is available. + * @note This method is guaranteed to be called on main, but implementations should be careful not + * to attempt to ascend the node tree when handling this, as the root node is locked when this is + * called. + */ +- (void)nodeWillCalculateLayout:(ASSizeRange)constrainedSize; + @end diff --git a/Source/ASDisplayNode+Layout.mm b/Source/ASDisplayNode+Layout.mm index 979db6ca39..205d8b1ffd 100644 --- a/Source/ASDisplayNode+Layout.mm +++ b/Source/ASDisplayNode+Layout.mm @@ -999,6 +999,12 @@ ASLayoutElementStyleExtensibilityForwarding _pendingLayoutTransition = nil; } +- (void)_setCalculatedDisplayNodeLayout:(const ASDisplayNodeLayout &)displayNodeLayout +{ + ASDN::MutexLocker l(__instanceLock__); + [self _locked_setCalculatedDisplayNodeLayout:displayNodeLayout]; +} + - (void)_locked_setCalculatedDisplayNodeLayout:(const ASDisplayNodeLayout &)displayNodeLayout { ASAssertLocked(__instanceLock__); diff --git a/Source/ASDisplayNode+Yoga.mm b/Source/ASDisplayNode+Yoga.mm index 8f4cfdc63a..93615cdd6c 100644 --- a/Source/ASDisplayNode+Yoga.mm +++ b/Source/ASDisplayNode+Yoga.mm @@ -19,6 +19,7 @@ #import #import #import +#import #define YOGA_LAYOUT_LOGGING 0 @@ -31,8 +32,19 @@ @implementation ASDisplayNode (Yoga) +- (ASDisplayNode *)yogaRoot +{ + ASDisplayNode *yogaRoot = self; + ASDisplayNode *yogaParent = nil; + while ((yogaParent = yogaRoot.yogaParent)) { + yogaRoot = yogaParent; + } + return yogaRoot; +} + - (void)setYogaChildren:(NSArray *)yogaChildren { + ASLockScope(self.yogaRoot); for (ASDisplayNode *child in [_yogaChildren copy]) { // Make sure to un-associate the YGNodeRef tree before replacing _yogaChildren // If this becomes a performance bottleneck, it can be optimized by not doing the NSArray removals here. @@ -51,11 +63,13 @@ - (void)addYogaChild:(ASDisplayNode *)child { + ASLockScope(self.yogaRoot); [self insertYogaChild:child atIndex:_yogaChildren.count]; } - (void)removeYogaChild:(ASDisplayNode *)child { + ASLockScope(self.yogaRoot); if (child == nil) { return; } @@ -68,6 +82,7 @@ - (void)insertYogaChild:(ASDisplayNode *)child atIndex:(NSUInteger)index { + ASLockScope(self.yogaRoot); if (child == nil) { return; } @@ -216,6 +231,7 @@ - (BOOL)shouldHaveYogaMeasureFunc { // Size calculation via calculateSizeThatFits: or layoutSpecThatFits: + // For these nodes, we assume they may need custom Baseline calculation too. // This will be used for ASTextNode, as well as any other node that has no Yoga children BOOL isLeafNode = (self.yogaChildren.count == 0); BOOL definesCustomLayout = [self implementsLayoutMethod]; @@ -261,11 +277,23 @@ return; } + [self enumerateInterfaceStateDelegates:^(id _Nonnull delegate) { + if ([delegate respondsToSelector:@selector(nodeWillCalculateLayout:)]) { + [delegate nodeWillCalculateLayout:rootConstrainedSize]; + } + }]; + ASLockScopeSelf(); // Prepare all children for the layout pass with the current Yoga tree configuration. - ASDisplayNodePerformBlockOnEveryYogaChild(self, ^(ASDisplayNode * _Nonnull node) { + ASDisplayNodePerformBlockOnEveryYogaChild(self, ^(ASDisplayNode *_Nonnull node) { node.yogaLayoutInProgress = YES; + ASDisplayNode *yogaParent = node.yogaParent; + if (yogaParent) { + node.style.parentAlignStyle = yogaParent.style.alignItems; + } else { + node.style.parentAlignStyle = ASStackLayoutAlignItemsNotSet; + }; }); if (ASSizeRangeEqualToSizeRange(rootConstrainedSize, ASSizeRangeUnconstrained)) { @@ -293,7 +321,9 @@ // Reset accessible elements, since layout may have changed. ASPerformBlockOnMainThread(^{ - [(_ASDisplayView *)self.view setAccessibilityElements:nil]; + if (self.nodeLoaded && !self.isSynchronous) { + [(_ASDisplayView *)self.view setAccessibilityElements:nil]; + } }); ASDisplayNodePerformBlockOnEveryYogaChild(self, ^(ASDisplayNode * _Nonnull node) { diff --git a/Source/ASNodeController+Beta.h b/Source/ASNodeController+Beta.h index 65150b0e59..d7f4e116e8 100644 --- a/Source/ASNodeController+Beta.h +++ b/Source/ASNodeController+Beta.h @@ -27,6 +27,9 @@ - (void)nodeDidLoad ASDISPLAYNODE_REQUIRES_SUPER; - (void)nodeDidLayout ASDISPLAYNODE_REQUIRES_SUPER; +// This is only called during Yoga-driven layouts. +- (void)nodeWillCalculateLayout:(ASSizeRange)constrainedSize ASDISPLAYNODE_REQUIRES_SUPER; + - (void)didEnterVisibleState ASDISPLAYNODE_REQUIRES_SUPER; - (void)didExitVisibleState ASDISPLAYNODE_REQUIRES_SUPER; diff --git a/Source/ASNodeController+Beta.mm b/Source/ASNodeController+Beta.mm index faaf8565da..767f23942c 100644 --- a/Source/ASNodeController+Beta.mm +++ b/Source/ASNodeController+Beta.mm @@ -73,6 +73,7 @@ // subclass overrides - (void)nodeDidLoad {} - (void)nodeDidLayout {} +- (void)nodeWillCalculateLayout:(ASSizeRange)constrainedSize {} - (void)didEnterVisibleState {} - (void)didExitVisibleState {} diff --git a/Source/Layout/ASLayoutElement.mm b/Source/Layout/ASLayoutElement.mm index ace1103da1..336b2acdcb 100644 --- a/Source/Layout/ASLayoutElement.mm +++ b/Source/Layout/ASLayoutElement.mm @@ -155,7 +155,7 @@ do {\ @implementation ASLayoutElementStyle { ASDN::RecursiveMutex __instanceLock__; ASLayoutElementStyleExtensions _extensions; - + std::atomic _size; std::atomic _spacingBefore; std::atomic _spacingAfter; @@ -180,6 +180,7 @@ do {\ std::atomic _padding; std::atomic _border; std::atomic _aspectRatio; + ASStackLayoutAlignItems _parentAlignStyle; #endif } @@ -202,6 +203,9 @@ do {\ self = [super init]; if (self) { _size = ASLayoutElementSizeMake(); +#if YOGA + _parentAlignStyle = ASStackLayoutAlignItemsNotSet; +#endif } return self; } @@ -777,6 +781,10 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__) - (ASEdgeInsets)padding { return _padding.load(); } - (ASEdgeInsets)border { return _border.load(); } - (CGFloat)aspectRatio { return _aspectRatio.load(); } +// private (ASLayoutElementStylePrivate.h) +- (ASStackLayoutAlignItems)parentAlignStyle { + return _parentAlignStyle; +} - (void)setFlexWrap:(YGWrap)flexWrap { _flexWrap.store(flexWrap); @@ -822,6 +830,10 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__) _aspectRatio.store(aspectRatio); ASLayoutElementStyleCallDelegate(ASYogaAspectRatioProperty); } +// private (ASLayoutElementStylePrivate.h) +- (void)setParentAlignStyle:(ASStackLayoutAlignItems)style { + _parentAlignStyle = style; +} #endif /* YOGA */ diff --git a/Source/Layout/ASYogaUtilities.h b/Source/Layout/ASYogaUtilities.h index cad80ecb0f..c3d1d8233c 100644 --- a/Source/Layout/ASYogaUtilities.h +++ b/Source/Layout/ASYogaUtilities.h @@ -26,6 +26,7 @@ @end +// pre-order, depth-first AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode *node, void(^block)(ASDisplayNode *node)); #pragma mark - Yoga Type Conversion Helpers @@ -40,9 +41,10 @@ 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, - float width, YGMeasureMode widthMode, - float height, YGMeasureMode heightMode); + float width, YGMeasureMode widthMode, + float height, YGMeasureMode heightMode); #pragma mark - Yoga Style Setter Helpers diff --git a/Source/Layout/ASYogaUtilities.mm b/Source/Layout/ASYogaUtilities.mm index 2cca2307c3..fa6e135920 100644 --- a/Source/Layout/ASYogaUtilities.mm +++ b/Source/Layout/ASYogaUtilities.mm @@ -7,7 +7,7 @@ // #import - +#import #if YOGA /* YOGA */ @implementation ASDisplayNode (YogaHelpers) @@ -143,23 +143,51 @@ void ASLayoutElementYogaUpdateMeasureFunc(YGNodeRef yogaNode, id element = (__bridge_transfer id)YGNodeGetContext(yogaNode); + __unused id element = (__bridge_transfer id)YGNodeGetContext(yogaNode); YGNodeSetContext(yogaNode, NULL); YGNodeSetMeasureFunc(yogaNode, NULL); + YGNodeSetBaselineFunc(yogaNode, NULL); + } +} + +float ASLayoutElementYogaBaselineFunc(YGNodeRef yogaNode, const float width, const float height) +{ + id layoutElement = (__bridge id)YGNodeGetContext(yogaNode); + ASDisplayNodeCAssert([layoutElement conformsToProtocol:@protocol(ASLayoutElement)], + @"Yoga context must be "); + + ASDisplayNode *displayNode = ASDynamicCast(layoutElement, ASDisplayNode); + + switch (displayNode.style.parentAlignStyle) { + case ASStackLayoutAlignItemsBaselineFirst: + return layoutElement.style.ascender; + case ASStackLayoutAlignItemsBaselineLast: + return height + layoutElement.style.descender; + default: + return 0; } } diff --git a/Source/Private/Layout/ASLayoutElementStylePrivate.h b/Source/Private/Layout/ASLayoutElementStylePrivate.h index 375be772e9..69e29824ef 100644 --- a/Source/Private/Layout/ASLayoutElementStylePrivate.h +++ b/Source/Private/Layout/ASLayoutElementStylePrivate.h @@ -9,6 +9,7 @@ #pragma once +#import #import @interface ASLayoutElementStyle () @@ -25,4 +26,6 @@ */ @property (nonatomic, readonly) ASLayoutElementSize size; +@property (nonatomic, assign) ASStackLayoutAlignItems parentAlignStyle; + @end From 14681c00c49aa5338b9b9a739de7230607bfdfe4 Mon Sep 17 00:00:00 2001 From: Max Wang Date: Wed, 24 Oct 2018 12:58:57 -0700 Subject: [PATCH 26/60] Assert node did load before did enter visible way 1 (#886) * fix SIMULATE_WEB_RESPONSE not imported #449 * Fix to make rangeMode update in right time * access layer to load node before enter visible * revert space --- CHANGELOG.md | 1 + Source/ASDisplayNode.mm | 16 +++++++++++++++- Tests/ASNetworkImageNodeTests.m | 1 + Tests/ASVideoNodeTests.m | 12 +++++++----- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23b3e097a6..f0e4cd1894 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master * Add your own contributions to the next release on the line below this with your name. +- [ASDisplayNode.m] Make sure node is loaded before enter visible. [Max Wang](https://github.com/wsdwsd0829). [#886](https://github.com/TextureGroup/Texture/pull/886) - [ASTextNode2] Add improved support for all line-break modes in experimental text node. [Kevin Smith](https://github.com/wiseoldduck). [#1150](https://github.com/TextureGroup/Texture/pull/1150) - [ASExperimentalFeatures.m] Fix mismatch name in experimental features. [Max Wang](https://github.com/wsdwsd0829). [#1159](https://github.com/TextureGroup/Texture/pull/1159) - [ASCollectionViewLayoutController] Set default tuning parameters before view is loaded. [Max Wang](https://github.com/wsdwsd0829). [#1158](https://github.com/TextureGroup/Texture/pull/1158) diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 7dd5c7d79c..24adf9414d 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -2265,7 +2265,14 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { [_subnodes insertObject:subnode atIndex:subnodeIndex]; _cachedSubnodes = nil; __instanceLock__.unlock(); - + + if (!isRasterized && self.nodeLoaded) { + // Trigger the subnode to load its layer, which will create its view if it needs one. + // By doing this prior to downward propagation of .interfaceState in _setSupernode:, + // we can guarantee that -didEnterVisibleState is only called with .isNodeLoaded = YES. + [subnode layer]; + } + // This call will apply our .hierarchyState to the new subnode. // If we are a managed hierarchy, as in ASCellNode trees, it will also apply our .interfaceState. [subnode _setSupernode:self]; @@ -3272,10 +3279,17 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { { // subclass override ASDisplayNodeAssertMainThread(); + + // Rasterized node's loading state is merged with root node of rasterized tree. + if (!(self.hierarchyState & ASHierarchyStateRasterized)) { + ASDisplayNodeAssert(self.isNodeLoaded, @"Node should be loaded before entering visible state."); + } + ASAssertUnlocked(__instanceLock__); [self enumerateInterfaceStateDelegates:^(id del) { [del didEnterVisibleState]; }]; + #if AS_ENABLE_TIPS [ASTipsController.shared nodeDidAppear:self]; #endif diff --git a/Tests/ASNetworkImageNodeTests.m b/Tests/ASNetworkImageNodeTests.m index 1dcc363e09..20026a995b 100644 --- a/Tests/ASNetworkImageNodeTests.m +++ b/Tests/ASNetworkImageNodeTests.m @@ -57,6 +57,7 @@ - (void)testThatProgressBlockIsSetAndClearedCorrectlyOnChangeURL { + [node layer]; [node enterInterfaceState:ASInterfaceStateInHierarchy]; // Set URL while visible, should set progress block diff --git a/Tests/ASVideoNodeTests.m b/Tests/ASVideoNodeTests.m index 6a4311cfce..727d5666b8 100644 --- a/Tests/ASVideoNodeTests.m +++ b/Tests/ASVideoNodeTests.m @@ -199,9 +199,9 @@ - (void)doPlayerLayerNodeIsNotAddedIfVisibleButShouldNotBePlaying { [_videoNode pause]; + [_videoNode layer]; [_videoNode setInterfaceState:ASInterfaceStateVisible | ASInterfaceStateDisplay]; - [_videoNode didLoad]; - + XCTAssert(![_videoNode.subnodes containsObject:_videoNode.playerNode]); } @@ -226,7 +226,8 @@ return playerLayer; }]; _videoNode.playerNode.layer.frame = CGRectZero; - + + [_videoNode layer]; [_videoNode didEnterVisibleState]; XCTAssertTrue(_videoNode.shouldBePlaying); @@ -304,7 +305,7 @@ _videoNode.asset = assetMock; _videoNode.shouldAutorepeat = NO; - [_videoNode didLoad]; + [_videoNode layer]; [_videoNode setInterfaceState:ASInterfaceStateVisible | ASInterfaceStateDisplay | ASInterfaceStatePreload]; [_videoNode prepareToPlayAsset:assetMock withKeys:_requestedKeys]; [_videoNode play]; @@ -325,7 +326,7 @@ _videoNode.asset = assetMock; _videoNode.shouldAutorepeat = YES; - [_videoNode didLoad]; + [_videoNode layer]; [_videoNode setInterfaceState:ASInterfaceStateVisible | ASInterfaceStateDisplay | ASInterfaceStatePreload]; [_videoNode prepareToPlayAsset:assetMock withKeys:_requestedKeys]; [_videoNode play]; @@ -342,6 +343,7 @@ _videoNode.asset = assetMock; + [_videoNode layer]; [_videoNode setInterfaceState:ASInterfaceStateVisible | ASInterfaceStateDisplay | ASInterfaceStatePreload]; [_videoNode prepareToPlayAsset:assetMock withKeys:_requestedKeys]; ASCATransactionQueueWait(nil); From 8382edd7ef5a8c2cf42695edcaa3b44006e5260a Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 25 Oct 2018 08:47:22 -0700 Subject: [PATCH 27/60] Move AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE into ASTextNodeCommon (#1191) --- Source/ASTextNode2.mm | 7 ------- Source/ASTextNodeCommon.h | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 4a43278da9..e11d3b9961 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -48,13 +48,6 @@ */ #define AS_TEXTNODE2_RECORD_ATTRIBUTED_STRINGS 0 -#define AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE() { \ - static dispatch_once_t onceToken; \ - dispatch_once(&onceToken, ^{ \ - NSLog(@"[Texture] Warning: Feature %@ is unimplemented in the experimental text node.", NSStringFromSelector(_cmd)); \ - });\ -} - /** * If it can't find a compatible layout, this method creates one. * diff --git a/Source/ASTextNodeCommon.h b/Source/ASTextNodeCommon.h index c702561e63..fbb32ca39e 100644 --- a/Source/ASTextNodeCommon.h +++ b/Source/ASTextNodeCommon.h @@ -10,6 +10,13 @@ @class ASTextNode; +#define AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE() { \ + static dispatch_once_t onceToken; \ + dispatch_once(&onceToken, ^{ \ + NSLog(@"[Texture] Warning: Feature %@ is unimplemented in %@.", NSStringFromSelector(_cmd), NSStringFromClass(self.class)); \ + });\ +} + /** * Highlight styles. */ From 25a3d331ee6a211aaf086c94f5768dff47884090 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Fri, 26 Oct 2018 07:43:22 -0700 Subject: [PATCH 28/60] Correct linePositionModifier behavior (#1192) --- CHANGELOG.md | 1 + Source/ASTextNode.h | 9 ++++ Source/ASTextNode.mm | 15 +++++++ Source/ASTextNode2.h | 6 +++ Source/ASTextNode2.mm | 11 +++++ .../TextExperiment/Component/ASTextLayout.m | 43 ++++++++++++------- 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0e4cd1894..a5e88138b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ - Add NSLocking conformance to ASNodeController [Michael Schneider](https://github.com/maicki)[#1179] (https://github.com/TextureGroup/Texture/pull/1179) - Don’t handle touches on additional attributed message if passthrough is enabled [Michael Schneider](https://github.com/maicki)[#1184] (https://github.com/TextureGroup/Texture/pull/1184) - Yoga integration improvements [Michael Schneider](https://github.com/maicki)[#1187] (https://github.com/TextureGroup/Texture/pull/1187) +- Correct linePositionModifier behavior [Michael Schneider](https://github.com/maicki)[#1192] (https://github.com/TextureGroup/Texture/pull/1192) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASTextNode.h b/Source/ASTextNode.h index b6c676a3a6..1048017e79 100644 --- a/Source/ASTextNode.h +++ b/Source/ASTextNode.h @@ -217,6 +217,15 @@ NS_ASSUME_NONNULL_BEGIN @end +/** + * @abstract Text node unsupported properties + */ +@interface ASTextNode (Unsupported) + +@property (nullable, nonatomic) id textContainerLinePositionModifier; + +@end + /** * @abstract Text node deprecated properties */ diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index c6a8ca10ad..ac39f8a5b3 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -1389,6 +1389,21 @@ static NSAttributedString *DefaultTruncationAttributedString() @end +@implementation ASTextNode (Unsupported) + +- (void)setTextContainerLinePositionModifier:(id)textContainerLinePositionModifier +{ + AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE(); +} + +- (id)textContainerLinePositionModifier +{ + AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE(); + return nil; +} + +@end + @implementation ASTextNode (Deprecated) - (void)setAttributedString:(NSAttributedString *)attributedString diff --git a/Source/ASTextNode2.h b/Source/ASTextNode2.h index 7718672515..442a476025 100644 --- a/Source/ASTextNode2.h +++ b/Source/ASTextNode2.h @@ -9,6 +9,8 @@ #import #import +@protocol ASTextLinePositionModifier; + NS_ASSUME_NONNULL_BEGIN /** @@ -207,6 +209,10 @@ NS_ASSUME_NONNULL_BEGIN + (void)enableDebugging; +#pragma mark - Layout and Sizing + +@property (nullable, nonatomic) id textContainerLinePositionModifier; + @end @interface ASTextNode2 (Unavailable) diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index e11d3b9961..397bff6fab 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -318,6 +318,17 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; return _textContainer.insets; } +- (void)setTextContainerLinePositionModifier:(id)modifier +{ + ASLockedSelfCompareAssignObjects(_textContainer.linePositionModifier, modifier); +} + +- (id)textContainerLinePositionModifier +{ + ASLockScopeSelf(); + return _textContainer.linePositionModifier; +} + - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize { ASDisplayNodeAssert(constrainedSize.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.width); diff --git a/Source/Private/TextExperiment/Component/ASTextLayout.m b/Source/Private/TextExperiment/Component/ASTextLayout.m index b1d9fee59c..2612d9a69e 100644 --- a/Source/Private/TextExperiment/Component/ASTextLayout.m +++ b/Source/Private/TextExperiment/Component/ASTextLayout.m @@ -102,6 +102,13 @@ static CGColorRef ASTextGetCGColor(CGColorRef color) { id _linePositionModifier; } +- (NSString *)description +{ + return [NSString + stringWithFormat:@"immutable: %@, insets: %@, size: %@", self->_readonly ? @"YES" : @"NO", + NSStringFromUIEdgeInsets(self->_insets), NSStringFromCGSize(self->_size)]; +} + + (instancetype)containerWithSize:(CGSize)size NS_RETURNS_RETAINED { return [self containerWithSize:size insets:UIEdgeInsetsZero]; } @@ -373,6 +380,14 @@ dispatch_semaphore_signal(_lock); return self; } +- (NSString *)description +{ + return [NSString stringWithFormat:@"lines: %ld, visibleRange:%@, textBoundingRect:%@", + [self.lines count], + NSStringFromRange(self.visibleRange), + NSStringFromCGRect(self.textBoundingRect)]; +} + + (ASTextLayout *)layoutWithContainerSize:(CGSize)size text:(NSAttributedString *)text { ASTextContainer *container = [ASTextContainer containerWithSize:size]; return [self layoutWithContainer:container text:text]; @@ -599,15 +614,24 @@ dispatch_semaphore_signal(_lock); position.y = cgPathBox.size.height + cgPathBox.origin.y - ctLineOrigin.y; ASTextLine *line = [ASTextLine lineWithCTLine:ctLine position:position vertical:isVerticalForm]; + + [lines addObject:line]; + } + + // Give user a chance to modify the line's position. + [container.linePositionModifier modifyLines:lines fromText:text inContainer:container]; + + NSUInteger i = 0; + for (ASTextLine *line in lines) { + CGPoint position = line.position; CGRect rect = line.bounds; - if (constraintSizeIsExtended) { if (isVerticalForm) { if (rect.origin.x + rect.size.width > constraintRectBeforeExtended.origin.x + constraintRectBeforeExtended.size.width) { measuringBeyondConstraints = YES; - }; + } } else { if (rect.origin.y + rect.size.height > constraintRectBeforeExtended.origin.y + @@ -640,11 +664,11 @@ dispatch_semaphore_signal(_lock); line.index = lineCurrentIdx; line.row = rowIdx; - [lines addObject:line]; + rowCount = rowIdx + 1; lineCurrentIdx ++; - if (i == 0) { + if (i++ == 0) { textBoundingRect = rect; } else if (!measuringBeyondConstraints) { if (maximumNumberOfRows == 0 || rowIdx < maximumNumberOfRows) { @@ -679,17 +703,6 @@ dispatch_semaphore_signal(_lock); } } - // Give user a chance to modify the line's position. - if (container.linePositionModifier) { - [container.linePositionModifier modifyLines:lines fromText:text inContainer:container]; - textBoundingRect = CGRectZero; - for (NSUInteger i = 0, max = lines.count; i < max; i++) { - ASTextLine *line = lines[i]; - if (i == 0) textBoundingRect = line.bounds; - else textBoundingRect = CGRectUnion(textBoundingRect, line.bounds); - } - } - lineRowsEdge = (ASRowEdge *) calloc(rowCount, sizeof(ASRowEdge)); if (lineRowsEdge == NULL) FAIL_AND_RETURN lineRowsIndex = (NSUInteger *) calloc(rowCount, sizeof(NSUInteger)); From 959dafc4a1b8b29b40732ebc587acab4cf24aa00 Mon Sep 17 00:00:00 2001 From: Kevin Date: Mon, 29 Oct 2018 07:35:45 -0700 Subject: [PATCH 29/60] Update ASButtonNode.mm (#1194) --- Source/ASButtonNode.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ASButtonNode.mm b/Source/ASButtonNode.mm index e4bbb88633..46bec93c51 100644 --- a/Source/ASButtonNode.mm +++ b/Source/ASButtonNode.mm @@ -63,7 +63,7 @@ _contentVerticalAlignment = ASVerticalAlignmentCenter; _contentEdgeInsets = UIEdgeInsetsZero; _imageAlignment = ASButtonNodeImageAlignmentBeginning; - self.accessibilityTraits = self.defaultAccessibilityTraits;; + self.accessibilityTraits = self.defaultAccessibilityTraits; } return self; } From 6ea7f06d84dd1751c44834339232f5e0a673eb6a Mon Sep 17 00:00:00 2001 From: Kevin Date: Mon, 29 Oct 2018 07:55:54 -0700 Subject: [PATCH 30/60] Fix shadowed var warning (and add clarity) #trivial (#1198) * Fix shadowed var warning (and add clarity) * Update ASTextLayout.m --- Source/Private/TextExperiment/Component/ASTextLayout.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Private/TextExperiment/Component/ASTextLayout.m b/Source/Private/TextExperiment/Component/ASTextLayout.m index 2612d9a69e..dc14b29409 100644 --- a/Source/Private/TextExperiment/Component/ASTextLayout.m +++ b/Source/Private/TextExperiment/Component/ASTextLayout.m @@ -621,7 +621,7 @@ dispatch_semaphore_signal(_lock); // Give user a chance to modify the line's position. [container.linePositionModifier modifyLines:lines fromText:text inContainer:container]; - NSUInteger i = 0; + BOOL first = YES; for (ASTextLine *line in lines) { CGPoint position = line.position; CGRect rect = line.bounds; @@ -668,7 +668,8 @@ dispatch_semaphore_signal(_lock); rowCount = rowIdx + 1; lineCurrentIdx ++; - if (i++ == 0) { + if (first) { + first = NO; textBoundingRect = rect; } else if (!measuringBeyondConstraints) { if (maximumNumberOfRows == 0 || rowIdx < maximumNumberOfRows) { From 4260cc98289424632111e894fa8d990f2793bab6 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Mon, 29 Oct 2018 08:35:00 -0700 Subject: [PATCH 31/60] Tweak a11y label aggregation behavior to enable container label overrides (#1199) Modified the ASDisplayNode accessibility label to only aggregate its sub-nodes' labels when it doesn't have any explicit accessibility label set on itself. If an existing label is already present, it is instead treated as an override to the container's a11y label. Added relevant tests. --- CHANGELOG.md | 1 + Source/Details/_ASDisplayViewAccessiblity.mm | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5e88138b4..d7ef7aa4b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ - Don’t handle touches on additional attributed message if passthrough is enabled [Michael Schneider](https://github.com/maicki)[#1184] (https://github.com/TextureGroup/Texture/pull/1184) - Yoga integration improvements [Michael Schneider](https://github.com/maicki)[#1187] (https://github.com/TextureGroup/Texture/pull/1187) - Correct linePositionModifier behavior [Michael Schneider](https://github.com/maicki)[#1192] (https://github.com/TextureGroup/Texture/pull/1192) +- Tweak a11y label aggregation behavior to enable container label overrides [Michael Schneider](https://github.com/maicki)[#1199] (https://github.com/TextureGroup/Texture/pull/1199) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index 284eacb3ae..a1207e9791 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -139,7 +139,14 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _ std::queue queue; queue.push(container); - ASDisplayNode *node; + // If the container does not have an accessibility label set, or if the label is meant for custom + // actions only, then aggregate its subnodes' labels. Otherwise, treat the label as an overriden + // value and do not perform the aggregation. + BOOL shouldAggregateSubnodeLabels = + (container.accessibilityLabel.length == 0) || + (container.accessibilityTraits & InteractiveAccessibilityTraitsMask()); + + ASDisplayNode *node = nil; while (!queue.empty()) { node = queue.front(); queue.pop(); @@ -156,7 +163,7 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _ action.containerNode = node.supernode; action.container = node.supernode.view; [actions addObject:action]; - } else { + } else if (node == container || shouldAggregateSubnodeLabels) { // Even though not surfaced to UIKit, create a non-interactive element for purposes of building sorted aggregated label. ASAccessibilityElement *nonInteractiveElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:node containerNode:container]; [labeledNodes addObject:nonInteractiveElement]; From 99fd25c5b88e4b982ae3ae9ba2ffa40e9c25c541 Mon Sep 17 00:00:00 2001 From: Max Wang Date: Mon, 29 Oct 2018 16:07:50 -0700 Subject: [PATCH 32/60] A11y for scrollnode (#1188) * 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. * Add a11y support for ASSCrollNode. * Changelog * Clean up. * fix braces * add test * disable for ci --- CHANGELOG.md | 1 + Source/ASScrollNode.mm | 5 +++ Source/Details/_ASDisplayViewAccessiblity.mm | 27 +++++++++++----- .../Private/ASDisplayNode+FrameworkPrivate.h | 4 +++ Tests/ASScrollNodeTests.m | 31 +++++++++++++++++++ 5 files changed, 60 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ef7aa4b8..43efca8efc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master * Add your own contributions to the next release on the line below this with your name. +- [ASScrollNode] A11y support for ASScrollNode. [Max Wang](https://github.com/wsdwsd0829). [#1188](https://github.com/TextureGroup/Texture/pull/1188) - [ASDisplayNode.m] Make sure node is loaded before enter visible. [Max Wang](https://github.com/wsdwsd0829). [#886](https://github.com/TextureGroup/Texture/pull/886) - [ASTextNode2] Add improved support for all line-break modes in experimental text node. [Kevin Smith](https://github.com/wiseoldduck). [#1150](https://github.com/TextureGroup/Texture/pull/1150) - [ASExperimentalFeatures.m] Fix mismatch name in experimental features. [Max Wang](https://github.com/wsdwsd0829). [#1159](https://github.com/TextureGroup/Texture/pull/1159) diff --git a/Source/ASScrollNode.mm b/Source/ASScrollNode.mm index c155b4749b..497ef1429a 100644 --- a/Source/ASScrollNode.mm +++ b/Source/ASScrollNode.mm @@ -52,6 +52,11 @@ } } +- (NSArray *)accessibilityElements +{ + return [self.asyncdisplaykit_node accessibilityElements]; +} + @end @implementation ASScrollNode diff --git a/Source/Details/_ASDisplayViewAccessiblity.mm b/Source/Details/_ASDisplayViewAccessiblity.mm index a1207e9791..21ed153546 100644 --- a/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Source/Details/_ASDisplayViewAccessiblity.mm @@ -131,7 +131,7 @@ static void CollectUIAccessibilityElementsForNode(ASDisplayNode *node, ASDisplay }); } -static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _ASDisplayView *view, NSMutableArray *elements) { +static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, UIView *view, NSMutableArray *elements) { UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:container containerNode:container]; NSMutableArray *labeledNodes = [[NSMutableArray alloc] init]; @@ -202,7 +202,7 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _ } /// Collect all accessibliity elements for a given view and view node -static void CollectAccessibilityElementsForView(_ASDisplayView *view, NSMutableArray *elements) +static void CollectAccessibilityElementsForView(UIView *view, NSMutableArray *elements) { ASDisplayNodeCAssertNotNil(elements, @"Should pass in a NSMutableArray"); @@ -265,17 +265,28 @@ static void CollectAccessibilityElementsForView(_ASDisplayView *view, NSMutableA if (viewNode == nil) { return @[]; } - if (_accessibilityElements == nil) { - NSMutableArray *accessibilityElements = [[NSMutableArray alloc] init]; - CollectAccessibilityElementsForView(self, accessibilityElements); - SortAccessibilityElements(accessibilityElements); - _accessibilityElements = accessibilityElements; + _accessibilityElements = [viewNode accessibilityElements]; } - return _accessibilityElements; } @end +@implementation ASDisplayNode (AccessibilityInternal) + +- (NSArray *)accessibilityElements +{ + if (!self.isNodeLoaded) { + ASDisplayNodeFailAssert(@"Cannot access accessibilityElements since node is not loaded"); + return @[]; + } + NSMutableArray *accessibilityElements = [[NSMutableArray alloc] init]; + CollectAccessibilityElementsForView(self.view, accessibilityElements); + SortAccessibilityElements(accessibilityElements); + return accessibilityElements; +} + +@end + #endif diff --git a/Source/Private/ASDisplayNode+FrameworkPrivate.h b/Source/Private/ASDisplayNode+FrameworkPrivate.h index 2101565bf3..c8d5476b3a 100644 --- a/Source/Private/ASDisplayNode+FrameworkPrivate.h +++ b/Source/Private/ASDisplayNode+FrameworkPrivate.h @@ -312,6 +312,10 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyStateChange(ASHierarc @end +@interface ASDisplayNode (AccessibilityInternal) +- (NSArray *)accessibilityElements; +@end; + @interface UIView (ASDisplayNodeInternal) @property (nullable, weak) ASDisplayNode *asyncdisplaykit_node; @end diff --git a/Tests/ASScrollNodeTests.m b/Tests/ASScrollNodeTests.m index f0d8fe2079..12c85262a8 100644 --- a/Tests/ASScrollNodeTests.m +++ b/Tests/ASScrollNodeTests.m @@ -132,4 +132,35 @@ ASXCTAssertEqualSizes(self.scrollNode.view.contentSize, subnodeSize); } +- (void)testASScrollNodeAccessibility { + ASDisplayNode *scrollNode = [[ASDisplayNode alloc] init]; + ASDisplayNode *node = [[ASDisplayNode alloc] init]; + node.isAccessibilityContainer = YES; + node.accessibilityLabel = @"node"; + [scrollNode addSubnode:node]; + node.frame = CGRectMake(0,0,100,100); + ASTextNode2 *text = [[ASTextNode2 alloc] init]; + text.attributedText = [[NSAttributedString alloc] initWithString:@"text"]; + [node addSubnode:text]; + + ASTextNode2 *text2 = [[ASTextNode2 alloc] init]; + text2.attributedText = [[NSAttributedString alloc] initWithString:@"text2"]; + [node addSubnode:text2]; + __unused UIView *view = scrollNode.view; + XCTAssertTrue(node.view.accessibilityElements.firstObject, @"node"); + + // Following tests will only pass when accessibility is enabled. + // More details: https://github.com/TextureGroup/Texture/pull/1188 + + // A bunch of a11y containers each of which hold aggregated labels. + /* NSArray *a11yElements = [scrollNode.view accessibilityElements]; + XCTAssertTrue(a11yElements.count > 0, @"accessibilityElements should exist"); + + UIAccessibilityElement *container = a11yElements.firstObject; + XCTAssertTrue(container.isAccessibilityElement == false && container.accessibilityElements.count > 0); + UIAccessibilityElement *ae = container.accessibilityElements.firstObject; + XCTAssertTrue([[ae accessibilityLabel] isEqualToString:@"node, text, text2"]); + */ +} + @end From be021434c82974a84b769df1975341adc4b3a176 Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 30 Oct 2018 13:19:23 -0700 Subject: [PATCH 33/60] Newline character support and truncated line sizing improvement. (#1193) * Newline character support and truncated line sizing improvement. For purposes of truncating text, respect explicit newlines. Don't size to smaller than truncated line width unless we have to. * Update CHANGELOG.md --- CHANGELOG.md | 1 + Source/ASTextNode2.mm | 5 ++++- .../TextExperiment/Component/ASTextLayout.m | 18 ++++++++++++++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43efca8efc..0f66775b3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master * Add your own contributions to the next release on the line below this with your name. +- [ASTextNode2] Newline character support and truncated line sizing improvement. [Kevin Smith](https://github.com/wiseoldduck). [#1193](https://github.com/TextureGroup/Texture/pull/1193) - [ASScrollNode] A11y support for ASScrollNode. [Max Wang](https://github.com/wsdwsd0829). [#1188](https://github.com/TextureGroup/Texture/pull/1188) - [ASDisplayNode.m] Make sure node is loaded before enter visible. [Max Wang](https://github.com/wsdwsd0829). [#886](https://github.com/TextureGroup/Texture/pull/886) - [ASTextNode2] Add improved support for all line-break modes in experimental text node. [Kevin Smith](https://github.com/wiseoldduck). [#1150](https://github.com/TextureGroup/Texture/pull/1150) diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 397bff6fab..b0c39bd586 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -350,7 +350,10 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; NSMutableAttributedString *mutableText = [_attributedText mutableCopy]; [self prepareAttributedString:mutableText isForIntrinsicSize:isCalculatingIntrinsicSize]; ASTextLayout *layout = ASTextNodeCompatibleLayoutWithContainerAndText(_textContainer, mutableText); - + if (layout.truncatedLine != nil && layout.truncatedLine.size.width > layout.textBoundingSize.width) { + return (CGSize) {MIN(constrainedSize.width, layout.truncatedLine.size.width), layout.textBoundingSize.height}; + } + return layout.textBoundingSize; } diff --git a/Source/Private/TextExperiment/Component/ASTextLayout.m b/Source/Private/TextExperiment/Component/ASTextLayout.m index dc14b29409..3b14425914 100644 --- a/Source/Private/TextExperiment/Component/ASTextLayout.m +++ b/Source/Private/TextExperiment/Component/ASTextLayout.m @@ -441,7 +441,7 @@ dispatch_semaphore_signal(_lock); // It may use larger constraint size when create CTFrame with // CTFramesetterCreateFrame in iOS 10. BOOL needFixLayoutSizeBug = AS_AT_LEAST_IOS10; - + layout = [[ASTextLayout alloc] _init]; layout.text = text; layout.container = container; @@ -834,23 +834,33 @@ dispatch_semaphore_signal(_lock); } } int i = 0; - if (type != kCTLineTruncationStart) { // Middle or End/Tail wants text preceding truncated content + if (type != kCTLineTruncationStart) { // Middle or End/Tail wants text preceding truncated content. i = removedLines.count - 1; while (atLeastOneLine < truncatedWidth && i >= 0) { + if (lastLineText.length > 0 && [lastLineText.string characterAtIndex:lastLineText.string.length - 1] == '\n') { // Explicit newlines are always "long enough". + [lastLineText deleteCharactersInRange:NSMakeRange(lastLineText.string.length - 1, 1)]; + break; + } [lastLineText appendAttributedString:[text attributedSubstringFromRange:removedLines[i].range]]; atLeastOneLine += removedLines[i--].width; } [lastLineText appendAttributedString:truncationToken]; } - if (type != kCTLineTruncationEnd && removedLines.count > 0) { // Middle or Start/Head wants text following truncated content + if (type != kCTLineTruncationEnd && removedLines.count > 0) { // Middle or Start/Head wants text following truncated content. i = 0; atLeastOneLine = removedLines[i].width; while (atLeastOneLine < truncatedWidth && i < removedLines.count) { atLeastOneLine += removedLines[i++].width; } for (i--; i >= 0; i--) { - [lastLineText appendAttributedString:[text attributedSubstringFromRange:removedLines[i].range]]; + NSAttributedString *nextLine = [text attributedSubstringFromRange:removedLines[i].range]; + if ([nextLine.string characterAtIndex:nextLine.string.length - 1] == '\n') { // Explicit newlines are always "long enough". + lastLineText = [NSMutableAttributedString new]; + } else { + [lastLineText appendAttributedString:nextLine]; + } } + [lastLineText insertAttributedString:truncationToken atIndex:0]; } CTLineRef ctLastLineExtend = CTLineCreateWithAttributedString((CFAttributedStringRef) lastLineText); From 055d27c45af6198a615988fccb412957e4403bf3 Mon Sep 17 00:00:00 2001 From: ernestmama <43187788+ernestmama@users.noreply.github.com> Date: Wed, 31 Oct 2018 17:06:48 -0700 Subject: [PATCH 34/60] ASTextNode2 to consider both width and height when determining if it is calculating an instrinsic size (#1196) --- Source/ASTextNode2.mm | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index b0c39bd586..9feb18afd6 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -340,12 +340,9 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; [self _ensureTruncationText]; // If the constrained size has a max/inf value on the text's forward direction, the text node is calculating its intrinsic size. - BOOL isCalculatingIntrinsicSize; - if (_textContainer.isVerticalForm) { - isCalculatingIntrinsicSize = (_textContainer.size.height >= ASTextContainerMaxSize.height); - } else { - isCalculatingIntrinsicSize = (_textContainer.size.width >= ASTextContainerMaxSize.width); - } + // Need to consider both width and height when determining if it is calculating instrinsic size. Even the constrained width is provided, the height can be inf + // it may provide a text that is longer than the width and require a wordWrapping line break mode and looking for the height to be calculated. + BOOL isCalculatingIntrinsicSize = (_textContainer.size.width >= ASTextContainerMaxSize.width) || (_textContainer.size.height >= ASTextContainerMaxSize.height); NSMutableAttributedString *mutableText = [_attributedText mutableCopy]; [self prepareAttributedString:mutableText isForIntrinsicSize:isCalculatingIntrinsicSize]; From fec14f831042a4b4ec1900888c3fdca16a85749f Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 1 Nov 2018 08:08:45 -0700 Subject: [PATCH 35/60] Fix logic cleaning data if delegate / dataSource changes and bring over logic to ASTableView (#1200) * Cleanup in ASTableView datasource/delegate change * Fix experiments logic * Add changelog entry --- CHANGELOG.md | 1 + Source/ASCollectionView.mm | 14 ++++++++++---- Source/ASTableView.mm | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f66775b3b..479ed1cad0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,7 @@ - Yoga integration improvements [Michael Schneider](https://github.com/maicki)[#1187] (https://github.com/TextureGroup/Texture/pull/1187) - Correct linePositionModifier behavior [Michael Schneider](https://github.com/maicki)[#1192] (https://github.com/TextureGroup/Texture/pull/1192) - Tweak a11y label aggregation behavior to enable container label overrides [Michael Schneider](https://github.com/maicki)[#1199] (https://github.com/TextureGroup/Texture/pull/1199) +- Fix logic cleaning data if delegate / dataSource changes and bring over logic to ASTableView [Michael Schneider](https://github.com/maicki)[#1200] (https://github.com/TextureGroup/Texture/pull/1200) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASCollectionView.mm b/Source/ASCollectionView.mm index 62380e4891..f451c7727c 100644 --- a/Source/ASCollectionView.mm +++ b/Source/ASCollectionView.mm @@ -576,10 +576,16 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier"; - (void)_asyncDelegateOrDataSourceDidChange { ASDisplayNodeAssertMainThread(); - - if (_asyncDataSource == nil && _asyncDelegate == nil && _isDeallocating && ASActivateExperimentalFeature(ASExperimentalClearDataDuringDeallocation)) { - [_dataController clearData]; - } + + if (_asyncDataSource == nil && _asyncDelegate == nil) { + if (ASActivateExperimentalFeature(ASExperimentalClearDataDuringDeallocation)) { + if (_isDeallocating) { + [_dataController clearData]; + } + } else { + [_dataController clearData]; + } + } } - (void)setCollectionViewLayout:(nonnull UICollectionViewLayout *)collectionViewLayout diff --git a/Source/ASTableView.mm b/Source/ASTableView.mm index b88906bf89..5854410c9b 100644 --- a/Source/ASTableView.mm +++ b/Source/ASTableView.mm @@ -436,6 +436,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; _dataController.validationErrorSource = asyncDataSource; super.dataSource = (id)_proxyDataSource; + [self _asyncDelegateOrDataSourceDidChange]; } - (id)asyncDelegate @@ -506,6 +507,22 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; } super.delegate = (id)_proxyDelegate; + [self _asyncDelegateOrDataSourceDidChange]; +} + +- (void)_asyncDelegateOrDataSourceDidChange +{ + ASDisplayNodeAssertMainThread(); + + if (_asyncDataSource == nil && _asyncDelegate == nil) { + if (ASActivateExperimentalFeature(ASExperimentalClearDataDuringDeallocation)) { + if (_isDeallocating) { + [_dataController clearData]; + } + } else { + [_dataController clearData]; + } + } } - (void)proxyTargetHasDeallocated:(ASDelegateProxy *)proxy From fde47a5e28ce59903b62d7ca965954b5b2c465c2 Mon Sep 17 00:00:00 2001 From: Kevin Date: Thu, 1 Nov 2018 08:10:44 -0700 Subject: [PATCH 36/60] Add tests for accessibility (#1205) --- Tests/ASDisplayViewAccessibilityTests.mm | 43 ++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Tests/ASDisplayViewAccessibilityTests.mm b/Tests/ASDisplayViewAccessibilityTests.mm index e35d1fa0bf..2bdc89e9f4 100644 --- a/Tests/ASDisplayViewAccessibilityTests.mm +++ b/Tests/ASDisplayViewAccessibilityTests.mm @@ -39,4 +39,47 @@ XCTAssertEqual([node.view indexOfAccessibilityElement:node.view.accessibilityElements.firstObject], 0);*/ } +- (void)testThatSubnodeAccessibilityLabelAggregationWorks { + // Setup nodes + ASDisplayNode *node = nil; + ASDisplayNode *innerNode1 = nil; + ASDisplayNode *innerNode2 = nil; + node = [[ASDisplayNode alloc] init]; + innerNode1 = [[ASDisplayNode alloc] init]; + innerNode2 = [[ASDisplayNode alloc] init]; + + // Initialize nodes with relevant accessibility data + node.isAccessibilityContainer = YES; + innerNode1.accessibilityLabel = @"hello"; + innerNode2.accessibilityLabel = @"world"; + + // Attach the subnodes to the parent node, then ensure their accessibility labels have been' + // aggregated to the parent's accessibility label + [node addSubnode:innerNode1]; + [node addSubnode:innerNode2]; + XCTAssertEqualObjects([node.view.accessibilityElements.firstObject accessibilityLabel], + @"hello, world", @"Subnode accessibility label aggregation broken %@", + [node.view.accessibilityElements.firstObject accessibilityLabel]); +} + +- (void)testThatContainerAccessibilityLabelOverrideStopsAggregation { + // Setup nodes + ASDisplayNode *node = nil; + ASDisplayNode *innerNode = nil; + node = [[ASDisplayNode alloc] init]; + innerNode = [[ASDisplayNode alloc] init]; + + // Initialize nodes with relevant accessibility data + node.isAccessibilityContainer = YES; + node.accessibilityLabel = @"hello"; + innerNode.accessibilityLabel = @"world"; + + // Attach the subnode to the parent node, then ensure the parent's accessibility label does not + // get aggregated with the subnode's label + [node addSubnode:innerNode]; + XCTAssertEqualObjects([node.view.accessibilityElements.firstObject accessibilityLabel], @"hello", + @"Container accessibility label override broken %@", + [node.view.accessibilityElements.firstObject accessibilityLabel]); +} + @end From 0380b270bb628cce595b83fb88b9d29fed8a3eb2 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Thu, 1 Nov 2018 19:40:16 -0700 Subject: [PATCH 37/60] Address Xcode warnings about unguarded availability and implicit self retains (#1207) --- Source/ASNetworkImageNode.mm | 34 +++++++++---------- Source/ASTextNode.mm | 6 ++-- Source/Details/ASMainSerialQueue.mm | 8 ++--- Source/Details/ASRecursiveUnfairLock.h | 2 +- Source/Details/ASTraitCollection.h | 8 ++--- .../TextExperiment/Component/ASTextLayout.m | 2 +- Source/TextKit/ASTextKitFontSizeAdjuster.mm | 10 +++--- Source/TextKit/ASTextKitRenderer.mm | 4 +-- Source/TextKit/ASTextKitTailTruncater.mm | 6 ++-- 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/Source/ASNetworkImageNode.mm b/Source/ASNetworkImageNode.mm index 1f5d907326..b7f4ed8eac 100644 --- a/Source/ASNetworkImageNode.mm +++ b/Source/ASNetworkImageNode.mm @@ -570,11 +570,11 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); // it and try again. { ASLockScopeSelf(); - url = _URL; + url = self->_URL; } - downloadIdentifier = [_downloader downloadImageWithURL:url + downloadIdentifier = [self->_downloader downloadImageWithURL:url callbackQueue:[self callbackQueue] downloadProgress:NULL completion:^(id _Nullable imageContainer, NSError * _Nullable error, id _Nullable downloadIdentifier, id _Nullable userInfo) { @@ -586,9 +586,9 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); { ASLockScopeSelf(); - if (ASObjectIsEqual(_URL, url)) { + if (ASObjectIsEqual(self->_URL, url)) { // The download we kicked off is correct, no need to do any more work. - _downloadIdentifier = downloadIdentifier; + self->_downloadIdentifier = downloadIdentifier; } else { // The URL changed since we kicked off our download task. This shouldn't happen often so we'll pay the cost and // cancel that request and kick off a new one. @@ -599,7 +599,7 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); if (cancelAndReattempt) { if (downloadIdentifier != nil) { as_log_verbose(ASImageLoadingLog(), "Canceling image download no resume for %@ id: %@", self, downloadIdentifier); - [_downloader cancelImageDownloadForIdentifier:downloadIdentifier]; + [self->_downloader cancelImageDownloadForIdentifier:downloadIdentifier]; } [self _downloadImageWithCompletion:finished]; return; @@ -631,11 +631,11 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); ASLockScopeSelf(); // Bail out if not the same URL anymore - if (!ASObjectIsEqual(URL, _URL)) { + if (!ASObjectIsEqual(URL, self->_URL)) { return; } - if (_shouldCacheImage) { + if (self->_shouldCacheImage) { [self _locked__setImage:[UIImage imageNamed:URL.path.lastPathComponent]]; } else { // First try to load the path directly, for efficiency assuming a developer who @@ -652,10 +652,10 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); // If the file may be an animated gif and then created an animated image. id animatedImage = nil; - if (_downloaderFlags.downloaderImplementsAnimatedImage) { + if (self->_downloaderFlags.downloaderImplementsAnimatedImage) { let data = [[NSData alloc] initWithContentsOfURL:URL]; if (data != nil) { - animatedImage = [_downloader animatedImageWithData:data]; + animatedImage = [self->_downloader animatedImageWithData:data]; if ([animatedImage respondsToSelector:@selector(isDataSupported:)] && [animatedImage isDataSupported:data] == NO) { animatedImage = nil; @@ -670,15 +670,15 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); } } - _imageLoaded = YES; + self->_imageLoaded = YES; [self _setCurrentImageQuality:1.0]; - if (_delegateFlags.delegateDidLoadImageWithInfo) { + if (self->_delegateFlags.delegateDidLoadImageWithInfo) { ASUnlockScope(self); let info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:ASNetworkImageSourceFileURL downloadIdentifier:nil userInfo:nil]; [delegate imageNode:self didLoadImage:self.image info:info]; - } else if (_delegateFlags.delegateDidLoadImage) { + } else if (self->_delegateFlags.delegateDidLoadImage) { ASUnlockScope(self); [delegate imageNode:self didLoadImage:self.image]; } @@ -729,17 +729,17 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); void (^calloutBlock)(ASNetworkImageNode *inst); if (newImage) { - if (_delegateFlags.delegateDidLoadImageWithInfo) { + if (self->_delegateFlags.delegateDidLoadImageWithInfo) { calloutBlock = ^(ASNetworkImageNode *strongSelf) { let info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:imageSource downloadIdentifier:downloadIdentifier userInfo:userInfo]; [delegate imageNode:strongSelf didLoadImage:newImage info:info]; }; - } else if (_delegateFlags.delegateDidLoadImage) { + } else if (self->_delegateFlags.delegateDidLoadImage) { calloutBlock = ^(ASNetworkImageNode *strongSelf) { [delegate imageNode:strongSelf didLoadImage:newImage]; }; } - } else if (error && _delegateFlags.delegateDidFailWithError) { + } else if (error && self->_delegateFlags.delegateDidFailWithError) { calloutBlock = ^(ASNetworkImageNode *strongSelf) { [delegate imageNode:strongSelf didFailWithError:error]; }; @@ -768,11 +768,11 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); ASImageCacherCompletion completion = ^(id imageContainer) { // If the cache sentinel changed, that means this request was cancelled. - if (ASLockedSelf(_cacheSentinel != cacheSentinel)) { + if (ASLockedSelf(self->_cacheSentinel != cacheSentinel)) { return; } - if ([imageContainer asdk_image] == nil && _downloader != nil) { + if ([imageContainer asdk_image] == nil && self->_downloader != nil) { [self _downloadImageWithCompletion:^(id imageContainer, NSError *error, id downloadIdentifier, id userInfo) { finished(imageContainer, error, downloadIdentifier, ASNetworkImageSourceDownload, userInfo); }]; diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index ac39f8a5b3..1cf8489c80 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -607,7 +607,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; return; } - for (NSString *attributeName in _linkAttributeNames) { + for (NSString *attributeName in self->_linkAttributeNames) { NSRange range; id value = [attributedString attribute:attributeName atIndex:characterIndex longestEffectiveRange:&range inRange:clampedRange]; NSString *name = attributeName; @@ -619,8 +619,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // If highlighting, check with delegate first. If not implemented, assume YES. if (highlighting - && [_delegate respondsToSelector:@selector(textNode:shouldHighlightLinkAttribute:value:atPoint:)] - && ![_delegate textNode:self shouldHighlightLinkAttribute:name value:value atPoint:point]) { + && [self->_delegate respondsToSelector:@selector(textNode:shouldHighlightLinkAttribute:value:atPoint:)] + && ![self->_delegate textNode:self shouldHighlightLinkAttribute:name value:value atPoint:point]) { value = nil; name = nil; } diff --git a/Source/Details/ASMainSerialQueue.mm b/Source/Details/ASMainSerialQueue.mm index 6a9baee50c..42d937ad47 100644 --- a/Source/Details/ASMainSerialQueue.mm +++ b/Source/Details/ASMainSerialQueue.mm @@ -52,16 +52,16 @@ { dispatch_block_t mainThread = ^{ do { - ASDN::MutexLocker l(_serialQueueLock); + ASDN::MutexLocker l(self->_serialQueueLock); dispatch_block_t block; - if (_blocks.count > 0) { + if (self->_blocks.count > 0) { block = _blocks[0]; - [_blocks removeObjectAtIndex:0]; + [self->_blocks removeObjectAtIndex:0]; } else { break; } { - ASDN::MutexUnlocker u(_serialQueueLock); + ASDN::MutexUnlocker u(self->_serialQueueLock); block(); } } while (true); diff --git a/Source/Details/ASRecursiveUnfairLock.h b/Source/Details/ASRecursiveUnfairLock.h index 22ab5c703c..d705e4d384 100644 --- a/Source/Details/ASRecursiveUnfairLock.h +++ b/Source/Details/ASRecursiveUnfairLock.h @@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN OS_UNFAIR_LOCK_AVAILABILITY typedef struct { - os_unfair_lock _lock; + os_unfair_lock _lock OS_UNFAIR_LOCK_AVAILABILITY; _Atomic(pthread_t) _thread; // Write-protected by lock int _count; // Protected by lock } ASRecursiveUnfairLock; diff --git a/Source/Details/ASTraitCollection.h b/Source/Details/ASTraitCollection.h index 72dedd616c..f1aa8ab187 100644 --- a/Source/Details/ASTraitCollection.h +++ b/Source/Details/ASTraitCollection.h @@ -61,11 +61,11 @@ typedef struct ASPrimitiveTraitCollection { UIUserInterfaceSizeClass verticalSizeClass; CGFloat displayScale; - UIDisplayGamut displayGamut; + UIDisplayGamut displayGamut API_AVAILABLE(ios(10.0)); UIUserInterfaceIdiom userInterfaceIdiom; UIForceTouchCapability forceTouchCapability; - UITraitEnvironmentLayoutDirection layoutDirection; + UITraitEnvironmentLayoutDirection layoutDirection API_AVAILABLE(ios(10.0)); #if TARGET_OS_TV UIUserInterfaceStyle userInterfaceStyle; #endif @@ -168,11 +168,11 @@ AS_SUBCLASSING_RESTRICTED @property (nonatomic, readonly) UIUserInterfaceSizeClass verticalSizeClass; @property (nonatomic, readonly) CGFloat displayScale; -@property (nonatomic, readonly) UIDisplayGamut displayGamut; +@property (nonatomic, readonly) UIDisplayGamut displayGamut API_AVAILABLE(ios(10.0)); @property (nonatomic, readonly) UIUserInterfaceIdiom userInterfaceIdiom; @property (nonatomic, readonly) UIForceTouchCapability forceTouchCapability; -@property (nonatomic, readonly) UITraitEnvironmentLayoutDirection layoutDirection; +@property (nonatomic, readonly) UITraitEnvironmentLayoutDirection layoutDirection API_AVAILABLE(ios(10.0)); #if TARGET_OS_TV @property (nonatomic, readonly) UIUserInterfaceStyle userInterfaceStyle; #endif diff --git a/Source/Private/TextExperiment/Component/ASTextLayout.m b/Source/Private/TextExperiment/Component/ASTextLayout.m index 3b14425914..98de735a1b 100644 --- a/Source/Private/TextExperiment/Component/ASTextLayout.m +++ b/Source/Private/TextExperiment/Component/ASTextLayout.m @@ -835,7 +835,7 @@ dispatch_semaphore_signal(_lock); } int i = 0; if (type != kCTLineTruncationStart) { // Middle or End/Tail wants text preceding truncated content. - i = removedLines.count - 1; + i = (int)removedLines.count - 1; while (atLeastOneLine < truncatedWidth && i >= 0) { if (lastLineText.length > 0 && [lastLineText.string characterAtIndex:lastLineText.string.length - 1] == '\n') { // Explicit newlines are always "long enough". [lastLineText deleteCharactersInRange:NSMakeRange(lastLineText.string.length - 1, 1)]; diff --git a/Source/TextKit/ASTextKitFontSizeAdjuster.mm b/Source/TextKit/ASTextKitFontSizeAdjuster.mm index 3837771239..1f4a397ac8 100644 --- a/Source/TextKit/ASTextKitFontSizeAdjuster.mm +++ b/Source/TextKit/ASTextKitFontSizeAdjuster.mm @@ -183,8 +183,8 @@ // check to see if we may need to shrink for any of these things BOOL longestWordFits = [longestWordNeedingResize length] ? NO : YES; - BOOL maxLinesFits = _attributes.maximumNumberOfLines > 0 ? NO : YES; - BOOL heightFits = isinf(_constrainedSize.height) ? YES : NO; + BOOL maxLinesFits = self->_attributes.maximumNumberOfLines > 0 ? NO : YES; + BOOL heightFits = isinf(self->_constrainedSize.height) ? YES : NO; CGSize longestWordSize = CGSizeZero; if (longestWordFits == NO) { @@ -204,7 +204,7 @@ if (longestWordFits == NO) { // we need to check the longest word to make sure it fits - longestWordFits = std::ceil((longestWordSize.width * adjustedScale) <= _constrainedSize.width); + longestWordFits = std::ceil((longestWordSize.width * adjustedScale) <= self->_constrainedSize.width); } // if the longest word fits, go ahead and check max line and height. If it didn't fit continue to the next scale factor @@ -216,14 +216,14 @@ // check to see if this scaled string fit in the max lines if (maxLinesFits == NO) { - maxLinesFits = ([self lineCountForString:scaledString] <= _attributes.maximumNumberOfLines); + maxLinesFits = ([self lineCountForString:scaledString] <= self->_attributes.maximumNumberOfLines); } // if max lines still doesn't fit, continue without checking that we fit in the constrained height if (maxLinesFits == YES && heightFits == NO) { // max lines fit so make sure that we fit in the constrained height. CGSize stringSize = [self boundingBoxForString:scaledString]; - heightFits = (stringSize.height <= _constrainedSize.height); + heightFits = (stringSize.height <= self->_constrainedSize.height); } } } diff --git a/Source/TextKit/ASTextKitRenderer.mm b/Source/TextKit/ASTextKitRenderer.mm index c7efb1d10e..6774dab9ac 100644 --- a/Source/TextKit/ASTextKitRenderer.mm +++ b/Source/TextKit/ASTextKitRenderer.mm @@ -128,7 +128,7 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet() // apply the string scale before truncating or else we may truncate the string after we've done the work to shrink it. [[self context] performBlockWithLockedTextKitComponents:^(NSLayoutManager *layoutManager, NSTextStorage *textStorage, NSTextContainer *textContainer) { NSMutableAttributedString *scaledString = [[NSMutableAttributedString alloc] initWithAttributedString:textStorage]; - [ASTextKitFontSizeAdjuster adjustFontSizeForAttributeString:scaledString withScaleFactor:_currentScaleFactor]; + [ASTextKitFontSizeAdjuster adjustFontSizeForAttributeString:scaledString withScaleFactor:self->_currentScaleFactor]; scaledTextStorage = [[NSTextStorage alloc] initWithAttributedString:scaledString]; [textStorage removeLayoutManager:layoutManager]; @@ -217,7 +217,7 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet() if (isScaled) { // if we are going to scale the text, swap out the non-scaled text for the scaled version. NSMutableAttributedString *scaledString = [[NSMutableAttributedString alloc] initWithAttributedString:textStorage]; - [ASTextKitFontSizeAdjuster adjustFontSizeForAttributeString:scaledString withScaleFactor:_currentScaleFactor]; + [ASTextKitFontSizeAdjuster adjustFontSizeForAttributeString:scaledString withScaleFactor:self->_currentScaleFactor]; scaledTextStorage = [[NSTextStorage alloc] initWithAttributedString:scaledString]; [textStorage removeLayoutManager:layoutManager]; diff --git a/Source/TextKit/ASTextKitTailTruncater.mm b/Source/TextKit/ASTextKitTailTruncater.mm index 1c4d73f496..3538693460 100644 --- a/Source/TextKit/ASTextKitTailTruncater.mm +++ b/Source/TextKit/ASTextKitTailTruncater.mm @@ -157,7 +157,7 @@ actualGlyphRange:NULL]; // Check if text is truncated, and if so apply our truncation string - if (visibleCharacterRange.length < originalStringLength && _truncationAttributedString.length > 0) { + if (visibleCharacterRange.length < originalStringLength && self->_truncationAttributedString.length > 0) { NSInteger firstCharacterIndexToReplace = [self _calculateCharacterIndexBeforeTruncationMessage:layoutManager textStorage:textStorage textContainer:textContainer]; @@ -171,10 +171,10 @@ textStorage.length - firstCharacterIndexToReplace); // Replace the end of the visible message with the truncation string [textStorage replaceCharactersInRange:truncationReplacementRange - withAttributedString:_truncationAttributedString]; + withAttributedString:self->_truncationAttributedString]; } - _visibleRanges = { visibleCharacterRange }; + self->_visibleRanges = { visibleCharacterRange }; }]; } From 8822bae0d51e4d414d3e2ecefe6895d53834bc64 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Fri, 2 Nov 2018 07:54:15 -0700 Subject: [PATCH 38/60] Follow up cleanup #trivial (#1203) * Remove whitespace at the end of the line * Fix indentation * Wrap if check for assertion in ASDISPLAYNODE_ASSERTIONS_ENABLED * Add testTextNodeSwitchWorksInMultiThreadEnvironment tests --- Source/ASDisplayNode+Yoga.mm | 2 +- Source/ASDisplayNode.mm | 4 ++- Tests/ASButtonNodeTests.m | 3 +- Tests/ASTextNodeTests.m | 57 ++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/Source/ASDisplayNode+Yoga.mm b/Source/ASDisplayNode+Yoga.mm index 93615cdd6c..235db6678a 100644 --- a/Source/ASDisplayNode+Yoga.mm +++ b/Source/ASDisplayNode+Yoga.mm @@ -35,7 +35,7 @@ - (ASDisplayNode *)yogaRoot { ASDisplayNode *yogaRoot = self; - ASDisplayNode *yogaParent = nil; + ASDisplayNode *yogaParent = nil; while ((yogaParent = yogaRoot.yogaParent)) { yogaRoot = yogaParent; } diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 24adf9414d..75604bc995 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -3280,11 +3280,13 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { // subclass override ASDisplayNodeAssertMainThread(); +#if ASDISPLAYNODE_ASSERTIONS_ENABLED // Rasterized node's loading state is merged with root node of rasterized tree. if (!(self.hierarchyState & ASHierarchyStateRasterized)) { ASDisplayNodeAssert(self.isNodeLoaded, @"Node should be loaded before entering visible state."); } - +#endif + ASAssertUnlocked(__instanceLock__); [self enumerateInterfaceStateDelegates:^(id del) { [del didEnterVisibleState]; diff --git a/Tests/ASButtonNodeTests.m b/Tests/ASButtonNodeTests.m index 1c0c0adb61..eb6249e451 100644 --- a/Tests/ASButtonNodeTests.m +++ b/Tests/ASButtonNodeTests.m @@ -41,8 +41,7 @@ // Disable the button and verify that accessibility traits has been updated correctly. buttonNode.enabled = NO; - UIAccessibilityTraits disabledButtonTrait = - UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled; + UIAccessibilityTraits disabledButtonTrait = UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled; XCTAssertTrue(buttonNode.accessibilityTraits == disabledButtonTrait, @"Should have disabled button accessibility trait, instead has %llu", buttonNode.accessibilityTraits); diff --git a/Tests/ASTextNodeTests.m b/Tests/ASTextNodeTests.m index daf8cf7d79..441ca8f103 100644 --- a/Tests/ASTextNodeTests.m +++ b/Tests/ASTextNodeTests.m @@ -50,6 +50,7 @@ @property (nonatomic) ASTextNode *textNode; @property (nonatomic, copy) NSAttributedString *attributedText; +@property (nonatomic) NSMutableArray *textNodeBucket; @end @@ -59,6 +60,7 @@ { [super setUp]; _textNode = [[ASTextNode alloc] init]; + _textNodeBucket = [[NSMutableArray alloc] init]; UIFontDescriptor *desc = [UIFontDescriptor fontDescriptorWithName:@"Didot" size:18]; @@ -247,6 +249,61 @@ XCTAssertEqualObjects(sc2.superclass, [ASTextNodeSubclass class]); } +- (void)testTextNodeSwitchWorksInMultiThreadEnvironment +{ + ASConfiguration *config = [ASConfiguration new]; + config.experimentalFeatures = ASExperimentalTextNode; + [ASConfigurationManager test_resetWithConfiguration:config]; + XCTestExpectation *exp = [self expectationWithDescription:@"wait for full bucket"]; + + dispatch_queue_t queue = dispatch_queue_create("com.texture.AsyncDisplayKit.ASTextNodeTestsQueue", DISPATCH_QUEUE_CONCURRENT); + dispatch_group_t g = dispatch_group_create(); + for (int i = 0; i < 20; i++) { + dispatch_group_async(g, queue, ^{ + ASTextNode *textNode = [[ASTextNodeSecondSubclass alloc] init]; + XCTAssert([textNode isKindOfClass:[ASTextNode2 class]]); + @synchronized(self.textNodeBucket) { + [self.textNodeBucket addObject:textNode]; + if (self.textNodeBucket.count == 20) { + [exp fulfill]; + } + } + }); + } + [self waitForExpectations:@[exp] timeout:3]; + exp = nil; + [self.textNodeBucket removeAllObjects]; +} + +- (void)testTextNodeSwitchWorksInMultiThreadEnvironment2 +{ + ASConfiguration *config = [ASConfiguration new]; + config.experimentalFeatures = ASExperimentalTextNode; + [ASConfigurationManager test_resetWithConfiguration:config]; + XCTestExpectation *exp = [self expectationWithDescription:@"wait for full bucket"]; + + NSLock *lock = [[NSLock alloc] init]; + NSMutableArray *textNodeBucket = [[NSMutableArray alloc] init]; + + dispatch_queue_t queue = dispatch_queue_create("com.texture.AsyncDisplayKit.ASTextNodeTestsQueue", DISPATCH_QUEUE_CONCURRENT); + dispatch_group_t g = dispatch_group_create(); + for (int i = 0; i < 20; i++) { + dispatch_group_async(g, queue, ^{ + ASTextNode *textNode = [[ASTextNodeSecondSubclass alloc] init]; + XCTAssert([textNode isKindOfClass:[ASTextNode2 class]]); + [lock lock]; + [textNodeBucket addObject:textNode]; + if (textNodeBucket.count == 20) { + [exp fulfill]; + } + [lock unlock]; + }); + } + [self waitForExpectations:@[exp] timeout:3]; + exp = nil; + [textNodeBucket removeAllObjects]; +} + @end @implementation ASTextNodeSubclass From d3591980e3ed26f3bd7706b13184f1117a45cc11 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Fri, 2 Nov 2018 08:42:45 -0700 Subject: [PATCH 39/60] Add a CircleCI configuration file --- .circleci/config.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..34f4040306 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,15 @@ +# iOS CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/ios-migrating-from-1-2/ for more details +# +version: 2 +jobs: + build: + + # Specify the Xcode version to use + macos: + xcode: "9.4.1" + + steps: + - checkout + - command: build.sh all From 7ccdcb94726febc273e7a0647f9c8ec9bc49104f Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Fri, 2 Nov 2018 09:12:51 -0700 Subject: [PATCH 40/60] Fix the config and limit the branch --- .circleci/config.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 34f4040306..1f2c6702b9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,10 +6,17 @@ version: 2 jobs: build: + # Limit to Testing branch + branches: + only: + - AHCircleCI + # Specify the Xcode version to use macos: xcode: "9.4.1" steps: - checkout - - command: build.sh all + - run: + name: Build.sh all + command: ./build.sh all From d0ba092a77296d4b35e3349046e6e9c45073ce40 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Fri, 2 Nov 2018 12:04:14 -0700 Subject: [PATCH 41/60] Convert the codebase to Objective-C++ (#1206) * Convert the codebase to Objective-C++ throughout. One language is better than two. * Put it back * Fix linker * Point explicitly to updated Weaver to unblock build * Revert "Point explicitly to updated Weaver to unblock build" This reverts commit fdc25296e8794d4e6e56c35f5fe6da2be3f71dbc. * Revert "Fix linker" This reverts commit 7be25f91519b8497ef42de79f115bcfbdb965c39. * Add in the frameworks * no message * Address spec lint warnings * Fix tvos build * Put that back * Address Michael's review * Add comment to kick CI --- AsyncDisplayKit.xcodeproj/project.pbxproj | 1220 +++++++++-------- CHANGELOG.md | 1 + .../{ASCGImageBuffer.m => ASCGImageBuffer.mm} | 2 +- Source/{ASCollections.m => ASCollections.mm} | 4 +- .../{ASConfiguration.m => ASConfiguration.mm} | 2 +- ...nInternal.m => ASConfigurationInternal.mm} | 2 +- ...enience.m => ASDisplayNode+Convenience.mm} | 2 +- ...alFeatures.m => ASExperimentalFeatures.mm} | 2 +- ...Controller.m => ASNavigationController.mm} | 2 +- ...geLoadInfo.m => ASNetworkImageLoadInfo.mm} | 2 +- ...PagerFlowLayout.m => ASPagerFlowLayout.mm} | 2 +- Source/{ASPagerNode.m => ASPagerNode.mm} | 2 +- ...bBarController.m => ASTabBarController.mm} | 2 +- Source/ASVideoPlayerNode.h | 2 +- ...tyProtocols.m => ASVisibilityProtocols.mm} | 2 +- ....m => AsyncDisplayKit+IGListKitMethods.mm} | 0 Source/Base/{ASAssert.m => ASAssert.mm} | 12 +- Source/Base/ASBaseDefines.h | 1 + ...e+Ancestry.m => ASDisplayNode+Ancestry.mm} | 2 +- Source/Base/{ASLog.m => ASLog.mm} | 2 +- ...ayKit+Debug.m => AsyncDisplayKit+Debug.mm} | 2 +- ...playKit+Tips.m => AsyncDisplayKit+Tips.mm} | 4 +- .../{ASBatchContext.m => ASBatchContext.mm} | 2 +- ...te.m => ASCollectionFlowLayoutDelegate.mm} | 2 +- ...Context.m => ASCollectionLayoutContext.mm} | 2 +- ....m => ASCollectionViewLayoutController.mm} | 2 +- ...r.m => ASCollectionViewLayoutInspector.mm} | 2 +- .../{ASDelegateProxy.m => ASDelegateProxy.mm} | 2 +- .../{ASElementMap.m => ASElementMap.mm} | 4 +- ...GraphicsContext.m => ASGraphicsContext.mm} | 4 +- Source/Details/{ASHashing.m => ASHashing.mm} | 2 +- ... => ASImageContainerProtocolCategories.mm} | 2 +- ....m => ASMutableAttributedStringBuilder.mm} | 2 +- ...elpers.m => ASObjectDescriptionHelpers.mm} | 2 +- ...loader.m => ASPINRemoteImageDownloader.mm} | 2 +- .../Details/{ASPageTable.m => ASPageTable.mm} | 2 +- ...est.m => ASPhotosFrameworkImageRequest.mm} | 2 +- ...eUnfairLock.m => ASRecursiveUnfairLock.mm} | 2 +- ...ScrollDirection.m => ASScrollDirection.mm} | 2 +- ...ontroller.m => ASTableLayoutController.mm} | 2 +- .../{ASTraceEvent.m => ASTraceEvent.mm} | 2 +- ...TraitCollection.m => ASTraitCollection.mm} | 2 +- .../Details/{ASWeakProxy.m => ASWeakProxy.mm} | 2 +- Source/Details/{ASWeakSet.m => ASWeakSet.mm} | 2 +- Source/Details/CoreGraphics+ASConvenience.m | 11 - ...et+ASHelpers.m => NSIndexSet+ASHelpers.mm} | 2 +- ...tableAttributedString+TextKitAdditions.mm} | 2 +- ...iner.m => _ASAsyncTransactionContainer.mm} | 2 +- ...ionGroup.m => _ASAsyncTransactionGroup.mm} | 2 +- ...> UICollectionViewLayout+ASConvenience.mm} | 2 +- ...bleView.m => _ASCollectionReusableView.mm} | 5 +- ...ionViewCell.m => _ASCollectionViewCell.mm} | 5 +- ...Kit.m => IGListAdapter+AsyncDisplayKit.mm} | 8 +- ...rtBoxCreator.m => ASAsciiArtBoxCreator.mm} | 4 +- .../{ASBatchFetching.m => ASBatchFetching.mm} | 2 +- ...Defines.m => ASCollectionLayoutDefines.mm} | 2 +- ...=> ASCollectionViewFlowLayoutInspector.mm} | 2 +- ...argetAction.m => ASControlTargetAction.mm} | 2 +- ...ultPlayButton.m => ASDefaultPlayButton.mm} | 2 +- ...ackButton.m => ASDefaultPlaybackButton.mm} | 2 +- .../Private/{ASDispatch.m => ASDispatch.mm} | 4 +- ....m => ASDisplayNodeCornerLayerDelegate.mm} | 2 +- ...odeTipState.m => ASDisplayNodeTipState.mm} | 2 +- ...ce.m => ASIGListAdapterBasedDataSource.mm} | 2 +- ...ode+CGExtras.m => ASImageNode+CGExtras.mm} | 4 +- ...InternalHelpers.m => ASInternalHelpers.mm} | 4 +- ...rovider.m => ASLayerBackingTipProvider.mm} | 2 +- ...bleElementMap.m => ASMutableElementMap.mm} | 4 +- ...erator.m => ASResponderChainEnumerator.mm} | 4 +- Source/Private/{ASSection.m => ASSection.mm} | 2 +- Source/Private/{ASTip.m => ASTip.mm} | 4 +- Source/Private/{ASTipNode.m => ASTipNode.mm} | 2 +- .../{ASTipProvider.m => ASTipProvider.mm} | 4 +- ...ASTipsController.m => ASTipsController.mm} | 4 +- .../{ASTipsWindow.m => ASTipsWindow.mm} | 4 +- ...yUtils.m => ASTwoDimensionalArrayUtils.mm} | 2 +- Source/Private/{ASWeakMap.m => ASWeakMap.mm} | 2 +- ...TextDebugOption.m => ASTextDebugOption.mm} | 2 +- .../{ASTextInput.m => ASTextInput.mm} | 2 +- .../{ASTextLayout.m => ASTextLayout.mm} | 2 +- .../Component/{ASTextLine.m => ASTextLine.mm} | 2 +- .../{ASTextAttribute.m => ASTextAttribute.mm} | 2 +- ...TextRunDelegate.m => ASTextRunDelegate.mm} | 2 +- .../{ASTextUtilities.m => ASTextUtilities.mm} | 2 +- ...+ASText.m => NSAttributedString+ASText.mm} | 2 +- ...le+ASText.m => NSParagraphStyle+ASText.mm} | 2 +- ...fo.m => _ASCollectionGalleryLayoutInfo.mm} | 2 +- .../{ASLayoutManager.m => ASLayoutManager.mm} | 2 +- ...itions.m => ASTextKitCoreTextAdditions.mm} | 2 +- ...ttribute.m => ASTextKitEntityAttribute.mm} | 2 +- ...deWordKerner.m => ASTextNodeWordKerner.mm} | 2 +- ...Convenience.m => UIImage+ASConvenience.mm} | 2 +- ...ayKit.m => UIResponder+AsyncDisplayKit.mm} | 0 ...itionContext.m => _ASTransitionContext.mm} | 2 +- ...ntrolNode+tvOS.m => ASControlNode+tvOS.mm} | 2 +- ...ASImageNode+tvOS.m => ASImageNode+tvOS.mm} | 3 +- ...m => ASAbsoluteLayoutSpecSnapshotTests.mm} | 2 +- ... => ASBasicImageDownloaderContextTests.mm} | 2 +- ...Tests.m => ASBasicImageDownloaderTests.mm} | 2 +- ...etchingTests.m => ASBatchFetchingTests.mm} | 2 +- ...ButtonNodeTests.m => ASButtonNodeTests.mm} | 2 +- Tests/{ASCALayerTests.m => ASCALayerTests.mm} | 2 +- ...m => ASCollectionModernDataSourceTests.mm} | 2 +- ...CollectionViewFlowLayoutInspectorTests.mm} | 2 +- ...llectionsTests.m => ASCollectionsTests.mm} | 2 +- ...urationTests.m => ASConfigurationTests.mm} | 0 ...ntrolNodeTests.m => ASControlNodeTests.mm} | 2 +- .../{ASDispatchTests.m => ASDispatchTests.mm} | 2 +- ...layLayerTests.m => ASDisplayLayerTests.mm} | 14 +- ...ests.m => ASDisplayNodeAppearanceTests.mm} | 18 +- ...rasTests.m => ASDisplayNodeExtrasTests.mm} | 2 +- ...=> ASDisplayNodeImplicitHierarchyTests.mm} | 3 +- ...tTests.m => ASDisplayNodeSnapshotTests.mm} | 2 +- ...tsHelper.m => ASDisplayNodeTestsHelper.mm} | 2 +- ...NodeTests.m => ASEditableTextNodeTests.mm} | 2 +- ...hotTests.m => ASImageNodeSnapshotTests.mm} | 2 +- ...IntegerMapTests.m => ASIntegerMapTests.mm} | 2 +- ...leTests.m => ASLayoutElementStyleTests.mm} | 2 +- ...ningTests.m => ASLayoutFlatteningTests.mm} | 2 +- ...r.m => ASLayoutSpecSnapshotTestsHelper.mm} | 2 +- ...LayoutSpecTests.m => ASLayoutSpecTests.mm} | 2 +- ...deTests.m => ASMultiplexImageNodeTests.mm} | 6 +- ... ASMutableAttributedStringBuilderTests.mm} | 2 +- ...Tests.m => ASNavigationControllerTests.mm} | 2 +- ...NodeTests.m => ASNetworkImageNodeTests.mm} | 2 +- ...ASPagerNodeTests.m => ASPagerNodeTests.mm} | 2 +- ...tContext.m => ASPerformanceTestContext.mm} | 12 +- ... => ASPhotosFrameworkImageRequestTests.mm} | 2 +- ...kTests.m => ASRecursiveUnfairLockTests.mm} | 2 +- ...oopQueueTests.m => ASRunLoopQueueTests.mm} | 2 +- ...ScrollNodeTests.m => ASScrollNodeTests.mm} | 2 +- ...apshotTestCase.m => ASSnapshotTestCase.mm} | 2 +- ...llerTests.m => ASTabBarControllerTests.mm} | 2 +- ...hrashTests.m => ASTableViewThrashTests.mm} | 2 +- ...s.m => ASTextKitCoreTextAdditionsTests.mm} | 2 +- ...hotTests.m => ASTextNode2SnapshotTests.mm} | 2 +- ...ASTextNode2Tests.m => ASTextNode2Tests.mm} | 2 +- ...eTests.m => ASTextNodePerformanceTests.mm} | 2 +- ...shotTests.m => ASTextNodeSnapshotTests.mm} | 2 +- .../{ASTextNodeTests.m => ASTextNodeTests.mm} | 2 +- ...ctionTests.m => ASTraitCollectionTests.mm} | 2 +- ...ViewTests.m => ASUICollectionViewTests.mm} | 27 +- ...ASVideoNodeTests.m => ASVideoNodeTests.mm} | 2 +- ...rollerTests.m => ASViewControllerTests.mm} | 2 +- Tests/{ASWeakMapTests.m => ASWeakMapTests.mm} | 2 +- Tests/{ASWeakSetTests.m => ASWeakSetTests.mm} | 2 +- ...rayDiffingTests.m => ArrayDiffingTests.mm} | 2 +- ...yNode+OCMock.m => ASDisplayNode+OCMock.mm} | 2 +- Tests/Common/{ASTestCase.m => ASTestCase.mm} | 2 +- ...elpers.m => NSInvocation+ASTestHelpers.mm} | 2 +- ...dditions.m => OCMockObject+ASAdditions.mm} | 10 +- Tests/TestHost/AppDelegate.m | 21 - .../TestHost/AppDelegate.mm | 7 +- Tests/TestHost/{main.m => main.mm} | 2 +- Texture.podspec | 9 +- 155 files changed, 841 insertions(+), 846 deletions(-) rename Source/{ASCGImageBuffer.m => ASCGImageBuffer.mm} (99%) rename Source/{ASCollections.m => ASCollections.mm} (96%) rename Source/{ASConfiguration.m => ASConfiguration.mm} (98%) rename Source/{ASConfigurationInternal.m => ASConfigurationInternal.mm} (99%) rename Source/{ASDisplayNode+Convenience.m => ASDisplayNode+Convenience.mm} (96%) rename Source/{ASExperimentalFeatures.m => ASExperimentalFeatures.mm} (98%) rename Source/{ASNavigationController.m => ASNavigationController.mm} (99%) rename Source/{ASNetworkImageLoadInfo.m => ASNetworkImageLoadInfo.mm} (95%) rename Source/{ASPagerFlowLayout.m => ASPagerFlowLayout.mm} (99%) rename Source/{ASPagerNode.m => ASPagerNode.mm} (99%) rename Source/{ASTabBarController.m => ASTabBarController.mm} (98%) rename Source/{ASVisibilityProtocols.m => ASVisibilityProtocols.mm} (95%) rename Source/{AsyncDisplayKit+IGListKitMethods.m => AsyncDisplayKit+IGListKitMethods.mm} (100%) rename Source/Base/{ASAssert.m => ASAssert.mm} (82%) rename Source/Base/{ASDisplayNode+Ancestry.m => ASDisplayNode+Ancestry.mm} (98%) rename Source/Base/{ASLog.m => ASLog.mm} (99%) rename Source/Debug/{AsyncDisplayKit+Debug.m => AsyncDisplayKit+Debug.mm} (99%) rename Source/Debug/{AsyncDisplayKit+Tips.m => AsyncDisplayKit+Tips.mm} (93%) rename Source/Details/{ASBatchContext.m => ASBatchContext.mm} (98%) rename Source/Details/{ASCollectionFlowLayoutDelegate.m => ASCollectionFlowLayoutDelegate.mm} (98%) rename Source/Details/{ASCollectionLayoutContext.m => ASCollectionLayoutContext.mm} (98%) rename Source/Details/{ASCollectionViewLayoutController.m => ASCollectionViewLayoutController.mm} (99%) rename Source/Details/{ASCollectionViewLayoutInspector.m => ASCollectionViewLayoutInspector.mm} (98%) rename Source/Details/{ASDelegateProxy.m => ASDelegateProxy.mm} (99%) rename Source/Details/{ASElementMap.m => ASElementMap.mm} (99%) rename Source/Details/{ASGraphicsContext.m => ASGraphicsContext.mm} (99%) rename Source/Details/{ASHashing.m => ASHashing.mm} (98%) rename Source/Details/{ASImageContainerProtocolCategories.m => ASImageContainerProtocolCategories.mm} (93%) rename Source/Details/{ASMutableAttributedStringBuilder.m => ASMutableAttributedStringBuilder.mm} (99%) rename Source/Details/{ASObjectDescriptionHelpers.m => ASObjectDescriptionHelpers.mm} (99%) rename Source/Details/{ASPINRemoteImageDownloader.m => ASPINRemoteImageDownloader.mm} (99%) rename Source/Details/{ASPageTable.m => ASPageTable.mm} (99%) rename Source/Details/{ASPhotosFrameworkImageRequest.m => ASPhotosFrameworkImageRequest.mm} (99%) rename Source/Details/{ASRecursiveUnfairLock.m => ASRecursiveUnfairLock.mm} (99%) rename Source/Details/{ASScrollDirection.m => ASScrollDirection.mm} (98%) rename Source/Details/{ASTableLayoutController.m => ASTableLayoutController.mm} (98%) rename Source/Details/{ASTraceEvent.m => ASTraceEvent.mm} (99%) rename Source/Details/{ASTraitCollection.m => ASTraitCollection.mm} (99%) rename Source/Details/{ASWeakProxy.m => ASWeakProxy.mm} (99%) rename Source/Details/{ASWeakSet.m => ASWeakSet.mm} (99%) delete mode 100644 Source/Details/CoreGraphics+ASConvenience.m rename Source/Details/{NSIndexSet+ASHelpers.m => NSIndexSet+ASHelpers.mm} (98%) rename Source/Details/{NSMutableAttributedString+TextKitAdditions.m => NSMutableAttributedString+TextKitAdditions.mm} (96%) rename Source/Details/Transactions/{_ASAsyncTransactionContainer.m => _ASAsyncTransactionContainer.mm} (99%) rename Source/Details/Transactions/{_ASAsyncTransactionGroup.m => _ASAsyncTransactionGroup.mm} (99%) rename Source/Details/{UICollectionViewLayout+ASConvenience.m => UICollectionViewLayout+ASConvenience.mm} (95%) rename Source/Details/{_ASCollectionReusableView.m => _ASCollectionReusableView.mm} (96%) rename Source/Details/{_ASCollectionViewCell.m => _ASCollectionViewCell.mm} (97%) rename Source/{IGListAdapter+AsyncDisplayKit.m => IGListAdapter+AsyncDisplayKit.mm} (89%) rename Source/Layout/{ASAsciiArtBoxCreator.m => ASAsciiArtBoxCreator.mm} (99%) rename Source/Private/{ASBatchFetching.m => ASBatchFetching.mm} (99%) rename Source/Private/{ASCollectionLayoutDefines.m => ASCollectionLayoutDefines.mm} (95%) rename Source/Private/{ASCollectionViewFlowLayoutInspector.m => ASCollectionViewFlowLayoutInspector.mm} (99%) rename Source/Private/{ASControlTargetAction.m => ASControlTargetAction.mm} (97%) rename Source/Private/{ASDefaultPlayButton.m => ASDefaultPlayButton.mm} (98%) rename Source/Private/{ASDefaultPlaybackButton.m => ASDefaultPlaybackButton.mm} (98%) rename Source/Private/{ASDispatch.m => ASDispatch.mm} (94%) rename Source/Private/{ASDisplayNodeCornerLayerDelegate.m => ASDisplayNodeCornerLayerDelegate.mm} (91%) rename Source/Private/{ASDisplayNodeTipState.m => ASDisplayNodeTipState.mm} (94%) rename Source/Private/{ASIGListAdapterBasedDataSource.m => ASIGListAdapterBasedDataSource.mm} (99%) rename Source/Private/{ASImageNode+CGExtras.m => ASImageNode+CGExtras.mm} (99%) rename Source/Private/{ASInternalHelpers.m => ASInternalHelpers.mm} (99%) rename Source/Private/{ASLayerBackingTipProvider.m => ASLayerBackingTipProvider.mm} (97%) rename Source/Private/{ASMutableElementMap.m => ASMutableElementMap.mm} (98%) rename Source/Private/{ASResponderChainEnumerator.m => ASResponderChainEnumerator.mm} (91%) rename Source/Private/{ASSection.m => ASSection.mm} (97%) rename Source/Private/{ASTip.m => ASTip.mm} (94%) rename Source/Private/{ASTipNode.m => ASTipNode.mm} (97%) rename Source/Private/{ASTipProvider.m => ASTipProvider.mm} (93%) rename Source/Private/{ASTipsController.m => ASTipsController.mm} (98%) rename Source/Private/{ASTipsWindow.m => ASTipsWindow.mm} (97%) rename Source/Private/{ASTwoDimensionalArrayUtils.m => ASTwoDimensionalArrayUtils.mm} (99%) rename Source/Private/{ASWeakMap.m => ASWeakMap.mm} (99%) rename Source/Private/TextExperiment/Component/{ASTextDebugOption.m => ASTextDebugOption.mm} (99%) rename Source/Private/TextExperiment/Component/{ASTextInput.m => ASTextInput.mm} (99%) rename Source/Private/TextExperiment/Component/{ASTextLayout.m => ASTextLayout.mm} (99%) rename Source/Private/TextExperiment/Component/{ASTextLine.m => ASTextLine.mm} (99%) rename Source/Private/TextExperiment/String/{ASTextAttribute.m => ASTextAttribute.mm} (99%) rename Source/Private/TextExperiment/String/{ASTextRunDelegate.m => ASTextRunDelegate.mm} (98%) rename Source/Private/TextExperiment/Utility/{ASTextUtilities.m => ASTextUtilities.mm} (99%) rename Source/Private/TextExperiment/Utility/{NSAttributedString+ASText.m => NSAttributedString+ASText.mm} (99%) rename Source/Private/TextExperiment/Utility/{NSParagraphStyle+ASText.m => NSParagraphStyle+ASText.mm} (99%) rename Source/Private/{_ASCollectionGalleryLayoutInfo.m => _ASCollectionGalleryLayoutInfo.mm} (97%) rename Source/TextKit/{ASLayoutManager.m => ASLayoutManager.mm} (98%) rename Source/TextKit/{ASTextKitCoreTextAdditions.m => ASTextKitCoreTextAdditions.mm} (99%) rename Source/TextKit/{ASTextKitEntityAttribute.m => ASTextKitEntityAttribute.mm} (96%) rename Source/TextKit/{ASTextNodeWordKerner.m => ASTextNodeWordKerner.mm} (99%) rename Source/{UIImage+ASConvenience.m => UIImage+ASConvenience.mm} (99%) rename Source/{UIResponder+AsyncDisplayKit.m => UIResponder+AsyncDisplayKit.mm} (100%) rename Source/{_ASTransitionContext.m => _ASTransitionContext.mm} (99%) rename Source/tvOS/{ASControlNode+tvOS.m => ASControlNode+tvOS.mm} (99%) rename Source/tvOS/{ASImageNode+tvOS.m => ASImageNode+tvOS.mm} (98%) rename Tests/{ASAbsoluteLayoutSpecSnapshotTests.m => ASAbsoluteLayoutSpecSnapshotTests.mm} (98%) rename Tests/{ASBasicImageDownloaderContextTests.m => ASBasicImageDownloaderContextTests.mm} (98%) rename Tests/{ASBasicImageDownloaderTests.m => ASBasicImageDownloaderTests.mm} (98%) rename Tests/{ASBatchFetchingTests.m => ASBatchFetchingTests.mm} (99%) rename Tests/{ASButtonNodeTests.m => ASButtonNodeTests.mm} (98%) rename Tests/{ASCALayerTests.m => ASCALayerTests.mm} (99%) rename Tests/{ASCollectionModernDataSourceTests.m => ASCollectionModernDataSourceTests.mm} (99%) rename Tests/{ASCollectionViewFlowLayoutInspectorTests.m => ASCollectionViewFlowLayoutInspectorTests.mm} (99%) rename Tests/{ASCollectionsTests.m => ASCollectionsTests.mm} (98%) rename Tests/{ASConfigurationTests.m => ASConfigurationTests.mm} (100%) rename Tests/{ASControlNodeTests.m => ASControlNodeTests.mm} (99%) rename Tests/{ASDispatchTests.m => ASDispatchTests.mm} (98%) rename Tests/{ASDisplayLayerTests.m => ASDisplayLayerTests.mm} (96%) rename Tests/{ASDisplayNodeAppearanceTests.m => ASDisplayNodeAppearanceTests.mm} (95%) rename Tests/{ASDisplayNodeExtrasTests.m => ASDisplayNodeExtrasTests.mm} (98%) rename Tests/{ASDisplayNodeImplicitHierarchyTests.m => ASDisplayNodeImplicitHierarchyTests.mm} (99%) rename Tests/{ASDisplayNodeSnapshotTests.m => ASDisplayNodeSnapshotTests.mm} (96%) rename Tests/{ASDisplayNodeTestsHelper.m => ASDisplayNodeTestsHelper.mm} (98%) rename Tests/{ASEditableTextNodeTests.m => ASEditableTextNodeTests.mm} (99%) rename Tests/{ASImageNodeSnapshotTests.m => ASImageNodeSnapshotTests.mm} (98%) rename Tests/{ASIntegerMapTests.m => ASIntegerMapTests.mm} (99%) rename Tests/{ASLayoutElementStyleTests.m => ASLayoutElementStyleTests.mm} (99%) rename Tests/{ASLayoutFlatteningTests.m => ASLayoutFlatteningTests.mm} (99%) rename Tests/{ASLayoutSpecSnapshotTestsHelper.m => ASLayoutSpecSnapshotTestsHelper.mm} (97%) rename Tests/{ASLayoutSpecTests.m => ASLayoutSpecTests.mm} (99%) rename Tests/{ASMultiplexImageNodeTests.m => ASMultiplexImageNodeTests.mm} (99%) rename Tests/{ASMutableAttributedStringBuilderTests.m => ASMutableAttributedStringBuilderTests.mm} (98%) rename Tests/{ASNavigationControllerTests.m => ASNavigationControllerTests.mm} (98%) rename Tests/{ASNetworkImageNodeTests.m => ASNetworkImageNodeTests.mm} (99%) rename Tests/{ASPagerNodeTests.m => ASPagerNodeTests.mm} (99%) rename Tests/{ASPerformanceTestContext.m => ASPerformanceTestContext.mm} (96%) rename Tests/{ASPhotosFrameworkImageRequestTests.m => ASPhotosFrameworkImageRequestTests.mm} (97%) rename Tests/{ASRecursiveUnfairLockTests.m => ASRecursiveUnfairLockTests.mm} (99%) rename Tests/{ASRunLoopQueueTests.m => ASRunLoopQueueTests.mm} (99%) rename Tests/{ASScrollNodeTests.m => ASScrollNodeTests.mm} (99%) rename Tests/{ASSnapshotTestCase.m => ASSnapshotTestCase.mm} (98%) rename Tests/{ASTabBarControllerTests.m => ASTabBarControllerTests.mm} (98%) rename Tests/{ASTableViewThrashTests.m => ASTableViewThrashTests.mm} (99%) rename Tests/{ASTextKitCoreTextAdditionsTests.m => ASTextKitCoreTextAdditionsTests.mm} (98%) rename Tests/{ASTextNode2SnapshotTests.m => ASTextNode2SnapshotTests.mm} (99%) rename Tests/{ASTextNode2Tests.m => ASTextNode2Tests.mm} (99%) rename Tests/{ASTextNodePerformanceTests.m => ASTextNodePerformanceTests.mm} (99%) rename Tests/{ASTextNodeSnapshotTests.m => ASTextNodeSnapshotTests.mm} (99%) rename Tests/{ASTextNodeTests.m => ASTextNodeTests.mm} (99%) rename Tests/{ASTraitCollectionTests.m => ASTraitCollectionTests.mm} (96%) rename Tests/{ASUICollectionViewTests.m => ASUICollectionViewTests.mm} (83%) rename Tests/{ASVideoNodeTests.m => ASVideoNodeTests.mm} (99%) rename Tests/{ASViewControllerTests.m => ASViewControllerTests.mm} (99%) rename Tests/{ASWeakMapTests.m => ASWeakMapTests.mm} (98%) rename Tests/{ASWeakSetTests.m => ASWeakSetTests.mm} (99%) rename Tests/{ArrayDiffingTests.m => ArrayDiffingTests.mm} (99%) rename Tests/Common/{ASDisplayNode+OCMock.m => ASDisplayNode+OCMock.mm} (94%) rename Tests/Common/{ASTestCase.m => ASTestCase.mm} (99%) rename Tests/Common/{NSInvocation+ASTestHelpers.m => NSInvocation+ASTestHelpers.mm} (95%) rename Tests/Common/{OCMockObject+ASAdditions.m => OCMockObject+ASAdditions.mm} (95%) delete mode 100644 Tests/TestHost/AppDelegate.m rename Source/Details/ASCollectionInternal.m => Tests/TestHost/AppDelegate.mm (76%) rename Tests/TestHost/{main.m => main.mm} (97%) diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 27d49fc5a8..2cfec88415 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -7,30 +7,30 @@ objects = { /* Begin PBXBuildFile section */ - 044284FD1BAA365100D16268 /* UICollectionViewLayout+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E0E1B371875007741D0 /* UICollectionViewLayout+ASConvenience.m */; }; + 044284FD1BAA365100D16268 /* UICollectionViewLayout+ASConvenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E0E1B371875007741D0 /* UICollectionViewLayout+ASConvenience.mm */; }; 044284FF1BAA3BD600D16268 /* UICollectionViewLayout+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E0D1B371875007741D0 /* UICollectionViewLayout+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; 044285081BAA63FE00D16268 /* ASBatchFetching.h in Headers */ = {isa = PBXBuildFile; fileRef = 044285051BAA63FE00D16268 /* ASBatchFetching.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 0442850A1BAA63FE00D16268 /* ASBatchFetching.m in Sources */ = {isa = PBXBuildFile; fileRef = 044285061BAA63FE00D16268 /* ASBatchFetching.m */; }; + 0442850A1BAA63FE00D16268 /* ASBatchFetching.mm in Sources */ = {isa = PBXBuildFile; fileRef = 044285061BAA63FE00D16268 /* ASBatchFetching.mm */; }; 0442850E1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0442850B1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 044285101BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 0442850C1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.m */; }; - 052EE0661A159FEF002C6279 /* ASMultiplexImageNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 052EE0651A159FEF002C6279 /* ASMultiplexImageNodeTests.m */; }; + 044285101BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0442850C1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.mm */; }; + 052EE0661A159FEF002C6279 /* ASMultiplexImageNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 052EE0651A159FEF002C6279 /* ASMultiplexImageNodeTests.mm */; }; 052EE06B1A15A0D8002C6279 /* TestResources in Resources */ = {isa = PBXBuildFile; fileRef = 052EE06A1A15A0D8002C6279 /* TestResources */; }; - 056D21551ABCEF50001107EF /* ASImageNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.m */; }; - 057D02C41AC0A66700C7AC3C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 057D02C31AC0A66700C7AC3C /* main.m */; }; - 057D02C71AC0A66700C7AC3C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 057D02C61AC0A66700C7AC3C /* AppDelegate.m */; }; + 056D21551ABCEF50001107EF /* ASImageNodeSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.mm */; }; + 057D02C41AC0A66700C7AC3C /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 057D02C31AC0A66700C7AC3C /* main.mm */; }; + 057D02C71AC0A66700C7AC3C /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 057D02C61AC0A66700C7AC3C /* AppDelegate.mm */; }; 058D09BE195D04C000B7D73C /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09BD195D04C000B7D73C /* XCTest.framework */; }; 058D09BF195D04C000B7D73C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09AF195D04C000B7D73C /* Foundation.framework */; }; 058D09C1195D04C000B7D73C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09C0195D04C000B7D73C /* UIKit.framework */; }; 058D09CA195D04C000B7D73C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 058D09C8195D04C000B7D73C /* InfoPlist.strings */; }; - 058D0A38195D057000B7D73C /* ASDisplayLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A2D195D057000B7D73C /* ASDisplayLayerTests.m */; }; - 058D0A39195D057000B7D73C /* ASDisplayNodeAppearanceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A2E195D057000B7D73C /* ASDisplayNodeAppearanceTests.m */; }; + 058D0A38195D057000B7D73C /* ASDisplayLayerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A2D195D057000B7D73C /* ASDisplayLayerTests.mm */; }; + 058D0A39195D057000B7D73C /* ASDisplayNodeAppearanceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A2E195D057000B7D73C /* ASDisplayNodeAppearanceTests.mm */; }; 058D0A3A195D057000B7D73C /* ASDisplayNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A2F195D057000B7D73C /* ASDisplayNodeTests.mm */; }; - 058D0A3B195D057000B7D73C /* ASDisplayNodeTestsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A31195D057000B7D73C /* ASDisplayNodeTestsHelper.m */; }; - 058D0A3C195D057000B7D73C /* ASMutableAttributedStringBuilderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A32195D057000B7D73C /* ASMutableAttributedStringBuilderTests.m */; }; - 058D0A3D195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A33195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.m */; }; - 058D0A40195D057000B7D73C /* ASTextNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A36195D057000B7D73C /* ASTextNodeTests.m */; }; + 058D0A3B195D057000B7D73C /* ASDisplayNodeTestsHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A31195D057000B7D73C /* ASDisplayNodeTestsHelper.mm */; }; + 058D0A3C195D057000B7D73C /* ASMutableAttributedStringBuilderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A32195D057000B7D73C /* ASMutableAttributedStringBuilderTests.mm */; }; + 058D0A3D195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A33195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.mm */; }; + 058D0A40195D057000B7D73C /* ASTextNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A36195D057000B7D73C /* ASTextNodeTests.mm */; }; 058D0A41195D057000B7D73C /* ASTextNodeWordKernerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A37195D057000B7D73C /* ASTextNodeWordKernerTests.mm */; }; - 05EA6FE71AC0966E00E35788 /* ASSnapshotTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.m */; }; + 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, ); }; }; @@ -38,8 +38,8 @@ 1A6C000D1FAB4E2100D05926 /* ASCornerLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A6C000B1FAB4E2000D05926 /* ASCornerLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1A6C000E1FAB4E2100D05926 /* ASCornerLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A6C000C1FAB4E2100D05926 /* ASCornerLayoutSpec.mm */; }; 1A6C00111FAB4EDD00D05926 /* ASCornerLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A6C000F1FAB4ED400D05926 /* ASCornerLayoutSpecSnapshotTests.mm */; }; - 242995D31B29743C00090100 /* ASBasicImageDownloaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 242995D21B29743C00090100 /* ASBasicImageDownloaderTests.m */; }; - 2538B6F31BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */; }; + 242995D31B29743C00090100 /* ASBasicImageDownloaderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 242995D21B29743C00090100 /* ASBasicImageDownloaderTests.mm */; }; + 2538B6F31BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.mm */; }; 254C6B521BF8FE6D003EC431 /* ASTextKitTruncationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 254C6B511BF8FE6D003EC431 /* ASTextKitTruncationTests.mm */; }; 254C6B541BF8FF2A003EC431 /* ASTextKitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 254C6B531BF8FF2A003EC431 /* ASTextKitTests.mm */; }; 254C6B731BF94DF4003EC431 /* ASTextKitCoreTextAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754BB1BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -56,28 +56,28 @@ 254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754A11BEE44CD00737CA5 /* ASTextKitTailTruncater.h */; settings = {ATTRIBUTES = (Private, ); }; }; 254C6B7F1BF94DF4003EC431 /* ASTextKitTruncating.h in Headers */ = {isa = PBXBuildFile; fileRef = 257754A31BEE44CD00737CA5 /* ASTextKitTruncating.h */; settings = {ATTRIBUTES = (Private, ); }; }; 254C6B821BF94F8A003EC431 /* ASTextKitComponents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754B71BEE458D00737CA5 /* ASTextKitComponents.mm */; }; - 254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.m */; }; - 254C6B841BF94F8A003EC431 /* ASTextNodeWordKerner.m in Sources */ = {isa = PBXBuildFile; fileRef = 257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.m */; }; + 254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.mm */; }; + 254C6B841BF94F8A003EC431 /* ASTextNodeWordKerner.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.mm */; }; 254C6B851BF94F8A003EC431 /* ASTextKitAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754941BEE44CD00737CA5 /* ASTextKitAttributes.mm */; }; 254C6B861BF94F8A003EC431 /* ASTextKitContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754971BEE44CD00737CA5 /* ASTextKitContext.mm */; }; - 254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 257754991BEE44CD00737CA5 /* ASTextKitEntityAttribute.m */; }; + 254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754991BEE44CD00737CA5 /* ASTextKitEntityAttribute.mm */; }; 254C6B881BF94F8A003EC431 /* ASTextKitRenderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2577549A1BEE44CD00737CA5 /* ASTextKitRenderer.mm */; }; 254C6B891BF94F8A003EC431 /* ASTextKitRenderer+Positioning.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2577549C1BEE44CD00737CA5 /* ASTextKitRenderer+Positioning.mm */; }; 254C6B8A1BF94F8A003EC431 /* ASTextKitRenderer+TextChecking.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2577549E1BEE44CD00737CA5 /* ASTextKitRenderer+TextChecking.mm */; }; 254C6B8B1BF94F8A003EC431 /* ASTextKitShadower.mm in Sources */ = {isa = PBXBuildFile; fileRef = 257754A01BEE44CD00737CA5 /* ASTextKitShadower.mm */; }; 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.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E327551C16819500A2170C /* ASPagerNode.m */; }; + 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, ); }; }; - 2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2911485B1A77147A005D0878 /* ASControlNodeTests.m */; }; - 296A0A351A951ABF005ACEAA /* ASBatchFetchingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.m */; }; - 29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 29CDC2E11AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m */; }; + 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 */; }; 2C107F5B1BA9F54500F13DE5 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */; }; + 34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.mm */; }; 34EFC75B1B701BAF00AD841F /* ASDimension.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED071B17843500DA7C62 /* ASDimension.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34EFC75C1B701BD200AD841F /* ASDimension.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED081B17843500DA7C62 /* ASDimension.mm */; }; 34EFC75D1B701BE900AD841F /* ASInternalHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 34EFC75E1B701BF000AD841F /* ASInternalHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.m */; }; + 34EFC75E1B701BF000AD841F /* ASInternalHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.mm */; }; 34EFC75F1B701C8600AD841F /* ASInsetLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED091B17843500DA7C62 /* ASInsetLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34EFC7601B701C8B00AD841F /* ASInsetLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutSpec.mm */; }; 34EFC7611B701C9C00AD841F /* ASBackgroundLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -99,48 +99,47 @@ 34EFC7731B701D0700AD841F /* ASAbsoluteLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED181B17843500DA7C62 /* ASAbsoluteLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34EFC7741B701D0A00AD841F /* ASAbsoluteLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED191B17843500DA7C62 /* ASAbsoluteLayoutSpec.mm */; }; 3917EBD41E9C2FC400D04A01 /* _ASCollectionReusableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 3917EBD21E9C2FC400D04A01 /* _ASCollectionReusableView.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 3917EBD51E9C2FC400D04A01 /* _ASCollectionReusableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.m */; }; + 3917EBD51E9C2FC400D04A01 /* _ASCollectionReusableView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.mm */; }; 3C9C128519E616EF00E942A0 /* ASTableViewTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C9C128419E616EF00E942A0 /* ASTableViewTests.mm */; }; - 4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.m */; }; - 4E9127691F64157600499623 /* ASRunLoopQueueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E9127681F64157600499623 /* ASRunLoopQueueTests.m */; }; - 509E68601B3AED8E009B9150 /* ASScrollDirection.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E111B371BD7007741D0 /* ASScrollDirection.m */; }; + 4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm */; }; + 4E9127691F64157600499623 /* ASRunLoopQueueTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4E9127681F64157600499623 /* ASRunLoopQueueTests.mm */; }; + 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 */; }; 509E68631B3AEDB4009B9150 /* ASCollectionViewLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */; }; - 509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.m */; }; + 509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.mm */; }; 509E68651B3AEDC5009B9150 /* CoreGraphics+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 509E68661B3AEDD7009B9150 /* CoreGraphics+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.m */; }; 636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */; }; - 636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */; }; + 636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.mm */; }; 680346941CE4052A0009FEB4 /* ASNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 68355B341CB579B9001D4E68 /* ASImageNode+AnimatedImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68355B2E1CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm */; }; - 68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */; }; - 68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */; }; + 68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.mm */; }; + 68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.mm */; }; 68355B411CB57A6C001D4E68 /* ASImageContainerProtocolCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */; settings = {ATTRIBUTES = (Public, ); }; }; 683F563720E409D700CEB7A3 /* ASDisplayNode+InterfaceState.h in Headers */ = {isa = PBXBuildFile; fileRef = 683F563620E409D600CEB7A3 /* ASDisplayNode+InterfaceState.h */; settings = {ATTRIBUTES = (Public, ); }; }; 68AF37DB1CBEF4D80077BF76 /* ASImageNode+AnimatedImagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 68B0277B1C1A79D60041016B /* ASDisplayNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; 68B8A4E21CBDB958007E4543 /* ASWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 68B8A4E41CBDB958007E4543 /* ASWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */; }; + 68B8A4E41CBDB958007E4543 /* ASWeakProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68B8A4E01CBDB958007E4543 /* ASWeakProxy.mm */; }; 68C215581DE10D330019C4BC /* ASCollectionViewLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 68C2155A1DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */; }; + 68C2155A1DE10D330019C4BC /* ASCollectionViewLayoutInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.mm */; }; 68EE0DBE1C1B4ED300BA1B99 /* ASMainSerialQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */; settings = {ATTRIBUTES = (Private, ); }; }; 68EE0DC01C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */; }; 68FC85E31CE29B7E00EDD713 /* ASTabBarController.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85E01CE29B7E00EDD713 /* ASTabBarController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 68FC85E51CE29B7E00EDD713 /* ASTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E11CE29B7E00EDD713 /* ASTabBarController.m */; }; - 68FC85E61CE29B9400EDD713 /* ASNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85DD1CE29AB700EDD713 /* ASNavigationController.m */; }; + 68FC85E51CE29B7E00EDD713 /* ASTabBarController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E11CE29B7E00EDD713 /* ASTabBarController.mm */; }; + 68FC85E61CE29B9400EDD713 /* ASNavigationController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85DD1CE29AB700EDD713 /* ASNavigationController.mm */; }; 68FC85EA1CE29C7D00EDD713 /* ASVisibilityProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */; }; + 68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.mm */; }; 6900C5F41E8072DA00BCD75C /* ASImageNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 6900C5F31E8072DA00BCD75C /* ASImageNode+Private.h */; }; 6907C2581DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 6907C2561DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6907C25A1DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m */; }; + 6907C25A1DC4ECFE00374C66 /* ASObjectDescriptionHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.mm */; }; 690BC8C120F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 690BC8BF20F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 690BC8C220F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m */; }; + 690BC8C220F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.mm */; }; 690C35621E055C5D00069B91 /* ASDimensionInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 690C35601E055C5D00069B91 /* ASDimensionInternal.mm */; }; 690C35641E055C7B00069B91 /* ASDimensionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 690C35631E055C7B00069B91 /* ASDimensionInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; 690ED58E1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 690ED58D1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 690ED5981E36D118000627C0 /* ASControlNode+tvOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 690ED5931E36D118000627C0 /* ASControlNode+tvOS.m */; }; - 690ED59B1E36D118000627C0 /* ASImageNode+tvOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 690ED5951E36D118000627C0 /* ASImageNode+tvOS.m */; }; + 690ED5981E36D118000627C0 /* ASControlNode+tvOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 690ED5931E36D118000627C0 /* ASControlNode+tvOS.mm */; }; + 690ED59B1E36D118000627C0 /* ASImageNode+tvOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 690ED5951E36D118000627C0 /* ASImageNode+tvOS.mm */; }; 692510141E74FB44003F2DD0 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 692510131E74FB44003F2DD0 /* Default-568h@2x.png */; }; 692BE8D71E36B65B00C86D87 /* ASLayoutSpecPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 692BE8D61E36B65B00C86D87 /* ASLayoutSpecPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 693A1DCA1ECC944E00D0C9D2 /* IGListAdapter+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = CCE04B201E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -155,7 +154,7 @@ 696FCB311D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 696FCB301D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm */; }; 6977965F1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 6977965D1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h */; settings = {ATTRIBUTES = (Private, ); }; }; 697796611D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */; }; - 697B315A1CFE4B410049936F /* ASEditableTextNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */; }; + 697B315A1CFE4B410049936F /* ASEditableTextNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 697B31591CFE4B410049936F /* ASEditableTextNodeTests.mm */; }; 698371DB1E4379CD00437585 /* ASNodeController+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 698371D91E4379CD00437585 /* ASNodeController+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; 698371DC1E4379CD00437585 /* ASNodeController+Beta.mm in Sources */ = {isa = PBXBuildFile; fileRef = 698371DA1E4379CD00437585 /* ASNodeController+Beta.mm */; }; 698C8B621CAB49FC0052DC3F /* ASLayoutElementExtensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 698C8B601CAB49FC0052DC3F /* ASLayoutElementExtensibility.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -167,21 +166,21 @@ 69CB62AE1CB8165900024920 /* _ASDisplayViewAccessiblity.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69CB62AA1CB8165900024920 /* _ASDisplayViewAccessiblity.mm */; }; 69E0E8A71D356C9400627613 /* ASEqualityHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 69F10C871C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 69FEE53D1D95A9AF0086F066 /* ASLayoutElementStyleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 69FEE53C1D95A9AF0086F066 /* ASLayoutElementStyleTests.m */; }; + 69FEE53D1D95A9AF0086F066 /* ASLayoutElementStyleTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69FEE53C1D95A9AF0086F066 /* ASLayoutElementStyleTests.mm */; }; 7630FFA81C9E267E007A7C0E /* ASVideoNode.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEC47DF1C20C2DD00EC1693 /* ASVideoNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 764D83D51C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 767E7F8E1C90191D0066C000 /* AsyncDisplayKit+Debug.m in Sources */ = {isa = PBXBuildFile; fileRef = 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */; }; + 767E7F8E1C90191D0066C000 /* AsyncDisplayKit+Debug.mm in Sources */ = {isa = PBXBuildFile; fileRef = 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.mm */; }; 7AB338661C55B3420055FDE8 /* ASRelativeLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7A06A7381C35F08800FE8DAA /* ASRelativeLayoutSpec.mm */; }; 7AB338671C55B3460055FDE8 /* ASRelativeLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7AB338691C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */; }; 8021EC1D1D2B00B100799119 /* UIImage+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 8021EC1A1D2B00B100799119 /* UIImage+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8021EC1F1D2B00B100799119 /* UIImage+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.m */; }; - 81E95C141D62639600336598 /* ASTextNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 81E95C131D62639600336598 /* ASTextNodeSnapshotTests.m */; }; - 83A7D95B1D44547700BF333E /* ASWeakMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A7D9591D44542100BF333E /* ASWeakMap.m */; }; + 8021EC1F1D2B00B100799119 /* UIImage+ASConvenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.mm */; }; + 81E95C141D62639600336598 /* ASTextNodeSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 81E95C131D62639600336598 /* ASTextNodeSnapshotTests.mm */; }; + 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.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A7D95D1D446A6E00BF333E /* ASWeakMapTests.m */; }; + 83A7D95E1D446A6E00BF333E /* ASWeakMapTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83A7D95D1D446A6E00BF333E /* ASWeakMapTests.mm */; }; 8BBBAB8C1CEBAF1700107FC6 /* ASDefaultPlaybackButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B0768B11CE752EC002E1453 /* ASDefaultPlaybackButton.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 8BBBAB8D1CEBAF1E00107FC6 /* ASDefaultPlaybackButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.m */; }; + 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, ); }; }; 8BDA5FC81CDBDF95007D13B2 /* ASVideoPlayerNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8BDA5FC41CDBDDE1007D13B2 /* ASVideoPlayerNode.mm */; }; 9019FBBF1ED8061D00C45F72 /* ASYogaUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 9019FBBB1ED8061D00C45F72 /* ASYogaUtilities.h */; }; @@ -193,10 +192,10 @@ 92DD2FE71BF4D0850074C9DD /* ASMapNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 92DD2FE21BF4B97E0074C9DD /* ASMapNode.mm */; }; 92DD2FE81BF4D0A80074C9DD /* ASMapNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 92DD2FE11BF4B97E0074C9DD /* ASMapNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9C49C3701B853961000B0DD5 /* ASStackLayoutElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C49C36E1B853957000B0DD5 /* ASStackLayoutElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9C55866B1BD54A1900B50E3A /* ASAsciiArtBoxCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */; }; + 9C55866B1BD54A1900B50E3A /* ASAsciiArtBoxCreator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.mm */; }; 9C55866C1BD54A3000B50E3A /* ASAsciiArtBoxCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5586671BD549CB00B50E3A /* ASAsciiArtBoxCreator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9C6BB3B31B8CC9C200F13F52 /* ASAbsoluteLayoutElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASAbsoluteLayoutElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9C70F2051CDA4F06007D6C76 /* ASTraitCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C70F2021CDA4EFA007D6C76 /* ASTraitCollection.m */; }; + 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 */; }; 9C70F20A1CDBE949007D6C76 /* ASTableNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFFC6C11CCAC768006A6476 /* ASTableNode.mm */; }; @@ -205,34 +204,34 @@ 9C70F20F1CDBE9FF007D6C76 /* ASLayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B30BF6501C5964B0004FCD53 /* ASLayoutManager.h */; settings = {ATTRIBUTES = (Private, ); }; }; 9C8898BC1C738BA800D6B02E /* ASTextKitFontSizeAdjuster.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C8898BA1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm */; }; 9C8898BD1C738BB800D6B02E /* ASTextKitFontSizeAdjuster.h in Headers */ = {isa = PBXBuildFile; fileRef = A32FEDD31C501B6A004F642A /* ASTextKitFontSizeAdjuster.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 9CC606651D24DF9E006581A0 /* NSIndexSet+ASHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */; }; + 9CC606651D24DF9E006581A0 /* NSIndexSet+ASHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.mm */; }; 9CDC18CD1B910E12004965E2 /* ASLayoutElementPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutElementPrivate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9F06E5CD1B4CAF4200F015D8 /* ASCollectionViewTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.mm */; }; - 9F98C0261DBE29E000476D92 /* ASControlTargetAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F98C0241DBDF2A300476D92 /* ASControlTargetAction.m */; }; + 9F98C0261DBE29E000476D92 /* ASControlTargetAction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9F98C0241DBDF2A300476D92 /* ASControlTargetAction.mm */; }; 9F98C0271DBE29FC00476D92 /* ASControlTargetAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F98C0231DBDF2A300476D92 /* ASControlTargetAction.h */; settings = {ATTRIBUTES = (Private, ); }; }; A2763D7A1CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = A2763D771CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; A37320101C571B740011FC94 /* ASTextNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = A373200E1C571B050011FC94 /* ASTextNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AC026B581BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B571BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.m */; }; + AC026B581BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC026B571BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.mm */; }; AC026B701BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; AC026B721BD57DBF00BBC17E /* _ASHierarchyChangeSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.mm */; }; AC47D9421B3B891B00AAEE9D /* ASCellNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC6456071B0A335000CF11B8 /* ASCellNode.mm */; }; AC6145411D8AFAE8003D62A2 /* ASSection.h in Headers */ = {isa = PBXBuildFile; fileRef = AC6145401D8AFAE8003D62A2 /* ASSection.h */; settings = {ATTRIBUTES = (Private, ); }; }; - AC6145441D8AFD4F003D62A2 /* ASSection.m in Sources */ = {isa = PBXBuildFile; fileRef = AC6145421D8AFD4F003D62A2 /* ASSection.m */; }; + AC6145441D8AFD4F003D62A2 /* ASSection.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC6145421D8AFD4F003D62A2 /* ASSection.mm */; }; AC7A2C181BDE11DF0093FE1A /* ASTableViewInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = AC7A2C161BDE11DF0093FE1A /* ASTableViewInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; ACE87A2C1D73696800D7FF06 /* ASSectionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = ACE87A2B1D73696800D7FF06 /* ASSectionContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; ACF6ED5C1B178DC700DA7C62 /* ASCenterLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED531B178DC700DA7C62 /* ASCenterLayoutSpecSnapshotTests.mm */; }; ACF6ED5D1B178DC700DA7C62 /* ASDimensionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED541B178DC700DA7C62 /* ASDimensionTests.mm */; }; ACF6ED5E1B178DC700DA7C62 /* ASInsetLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED551B178DC700DA7C62 /* ASInsetLayoutSpecSnapshotTests.mm */; }; - ACF6ED601B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED581B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.m */; }; + ACF6ED601B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED581B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.mm */; }; ACF6ED611B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED591B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm */; }; ACF6ED621B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED5A1B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm */; }; ACF6ED631B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED5B1B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm */; }; AE440175210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE440174210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm */; }; - AE6987C11DD04E1000B9E458 /* ASPagerNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AE6987C01DD04E1000B9E458 /* ASPagerNodeTests.m */; }; - AEEC47E41C21D3D200EC1693 /* ASVideoNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.m */; }; + AE6987C11DD04E1000B9E458 /* ASPagerNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE6987C01DD04E1000B9E458 /* ASPagerNodeTests.mm */; }; + AEEC47E41C21D3D200EC1693 /* ASVideoNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.mm */; }; B13CA0F81C519EBA00E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = B13CA0F61C519E9400E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; B13CA1011C52004900E031AB /* ASCollectionNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = B13CA0FF1C52004900E031AB /* ASCollectionNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B30BF6541C59D889004FCD53 /* ASLayoutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B30BF6511C5964B0004FCD53 /* ASLayoutManager.m */; }; + B30BF6541C59D889004FCD53 /* ASLayoutManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = B30BF6511C5964B0004FCD53 /* ASLayoutManager.mm */; }; B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35061F51B010EFD0018CF92 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35061F61B010EFD0018CF92 /* ASCollectionView.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC3C4A501A1139C100143C57 /* ASCollectionView.mm */; }; @@ -267,31 +266,31 @@ B35062131B010EFD0018CF92 /* ASBasicImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 054963471A1EA066000F8E56 /* ASBasicImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35062141B010EFD0018CF92 /* ASBasicImageDownloader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 054963481A1EA066000F8E56 /* ASBasicImageDownloader.mm */; }; B35062151B010EFD0018CF92 /* ASBatchContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 299DA1A71A828D2900162D41 /* ASBatchContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B35062161B010EFD0018CF92 /* ASBatchContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 299DA1A81A828D2900162D41 /* ASBatchContext.m */; }; + B35062161B010EFD0018CF92 /* ASBatchContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 299DA1A81A828D2900162D41 /* ASBatchContext.mm */; }; B35062171B010EFD0018CF92 /* ASDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = 464052191A3F83C40061C0BA /* ASDataController.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35062181B010EFD0018CF92 /* ASDataController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4640521A1A3F83C40061C0BA /* ASDataController.mm */; }; B350621B1B010EFD0018CF92 /* ASTableLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4640521B1A3F83C40061C0BA /* ASTableLayoutController.h */; settings = {ATTRIBUTES = (Private, ); }; }; - B350621C1B010EFD0018CF92 /* ASTableLayoutController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4640521C1A3F83C40061C0BA /* ASTableLayoutController.m */; }; + B350621C1B010EFD0018CF92 /* ASTableLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4640521C1A3F83C40061C0BA /* ASTableLayoutController.mm */; }; B350621D1B010EFD0018CF92 /* ASHighlightOverlayLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09E6195D050800B7D73C /* ASHighlightOverlayLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; B350621E1B010EFD0018CF92 /* ASHighlightOverlayLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09E7195D050800B7D73C /* ASHighlightOverlayLayer.mm */; }; B350621F1B010EFD0018CF92 /* ASImageProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35062201B010EFD0018CF92 /* ASLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4640521D1A3F83C40061C0BA /* ASLayoutController.h */; }; B35062211B010EFD0018CF92 /* ASLayoutRangeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C59991A956527007E5DD6 /* ASLayoutRangeType.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35062241B010EFD0018CF92 /* ASMutableAttributedStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09E8195D050800B7D73C /* ASMutableAttributedStringBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B35062251B010EFD0018CF92 /* ASMutableAttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.m */; }; + B35062251B010EFD0018CF92 /* ASMutableAttributedStringBuilder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.mm */; }; B35062261B010EFD0018CF92 /* ASRangeController.h in Headers */ = {isa = PBXBuildFile; fileRef = 055F1A3619ABD413004DAFF1 /* ASRangeController.h */; }; B35062271B010EFD0018CF92 /* ASRangeController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 055F1A3719ABD413004DAFF1 /* ASRangeController.mm */; }; B350622D1B010EFD0018CF92 /* ASScrollDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 296A0A311A951715005ACEAA /* ASScrollDirection.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35062391B010EFD0018CF92 /* ASThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D0A12195D050800B7D73C /* ASThread.h */; settings = {ATTRIBUTES = (Public, ); }; }; B350623A1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09F5195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09F6195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m */; }; + B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09F6195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.mm */; }; B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09F8195D050800B7D73C /* _ASAsyncTransaction.h */; settings = {ATTRIBUTES = (Public, ); }; }; B350623D1B010EFD0018CF92 /* _ASAsyncTransaction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09F9195D050800B7D73C /* _ASAsyncTransaction.mm */; }; B350623E1B010EFD0018CF92 /* _ASAsyncTransactionContainer+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09FA195D050800B7D73C /* _ASAsyncTransactionContainer+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; B350623F1B010EFD0018CF92 /* _ASAsyncTransactionContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09FB195D050800B7D73C /* _ASAsyncTransactionContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09FC195D050800B7D73C /* _ASAsyncTransactionContainer.m */; }; + B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09FC195D050800B7D73C /* _ASAsyncTransactionContainer.mm */; }; B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09FD195D050800B7D73C /* _ASAsyncTransactionGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B35062421B010EFD0018CF92 /* _ASAsyncTransactionGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09FE195D050800B7D73C /* _ASAsyncTransactionGroup.m */; }; + B35062421B010EFD0018CF92 /* _ASAsyncTransactionGroup.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09FE195D050800B7D73C /* _ASAsyncTransactionGroup.mm */; }; B35062431B010EFD0018CF92 /* UIView+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09FF195D050800B7D73C /* UIView+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35062461B010EFD0018CF92 /* ASBasicImageDownloaderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2967F9E11AB0A4CF0072E4AB /* ASBasicImageDownloaderInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; B35062491B010EFD0018CF92 /* _ASCoreAnimationExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -305,166 +304,176 @@ B35062511B010EFD0018CF92 /* ASDisplayNode+UIViewBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A0B195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm */; }; B35062521B010EFD0018CF92 /* ASDisplayNodeInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D0A0C195D050800B7D73C /* ASDisplayNodeInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; B35062531B010EFD0018CF92 /* ASImageNode+CGExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D0A0D195D050800B7D73C /* ASImageNode+CGExtras.h */; settings = {ATTRIBUTES = (Private, ); }; }; - B35062541B010EFD0018CF92 /* ASImageNode+CGExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */; }; + B35062541B010EFD0018CF92 /* ASImageNode+CGExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.mm */; }; B35062571B010F070018CF92 /* ASAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D0A43195D058D00B7D73C /* ASAssert.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35062581B010F070018CF92 /* ASAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 0516FA3A1A15563400B4EBED /* ASAvailability.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35062591B010F070018CF92 /* ASBaseDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D0A44195D058D00B7D73C /* ASBaseDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; B350625C1B010F070018CF92 /* ASLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 0516FA3B1A15563400B4EBED /* ASLog.h */; settings = {ATTRIBUTES = (Public, ); }; }; B350625D1B0111740018CF92 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943141A1575670030A7D0 /* Photos.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; B350625E1B0111780018CF92 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943121A1575630030A7D0 /* AssetsLibrary.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - BB5FC3CE1F9BA689007F191E /* ASNavigationControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BB5FC3CD1F9BA688007F191E /* ASNavigationControllerTests.m */; }; - BB5FC3D11F9C9389007F191E /* ASTabBarControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BB5FC3D01F9C9389007F191E /* ASTabBarControllerTests.m */; }; + BB5FC3CE1F9BA689007F191E /* ASNavigationControllerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = BB5FC3CD1F9BA688007F191E /* ASNavigationControllerTests.mm */; }; + BB5FC3D11F9C9389007F191E /* ASTabBarControllerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = BB5FC3D01F9C9389007F191E /* ASTabBarControllerTests.mm */; }; C018DF21216BF26700181FDA /* ASAbstractLayoutController+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = C018DF20216BF26600181FDA /* ASAbstractLayoutController+FrameworkPrivate.h */; }; - C057D9BD20B5453D00FC9112 /* ASTextNode2SnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.m */; }; + C057D9BD20B5453D00FC9112 /* ASTextNode2SnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.mm */; }; C78F7E2B1BF7809800CDEAFC /* ASTableNode.h in Headers */ = {isa = PBXBuildFile; fileRef = B0F880581BEAEC7500D17647 /* ASTableNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; CC034A091E60BEB400626263 /* ASDisplayNode+Convenience.h in Headers */ = {isa = PBXBuildFile; fileRef = CC034A071E60BEB400626263 /* ASDisplayNode+Convenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CC034A0A1E60BEB400626263 /* ASDisplayNode+Convenience.m in Sources */ = {isa = PBXBuildFile; fileRef = CC034A081E60BEB400626263 /* ASDisplayNode+Convenience.m */; }; + CC034A0A1E60BEB400626263 /* ASDisplayNode+Convenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC034A081E60BEB400626263 /* ASDisplayNode+Convenience.mm */; }; CC034A131E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = CC034A111E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CC034A141E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = CC034A121E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m */; }; - CC051F1F1D7A286A006434CB /* ASCALayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC051F1E1D7A286A006434CB /* ASCALayerTests.m */; }; - CC0AEEA41D66316E005D1C78 /* ASUICollectionViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.m */; }; - CC0F885B1E42807F00576FED /* ASCollectionViewFlowLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0F88591E42807F00576FED /* ASCollectionViewFlowLayoutInspector.m */; }; + CC034A141E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC034A121E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.mm */; }; + CC051F1F1D7A286A006434CB /* ASCALayerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC051F1E1D7A286A006434CB /* ASCALayerTests.mm */; }; + CC0AEEA41D66316E005D1C78 /* ASUICollectionViewTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.mm */; }; + CC0F885B1E42807F00576FED /* ASCollectionViewFlowLayoutInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC0F88591E42807F00576FED /* ASCollectionViewFlowLayoutInspector.mm */; }; CC0F885C1E42807F00576FED /* ASCollectionViewFlowLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = CC0F885A1E42807F00576FED /* ASCollectionViewFlowLayoutInspector.h */; settings = {ATTRIBUTES = (Private, ); }; }; - CC0F885F1E4280B800576FED /* _ASCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0F885D1E4280B800576FED /* _ASCollectionViewCell.m */; }; + CC0F885F1E4280B800576FED /* _ASCollectionViewCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC0F885D1E4280B800576FED /* _ASCollectionViewCell.mm */; }; CC0F88601E4280B800576FED /* _ASCollectionViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = CC0F885E1E4280B800576FED /* _ASCollectionViewCell.h */; settings = {ATTRIBUTES = (Private, ); }; }; 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.m in Sources */ = {isa = PBXBuildFile; fileRef = CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.m */; }; + 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 */; }; CC2F65EE1E5FFB1600DA57C9 /* ASMutableElementMap.h in Headers */ = {isa = PBXBuildFile; fileRef = CC2F65EC1E5FFB1600DA57C9 /* ASMutableElementMap.h */; }; - CC2F65EF1E5FFB1600DA57C9 /* ASMutableElementMap.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.m */; }; + CC2F65EF1E5FFB1600DA57C9 /* ASMutableElementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.mm */; }; CC35CEC320DD7F600006448D /* ASCollections.h in Headers */ = {isa = PBXBuildFile; fileRef = CC35CEC120DD7F600006448D /* ASCollections.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CC35CEC420DD7F600006448D /* ASCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = CC35CEC220DD7F600006448D /* ASCollections.m */; }; - CC35CEC620DD87280006448D /* ASCollectionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC35CEC520DD87280006448D /* ASCollectionsTests.m */; }; + CC35CEC420DD7F600006448D /* ASCollections.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC35CEC220DD7F600006448D /* ASCollections.mm */; }; + CC35CEC620DD87280006448D /* ASCollectionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC35CEC520DD87280006448D /* ASCollectionsTests.mm */; }; + CC36C18F218B841600232F23 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C18E218B841600232F23 /* UIKit.framework */; }; + CC36C191218B841A00232F23 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C190218B841A00232F23 /* CoreText.framework */; }; + CC36C193218B842E00232F23 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C192218B842E00232F23 /* CoreGraphics.framework */; }; + CC36C194218B844800232F23 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09AF195D04C000B7D73C /* Foundation.framework */; }; + CC36C196218B845B00232F23 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C195218B845B00232F23 /* AVFoundation.framework */; }; + CC36C198218B846300232F23 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C197218B846300232F23 /* QuartzCore.framework */; }; + CC36C19A218B846F00232F23 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C199218B846F00232F23 /* CoreLocation.framework */; }; + CC36C19C218B847400232F23 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C19B218B847400232F23 /* CoreMedia.framework */; }; + CC36C19D218B849C00232F23 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C18E218B841600232F23 /* UIKit.framework */; }; + CC36C19E218B894400232F23 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C195218B845B00232F23 /* AVFoundation.framework */; }; + CC36C19F218B894800232F23 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC36C19B218B847400232F23 /* CoreMedia.framework */; }; CC3B20841C3F76D600798563 /* ASPendingStateController.h in Headers */ = {isa = PBXBuildFile; fileRef = CC3B20811C3F76D600798563 /* ASPendingStateController.h */; settings = {ATTRIBUTES = (Private, ); }; }; CC3B20861C3F76D600798563 /* ASPendingStateController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B20821C3F76D600798563 /* ASPendingStateController.mm */; }; CC3B208A1C3F7A5400798563 /* ASWeakSet.h in Headers */ = {isa = PBXBuildFile; fileRef = CC3B20871C3F7A5400798563 /* ASWeakSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CC3B208C1C3F7A5400798563 /* ASWeakSet.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3B20881C3F7A5400798563 /* ASWeakSet.m */; }; - CC3B208E1C3F7D0A00798563 /* ASWeakSetTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */; }; + CC3B208C1C3F7A5400798563 /* ASWeakSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B20881C3F7A5400798563 /* ASWeakSet.mm */; }; + CC3B208E1C3F7D0A00798563 /* ASWeakSetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.mm */; }; CC3B20901C3F892D00798563 /* ASBridgedPropertiesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */; }; - CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */; }; + CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.mm */; }; CC4C2A771D88E3BF0039ACAB /* ASTraceEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4C2A751D88E3BF0039ACAB /* ASTraceEvent.h */; settings = {ATTRIBUTES = (Private, ); }; }; - CC4C2A791D88E3BF0039ACAB /* ASTraceEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.m */; }; + CC4C2A791D88E3BF0039ACAB /* ASTraceEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.mm */; }; CC54A81C1D70079800296A24 /* ASDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = CC54A81B1D70077A00296A24 /* ASDispatch.h */; settings = {ATTRIBUTES = (Private, ); }; }; - CC54A81E1D7008B300296A24 /* ASDispatchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC54A81D1D7008B300296A24 /* ASDispatchTests.m */; }; + CC54A81E1D7008B300296A24 /* ASDispatchTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC54A81D1D7008B300296A24 /* ASDispatchTests.mm */; }; CC55A70D1E529FA200594372 /* UIResponder+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.m in Sources */ = {isa = PBXBuildFile; fileRef = CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */; }; + CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.mm */; }; CC55A7111E52A0F200594372 /* ASResponderChainEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */; }; - CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */; }; + CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.mm */; }; CC56013B1F06E9A700DC4FBE /* ASIntegerMap.h in Headers */ = {isa = PBXBuildFile; fileRef = CC5601391F06E9A700DC4FBE /* ASIntegerMap.h */; }; CC56013C1F06E9A700DC4FBE /* ASIntegerMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC56013A1F06E9A700DC4FBE /* ASIntegerMap.mm */; }; CC57EAF71E3939350034C595 /* ASCollectionView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = CC2E317F1DAC353700EEE891 /* ASCollectionView+Undeprecated.h */; settings = {ATTRIBUTES = (Private, ); }; }; CC57EAF81E3939450034C595 /* ASTableView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */; settings = {ATTRIBUTES = (Private, ); }; }; - CC583AD61EF9BDBE00134156 /* ASTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = CC583AC21EF9BAB400134156 /* ASTestCase.m */; }; - CC583AD71EF9BDC100134156 /* NSInvocation+ASTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = CC583AC51EF9BAB400134156 /* NSInvocation+ASTestHelpers.m */; }; - CC583AD81EF9BDC300134156 /* OCMockObject+ASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC583AC71EF9BAB400134156 /* OCMockObject+ASAdditions.m */; }; - CC583AD91EF9BDC600134156 /* ASDisplayNode+OCMock.m in Sources */ = {isa = PBXBuildFile; fileRef = CC583AC01EF9BAB400134156 /* ASDisplayNode+OCMock.m */; }; + CC583AD61EF9BDBE00134156 /* ASTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC583AC21EF9BAB400134156 /* ASTestCase.mm */; }; + CC583AD71EF9BDC100134156 /* NSInvocation+ASTestHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC583AC51EF9BAB400134156 /* NSInvocation+ASTestHelpers.mm */; }; + 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, ); }; }; CC6AA2DA1E9F03B900978E87 /* ASDisplayNode+Ancestry.h in Headers */ = {isa = PBXBuildFile; fileRef = CC6AA2D81E9F03B900978E87 /* ASDisplayNode+Ancestry.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CC6AA2DB1E9F03B900978E87 /* ASDisplayNode+Ancestry.m in Sources */ = {isa = PBXBuildFile; fileRef = CC6AA2D91E9F03B900978E87 /* ASDisplayNode+Ancestry.m */; }; + 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, ); }; }; - CC7AF198200DAB2200A21BDE /* ASExperimentalFeatures.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7AF197200D9E8400A21BDE /* ASExperimentalFeatures.m */; }; - CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */; }; + CC7AF198200DAB2200A21BDE /* ASExperimentalFeatures.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC7AF197200D9E8400A21BDE /* ASExperimentalFeatures.mm */; }; + CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.mm */; }; CC7FD9E21BB603FF005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; CC84C7F220474C5300A3851B /* ASCGImageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = CC84C7F020474C5300A3851B /* ASCGImageBuffer.h */; }; - CC84C7F320474C5300A3851B /* ASCGImageBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC84C7F120474C5300A3851B /* ASCGImageBuffer.m */; }; + CC84C7F320474C5300A3851B /* ASCGImageBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC84C7F120474C5300A3851B /* ASCGImageBuffer.mm */; }; CC87BB951DA8193C0090E380 /* ASCellNode+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = CC87BB941DA8193C0090E380 /* ASCellNode+Internal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - CC8B05D61D73836400F54286 /* ASPerformanceTestContext.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8B05D51D73836400F54286 /* ASPerformanceTestContext.m */; }; - CC8B05D81D73979700F54286 /* ASTextNodePerformanceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.m */; }; + 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.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.m */; }; + CCA221D31D6FA7EF00AF6A0F /* ASViewControllerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.mm */; }; CCA282B41E9EA7310037E8B7 /* ASTipsController.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282B21E9EA7310037E8B7 /* ASTipsController.h */; }; - CCA282B51E9EA7310037E8B7 /* ASTipsController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282B31E9EA7310037E8B7 /* ASTipsController.m */; }; + 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, ); }; }; - CCA282B91E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282B71E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.m */; }; + CCA282B91E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA282B71E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.mm */; }; CCA282BC1E9EABDD0037E8B7 /* ASTipProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282BA1E9EABDD0037E8B7 /* ASTipProvider.h */; }; - CCA282BD1E9EABDD0037E8B7 /* ASTipProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282BB1E9EABDD0037E8B7 /* ASTipProvider.m */; }; + CCA282BD1E9EABDD0037E8B7 /* ASTipProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA282BB1E9EABDD0037E8B7 /* ASTipProvider.mm */; }; CCA282C01E9EAE010037E8B7 /* ASTip.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282BE1E9EAE010037E8B7 /* ASTip.h */; }; - CCA282C11E9EAE010037E8B7 /* ASTip.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282BF1E9EAE010037E8B7 /* ASTip.m */; }; + CCA282C11E9EAE010037E8B7 /* ASTip.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA282BF1E9EAE010037E8B7 /* ASTip.mm */; }; CCA282C41E9EAE630037E8B7 /* ASLayerBackingTipProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282C21E9EAE630037E8B7 /* ASLayerBackingTipProvider.h */; }; - CCA282C51E9EAE630037E8B7 /* ASLayerBackingTipProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282C31E9EAE630037E8B7 /* ASLayerBackingTipProvider.m */; }; + CCA282C51E9EAE630037E8B7 /* ASLayerBackingTipProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA282C31E9EAE630037E8B7 /* ASLayerBackingTipProvider.mm */; }; CCA282C81E9EB64B0037E8B7 /* ASDisplayNodeTipState.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282C61E9EB64B0037E8B7 /* ASDisplayNodeTipState.h */; }; - CCA282C91E9EB64B0037E8B7 /* ASDisplayNodeTipState.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282C71E9EB64B0037E8B7 /* ASDisplayNodeTipState.m */; }; + CCA282C91E9EB64B0037E8B7 /* ASDisplayNodeTipState.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA282C71E9EB64B0037E8B7 /* ASDisplayNodeTipState.mm */; }; CCA282CC1E9EB73E0037E8B7 /* ASTipNode.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282CA1E9EB73E0037E8B7 /* ASTipNode.h */; }; - CCA282CD1E9EB73E0037E8B7 /* ASTipNode.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282CB1E9EB73E0037E8B7 /* ASTipNode.m */; }; + CCA282CD1E9EB73E0037E8B7 /* ASTipNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA282CB1E9EB73E0037E8B7 /* ASTipNode.mm */; }; CCA282D01E9EBF6C0037E8B7 /* ASTipsWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282CE1E9EBF6C0037E8B7 /* ASTipsWindow.h */; }; - CCA282D11E9EBF6C0037E8B7 /* ASTipsWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.m */; }; - CCA5F62E1EECC2A80060C137 /* ASAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA5F62D1EECC2A80060C137 /* ASAssert.m */; }; + CCA282D11E9EBF6C0037E8B7 /* ASTipsWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.mm */; }; + CCA5F62E1EECC2A80060C137 /* ASAssert.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCA5F62D1EECC2A80060C137 /* ASAssert.mm */; }; CCAA0B7F206ADBF30057B336 /* ASRecursiveUnfairLock.h in Headers */ = {isa = PBXBuildFile; fileRef = CCAA0B7D206ADBF30057B336 /* ASRecursiveUnfairLock.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CCAA0B80206ADBF30057B336 /* ASRecursiveUnfairLock.m in Sources */ = {isa = PBXBuildFile; fileRef = CCAA0B7E206ADBF30057B336 /* ASRecursiveUnfairLock.m */; }; - CCAA0B82206ADECB0057B336 /* ASRecursiveUnfairLockTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCAA0B81206ADECB0057B336 /* ASRecursiveUnfairLockTests.m */; }; - CCB1F95A1EFB60A5009C7475 /* ASLog.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB1F9591EFB60A5009C7475 /* ASLog.m */; }; + CCAA0B80206ADBF30057B336 /* ASRecursiveUnfairLock.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCAA0B7E206ADBF30057B336 /* ASRecursiveUnfairLock.mm */; }; + CCAA0B82206ADECB0057B336 /* ASRecursiveUnfairLockTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCAA0B81206ADECB0057B336 /* ASRecursiveUnfairLockTests.mm */; }; + CCB1F95A1EFB60A5009C7475 /* ASLog.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCB1F9591EFB60A5009C7475 /* ASLog.mm */; }; CCB1F95C1EFB6350009C7475 /* ASSignpost.h in Headers */ = {isa = PBXBuildFile; fileRef = CCB1F95B1EFB6316009C7475 /* ASSignpost.h */; }; - CCB2F34D1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */; }; + CCB2F34D1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.mm */; }; CCBBBF5D1EB161760069AA91 /* ASRangeManagingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = CCBBBF5C1EB161760069AA91 /* ASRangeManagingNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; CCBDDD0520C62A2D00CBA922 /* ASMainThreadDeallocation.h in Headers */ = {isa = PBXBuildFile; fileRef = CCBDDD0320C62A2D00CBA922 /* ASMainThreadDeallocation.h */; settings = {ATTRIBUTES = (Public, ); }; }; CCBDDD0620C62A2D00CBA922 /* ASMainThreadDeallocation.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCBDDD0420C62A2D00CBA922 /* ASMainThreadDeallocation.mm */; }; CCCCCCD51EC3EF060087FE10 /* ASTextDebugOption.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCC31EC3EF060087FE10 /* ASTextDebugOption.h */; }; - CCCCCCD61EC3EF060087FE10 /* ASTextDebugOption.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCC41EC3EF060087FE10 /* ASTextDebugOption.m */; }; + CCCCCCD61EC3EF060087FE10 /* ASTextDebugOption.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCC41EC3EF060087FE10 /* ASTextDebugOption.mm */; }; CCCCCCD71EC3EF060087FE10 /* ASTextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCC51EC3EF060087FE10 /* ASTextInput.h */; }; - CCCCCCD81EC3EF060087FE10 /* ASTextInput.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCC61EC3EF060087FE10 /* ASTextInput.m */; }; + CCCCCCD81EC3EF060087FE10 /* ASTextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCC61EC3EF060087FE10 /* ASTextInput.mm */; }; CCCCCCD91EC3EF060087FE10 /* ASTextLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCC71EC3EF060087FE10 /* ASTextLayout.h */; }; - CCCCCCDA1EC3EF060087FE10 /* ASTextLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCC81EC3EF060087FE10 /* ASTextLayout.m */; }; + CCCCCCDA1EC3EF060087FE10 /* ASTextLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCC81EC3EF060087FE10 /* ASTextLayout.mm */; }; CCCCCCDB1EC3EF060087FE10 /* ASTextLine.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCC91EC3EF060087FE10 /* ASTextLine.h */; }; - CCCCCCDC1EC3EF060087FE10 /* ASTextLine.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCCA1EC3EF060087FE10 /* ASTextLine.m */; }; + CCCCCCDC1EC3EF060087FE10 /* ASTextLine.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCCA1EC3EF060087FE10 /* ASTextLine.mm */; }; CCCCCCDD1EC3EF060087FE10 /* ASTextAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCCC1EC3EF060087FE10 /* ASTextAttribute.h */; }; - CCCCCCDE1EC3EF060087FE10 /* ASTextAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCCD1EC3EF060087FE10 /* ASTextAttribute.m */; }; + CCCCCCDE1EC3EF060087FE10 /* ASTextAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCCD1EC3EF060087FE10 /* ASTextAttribute.mm */; }; CCCCCCDF1EC3EF060087FE10 /* ASTextRunDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCCE1EC3EF060087FE10 /* ASTextRunDelegate.h */; }; - CCCCCCE01EC3EF060087FE10 /* ASTextRunDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCCF1EC3EF060087FE10 /* ASTextRunDelegate.m */; }; + CCCCCCE01EC3EF060087FE10 /* ASTextRunDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCCF1EC3EF060087FE10 /* ASTextRunDelegate.mm */; }; CCCCCCE11EC3EF060087FE10 /* ASTextUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCD11EC3EF060087FE10 /* ASTextUtilities.h */; }; - CCCCCCE21EC3EF060087FE10 /* ASTextUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCD21EC3EF060087FE10 /* ASTextUtilities.m */; }; + CCCCCCE21EC3EF060087FE10 /* ASTextUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCD21EC3EF060087FE10 /* ASTextUtilities.mm */; }; CCCCCCE31EC3EF060087FE10 /* NSParagraphStyle+ASText.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCD31EC3EF060087FE10 /* NSParagraphStyle+ASText.h */; }; - CCCCCCE41EC3EF060087FE10 /* NSParagraphStyle+ASText.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCD41EC3EF060087FE10 /* NSParagraphStyle+ASText.m */; }; + CCCCCCE41EC3EF060087FE10 /* NSParagraphStyle+ASText.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCD41EC3EF060087FE10 /* NSParagraphStyle+ASText.mm */; }; CCCCCCE71EC3F0FC0087FE10 /* NSAttributedString+ASText.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCE51EC3F0FC0087FE10 /* NSAttributedString+ASText.h */; }; - CCCCCCE81EC3F0FC0087FE10 /* NSAttributedString+ASText.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCE61EC3F0FC0087FE10 /* NSAttributedString+ASText.m */; }; + CCCCCCE81EC3F0FC0087FE10 /* NSAttributedString+ASText.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCE61EC3F0FC0087FE10 /* NSAttributedString+ASText.mm */; }; CCDC9B4D200991D10063C1F8 /* ASGraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = CCDC9B4B200991D10063C1F8 /* ASGraphicsContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CCDC9B4E200991D10063C1F8 /* ASGraphicsContext.m in Sources */ = {isa = PBXBuildFile; fileRef = CCDC9B4C200991D10063C1F8 /* ASGraphicsContext.m */; }; - CCDD148B1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.m */; }; - CCE4F9B31F0D60AC00062E4E /* ASIntegerMapTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.m */; }; + CCDC9B4E200991D10063C1F8 /* ASGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCDC9B4C200991D10063C1F8 /* ASGraphicsContext.mm */; }; + CCDD148B1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.mm */; }; + CCE4F9B31F0D60AC00062E4E /* ASIntegerMapTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.mm */; }; CCE4F9B51F0DA4F300062E4E /* ASLayoutEngineTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9B41F0DA4F300062E4E /* ASLayoutEngineTests.mm */; }; CCE4F9BA1F0DBB5000062E4E /* ASLayoutTestNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9B71F0DBA5000062E4E /* ASLayoutTestNode.mm */; }; CCE4F9BE1F0ECE5200062E4E /* ASTLayoutFixture.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9BD1F0ECE5200062E4E /* ASTLayoutFixture.mm */; }; CCED5E3E2020D36800395C40 /* ASNetworkImageLoadInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = CCED5E3C2020D36800395C40 /* ASNetworkImageLoadInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CCED5E3F2020D36800395C40 /* ASNetworkImageLoadInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.m */; }; + CCED5E3F2020D36800395C40 /* ASNetworkImageLoadInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.mm */; }; CCED5E412020D49D00395C40 /* ASNetworkImageLoadInfo+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CCED5E402020D41600395C40 /* ASNetworkImageLoadInfo+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; CCEDDDCA200C2AC300FFCD0A /* ASConfigurationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = CCEDDDC8200C2AC300FFCD0A /* ASConfigurationInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CCEDDDCB200C2AC300FFCD0A /* ASConfigurationInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDC9200C2AC300FFCD0A /* ASConfigurationInternal.m */; }; + CCEDDDCB200C2AC300FFCD0A /* ASConfigurationInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDC9200C2AC300FFCD0A /* ASConfigurationInternal.mm */; }; CCEDDDCD200C2CB900FFCD0A /* ASConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = CCEDDDCC200C2CB900FFCD0A /* ASConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; CCEDDDCF200C42A200FFCD0A /* ASConfigurationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = CCEDDDCE200C42A200FFCD0A /* ASConfigurationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CCEDDDD1200C488000FFCD0A /* ASConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDD0200C488000FFCD0A /* ASConfiguration.m */; }; - CCEDDDD9200C518800FFCD0A /* ASConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.m */; }; + CCEDDDD1200C488000FFCD0A /* ASConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDD0200C488000FFCD0A /* ASConfiguration.mm */; }; + CCEDDDD9200C518800FFCD0A /* ASConfigurationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.mm */; }; CCF18FF41D2575E300DF5895 /* NSIndexSet+ASHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; }; CCF1FF5E20C4785000AAD8FC /* ASLocking.h in Headers */ = {isa = PBXBuildFile; fileRef = CCF1FF5D20C4785000AAD8FC /* ASLocking.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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.m in Sources */ = {isa = PBXBuildFile; fileRef = DB55C2601C6408D6004EDCF5 /* _ASTransitionContext.m */; }; + 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.m in Sources */ = {isa = PBXBuildFile; fileRef = DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.m */; }; - DBC453221C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DBC453211C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.m */; }; + DBC452DE1C5C6A6A00B16017 /* ArrayDiffingTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.mm */; }; + DBC453221C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBC453211C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.mm */; }; DBDB83951C6E879900D0098C /* ASPagerFlowLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = DBDB83921C6E879900D0098C /* ASPagerFlowLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DBDB83971C6E879900D0098C /* ASPagerFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = DBDB83931C6E879900D0098C /* ASPagerFlowLayout.m */; }; + DBDB83971C6E879900D0098C /* ASPagerFlowLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBDB83931C6E879900D0098C /* ASPagerFlowLayout.mm */; }; DE4843DC1C93EAC100A1F33B /* ASLayoutTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */; settings = {ATTRIBUTES = (Private, ); }; }; DE6EA3231C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DE6EA3211C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; DE84918D1C8FFF2B003D89E9 /* ASRunLoopQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; DE84918E1C8FFF9F003D89E9 /* ASRunLoopQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */; }; DE8BEAC21C2DF3FC00D57C12 /* ASDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = DE8BEABF1C2DF3FC00D57C12 /* ASDelegateProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DE8BEAC41C2DF3FC00D57C12 /* ASDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = DE8BEAC01C2DF3FC00D57C12 /* ASDelegateProxy.m */; }; + DE8BEAC41C2DF3FC00D57C12 /* ASDelegateProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = DE8BEAC01C2DF3FC00D57C12 /* ASDelegateProxy.mm */; }; DEB8ED7C1DD003D300DBDE55 /* ASLayoutTransition.mm in Sources */ = {isa = PBXBuildFile; fileRef = E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */; }; DEC146B71C37A16A004A0EE7 /* ASCollectionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DEC146B41C37A16A004A0EE7 /* ASCollectionInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DEC146B91C37A16A004A0EE7 /* ASCollectionInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = DEC146B51C37A16A004A0EE7 /* ASCollectionInternal.m */; }; 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 */; }; - E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.m */; }; + 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 */; }; - E54E81FD1EB357BD00FFE8E1 /* ASPageTable.m in Sources */ = {isa = PBXBuildFile; fileRef = E54E81FB1EB357BD00FFE8E1 /* ASPageTable.m */; }; + E54E81FD1EB357BD00FFE8E1 /* ASPageTable.mm in Sources */ = {isa = PBXBuildFile; fileRef = E54E81FB1EB357BD00FFE8E1 /* ASPageTable.mm */; }; E55D86331CA8A14000A0C26F /* ASLayoutElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */; }; E5667E8C1F33871300FA6FC0 /* _ASCollectionGalleryLayoutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = E5667E8B1F33871300FA6FC0 /* _ASCollectionGalleryLayoutInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - E5667E8E1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = E5667E8D1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.m */; }; + E5667E8E1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5667E8D1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.mm */; }; E5711A2C1C840C81009619D4 /* ASCollectionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E5711A2A1C840C81009619D4 /* ASCollectionElement.h */; settings = {ATTRIBUTES = (Private, ); }; }; E5711A301C840C96009619D4 /* ASCollectionElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASCollectionElement.mm */; }; E5775AFC1F13CE9F00CAC9BC /* _ASCollectionGalleryLayoutItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E5775AFB1F13CE9F00CAC9BC /* _ASCollectionGalleryLayoutItem.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -472,21 +481,21 @@ E5775B001F13D25400CAC9BC /* ASCollectionLayoutState+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = E5775AFF1F13D25400CAC9BC /* ASCollectionLayoutState+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; E5775B021F16759300CAC9BC /* ASCollectionLayoutCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E5775B011F16759300CAC9BC /* ASCollectionLayoutCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; E5775B041F16759F00CAC9BC /* ASCollectionLayoutCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5775B031F16759F00CAC9BC /* ASCollectionLayoutCache.mm */; }; - E5855DEF1EBB4D83003639AE /* ASCollectionLayoutDefines.m in Sources */ = {isa = PBXBuildFile; fileRef = E5855DED1EBB4D83003639AE /* ASCollectionLayoutDefines.m */; }; + E5855DEF1EBB4D83003639AE /* ASCollectionLayoutDefines.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5855DED1EBB4D83003639AE /* ASCollectionLayoutDefines.mm */; }; E5855DF01EBB4D83003639AE /* ASCollectionLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = E5855DEE1EBB4D83003639AE /* ASCollectionLayoutDefines.h */; settings = {ATTRIBUTES = (Private, ); }; }; - E586F96C1F9F9E2900ECE00E /* ASScrollNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E586F96B1F9F9E2900ECE00E /* ASScrollNodeTests.m */; }; + E586F96C1F9F9E2900ECE00E /* ASScrollNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = E586F96B1F9F9E2900ECE00E /* ASScrollNodeTests.mm */; }; E58E9E421E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E58E9E3D1E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E58E9E431E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E58E9E3E1E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.m */; }; + E58E9E431E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E58E9E3E1E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.mm */; }; E58E9E441E941D74004CFC59 /* ASCollectionLayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E58E9E3F1E941D74004CFC59 /* ASCollectionLayoutContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E58E9E451E941D74004CFC59 /* ASCollectionLayoutContext.m in Sources */ = {isa = PBXBuildFile; fileRef = E58E9E401E941D74004CFC59 /* ASCollectionLayoutContext.m */; }; + E58E9E451E941D74004CFC59 /* ASCollectionLayoutContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = E58E9E401E941D74004CFC59 /* ASCollectionLayoutContext.mm */; }; E58E9E461E941D74004CFC59 /* ASCollectionLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E58E9E411E941D74004CFC59 /* ASCollectionLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; E58E9E491E941DA5004CFC59 /* ASCollectionLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E58E9E471E941DA5004CFC59 /* ASCollectionLayout.h */; settings = {ATTRIBUTES = (Private, ); }; }; E58E9E4A1E941DA5004CFC59 /* ASCollectionLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = E58E9E481E941DA5004CFC59 /* ASCollectionLayout.mm */; }; E5B077FF1E69F4EB00C24B5B /* ASElementMap.h in Headers */ = {isa = PBXBuildFile; fileRef = E5B077FD1E69F4EB00C24B5B /* ASElementMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E5B078001E69F4EB00C24B5B /* ASElementMap.m in Sources */ = {isa = PBXBuildFile; fileRef = E5B077FE1E69F4EB00C24B5B /* ASElementMap.m */; }; + E5B078001E69F4EB00C24B5B /* ASElementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5B077FE1E69F4EB00C24B5B /* ASElementMap.mm */; }; E5B225281F1790D6001E1431 /* ASHashing.h in Headers */ = {isa = PBXBuildFile; fileRef = E5B225271F1790B5001E1431 /* ASHashing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E5B225291F1790EE001E1431 /* ASHashing.m in Sources */ = {isa = PBXBuildFile; fileRef = E5B225261F1790B5001E1431 /* ASHashing.m */; }; - E5B2252E1F17E521001E1431 /* ASDispatch.m in Sources */ = {isa = PBXBuildFile; fileRef = E5B2252D1F17E521001E1431 /* ASDispatch.m */; }; + E5B225291F1790EE001E1431 /* ASHashing.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5B225261F1790B5001E1431 /* ASHashing.mm */; }; + E5B2252E1F17E521001E1431 /* ASDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5B2252D1F17E521001E1431 /* ASDispatch.mm */; }; E5B5B9D11E9BAD9800A6B726 /* ASCollectionLayoutContext+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = E5B5B9D01E9BAD9800A6B726 /* ASCollectionLayoutContext+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; E5C347B11ECB3D9200EC4BE4 /* ASBatchFetchingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E5C347B01ECB3D9200EC4BE4 /* ASBatchFetchingDelegate.h */; }; E5C347B31ECB40AA00EC4BE4 /* ASTableNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = E5C347B21ECB40AA00EC4BE4 /* ASTableNode+Beta.h */; }; @@ -494,10 +503,10 @@ E5E281761E71C845006B67C2 /* ASCollectionLayoutState.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5E281751E71C845006B67C2 /* ASCollectionLayoutState.mm */; }; E5E2D72E1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E5E2D72D1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; E5E2D7301EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5E2D72F1EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm */; }; - F325E48C21745F9E00AC93A4 /* ASButtonNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F325E48B21745F9E00AC93A4 /* ASButtonNodeTests.m */; }; - F325E490217460B100AC93A4 /* ASTextNode2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = F325E48F217460B000AC93A4 /* ASTextNode2Tests.m */; }; + F325E48C21745F9E00AC93A4 /* ASButtonNodeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F325E48B21745F9E00AC93A4 /* ASButtonNodeTests.mm */; }; + F325E490217460B100AC93A4 /* ASTextNode2Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F325E48F217460B000AC93A4 /* ASTextNode2Tests.mm */; }; F3F698D2211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */; }; - F711994E1D20C21100568860 /* ASDisplayNodeExtrasTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */; }; + F711994E1D20C21100568860 /* ASDisplayNodeExtrasTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.mm */; }; FA4FAF15200A850200E735BD /* ASControlNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4FAF14200A850200E735BD /* ASControlNode+Private.h */; }; /* End PBXBuildFile section */ @@ -514,16 +523,16 @@ /* Begin PBXFileReference section */ 044285011BAA3CC700D16268 /* AsyncDisplayKit.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = AsyncDisplayKit.modulemap; sourceTree = ""; }; 044285051BAA63FE00D16268 /* ASBatchFetching.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBatchFetching.h; sourceTree = ""; }; - 044285061BAA63FE00D16268 /* ASBatchFetching.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBatchFetching.m; sourceTree = ""; }; + 044285061BAA63FE00D16268 /* ASBatchFetching.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBatchFetching.mm; sourceTree = ""; }; 0442850B1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTwoDimensionalArrayUtils.h; sourceTree = ""; }; - 0442850C1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTwoDimensionalArrayUtils.m; sourceTree = ""; }; + 0442850C1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTwoDimensionalArrayUtils.mm; sourceTree = ""; }; 0516FA3A1A15563400B4EBED /* ASAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASAvailability.h; sourceTree = ""; }; 0516FA3B1A15563400B4EBED /* ASLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLog.h; sourceTree = ""; }; 0516FA3E1A1563D200B4EBED /* ASMultiplexImageNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMultiplexImageNode.h; sourceTree = ""; }; 0516FA3F1A1563D200B4EBED /* ASMultiplexImageNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMultiplexImageNode.mm; sourceTree = ""; }; 051943121A1575630030A7D0 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; 051943141A1575670030A7D0 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; }; - 052EE0651A159FEF002C6279 /* ASMultiplexImageNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASMultiplexImageNodeTests.m; sourceTree = ""; }; + 052EE0651A159FEF002C6279 /* ASMultiplexImageNodeTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMultiplexImageNodeTests.mm; sourceTree = ""; }; 052EE06A1A15A0D8002C6279 /* TestResources */ = {isa = PBXFileReference; lastKnownFileType = folder; path = TestResources; sourceTree = ""; }; 054963471A1EA066000F8E56 /* ASBasicImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBasicImageDownloader.h; sourceTree = ""; }; 054963481A1EA066000F8E56 /* ASBasicImageDownloader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBasicImageDownloader.mm; sourceTree = ""; }; @@ -535,13 +544,13 @@ 055F1A3719ABD413004DAFF1 /* ASRangeController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeController.mm; sourceTree = ""; }; 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCellNode.h; sourceTree = ""; }; 056D21501ABCEDA1001107EF /* ASSnapshotTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSnapshotTestCase.h; sourceTree = ""; }; - 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASImageNodeSnapshotTests.m; sourceTree = ""; }; + 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASImageNodeSnapshotTests.mm; sourceTree = ""; }; 0574D5E119C110610097DC25 /* ASTableViewProtocols.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASTableViewProtocols.h; sourceTree = ""; }; 057D02BF1AC0A66700C7AC3C /* AsyncDisplayKitTestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AsyncDisplayKitTestHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; 057D02C21AC0A66700C7AC3C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 057D02C31AC0A66700C7AC3C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 057D02C31AC0A66700C7AC3C /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; 057D02C51AC0A66700C7AC3C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 057D02C61AC0A66700C7AC3C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppDelegate.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 057D02C61AC0A66700C7AC3C /* AppDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = AppDelegate.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 0587F9BB1A7309ED00AFF0BA /* ASEditableTextNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEditableTextNode.h; sourceTree = ""; }; 0587F9BC1A7309ED00AFF0BA /* ASEditableTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASEditableTextNode.mm; sourceTree = ""; }; 058D09AF195D04C000B7D73C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -569,16 +578,16 @@ 058D09E6195D050800B7D73C /* ASHighlightOverlayLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASHighlightOverlayLayer.h; sourceTree = ""; }; 058D09E7195D050800B7D73C /* ASHighlightOverlayLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASHighlightOverlayLayer.mm; sourceTree = ""; }; 058D09E8195D050800B7D73C /* ASMutableAttributedStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMutableAttributedStringBuilder.h; sourceTree = ""; }; - 058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASMutableAttributedStringBuilder.m; sourceTree = ""; }; + 058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMutableAttributedStringBuilder.mm; sourceTree = ""; }; 058D09F5195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableAttributedString+TextKitAdditions.h"; sourceTree = ""; }; - 058D09F6195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableAttributedString+TextKitAdditions.m"; sourceTree = ""; }; + 058D09F6195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSMutableAttributedString+TextKitAdditions.mm"; sourceTree = ""; }; 058D09F8195D050800B7D73C /* _ASAsyncTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASAsyncTransaction.h; sourceTree = ""; }; 058D09F9195D050800B7D73C /* _ASAsyncTransaction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = _ASAsyncTransaction.mm; sourceTree = ""; }; 058D09FA195D050800B7D73C /* _ASAsyncTransactionContainer+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "_ASAsyncTransactionContainer+Private.h"; sourceTree = ""; }; 058D09FB195D050800B7D73C /* _ASAsyncTransactionContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASAsyncTransactionContainer.h; sourceTree = ""; }; - 058D09FC195D050800B7D73C /* _ASAsyncTransactionContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = _ASAsyncTransactionContainer.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 058D09FC195D050800B7D73C /* _ASAsyncTransactionContainer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = _ASAsyncTransactionContainer.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 058D09FD195D050800B7D73C /* _ASAsyncTransactionGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASAsyncTransactionGroup.h; sourceTree = ""; }; - 058D09FE195D050800B7D73C /* _ASAsyncTransactionGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = _ASAsyncTransactionGroup.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 058D09FE195D050800B7D73C /* _ASAsyncTransactionGroup.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = _ASAsyncTransactionGroup.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 058D09FF195D050800B7D73C /* UIView+ASConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ASConvenience.h"; sourceTree = ""; }; 058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASCoreAnimationExtras.h; sourceTree = ""; }; 058D0A04195D050800B7D73C /* _ASCoreAnimationExtras.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = _ASCoreAnimationExtras.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; @@ -591,20 +600,20 @@ 058D0A0B195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASDisplayNode+UIViewBridge.mm"; sourceTree = ""; }; 058D0A0C195D050800B7D73C /* ASDisplayNodeInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeInternal.h; sourceTree = ""; }; 058D0A0D195D050800B7D73C /* ASImageNode+CGExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+CGExtras.h"; sourceTree = ""; }; - 058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASImageNode+CGExtras.m"; sourceTree = ""; }; + 058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASImageNode+CGExtras.mm"; sourceTree = ""; }; 058D0A12195D050800B7D73C /* ASThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASThread.h; sourceTree = ""; }; - 058D0A2D195D057000B7D73C /* ASDisplayLayerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASDisplayLayerTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 058D0A2E195D057000B7D73C /* ASDisplayNodeAppearanceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASDisplayNodeAppearanceTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 058D0A2D195D057000B7D73C /* ASDisplayLayerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDisplayLayerTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 058D0A2E195D057000B7D73C /* ASDisplayNodeAppearanceTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDisplayNodeAppearanceTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 058D0A2F195D057000B7D73C /* ASDisplayNodeTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeTests.mm; sourceTree = ""; }; 058D0A30195D057000B7D73C /* ASDisplayNodeTestsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeTestsHelper.h; sourceTree = ""; }; - 058D0A31195D057000B7D73C /* ASDisplayNodeTestsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeTestsHelper.m; sourceTree = ""; }; - 058D0A32195D057000B7D73C /* ASMutableAttributedStringBuilderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASMutableAttributedStringBuilderTests.m; sourceTree = ""; }; - 058D0A33195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextKitCoreTextAdditionsTests.m; sourceTree = ""; }; - 058D0A36195D057000B7D73C /* ASTextNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextNodeTests.m; sourceTree = ""; }; + 058D0A31195D057000B7D73C /* ASDisplayNodeTestsHelper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeTestsHelper.mm; sourceTree = ""; }; + 058D0A32195D057000B7D73C /* ASMutableAttributedStringBuilderTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMutableAttributedStringBuilderTests.mm; sourceTree = ""; }; + 058D0A33195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextKitCoreTextAdditionsTests.mm; sourceTree = ""; }; + 058D0A36195D057000B7D73C /* ASTextNodeTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextNodeTests.mm; sourceTree = ""; }; 058D0A37195D057000B7D73C /* ASTextNodeWordKernerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextNodeWordKernerTests.mm; sourceTree = ""; }; 058D0A43195D058D00B7D73C /* ASAssert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASAssert.h; sourceTree = ""; }; 058D0A44195D058D00B7D73C /* ASBaseDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBaseDefines.h; sourceTree = ""; }; - 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASSnapshotTestCase.m; 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 = ""; }; @@ -615,16 +624,15 @@ 1A6C000C1FAB4E2100D05926 /* ASCornerLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCornerLayoutSpec.mm; sourceTree = ""; }; 1A6C000F1FAB4ED400D05926 /* ASCornerLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCornerLayoutSpecSnapshotTests.mm; sourceTree = ""; }; 205F0E0D1B371875007741D0 /* UICollectionViewLayout+ASConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionViewLayout+ASConvenience.h"; sourceTree = ""; }; - 205F0E0E1B371875007741D0 /* UICollectionViewLayout+ASConvenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionViewLayout+ASConvenience.m"; sourceTree = ""; }; - 205F0E111B371BD7007741D0 /* ASScrollDirection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASScrollDirection.m; sourceTree = ""; }; + 205F0E0E1B371875007741D0 /* UICollectionViewLayout+ASConvenience.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UICollectionViewLayout+ASConvenience.mm"; sourceTree = ""; }; + 205F0E111B371BD7007741D0 /* ASScrollDirection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASScrollDirection.mm; sourceTree = ""; }; 205F0E171B37339C007741D0 /* ASAbstractLayoutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASAbstractLayoutController.h; sourceTree = ""; }; 205F0E181B37339C007741D0 /* ASAbstractLayoutController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASAbstractLayoutController.mm; sourceTree = ""; }; 205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewLayoutController.h; sourceTree = ""; }; - 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewLayoutController.m; sourceTree = ""; }; + 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionViewLayoutController.mm; sourceTree = ""; }; 205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CoreGraphics+ASConvenience.h"; sourceTree = ""; }; - 205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CoreGraphics+ASConvenience.m"; sourceTree = ""; }; - 242995D21B29743C00090100 /* ASBasicImageDownloaderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBasicImageDownloaderTests.m; sourceTree = ""; }; - 2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASCollectionViewFlowLayoutInspectorTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 242995D21B29743C00090100 /* ASBasicImageDownloaderTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBasicImageDownloaderTests.mm; sourceTree = ""; }; + 2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCollectionViewFlowLayoutInspectorTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 254C6B511BF8FE6D003EC431 /* ASTextKitTruncationTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextKitTruncationTests.mm; sourceTree = ""; }; 254C6B531BF8FF2A003EC431 /* ASTextKitTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextKitTests.mm; sourceTree = ""; }; 257754931BEE44CD00737CA5 /* ASTextKitRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitRenderer.h; path = TextKit/ASTextKitRenderer.h; sourceTree = ""; }; @@ -633,7 +641,7 @@ 257754961BEE44CD00737CA5 /* ASTextKitContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitContext.h; path = TextKit/ASTextKitContext.h; sourceTree = ""; }; 257754971BEE44CD00737CA5 /* ASTextKitContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitContext.mm; path = TextKit/ASTextKitContext.mm; sourceTree = ""; }; 257754981BEE44CD00737CA5 /* ASTextKitEntityAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitEntityAttribute.h; path = TextKit/ASTextKitEntityAttribute.h; sourceTree = ""; }; - 257754991BEE44CD00737CA5 /* ASTextKitEntityAttribute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASTextKitEntityAttribute.m; path = TextKit/ASTextKitEntityAttribute.m; sourceTree = ""; }; + 257754991BEE44CD00737CA5 /* ASTextKitEntityAttribute.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitEntityAttribute.mm; path = TextKit/ASTextKitEntityAttribute.mm; sourceTree = ""; }; 2577549A1BEE44CD00737CA5 /* ASTextKitRenderer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitRenderer.mm; path = TextKit/ASTextKitRenderer.mm; sourceTree = ""; }; 2577549B1BEE44CD00737CA5 /* ASTextKitRenderer+Positioning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ASTextKitRenderer+Positioning.h"; path = "TextKit/ASTextKitRenderer+Positioning.h"; sourceTree = ""; }; 2577549C1BEE44CD00737CA5 /* ASTextKitRenderer+Positioning.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASTextKitRenderer+Positioning.mm"; path = "TextKit/ASTextKitRenderer+Positioning.mm"; sourceTree = ""; }; @@ -645,62 +653,62 @@ 257754A21BEE44CD00737CA5 /* ASTextKitTailTruncater.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitTailTruncater.mm; path = TextKit/ASTextKitTailTruncater.mm; sourceTree = ""; }; 257754A31BEE44CD00737CA5 /* ASTextKitTruncating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitTruncating.h; path = TextKit/ASTextKitTruncating.h; sourceTree = ""; }; 257754B71BEE458D00737CA5 /* ASTextKitComponents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitComponents.mm; path = TextKit/ASTextKitComponents.mm; sourceTree = ""; }; - 257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASTextKitCoreTextAdditions.m; path = TextKit/ASTextKitCoreTextAdditions.m; sourceTree = ""; }; + 257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitCoreTextAdditions.mm; path = TextKit/ASTextKitCoreTextAdditions.mm; sourceTree = ""; }; 257754B91BEE458E00737CA5 /* ASTextNodeWordKerner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextNodeWordKerner.h; path = TextKit/ASTextNodeWordKerner.h; sourceTree = ""; }; 257754BA1BEE458E00737CA5 /* ASTextKitComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitComponents.h; path = TextKit/ASTextKitComponents.h; sourceTree = ""; }; 257754BB1BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextKitCoreTextAdditions.h; path = TextKit/ASTextKitCoreTextAdditions.h; sourceTree = ""; }; 257754BC1BEE458E00737CA5 /* ASTextNodeTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTextNodeTypes.h; path = TextKit/ASTextNodeTypes.h; sourceTree = ""; }; - 257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASTextNodeWordKerner.m; path = TextKit/ASTextNodeWordKerner.m; sourceTree = ""; }; + 257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextNodeWordKerner.mm; path = TextKit/ASTextNodeWordKerner.mm; sourceTree = ""; }; 25E327541C16819500A2170C /* ASPagerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASPagerNode.h; sourceTree = ""; }; - 25E327551C16819500A2170C /* ASPagerNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASPagerNode.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 2911485B1A77147A005D0878 /* ASControlNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNodeTests.m; sourceTree = ""; }; + 25E327551C16819500A2170C /* ASPagerNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASPagerNode.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 2911485B1A77147A005D0878 /* ASControlNodeTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASControlNodeTests.mm; sourceTree = ""; }; 292C59991A956527007E5DD6 /* ASLayoutRangeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutRangeType.h; sourceTree = ""; }; 2967F9E11AB0A4CF0072E4AB /* ASBasicImageDownloaderInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASBasicImageDownloaderInternal.h; sourceTree = ""; }; 296A0A311A951715005ACEAA /* ASScrollDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASScrollDirection.h; path = Source/Details/ASScrollDirection.h; sourceTree = SOURCE_ROOT; }; - 296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASBatchFetchingTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASBatchFetchingTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 299DA1A71A828D2900162D41 /* ASBatchContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBatchContext.h; sourceTree = ""; }; - 299DA1A81A828D2900162D41 /* ASBatchContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBatchContext.m; sourceTree = ""; }; - 29CDC2E11AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASBasicImageDownloaderContextTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 299DA1A81A828D2900162D41 /* ASBatchContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBatchContext.mm; sourceTree = ""; }; + 29CDC2E11AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASBasicImageDownloaderContextTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 3917EBD21E9C2FC400D04A01 /* _ASCollectionReusableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASCollectionReusableView.h; sourceTree = ""; }; - 3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _ASCollectionReusableView.m; sourceTree = ""; }; + 3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASCollectionReusableView.mm; sourceTree = ""; }; 3C9C128419E616EF00E942A0 /* ASTableViewTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASTableViewTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASTraitCollectionTests.m; sourceTree = ""; }; + 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTraitCollectionTests.mm; sourceTree = ""; }; 464052191A3F83C40061C0BA /* ASDataController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASDataController.h; sourceTree = ""; }; 4640521A1A3F83C40061C0BA /* ASDataController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDataController.mm; sourceTree = ""; }; 4640521B1A3F83C40061C0BA /* ASTableLayoutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTableLayoutController.h; sourceTree = ""; }; - 4640521C1A3F83C40061C0BA /* ASTableLayoutController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableLayoutController.m; sourceTree = ""; }; + 4640521C1A3F83C40061C0BA /* ASTableLayoutController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTableLayoutController.mm; sourceTree = ""; }; 4640521D1A3F83C40061C0BA /* ASLayoutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutController.h; sourceTree = ""; }; - 4E9127681F64157600499623 /* ASRunLoopQueueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASRunLoopQueueTests.m; sourceTree = ""; }; + 4E9127681F64157600499623 /* ASRunLoopQueueTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRunLoopQueueTests.mm; sourceTree = ""; }; 68355B2E1CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASImageNode+AnimatedImage.mm"; sourceTree = ""; }; - 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPINRemoteImageDownloader.m; 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 = ""; }; - 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASImageContainerProtocolCategories.m; sourceTree = ""; }; + 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASImageContainerProtocolCategories.mm; sourceTree = ""; }; 68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPINRemoteImageDownloader.h; sourceTree = ""; }; 683F563620E409D600CEB7A3 /* ASDisplayNode+InterfaceState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+InterfaceState.h"; sourceTree = ""; }; 68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+Beta.h"; sourceTree = ""; }; 68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+AnimatedImagePrivate.h"; sourceTree = ""; }; 68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASWeakProxy.h; sourceTree = ""; }; - 68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakProxy.m; sourceTree = ""; }; + 68B8A4E01CBDB958007E4543 /* ASWeakProxy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASWeakProxy.mm; sourceTree = ""; }; 68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewLayoutInspector.h; sourceTree = ""; }; - 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewLayoutInspector.m; sourceTree = ""; }; + 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionViewLayoutInspector.mm; sourceTree = ""; }; 68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMainSerialQueue.h; sourceTree = ""; }; 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMainSerialQueue.mm; sourceTree = ""; }; 68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASNavigationController.h; sourceTree = ""; }; - 68FC85DD1CE29AB700EDD713 /* ASNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASNavigationController.m; sourceTree = ""; }; + 68FC85DD1CE29AB700EDD713 /* ASNavigationController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASNavigationController.mm; sourceTree = ""; }; 68FC85E01CE29B7E00EDD713 /* ASTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTabBarController.h; sourceTree = ""; }; - 68FC85E11CE29B7E00EDD713 /* ASTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTabBarController.m; sourceTree = ""; }; + 68FC85E11CE29B7E00EDD713 /* ASTabBarController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTabBarController.mm; sourceTree = ""; }; 68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASVisibilityProtocols.h; sourceTree = ""; }; - 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASVisibilityProtocols.m; sourceTree = ""; }; + 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASVisibilityProtocols.mm; sourceTree = ""; }; 6900C5F31E8072DA00BCD75C /* ASImageNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+Private.h"; sourceTree = ""; }; 6907C2561DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASObjectDescriptionHelpers.h; sourceTree = ""; }; - 6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASObjectDescriptionHelpers.m; sourceTree = ""; }; + 6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASObjectDescriptionHelpers.mm; sourceTree = ""; }; 690BC8BF20F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeCornerLayerDelegate.h; sourceTree = ""; }; - 690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeCornerLayerDelegate.m; sourceTree = ""; }; + 690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeCornerLayerDelegate.mm; sourceTree = ""; }; 690C35601E055C5D00069B91 /* ASDimensionInternal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDimensionInternal.mm; sourceTree = ""; }; 690C35631E055C7B00069B91 /* ASDimensionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDimensionInternal.h; sourceTree = ""; }; 690ED58D1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutElementStylePrivate.h; sourceTree = ""; }; - 690ED5931E36D118000627C0 /* ASControlNode+tvOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASControlNode+tvOS.m"; sourceTree = ""; }; - 690ED5951E36D118000627C0 /* ASImageNode+tvOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASImageNode+tvOS.m"; sourceTree = ""; }; + 690ED5931E36D118000627C0 /* ASControlNode+tvOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASControlNode+tvOS.mm"; sourceTree = ""; }; + 690ED5951E36D118000627C0 /* ASImageNode+tvOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASImageNode+tvOS.mm"; sourceTree = ""; }; 692510131E74FB44003F2DD0 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 692BE8D61E36B65B00C86D87 /* ASLayoutSpecPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutSpecPrivate.h; sourceTree = ""; }; 6947B0BC1E36B4E30007C478 /* ASStackUnpositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackUnpositionedLayout.h; sourceTree = ""; }; @@ -714,35 +722,35 @@ 696FCB301D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASBackgroundLayoutSpecSnapshotTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 6977965D1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASLayoutSpec+Subclasses.h"; sourceTree = ""; }; 6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASLayoutSpec+Subclasses.mm"; sourceTree = ""; }; - 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASEditableTextNodeTests.m; sourceTree = ""; }; + 697B31591CFE4B410049936F /* ASEditableTextNodeTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASEditableTextNodeTests.mm; sourceTree = ""; }; 698371D91E4379CD00437585 /* ASNodeController+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASNodeController+Beta.h"; sourceTree = ""; }; 698371DA1E4379CD00437585 /* ASNodeController+Beta.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASNodeController+Beta.mm"; sourceTree = ""; }; 698C8B601CAB49FC0052DC3F /* ASLayoutElementExtensibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutElementExtensibility.h; sourceTree = ""; }; 698DFF431E36B6C9002891F1 /* ASStackLayoutSpecUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackLayoutSpecUtilities.h; sourceTree = ""; }; 698DFF461E36B7E9002891F1 /* ASLayoutSpecUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutSpecUtilities.h; sourceTree = ""; }; - 699B83501E3C1BA500433FA4 /* ASLayoutSpecTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLayoutSpecTests.m; sourceTree = ""; }; + 699B83501E3C1BA500433FA4 /* ASLayoutSpecTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutSpecTests.mm; sourceTree = ""; }; 69B225661D72535E00B25B22 /* ASDisplayNodeLayoutTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeLayoutTests.mm; sourceTree = ""; }; 69BCE3D71EC6513B007DCCAD /* ASDisplayNode+Layout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASDisplayNode+Layout.mm"; sourceTree = ""; }; 69CB62A91CB8165900024920 /* _ASDisplayViewAccessiblity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASDisplayViewAccessiblity.h; sourceTree = ""; }; 69CB62AA1CB8165900024920 /* _ASDisplayViewAccessiblity.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASDisplayViewAccessiblity.mm; sourceTree = ""; }; 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASRangeControllerUpdateRangeProtocol+Beta.h"; sourceTree = ""; }; - 69FEE53C1D95A9AF0086F066 /* ASLayoutElementStyleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLayoutElementStyleTests.m; sourceTree = ""; }; + 69FEE53C1D95A9AF0086F066 /* ASLayoutElementStyleTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutElementStyleTests.mm; sourceTree = ""; }; 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = ""; }; 764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit+Debug.h"; sourceTree = ""; }; - 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AsyncDisplayKit+Debug.m"; sourceTree = ""; }; + 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "AsyncDisplayKit+Debug.mm"; sourceTree = ""; }; 7A06A7381C35F08800FE8DAA /* ASRelativeLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRelativeLayoutSpec.mm; sourceTree = ""; }; 7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRelativeLayoutSpec.h; sourceTree = ""; }; 7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRelativeLayoutSpecSnapshotTests.mm; sourceTree = ""; }; 8021EC1A1D2B00B100799119 /* UIImage+ASConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+ASConvenience.h"; sourceTree = ""; }; - 8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ASConvenience.m"; sourceTree = ""; }; - 81E95C131D62639600336598 /* ASTextNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextNodeSnapshotTests.m; sourceTree = ""; }; + 8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UIImage+ASConvenience.mm"; sourceTree = ""; }; + 81E95C131D62639600336598 /* ASTextNodeSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextNodeSnapshotTests.mm; sourceTree = ""; }; 81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRunLoopQueue.h; path = ../ASRunLoopQueue.h; sourceTree = ""; }; 81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRunLoopQueue.mm; path = ../ASRunLoopQueue.mm; sourceTree = ""; }; 83A7D9581D44542100BF333E /* ASWeakMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASWeakMap.h; sourceTree = ""; }; - 83A7D9591D44542100BF333E /* ASWeakMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakMap.m; sourceTree = ""; }; - 83A7D95D1D446A6E00BF333E /* ASWeakMapTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakMapTests.m; sourceTree = ""; }; + 83A7D9591D44542100BF333E /* ASWeakMap.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASWeakMap.mm; sourceTree = ""; }; + 83A7D95D1D446A6E00BF333E /* ASWeakMapTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASWeakMapTests.mm; sourceTree = ""; }; 8B0768B11CE752EC002E1453 /* ASDefaultPlaybackButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDefaultPlaybackButton.h; sourceTree = ""; }; - 8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDefaultPlaybackButton.m; sourceTree = ""; }; + 8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDefaultPlaybackButton.mm; sourceTree = ""; }; 8BDA5FC31CDBDDE1007D13B2 /* ASVideoPlayerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASVideoPlayerNode.h; sourceTree = ""; }; 8BDA5FC41CDBDDE1007D13B2 /* ASVideoPlayerNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASVideoPlayerNode.mm; sourceTree = ""; }; 9019FBBB1ED8061D00C45F72 /* ASYogaUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASYogaUtilities.h; sourceTree = ""; }; @@ -755,22 +763,22 @@ 92DD2FE51BF4D05E0074C9DD /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 9C49C36E1B853957000B0DD5 /* ASStackLayoutElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackLayoutElement.h; sourceTree = ""; }; 9C5586671BD549CB00B50E3A /* ASAsciiArtBoxCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASAsciiArtBoxCreator.h; sourceTree = ""; }; - 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASAsciiArtBoxCreator.m; sourceTree = ""; }; + 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASAsciiArtBoxCreator.mm; sourceTree = ""; }; 9C6BB3B01B8CC9C200F13F52 /* ASAbsoluteLayoutElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASAbsoluteLayoutElement.h; sourceTree = ""; }; 9C70F2011CDA4EFA007D6C76 /* ASTraitCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTraitCollection.h; sourceTree = ""; }; - 9C70F2021CDA4EFA007D6C76 /* ASTraitCollection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTraitCollection.m; sourceTree = ""; }; + 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 = ""; }; 9CFFC6C11CCAC768006A6476 /* ASTableNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTableNode.mm; sourceTree = ""; }; 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCollectionViewTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 9F98C0231DBDF2A300476D92 /* ASControlTargetAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASControlTargetAction.h; sourceTree = ""; }; - 9F98C0241DBDF2A300476D92 /* ASControlTargetAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlTargetAction.m; sourceTree = ""; }; + 9F98C0241DBDF2A300476D92 /* ASControlTargetAction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASControlTargetAction.mm; sourceTree = ""; }; A2763D771CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASPINRemoteImageDownloader.h; path = Details/ASPINRemoteImageDownloader.h; sourceTree = ""; }; - A2763D781CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASPINRemoteImageDownloader.m; path = Details/ASPINRemoteImageDownloader.m; sourceTree = ""; }; + A2763D781CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASPINRemoteImageDownloader.mm; path = Details/ASPINRemoteImageDownloader.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 = ""; }; - AC026B571BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASAbsoluteLayoutSpecSnapshotTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + 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 = ""; }; AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackLayoutDefines.h; sourceTree = ""; }; @@ -778,7 +786,7 @@ AC3C4A501A1139C100143C57 /* ASCollectionView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCollectionView.mm; sourceTree = ""; }; AC3C4A531A113EEC00143C57 /* ASCollectionViewProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewProtocols.h; sourceTree = ""; }; AC6145401D8AFAE8003D62A2 /* ASSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASSection.h; path = ../Private/ASSection.h; sourceTree = ""; }; - AC6145421D8AFD4F003D62A2 /* ASSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASSection.m; path = ../Private/ASSection.m; sourceTree = ""; }; + 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 = ""; }; @@ -805,152 +813,159 @@ ACF6ED181B17843500DA7C62 /* ASAbsoluteLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASAbsoluteLayoutSpec.h; sourceTree = ""; }; ACF6ED191B17843500DA7C62 /* ASAbsoluteLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASAbsoluteLayoutSpec.mm; sourceTree = ""; }; ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASInternalHelpers.h; sourceTree = ""; }; - ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASInternalHelpers.m; sourceTree = ""; }; + ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASInternalHelpers.mm; sourceTree = ""; }; ACF6ED531B178DC700DA7C62 /* ASCenterLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCenterLayoutSpecSnapshotTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; ACF6ED541B178DC700DA7C62 /* ASDimensionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDimensionTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; ACF6ED551B178DC700DA7C62 /* ASInsetLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASInsetLayoutSpecSnapshotTests.mm; sourceTree = ""; }; ACF6ED571B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutSpecSnapshotTestsHelper.h; sourceTree = ""; }; - ACF6ED581B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASLayoutSpecSnapshotTestsHelper.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + ACF6ED581B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASLayoutSpecSnapshotTestsHelper.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; ACF6ED591B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASOverlayLayoutSpecSnapshotTests.mm; sourceTree = ""; }; ACF6ED5A1B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRatioLayoutSpecSnapshotTests.mm; sourceTree = ""; }; ACF6ED5B1B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackLayoutSpecSnapshotTests.mm; sourceTree = ""; }; AE440174210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextKitFontSizeAdjusterTests.mm; sourceTree = ""; }; - AE6987C01DD04E1000B9E458 /* ASPagerNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPagerNodeTests.m; sourceTree = ""; }; + AE6987C01DD04E1000B9E458 /* ASPagerNodeTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPagerNodeTests.mm; sourceTree = ""; }; AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDefaultPlayButton.h; sourceTree = ""; }; - AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDefaultPlayButton.m; sourceTree = ""; }; + AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDefaultPlayButton.mm; sourceTree = ""; }; AEEC47DF1C20C2DD00EC1693 /* ASVideoNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASVideoNode.h; sourceTree = ""; }; AEEC47E01C20C2DD00EC1693 /* ASVideoNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASVideoNode.mm; sourceTree = ""; }; - AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASVideoNodeTests.m; sourceTree = ""; }; + AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASVideoNodeTests.mm; sourceTree = ""; }; B0F880581BEAEC7500D17647 /* ASTableNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTableNode.h; sourceTree = ""; }; B13CA0F61C519E9400E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewLayoutFacilitatorProtocol.h; sourceTree = ""; }; B13CA0FF1C52004900E031AB /* ASCollectionNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCollectionNode+Beta.h"; sourceTree = ""; }; B30BF6501C5964B0004FCD53 /* ASLayoutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutManager.h; path = TextKit/ASLayoutManager.h; sourceTree = ""; }; - B30BF6511C5964B0004FCD53 /* ASLayoutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASLayoutManager.m; path = TextKit/ASLayoutManager.m; sourceTree = ""; }; + B30BF6511C5964B0004FCD53 /* ASLayoutManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutManager.mm; path = TextKit/ASLayoutManager.mm; sourceTree = ""; }; B35061DA1B010EDF0018CF92 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - BB5FC3CD1F9BA688007F191E /* ASNavigationControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASNavigationControllerTests.m; sourceTree = ""; }; - BB5FC3D01F9C9389007F191E /* ASTabBarControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASTabBarControllerTests.m; sourceTree = ""; }; + BB5FC3CD1F9BA688007F191E /* ASNavigationControllerTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASNavigationControllerTests.mm; sourceTree = ""; }; + BB5FC3D01F9C9389007F191E /* ASTabBarControllerTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTabBarControllerTests.mm; sourceTree = ""; }; BDC2D162BD55A807C1475DA5 /* Pods-AsyncDisplayKitTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.profile.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.profile.xcconfig"; sourceTree = ""; }; C018DF20216BF26600181FDA /* ASAbstractLayoutController+FrameworkPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASAbstractLayoutController+FrameworkPrivate.h"; sourceTree = ""; }; - C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASTextNode2SnapshotTests.m; sourceTree = ""; }; + C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextNode2SnapshotTests.mm; sourceTree = ""; }; CC034A071E60BEB400626263 /* ASDisplayNode+Convenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+Convenience.h"; sourceTree = ""; }; - CC034A081E60BEB400626263 /* ASDisplayNode+Convenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASDisplayNode+Convenience.m"; sourceTree = ""; }; + CC034A081E60BEB400626263 /* ASDisplayNode+Convenience.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASDisplayNode+Convenience.mm"; sourceTree = ""; }; CC034A111E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit+IGListKitMethods.h"; sourceTree = ""; }; - CC034A121E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AsyncDisplayKit+IGListKitMethods.m"; sourceTree = ""; }; - CC051F1E1D7A286A006434CB /* ASCALayerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCALayerTests.m; sourceTree = ""; }; - CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASUICollectionViewTests.m; sourceTree = ""; }; - CC0F88591E42807F00576FED /* ASCollectionViewFlowLayoutInspector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewFlowLayoutInspector.m; sourceTree = ""; }; + CC034A121E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "AsyncDisplayKit+IGListKitMethods.mm"; sourceTree = ""; }; + CC051F1E1D7A286A006434CB /* ASCALayerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCALayerTests.mm; sourceTree = ""; }; + CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASUICollectionViewTests.mm; sourceTree = ""; }; + CC0F88591E42807F00576FED /* ASCollectionViewFlowLayoutInspector.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionViewFlowLayoutInspector.mm; sourceTree = ""; }; CC0F885A1E42807F00576FED /* ASCollectionViewFlowLayoutInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewFlowLayoutInspector.h; sourceTree = ""; }; - CC0F885D1E4280B800576FED /* _ASCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _ASCollectionViewCell.m; sourceTree = ""; }; + 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.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASNetworkImageNodeTests.m; 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 = ""; }; CC2E317F1DAC353700EEE891 /* ASCollectionView+Undeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCollectionView+Undeprecated.h"; sourceTree = ""; }; CC2F65EC1E5FFB1600DA57C9 /* ASMutableElementMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMutableElementMap.h; sourceTree = ""; }; - CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASMutableElementMap.m; sourceTree = ""; }; + CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMutableElementMap.mm; sourceTree = ""; }; CC35CEC120DD7F600006448D /* ASCollections.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASCollections.h; sourceTree = ""; }; - CC35CEC220DD7F600006448D /* ASCollections.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASCollections.m; sourceTree = ""; }; - CC35CEC520DD87280006448D /* ASCollectionsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASCollectionsTests.m; sourceTree = ""; }; + CC35CEC220DD7F600006448D /* ASCollections.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollections.mm; sourceTree = ""; }; + CC35CEC520DD87280006448D /* ASCollectionsTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionsTests.mm; sourceTree = ""; }; + CC36C18E218B841600232F23 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + CC36C190218B841A00232F23 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; + CC36C192218B842E00232F23 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + CC36C195218B845B00232F23 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + CC36C197218B846300232F23 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + CC36C199218B846F00232F23 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + CC36C19B218B847400232F23 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; CC3B20811C3F76D600798563 /* ASPendingStateController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPendingStateController.h; sourceTree = ""; }; CC3B20821C3F76D600798563 /* ASPendingStateController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPendingStateController.mm; sourceTree = ""; }; CC3B20871C3F7A5400798563 /* ASWeakSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASWeakSet.h; sourceTree = ""; }; - CC3B20881C3F7A5400798563 /* ASWeakSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakSet.m; sourceTree = ""; }; - CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakSetTests.m; sourceTree = ""; }; + CC3B20881C3F7A5400798563 /* ASWeakSet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASWeakSet.mm; sourceTree = ""; }; + CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASWeakSetTests.mm; sourceTree = ""; }; CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASBridgedPropertiesTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewThrashTests.m; sourceTree = ""; }; + CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTableViewThrashTests.mm; sourceTree = ""; }; CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexSet+ASHelpers.h"; sourceTree = ""; }; - CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSIndexSet+ASHelpers.m"; sourceTree = ""; }; + CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSIndexSet+ASHelpers.mm"; sourceTree = ""; }; CC4C2A751D88E3BF0039ACAB /* ASTraceEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTraceEvent.h; sourceTree = ""; }; - CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTraceEvent.m; sourceTree = ""; }; + CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTraceEvent.mm; sourceTree = ""; }; CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASTableView+Undeprecated.h"; sourceTree = ""; }; CC54A81B1D70077A00296A24 /* ASDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASDispatch.h; sourceTree = ""; }; - CC54A81D1D7008B300296A24 /* ASDispatchTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASDispatchTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + CC54A81D1D7008B300296A24 /* ASDispatchTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDispatchTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIResponder+AsyncDisplayKit.h"; sourceTree = ""; }; - CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIResponder+AsyncDisplayKit.m"; sourceTree = ""; }; + CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UIResponder+AsyncDisplayKit.mm"; sourceTree = ""; }; CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASResponderChainEnumerator.h; sourceTree = ""; }; - CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASResponderChainEnumerator.m; sourceTree = ""; }; + CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASResponderChainEnumerator.mm; sourceTree = ""; }; CC5601391F06E9A700DC4FBE /* ASIntegerMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIntegerMap.h; sourceTree = ""; }; CC56013A1F06E9A700DC4FBE /* ASIntegerMap.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASIntegerMap.mm; sourceTree = ""; }; CC57EAF91E394EA40034C595 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - CC583AC01EF9BAB400134156 /* ASDisplayNode+OCMock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "ASDisplayNode+OCMock.m"; sourceTree = ""; }; + CC583AC01EF9BAB400134156 /* ASDisplayNode+OCMock.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASDisplayNode+OCMock.mm"; sourceTree = ""; }; CC583AC11EF9BAB400134156 /* ASTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASTestCase.h; sourceTree = ""; }; - CC583AC21EF9BAB400134156 /* ASTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASTestCase.m; sourceTree = ""; }; + CC583AC21EF9BAB400134156 /* ASTestCase.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTestCase.mm; sourceTree = ""; }; CC583AC31EF9BAB400134156 /* ASXCTExtensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASXCTExtensions.h; sourceTree = ""; }; CC583AC41EF9BAB400134156 /* NSInvocation+ASTestHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSInvocation+ASTestHelpers.h"; sourceTree = ""; }; - CC583AC51EF9BAB400134156 /* NSInvocation+ASTestHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSInvocation+ASTestHelpers.m"; sourceTree = ""; }; + CC583AC51EF9BAB400134156 /* NSInvocation+ASTestHelpers.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSInvocation+ASTestHelpers.mm"; sourceTree = ""; }; CC583AC61EF9BAB400134156 /* OCMockObject+ASAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OCMockObject+ASAdditions.h"; sourceTree = ""; }; - CC583AC71EF9BAB400134156 /* OCMockObject+ASAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "OCMockObject+ASAdditions.m"; 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 = ""; }; 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.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "ASDisplayNode+Ancestry.m"; path = "Base/ASDisplayNode+Ancestry.m"; 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 = ""; }; - CC7AF197200D9E8400A21BDE /* ASExperimentalFeatures.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASExperimentalFeatures.m; sourceTree = ""; }; + CC7AF197200D9E8400A21BDE /* ASExperimentalFeatures.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASExperimentalFeatures.mm; sourceTree = ""; }; CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPhotosFrameworkImageRequest.h; sourceTree = ""; }; - CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequest.m; sourceTree = ""; }; - CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequestTests.m; sourceTree = ""; }; + CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPhotosFrameworkImageRequest.mm; sourceTree = ""; }; + CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPhotosFrameworkImageRequestTests.mm; sourceTree = ""; }; CC84C7F020474C5300A3851B /* ASCGImageBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASCGImageBuffer.h; sourceTree = ""; }; - CC84C7F120474C5300A3851B /* ASCGImageBuffer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASCGImageBuffer.m; sourceTree = ""; }; + CC84C7F120474C5300A3851B /* ASCGImageBuffer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCGImageBuffer.mm; sourceTree = ""; }; CC87BB941DA8193C0090E380 /* ASCellNode+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCellNode+Internal.h"; sourceTree = ""; }; CC8B05D41D73836400F54286 /* ASPerformanceTestContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPerformanceTestContext.h; sourceTree = ""; }; - CC8B05D51D73836400F54286 /* ASPerformanceTestContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPerformanceTestContext.m; sourceTree = ""; }; - CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextNodePerformanceTests.m; sourceTree = ""; }; - CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASViewControllerTests.m; 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 = ""; }; CCA282B21E9EA7310037E8B7 /* ASTipsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTipsController.h; sourceTree = ""; }; - CCA282B31E9EA7310037E8B7 /* ASTipsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTipsController.m; 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 = ""; }; - CCA282B71E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AsyncDisplayKit+Tips.m"; sourceTree = ""; }; + CCA282B71E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "AsyncDisplayKit+Tips.mm"; sourceTree = ""; }; CCA282BA1E9EABDD0037E8B7 /* ASTipProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTipProvider.h; sourceTree = ""; }; - CCA282BB1E9EABDD0037E8B7 /* ASTipProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTipProvider.m; sourceTree = ""; }; + CCA282BB1E9EABDD0037E8B7 /* ASTipProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTipProvider.mm; sourceTree = ""; }; CCA282BE1E9EAE010037E8B7 /* ASTip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTip.h; sourceTree = ""; }; - CCA282BF1E9EAE010037E8B7 /* ASTip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTip.m; sourceTree = ""; }; + CCA282BF1E9EAE010037E8B7 /* ASTip.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTip.mm; sourceTree = ""; }; CCA282C21E9EAE630037E8B7 /* ASLayerBackingTipProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayerBackingTipProvider.h; sourceTree = ""; }; - CCA282C31E9EAE630037E8B7 /* ASLayerBackingTipProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLayerBackingTipProvider.m; sourceTree = ""; }; + CCA282C31E9EAE630037E8B7 /* ASLayerBackingTipProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayerBackingTipProvider.mm; sourceTree = ""; }; CCA282C61E9EB64B0037E8B7 /* ASDisplayNodeTipState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeTipState.h; sourceTree = ""; }; - CCA282C71E9EB64B0037E8B7 /* ASDisplayNodeTipState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeTipState.m; sourceTree = ""; }; + CCA282C71E9EB64B0037E8B7 /* ASDisplayNodeTipState.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeTipState.mm; sourceTree = ""; }; CCA282CA1E9EB73E0037E8B7 /* ASTipNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTipNode.h; sourceTree = ""; }; - CCA282CB1E9EB73E0037E8B7 /* ASTipNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTipNode.m; sourceTree = ""; }; + CCA282CB1E9EB73E0037E8B7 /* ASTipNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTipNode.mm; sourceTree = ""; }; CCA282CE1E9EBF6C0037E8B7 /* ASTipsWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTipsWindow.h; sourceTree = ""; }; - CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTipsWindow.m; sourceTree = ""; }; - CCA5F62D1EECC2A80060C137 /* ASAssert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASAssert.m; sourceTree = ""; }; + CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTipsWindow.mm; sourceTree = ""; }; + CCA5F62D1EECC2A80060C137 /* ASAssert.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASAssert.mm; sourceTree = ""; }; CCAA0B7D206ADBF30057B336 /* ASRecursiveUnfairLock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASRecursiveUnfairLock.h; sourceTree = ""; }; - CCAA0B7E206ADBF30057B336 /* ASRecursiveUnfairLock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASRecursiveUnfairLock.m; sourceTree = ""; }; - CCAA0B81206ADECB0057B336 /* ASRecursiveUnfairLockTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASRecursiveUnfairLockTests.m; sourceTree = ""; }; - CCB1F9591EFB60A5009C7475 /* ASLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLog.m; sourceTree = ""; }; + CCAA0B7E206ADBF30057B336 /* ASRecursiveUnfairLock.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRecursiveUnfairLock.mm; sourceTree = ""; }; + CCAA0B81206ADECB0057B336 /* ASRecursiveUnfairLockTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRecursiveUnfairLockTests.mm; sourceTree = ""; }; + CCB1F9591EFB60A5009C7475 /* ASLog.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLog.mm; sourceTree = ""; }; CCB1F95B1EFB6316009C7475 /* ASSignpost.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASSignpost.h; sourceTree = ""; }; - CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeSnapshotTests.m; sourceTree = ""; }; + CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeSnapshotTests.mm; sourceTree = ""; }; CCBBBF5C1EB161760069AA91 /* ASRangeManagingNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeManagingNode.h; sourceTree = ""; }; - CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIGListAdapterBasedDataSource.m; sourceTree = ""; }; + CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASIGListAdapterBasedDataSource.mm; sourceTree = ""; }; CCBD05DF1E4147B000D18509 /* ASIGListAdapterBasedDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIGListAdapterBasedDataSource.h; sourceTree = ""; }; CCBDDD0320C62A2D00CBA922 /* ASMainThreadDeallocation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASMainThreadDeallocation.h; sourceTree = ""; }; CCBDDD0420C62A2D00CBA922 /* ASMainThreadDeallocation.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMainThreadDeallocation.mm; sourceTree = ""; }; CCCCCCC31EC3EF060087FE10 /* ASTextDebugOption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextDebugOption.h; sourceTree = ""; }; - CCCCCCC41EC3EF060087FE10 /* ASTextDebugOption.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextDebugOption.m; sourceTree = ""; }; + CCCCCCC41EC3EF060087FE10 /* ASTextDebugOption.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextDebugOption.mm; sourceTree = ""; }; CCCCCCC51EC3EF060087FE10 /* ASTextInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextInput.h; sourceTree = ""; }; - CCCCCCC61EC3EF060087FE10 /* ASTextInput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextInput.m; sourceTree = ""; }; + CCCCCCC61EC3EF060087FE10 /* ASTextInput.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextInput.mm; sourceTree = ""; }; CCCCCCC71EC3EF060087FE10 /* ASTextLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextLayout.h; sourceTree = ""; }; - CCCCCCC81EC3EF060087FE10 /* ASTextLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextLayout.m; sourceTree = ""; }; + CCCCCCC81EC3EF060087FE10 /* ASTextLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextLayout.mm; sourceTree = ""; }; CCCCCCC91EC3EF060087FE10 /* ASTextLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextLine.h; sourceTree = ""; }; - CCCCCCCA1EC3EF060087FE10 /* ASTextLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextLine.m; sourceTree = ""; }; + CCCCCCCA1EC3EF060087FE10 /* ASTextLine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextLine.mm; sourceTree = ""; }; CCCCCCCC1EC3EF060087FE10 /* ASTextAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextAttribute.h; sourceTree = ""; }; - CCCCCCCD1EC3EF060087FE10 /* ASTextAttribute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextAttribute.m; sourceTree = ""; }; + CCCCCCCD1EC3EF060087FE10 /* ASTextAttribute.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextAttribute.mm; sourceTree = ""; }; CCCCCCCE1EC3EF060087FE10 /* ASTextRunDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextRunDelegate.h; sourceTree = ""; }; - CCCCCCCF1EC3EF060087FE10 /* ASTextRunDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextRunDelegate.m; sourceTree = ""; }; + CCCCCCCF1EC3EF060087FE10 /* ASTextRunDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextRunDelegate.mm; sourceTree = ""; }; CCCCCCD11EC3EF060087FE10 /* ASTextUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextUtilities.h; sourceTree = ""; }; - CCCCCCD21EC3EF060087FE10 /* ASTextUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextUtilities.m; sourceTree = ""; }; + CCCCCCD21EC3EF060087FE10 /* ASTextUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextUtilities.mm; sourceTree = ""; }; CCCCCCD31EC3EF060087FE10 /* NSParagraphStyle+ASText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSParagraphStyle+ASText.h"; sourceTree = ""; }; - CCCCCCD41EC3EF060087FE10 /* NSParagraphStyle+ASText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSParagraphStyle+ASText.m"; sourceTree = ""; }; + CCCCCCD41EC3EF060087FE10 /* NSParagraphStyle+ASText.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSParagraphStyle+ASText.mm"; sourceTree = ""; }; CCCCCCE51EC3F0FC0087FE10 /* NSAttributedString+ASText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+ASText.h"; sourceTree = ""; }; - CCCCCCE61EC3F0FC0087FE10 /* NSAttributedString+ASText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+ASText.m"; sourceTree = ""; }; + CCCCCCE61EC3F0FC0087FE10 /* NSAttributedString+ASText.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSAttributedString+ASText.mm"; sourceTree = ""; }; CCDC9B4B200991D10063C1F8 /* ASGraphicsContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASGraphicsContext.h; sourceTree = ""; }; - CCDC9B4C200991D10063C1F8 /* ASGraphicsContext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASGraphicsContext.m; sourceTree = ""; }; - CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionModernDataSourceTests.m; sourceTree = ""; }; + CCDC9B4C200991D10063C1F8 /* ASGraphicsContext.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASGraphicsContext.mm; sourceTree = ""; }; + CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionModernDataSourceTests.mm; sourceTree = ""; }; CCE04B1E1E313EA7006AEBBB /* ASSectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSectionController.h; sourceTree = ""; }; CCE04B201E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "IGListAdapter+AsyncDisplayKit.h"; sourceTree = ""; }; - CCE04B211E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "IGListAdapter+AsyncDisplayKit.m"; sourceTree = ""; }; + CCE04B211E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "IGListAdapter+AsyncDisplayKit.mm"; sourceTree = ""; }; CCE04B2B1E314A32006AEBBB /* ASSupplementaryNodeSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSupplementaryNodeSource.h; sourceTree = ""; }; - CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIntegerMapTests.m; sourceTree = ""; }; + CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASIntegerMapTests.mm; sourceTree = ""; }; CCE4F9B41F0DA4F300062E4E /* ASLayoutEngineTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutEngineTests.mm; sourceTree = ""; }; CCE4F9B61F0DBA5000062E4E /* ASLayoutTestNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutTestNode.h; sourceTree = ""; }; CCE4F9B71F0DBA5000062E4E /* ASLayoutTestNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutTestNode.mm; sourceTree = ""; }; @@ -958,43 +973,42 @@ CCE4F9BC1F0ECE5200062E4E /* ASTLayoutFixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTLayoutFixture.h; sourceTree = ""; }; CCE4F9BD1F0ECE5200062E4E /* ASTLayoutFixture.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTLayoutFixture.mm; sourceTree = ""; }; CCED5E3C2020D36800395C40 /* ASNetworkImageLoadInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASNetworkImageLoadInfo.h; sourceTree = ""; }; - CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASNetworkImageLoadInfo.m; sourceTree = ""; }; + CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASNetworkImageLoadInfo.mm; sourceTree = ""; }; CCED5E402020D41600395C40 /* ASNetworkImageLoadInfo+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASNetworkImageLoadInfo+Private.h"; sourceTree = ""; }; CCEDDDC8200C2AC300FFCD0A /* ASConfigurationInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASConfigurationInternal.h; sourceTree = ""; }; - CCEDDDC9200C2AC300FFCD0A /* ASConfigurationInternal.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASConfigurationInternal.m; sourceTree = ""; }; + CCEDDDC9200C2AC300FFCD0A /* ASConfigurationInternal.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASConfigurationInternal.mm; sourceTree = ""; }; CCEDDDCC200C2CB900FFCD0A /* ASConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASConfiguration.h; sourceTree = ""; }; CCEDDDCE200C42A200FFCD0A /* ASConfigurationDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASConfigurationDelegate.h; sourceTree = ""; }; - CCEDDDD0200C488000FFCD0A /* ASConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASConfiguration.m; sourceTree = ""; }; - CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASConfigurationTests.m; sourceTree = ""; }; + CCEDDDD0200C488000FFCD0A /* ASConfiguration.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASConfiguration.mm; sourceTree = ""; }; + CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASConfigurationTests.mm; sourceTree = ""; }; CCF1FF5D20C4785000AAD8FC /* ASLocking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASLocking.h; sourceTree = ""; }; D3779BCFF841AD3EB56537ED /* Pods-AsyncDisplayKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.release.xcconfig"; sourceTree = ""; }; D785F6601A74327E00291744 /* ASScrollNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASScrollNode.h; sourceTree = ""; }; D785F6611A74327E00291744 /* ASScrollNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASScrollNode.mm; sourceTree = ""; }; DB55C25F1C6408D6004EDCF5 /* _ASTransitionContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = _ASTransitionContext.h; path = ../_ASTransitionContext.h; sourceTree = ""; }; - DB55C2601C6408D6004EDCF5 /* _ASTransitionContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = _ASTransitionContext.m; path = ../_ASTransitionContext.m; sourceTree = ""; }; + DB55C2601C6408D6004EDCF5 /* _ASTransitionContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASTransitionContext.mm; path = ../_ASTransitionContext.mm; sourceTree = ""; }; DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASContextTransitioning.h; sourceTree = ""; }; DBC452D91C5BF64600B16017 /* NSArray+Diffing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Diffing.h"; sourceTree = ""; }; DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSArray+Diffing.mm"; sourceTree = ""; }; - DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ArrayDiffingTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - DBC453211C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASDisplayNodeImplicitHierarchyTests.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ArrayDiffingTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + DBC453211C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDisplayNodeImplicitHierarchyTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; DBDB83921C6E879900D0098C /* ASPagerFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPagerFlowLayout.h; sourceTree = ""; }; - DBDB83931C6E879900D0098C /* ASPagerFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPagerFlowLayout.m; sourceTree = ""; }; + DBDB83931C6E879900D0098C /* ASPagerFlowLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPagerFlowLayout.mm; sourceTree = ""; }; DE6EA3211C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+FrameworkPrivate.h"; sourceTree = ""; }; DE8BEABF1C2DF3FC00D57C12 /* ASDelegateProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDelegateProxy.h; sourceTree = ""; }; - DE8BEAC01C2DF3FC00D57C12 /* ASDelegateProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDelegateProxy.m; sourceTree = ""; }; + DE8BEAC01C2DF3FC00D57C12 /* ASDelegateProxy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDelegateProxy.mm; sourceTree = ""; }; DEC146B41C37A16A004A0EE7 /* ASCollectionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASCollectionInternal.h; path = Details/ASCollectionInternal.h; sourceTree = ""; }; - DEC146B51C37A16A004A0EE7 /* ASCollectionInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASCollectionInternal.m; path = Details/ASCollectionInternal.m; 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 = ""; }; - E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLayoutFlatteningTests.m; 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 = ""; }; E54E00711F1D3828000B30D7 /* ASPagerNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASPagerNode+Beta.h"; sourceTree = ""; }; E54E81FA1EB357BD00FFE8E1 /* ASPageTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPageTable.h; sourceTree = ""; }; - E54E81FB1EB357BD00FFE8E1 /* ASPageTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPageTable.m; sourceTree = ""; }; + E54E81FB1EB357BD00FFE8E1 /* ASPageTable.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPageTable.mm; sourceTree = ""; }; E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutElement.mm; sourceTree = ""; }; E5667E8B1F33871300FA6FC0 /* _ASCollectionGalleryLayoutInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASCollectionGalleryLayoutInfo.h; sourceTree = ""; }; - E5667E8D1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _ASCollectionGalleryLayoutInfo.m; sourceTree = ""; }; + E5667E8D1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASCollectionGalleryLayoutInfo.mm; sourceTree = ""; }; E5711A2A1C840C81009619D4 /* ASCollectionElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionElement.h; sourceTree = ""; }; E5711A2D1C840C96009619D4 /* ASCollectionElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionElement.mm; sourceTree = ""; }; E5775AFB1F13CE9F00CAC9BC /* _ASCollectionGalleryLayoutItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASCollectionGalleryLayoutItem.h; sourceTree = ""; }; @@ -1002,21 +1016,21 @@ E5775AFF1F13D25400CAC9BC /* ASCollectionLayoutState+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCollectionLayoutState+Private.h"; sourceTree = ""; }; E5775B011F16759300CAC9BC /* ASCollectionLayoutCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionLayoutCache.h; sourceTree = ""; }; E5775B031F16759F00CAC9BC /* ASCollectionLayoutCache.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionLayoutCache.mm; sourceTree = ""; }; - E5855DED1EBB4D83003639AE /* ASCollectionLayoutDefines.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionLayoutDefines.m; sourceTree = ""; }; + E5855DED1EBB4D83003639AE /* ASCollectionLayoutDefines.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionLayoutDefines.mm; sourceTree = ""; }; E5855DEE1EBB4D83003639AE /* ASCollectionLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionLayoutDefines.h; sourceTree = ""; }; - E586F96B1F9F9E2900ECE00E /* ASScrollNodeTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASScrollNodeTests.m; sourceTree = ""; }; + E586F96B1F9F9E2900ECE00E /* ASScrollNodeTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASScrollNodeTests.mm; sourceTree = ""; }; E58E9E3D1E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionFlowLayoutDelegate.h; sourceTree = ""; }; - E58E9E3E1E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionFlowLayoutDelegate.m; sourceTree = ""; }; + E58E9E3E1E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionFlowLayoutDelegate.mm; sourceTree = ""; }; E58E9E3F1E941D74004CFC59 /* ASCollectionLayoutContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionLayoutContext.h; sourceTree = ""; }; - E58E9E401E941D74004CFC59 /* ASCollectionLayoutContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionLayoutContext.m; sourceTree = ""; }; + E58E9E401E941D74004CFC59 /* ASCollectionLayoutContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionLayoutContext.mm; sourceTree = ""; }; E58E9E411E941D74004CFC59 /* ASCollectionLayoutDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionLayoutDelegate.h; sourceTree = ""; }; E58E9E471E941DA5004CFC59 /* ASCollectionLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionLayout.h; sourceTree = ""; }; E58E9E481E941DA5004CFC59 /* ASCollectionLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionLayout.mm; sourceTree = ""; }; E5B077FD1E69F4EB00C24B5B /* ASElementMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASElementMap.h; sourceTree = ""; }; - E5B077FE1E69F4EB00C24B5B /* ASElementMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASElementMap.m; sourceTree = ""; }; - E5B225261F1790B5001E1431 /* ASHashing.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASHashing.m; sourceTree = ""; }; + E5B077FE1E69F4EB00C24B5B /* ASElementMap.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASElementMap.mm; sourceTree = ""; }; + E5B225261F1790B5001E1431 /* ASHashing.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASHashing.mm; sourceTree = ""; }; E5B225271F1790B5001E1431 /* ASHashing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASHashing.h; sourceTree = ""; }; - E5B2252D1F17E521001E1431 /* ASDispatch.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASDispatch.m; sourceTree = ""; }; + E5B2252D1F17E521001E1431 /* ASDispatch.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDispatch.mm; sourceTree = ""; }; E5B5B9D01E9BAD9800A6B726 /* ASCollectionLayoutContext+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCollectionLayoutContext+Private.h"; sourceTree = ""; }; E5C347B01ECB3D9200EC4BE4 /* ASBatchFetchingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBatchFetchingDelegate.h; sourceTree = ""; }; E5C347B21ECB40AA00EC4BE4 /* ASTableNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASTableNode+Beta.h"; sourceTree = ""; }; @@ -1025,10 +1039,10 @@ 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.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASButtonNodeTests.m; sourceTree = ""; }; - F325E48F217460B000AC93A4 /* ASTextNode2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASTextNode2Tests.m; sourceTree = ""; }; + 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 = ""; }; - F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeExtrasTests.m; sourceTree = ""; }; + F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeExtrasTests.mm; sourceTree = ""; }; FA4FAF14200A850200E735BD /* ASControlNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+Private.h"; sourceTree = ""; }; FB07EABBCF28656C6297BC2D /* Pods-AsyncDisplayKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1038,6 +1052,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + CC36C19D218B849C00232F23 /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1045,6 +1060,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + CC36C19F218B894800232F23 /* CoreMedia.framework in Frameworks */, + CC36C19E218B894400232F23 /* AVFoundation.framework in Frameworks */, CC90E1F41E383C0400FED591 /* AsyncDisplayKit.framework in Frameworks */, 058D09BE195D04C000B7D73C /* XCTest.framework in Frameworks */, 058D09C1195D04C000B7D73C /* UIKit.framework in Frameworks */, @@ -1057,6 +1074,14 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + CC36C19C218B847400232F23 /* CoreMedia.framework in Frameworks */, + CC36C19A218B846F00232F23 /* CoreLocation.framework in Frameworks */, + CC36C198218B846300232F23 /* QuartzCore.framework in Frameworks */, + CC36C196218B845B00232F23 /* AVFoundation.framework in Frameworks */, + CC36C194218B844800232F23 /* Foundation.framework in Frameworks */, + CC36C193218B842E00232F23 /* CoreGraphics.framework in Frameworks */, + CC36C191218B841A00232F23 /* CoreText.framework in Frameworks */, + CC36C18F218B841600232F23 /* UIKit.framework in Frameworks */, 92DD2FE61BF4D05E0074C9DD /* MapKit.framework in Frameworks */, B350625E1B0111780018CF92 /* AssetsLibrary.framework in Frameworks */, B350625D1B0111740018CF92 /* Photos.framework in Frameworks */, @@ -1070,7 +1095,7 @@ isa = PBXGroup; children = ( 057D02C51AC0A66700C7AC3C /* AppDelegate.h */, - 057D02C61AC0A66700C7AC3C /* AppDelegate.m */, + 057D02C61AC0A66700C7AC3C /* AppDelegate.mm */, 057D02C11AC0A66700C7AC3C /* Supporting Files */, ); name = AsyncDisplayKitTestHost; @@ -1082,7 +1107,7 @@ children = ( 692510131E74FB44003F2DD0 /* Default-568h@2x.png */, 057D02C21AC0A66700C7AC3C /* Info.plist */, - 057D02C31AC0A66700C7AC3C /* main.m */, + 057D02C31AC0A66700C7AC3C /* main.mm */, ); name = "Supporting Files"; sourceTree = ""; @@ -1115,6 +1140,13 @@ 058D09AE195D04C000B7D73C /* Frameworks */ = { isa = PBXGroup; children = ( + CC36C19B218B847400232F23 /* CoreMedia.framework */, + CC36C199218B846F00232F23 /* CoreLocation.framework */, + CC36C197218B846300232F23 /* QuartzCore.framework */, + CC36C195218B845B00232F23 /* AVFoundation.framework */, + CC36C192218B842E00232F23 /* CoreGraphics.framework */, + CC36C190218B841A00232F23 /* CoreText.framework */, + CC36C18E218B841600232F23 /* UIKit.framework */, 92DD2FE51BF4D05E0074C9DD /* MapKit.framework */, 051943141A1575670030A7D0 /* Photos.framework */, 051943121A1575630030A7D0 /* AssetsLibrary.framework */, @@ -1130,7 +1162,7 @@ isa = PBXGroup; children = ( CC35CEC120DD7F600006448D /* ASCollections.h */, - CC35CEC220DD7F600006448D /* ASCollections.m */, + CC35CEC220DD7F600006448D /* ASCollections.mm */, 058D0A42195D058D00B7D73C /* Base */, CCE04B1D1E313E99006AEBBB /* Collection Data Adapter */, DE89C1691DCEB9CC00D49D74 /* Debug */, @@ -1144,16 +1176,15 @@ DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */, DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */, CCEDDDCC200C2CB900FFCD0A /* ASConfiguration.h */, - CCEDDDD0200C488000FFCD0A /* ASConfiguration.m */, + CCEDDDD0200C488000FFCD0A /* ASConfiguration.mm */, CCEDDDC8200C2AC300FFCD0A /* ASConfigurationInternal.h */, - CCEDDDC9200C2AC300FFCD0A /* ASConfigurationInternal.m */, + CCEDDDC9200C2AC300FFCD0A /* ASConfigurationInternal.mm */, CCEDDDCE200C42A200FFCD0A /* ASConfigurationDelegate.h */, 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */, AC6456071B0A335000CF11B8 /* ASCellNode.mm */, CC84C7F020474C5300A3851B /* ASCGImageBuffer.h */, - CC84C7F120474C5300A3851B /* ASCGImageBuffer.m */, + CC84C7F120474C5300A3851B /* ASCGImageBuffer.mm */, DEC146B41C37A16A004A0EE7 /* ASCollectionInternal.h */, - DEC146B51C37A16A004A0EE7 /* ASCollectionInternal.m */, 18C2ED7C1B9B7DE800F627B3 /* ASCollectionNode.h */, 18C2ED7D1B9B7DE800F627B3 /* ASCollectionNode.mm */, B13CA0FF1C52004900E031AB /* ASCollectionNode+Beta.h */, @@ -1168,10 +1199,10 @@ 058D09D8195D050800B7D73C /* ASDisplayNode.h */, 058D09D9195D050800B7D73C /* ASDisplayNode.mm */, CC6AA2D81E9F03B900978E87 /* ASDisplayNode+Ancestry.h */, - CC6AA2D91E9F03B900978E87 /* ASDisplayNode+Ancestry.m */, + CC6AA2D91E9F03B900978E87 /* ASDisplayNode+Ancestry.mm */, 68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */, CC034A071E60BEB400626263 /* ASDisplayNode+Convenience.h */, - CC034A081E60BEB400626263 /* ASDisplayNode+Convenience.m */, + CC034A081E60BEB400626263 /* ASDisplayNode+Convenience.mm */, 683F563620E409D600CEB7A3 /* ASDisplayNode+InterfaceState.h */, 69BCE3D71EC6513B007DCCAD /* ASDisplayNode+Layout.mm */, 058D09DA195D050800B7D73C /* ASDisplayNode+Subclasses.h */, @@ -1181,7 +1212,7 @@ 0587F9BB1A7309ED00AFF0BA /* ASEditableTextNode.h */, 0587F9BC1A7309ED00AFF0BA /* ASEditableTextNode.mm */, CC7AF195200D9BD500A21BDE /* ASExperimentalFeatures.h */, - CC7AF197200D9E8400A21BDE /* ASExperimentalFeatures.m */, + CC7AF197200D9E8400A21BDE /* ASExperimentalFeatures.mm */, 058D09DD195D050800B7D73C /* ASImageNode.h */, 058D09DE195D050800B7D73C /* ASImageNode.mm */, 68355B2E1CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm */, @@ -1193,26 +1224,26 @@ 0516FA3E1A1563D200B4EBED /* ASMultiplexImageNode.h */, 0516FA3F1A1563D200B4EBED /* ASMultiplexImageNode.mm */, 68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */, - 68FC85DD1CE29AB700EDD713 /* ASNavigationController.m */, + 68FC85DD1CE29AB700EDD713 /* ASNavigationController.mm */, CCED5E3C2020D36800395C40 /* ASNetworkImageLoadInfo.h */, - CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.m */, + CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.mm */, 055B9FA61A1C154B00035D6D /* ASNetworkImageNode.h */, 055B9FA71A1C154B00035D6D /* ASNetworkImageNode.mm */, 698371D91E4379CD00437585 /* ASNodeController+Beta.h */, 698371DA1E4379CD00437585 /* ASNodeController+Beta.mm */, DBDB83921C6E879900D0098C /* ASPagerFlowLayout.h */, - DBDB83931C6E879900D0098C /* ASPagerFlowLayout.m */, + DBDB83931C6E879900D0098C /* ASPagerFlowLayout.mm */, 25E327541C16819500A2170C /* ASPagerNode.h */, - 25E327551C16819500A2170C /* ASPagerNode.m */, + 25E327551C16819500A2170C /* ASPagerNode.mm */, E54E00711F1D3828000B30D7 /* ASPagerNode+Beta.h */, A2763D771CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.h */, - A2763D781CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.m */, + A2763D781CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.mm */, CCBBBF5C1EB161760069AA91 /* ASRangeManagingNode.h */, D785F6601A74327E00291744 /* ASScrollNode.h */, D785F6611A74327E00291744 /* ASScrollNode.mm */, ACE87A2B1D73696800D7FF06 /* ASSectionContext.h */, 68FC85E01CE29B7E00EDD713 /* ASTabBarController.h */, - 68FC85E11CE29B7E00EDD713 /* ASTabBarController.m */, + 68FC85E11CE29B7E00EDD713 /* ASTabBarController.mm */, B0F880581BEAEC7500D17647 /* ASTableNode.h */, 9CFFC6C11CCAC768006A6476 /* ASTableNode.mm */, E5C347B21ECB40AA00EC4BE4 /* ASTableNode+Beta.h */, @@ -1233,12 +1264,12 @@ ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */, 9CFFC6BF1CCAC73C006A6476 /* ASViewController.mm */, 68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */, - 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */, + 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.mm */, 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */, 8021EC1A1D2B00B100799119 /* UIImage+ASConvenience.h */, - 8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.m */, + 8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.mm */, CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */, - CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */, + CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.mm */, ); path = Source; sourceTree = ""; @@ -1255,85 +1286,85 @@ 058D09C5195D04C000B7D73C /* Tests */ = { isa = PBXGroup; children = ( - F325E48F217460B000AC93A4 /* ASTextNode2Tests.m */, - F325E48B21745F9E00AC93A4 /* ASButtonNodeTests.m */, + F325E48F217460B000AC93A4 /* ASTextNode2Tests.mm */, + F325E48B21745F9E00AC93A4 /* ASButtonNodeTests.mm */, F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */, - DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.m */, - AC026B571BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.m */, + DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.mm */, + AC026B571BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.mm */, 696FCB301D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm */, - 29CDC2E11AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m */, - 242995D21B29743C00090100 /* ASBasicImageDownloaderTests.m */, - 296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.m */, + 29CDC2E11AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.mm */, + 242995D21B29743C00090100 /* ASBasicImageDownloaderTests.mm */, + 296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.mm */, CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */, - CC051F1E1D7A286A006434CB /* ASCALayerTests.m */, + CC051F1E1D7A286A006434CB /* ASCALayerTests.mm */, ACF6ED531B178DC700DA7C62 /* ASCenterLayoutSpecSnapshotTests.mm */, - CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.m */, - CC35CEC520DD87280006448D /* ASCollectionsTests.m */, - 2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */, + CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.mm */, + CC35CEC520DD87280006448D /* ASCollectionsTests.mm */, + 2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.mm */, 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.mm */, - CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.m */, - 2911485B1A77147A005D0878 /* ASControlNodeTests.m */, + CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.mm */, + 2911485B1A77147A005D0878 /* ASControlNodeTests.mm */, 1A6C000F1FAB4ED400D05926 /* ASCornerLayoutSpecSnapshotTests.mm */, ACF6ED541B178DC700DA7C62 /* ASDimensionTests.mm */, - CC54A81D1D7008B300296A24 /* ASDispatchTests.m */, - 058D0A2D195D057000B7D73C /* ASDisplayLayerTests.m */, - 058D0A2E195D057000B7D73C /* ASDisplayNodeAppearanceTests.m */, - F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */, - DBC453211C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.m */, + CC54A81D1D7008B300296A24 /* ASDispatchTests.mm */, + 058D0A2D195D057000B7D73C /* ASDisplayLayerTests.mm */, + 058D0A2E195D057000B7D73C /* ASDisplayNodeAppearanceTests.mm */, + F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.mm */, + DBC453211C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.mm */, 69B225661D72535E00B25B22 /* ASDisplayNodeLayoutTests.mm */, - CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */, + CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.mm */, 058D0A2F195D057000B7D73C /* ASDisplayNodeTests.mm */, 058D0A30195D057000B7D73C /* ASDisplayNodeTestsHelper.h */, - 058D0A31195D057000B7D73C /* ASDisplayNodeTestsHelper.m */, - 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */, - 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.m */, + 058D0A31195D057000B7D73C /* ASDisplayNodeTestsHelper.mm */, + 697B31591CFE4B410049936F /* ASEditableTextNodeTests.mm */, + 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.mm */, ACF6ED551B178DC700DA7C62 /* ASInsetLayoutSpecSnapshotTests.mm */, - CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.m */, - 69FEE53C1D95A9AF0086F066 /* ASLayoutElementStyleTests.m */, + CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.mm */, + 69FEE53C1D95A9AF0086F066 /* ASLayoutElementStyleTests.mm */, CCE4F9B41F0DA4F300062E4E /* ASLayoutEngineTests.mm */, - E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.m */, + E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.mm */, ACF6ED571B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.h */, - ACF6ED581B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.m */, - 699B83501E3C1BA500433FA4 /* ASLayoutSpecTests.m */, + ACF6ED581B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.mm */, + 699B83501E3C1BA500433FA4 /* ASLayoutSpecTests.mm */, CCE4F9B61F0DBA5000062E4E /* ASLayoutTestNode.h */, CCE4F9B71F0DBA5000062E4E /* ASLayoutTestNode.mm */, - 052EE0651A159FEF002C6279 /* ASMultiplexImageNodeTests.m */, - 058D0A32195D057000B7D73C /* ASMutableAttributedStringBuilderTests.m */, - BB5FC3CD1F9BA688007F191E /* ASNavigationControllerTests.m */, - CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.m */, + 052EE0651A159FEF002C6279 /* ASMultiplexImageNodeTests.mm */, + 058D0A32195D057000B7D73C /* ASMutableAttributedStringBuilderTests.mm */, + BB5FC3CD1F9BA688007F191E /* ASNavigationControllerTests.mm */, + CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.mm */, ACF6ED591B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm */, - AE6987C01DD04E1000B9E458 /* ASPagerNodeTests.m */, + AE6987C01DD04E1000B9E458 /* ASPagerNodeTests.mm */, CC8B05D41D73836400F54286 /* ASPerformanceTestContext.h */, - CC8B05D51D73836400F54286 /* ASPerformanceTestContext.m */, - CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */, + CC8B05D51D73836400F54286 /* ASPerformanceTestContext.mm */, + CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.mm */, ACF6ED5A1B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm */, - CCAA0B81206ADECB0057B336 /* ASRecursiveUnfairLockTests.m */, + CCAA0B81206ADECB0057B336 /* ASRecursiveUnfairLockTests.mm */, 7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */, - 4E9127681F64157600499623 /* ASRunLoopQueueTests.m */, - E586F96B1F9F9E2900ECE00E /* ASScrollNodeTests.m */, + 4E9127681F64157600499623 /* ASRunLoopQueueTests.mm */, + E586F96B1F9F9E2900ECE00E /* ASScrollNodeTests.mm */, 056D21501ABCEDA1001107EF /* ASSnapshotTestCase.h */, - 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.m */, + 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.mm */, ACF6ED5B1B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm */, - BB5FC3D01F9C9389007F191E /* ASTabBarControllerTests.m */, + BB5FC3D01F9C9389007F191E /* ASTabBarControllerTests.mm */, 3C9C128419E616EF00E942A0 /* ASTableViewTests.mm */, - CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */, - 058D0A33195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.m */, + CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.mm */, + 058D0A33195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.mm */, AE440174210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm */, 254C6B531BF8FF2A003EC431 /* ASTextKitTests.mm */, 254C6B511BF8FE6D003EC431 /* ASTextKitTruncationTests.mm */, - C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.m */, - CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.m */, - 81E95C131D62639600336598 /* ASTextNodeSnapshotTests.m */, - 058D0A36195D057000B7D73C /* ASTextNodeTests.m */, + C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.mm */, + CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.mm */, + 81E95C131D62639600336598 /* ASTextNodeSnapshotTests.mm */, + 058D0A36195D057000B7D73C /* ASTextNodeTests.mm */, 058D0A37195D057000B7D73C /* ASTextNodeWordKernerTests.mm */, CCE4F9BC1F0ECE5200062E4E /* ASTLayoutFixture.h */, CCE4F9BD1F0ECE5200062E4E /* ASTLayoutFixture.mm */, - 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.m */, - CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.m */, - AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.m */, - CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.m */, - 83A7D95D1D446A6E00BF333E /* ASWeakMapTests.m */, - CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */, + 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm */, + CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.mm */, + AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.mm */, + CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.mm */, + 83A7D95D1D446A6E00BF333E /* ASWeakMapTests.mm */, + CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.mm */, 695BE2541DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm */, 057D02C01AC0A66700C7AC3C /* AsyncDisplayKitTestHost */, CC583ABF1EF9BAB400134156 /* Common */, @@ -1361,9 +1392,9 @@ 25B171EA1C12242700508A7A /* Data Controller */, 058D09F7195D050800B7D73C /* Transactions */, 3917EBD21E9C2FC400D04A01 /* _ASCollectionReusableView.h */, - 3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.m */, + 3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.mm */, CC0F885E1E4280B800576FED /* _ASCollectionViewCell.h */, - CC0F885D1E4280B800576FED /* _ASCollectionViewCell.m */, + CC0F885D1E4280B800576FED /* _ASCollectionViewCell.mm */, 058D09E2195D050800B7D73C /* _ASDisplayLayer.h */, 058D09E3195D050800B7D73C /* _ASDisplayLayer.mm */, 058D09E4195D050800B7D73C /* _ASDisplayView.h */, @@ -1375,22 +1406,22 @@ 054963471A1EA066000F8E56 /* ASBasicImageDownloader.h */, 054963481A1EA066000F8E56 /* ASBasicImageDownloader.mm */, 299DA1A71A828D2900162D41 /* ASBatchContext.h */, - 299DA1A81A828D2900162D41 /* ASBatchContext.m */, + 299DA1A81A828D2900162D41 /* ASBatchContext.mm */, E5C347B01ECB3D9200EC4BE4 /* ASBatchFetchingDelegate.h */, 205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */, - 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.m */, + 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.mm */, 68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */, - 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */, + 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.mm */, 696F01EA1DD2AF450049FBD5 /* ASEventLog.h */, 696F01EB1DD2AF450049FBD5 /* ASEventLog.mm */, CCDC9B4B200991D10063C1F8 /* ASGraphicsContext.h */, - CCDC9B4C200991D10063C1F8 /* ASGraphicsContext.m */, + CCDC9B4C200991D10063C1F8 /* ASGraphicsContext.mm */, E5B225271F1790B5001E1431 /* ASHashing.h */, - E5B225261F1790B5001E1431 /* ASHashing.m */, + E5B225261F1790B5001E1431 /* ASHashing.mm */, 058D09E6195D050800B7D73C /* ASHighlightOverlayLayer.h */, 058D09E7195D050800B7D73C /* ASHighlightOverlayLayer.mm */, 68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */, - 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */, + 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.mm */, 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */, CC5601391F06E9A700DC4FBE /* ASIntegerMap.h */, CC56013A1F06E9A700DC4FBE /* ASIntegerMap.mm */, @@ -1399,43 +1430,42 @@ 68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */, 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */, 058D09E8195D050800B7D73C /* ASMutableAttributedStringBuilder.h */, - 058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.m */, + 058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.mm */, 6907C2561DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h */, - 6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m */, + 6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.mm */, CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */, - CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */, + CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.mm */, 68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */, - 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */, + 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.mm */, 055F1A3619ABD413004DAFF1 /* ASRangeController.h */, 055F1A3719ABD413004DAFF1 /* ASRangeController.mm */, 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */, CCAA0B7D206ADBF30057B336 /* ASRecursiveUnfairLock.h */, - CCAA0B7E206ADBF30057B336 /* ASRecursiveUnfairLock.m */, + CCAA0B7E206ADBF30057B336 /* ASRecursiveUnfairLock.mm */, 81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */, 81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */, 296A0A311A951715005ACEAA /* ASScrollDirection.h */, - 205F0E111B371BD7007741D0 /* ASScrollDirection.m */, + 205F0E111B371BD7007741D0 /* ASScrollDirection.mm */, 4640521B1A3F83C40061C0BA /* ASTableLayoutController.h */, - 4640521C1A3F83C40061C0BA /* ASTableLayoutController.m */, + 4640521C1A3F83C40061C0BA /* ASTableLayoutController.mm */, 058D0A12195D050800B7D73C /* ASThread.h */, CC4C2A751D88E3BF0039ACAB /* ASTraceEvent.h */, - CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.m */, + CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.mm */, 9C70F2011CDA4EFA007D6C76 /* ASTraitCollection.h */, - 9C70F2021CDA4EFA007D6C76 /* ASTraitCollection.m */, + 9C70F2021CDA4EFA007D6C76 /* ASTraitCollection.mm */, 68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */, - 68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */, + 68B8A4E01CBDB958007E4543 /* ASWeakProxy.mm */, CC3B20871C3F7A5400798563 /* ASWeakSet.h */, - CC3B20881C3F7A5400798563 /* ASWeakSet.m */, + CC3B20881C3F7A5400798563 /* ASWeakSet.mm */, 205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */, - 205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.m */, DBC452D91C5BF64600B16017 /* NSArray+Diffing.h */, DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */, CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */, - CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */, + CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.mm */, 058D09F5195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.h */, - 058D09F6195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m */, + 058D09F6195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.mm */, 205F0E0D1B371875007741D0 /* UICollectionViewLayout+ASConvenience.h */, - 205F0E0E1B371875007741D0 /* UICollectionViewLayout+ASConvenience.m */, + 205F0E0E1B371875007741D0 /* UICollectionViewLayout+ASConvenience.mm */, 058D09FF195D050800B7D73C /* UIView+ASConvenience.h */, ); path = Details; @@ -1447,10 +1477,10 @@ 058D09F8195D050800B7D73C /* _ASAsyncTransaction.h */, 058D09F9195D050800B7D73C /* _ASAsyncTransaction.mm */, 058D09FB195D050800B7D73C /* _ASAsyncTransactionContainer.h */, - 058D09FC195D050800B7D73C /* _ASAsyncTransactionContainer.m */, + 058D09FC195D050800B7D73C /* _ASAsyncTransactionContainer.mm */, 058D09FA195D050800B7D73C /* _ASAsyncTransactionContainer+Private.h */, 058D09FD195D050800B7D73C /* _ASAsyncTransactionGroup.h */, - 058D09FE195D050800B7D73C /* _ASAsyncTransactionGroup.m */, + 058D09FE195D050800B7D73C /* _ASAsyncTransactionGroup.mm */, ); path = Transactions; sourceTree = ""; @@ -1471,66 +1501,66 @@ 058D0A06195D050800B7D73C /* _ASPendingState.mm */, 058D0A07195D050800B7D73C /* _ASScopeTimer.h */, DB55C25F1C6408D6004EDCF5 /* _ASTransitionContext.h */, - DB55C2601C6408D6004EDCF5 /* _ASTransitionContext.m */, + DB55C2601C6408D6004EDCF5 /* _ASTransitionContext.mm */, 2967F9E11AB0A4CF0072E4AB /* ASBasicImageDownloaderInternal.h */, 044285051BAA63FE00D16268 /* ASBatchFetching.h */, - 044285061BAA63FE00D16268 /* ASBatchFetching.m */, + 044285061BAA63FE00D16268 /* ASBatchFetching.mm */, CC87BB941DA8193C0090E380 /* ASCellNode+Internal.h */, CC2E317F1DAC353700EEE891 /* ASCollectionView+Undeprecated.h */, CC0F885A1E42807F00576FED /* ASCollectionViewFlowLayoutInspector.h */, - CC0F88591E42807F00576FED /* ASCollectionViewFlowLayoutInspector.m */, + CC0F88591E42807F00576FED /* ASCollectionViewFlowLayoutInspector.mm */, FA4FAF14200A850200E735BD /* ASControlNode+Private.h */, 9F98C0231DBDF2A300476D92 /* ASControlTargetAction.h */, - 9F98C0241DBDF2A300476D92 /* ASControlTargetAction.m */, + 9F98C0241DBDF2A300476D92 /* ASControlTargetAction.mm */, 8B0768B11CE752EC002E1453 /* ASDefaultPlaybackButton.h */, - 8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.m */, + 8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.mm */, AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */, - AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */, + AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.mm */, CC54A81B1D70077A00296A24 /* ASDispatch.h */, - E5B2252D1F17E521001E1431 /* ASDispatch.m */, + E5B2252D1F17E521001E1431 /* ASDispatch.mm */, 058D0A08195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm */, 058D0A09195D050800B7D73C /* ASDisplayNode+DebugTiming.h */, 058D0A0A195D050800B7D73C /* ASDisplayNode+DebugTiming.mm */, DE6EA3211C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h */, 058D0A0B195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm */, 690BC8BF20F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.h */, - 690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m */, + 690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.mm */, 058D0A0C195D050800B7D73C /* ASDisplayNodeInternal.h */, 6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */, CCA282C61E9EB64B0037E8B7 /* ASDisplayNodeTipState.h */, - CCA282C71E9EB64B0037E8B7 /* ASDisplayNodeTipState.m */, + CCA282C71E9EB64B0037E8B7 /* ASDisplayNodeTipState.mm */, 68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */, 058D0A0D195D050800B7D73C /* ASImageNode+CGExtras.h */, - 058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */, + 058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.mm */, 6900C5F31E8072DA00BCD75C /* ASImageNode+Private.h */, ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */, - ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.m */, + ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.mm */, CCA282C21E9EAE630037E8B7 /* ASLayerBackingTipProvider.h */, - CCA282C31E9EAE630037E8B7 /* ASLayerBackingTipProvider.m */, + CCA282C31E9EAE630037E8B7 /* ASLayerBackingTipProvider.mm */, E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */, E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */, CC2F65EC1E5FFB1600DA57C9 /* ASMutableElementMap.h */, - CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.m */, + CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.mm */, CCED5E402020D41600395C40 /* ASNetworkImageLoadInfo+Private.h */, CC3B20811C3F76D600798563 /* ASPendingStateController.h */, CC3B20821C3F76D600798563 /* ASPendingStateController.mm */, CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */, - CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */, + CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.mm */, CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */, CCA282BE1E9EAE010037E8B7 /* ASTip.h */, - CCA282BF1E9EAE010037E8B7 /* ASTip.m */, + CCA282BF1E9EAE010037E8B7 /* ASTip.mm */, CCA282CA1E9EB73E0037E8B7 /* ASTipNode.h */, - CCA282CB1E9EB73E0037E8B7 /* ASTipNode.m */, + CCA282CB1E9EB73E0037E8B7 /* ASTipNode.mm */, CCA282BA1E9EABDD0037E8B7 /* ASTipProvider.h */, - CCA282BB1E9EABDD0037E8B7 /* ASTipProvider.m */, + CCA282BB1E9EABDD0037E8B7 /* ASTipProvider.mm */, CCA282B21E9EA7310037E8B7 /* ASTipsController.h */, - CCA282B31E9EA7310037E8B7 /* ASTipsController.m */, + CCA282B31E9EA7310037E8B7 /* ASTipsController.mm */, CCA282CE1E9EBF6C0037E8B7 /* ASTipsWindow.h */, - CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.m */, + CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.mm */, 0442850B1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.h */, - 0442850C1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.m */, + 0442850C1BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.mm */, 83A7D9581D44542100BF333E /* ASWeakMap.h */, - 83A7D9591D44542100BF333E /* ASWeakMap.m */, + 83A7D9591D44542100BF333E /* ASWeakMap.mm */, ); path = Private; sourceTree = ""; @@ -1539,12 +1569,12 @@ isa = PBXGroup; children = ( 058D0A43195D058D00B7D73C /* ASAssert.h */, - CCA5F62D1EECC2A80060C137 /* ASAssert.m */, + CCA5F62D1EECC2A80060C137 /* ASAssert.mm */, 0516FA3A1A15563400B4EBED /* ASAvailability.h */, 058D0A44195D058D00B7D73C /* ASBaseDefines.h */, 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */, 0516FA3B1A15563400B4EBED /* ASLog.h */, - CCB1F9591EFB60A5009C7475 /* ASLog.m */, + CCB1F9591EFB60A5009C7475 /* ASLog.mm */, CCB1F95B1EFB6316009C7475 /* ASSignpost.h */, ); path = Base; @@ -1554,7 +1584,7 @@ isa = PBXGroup; children = ( B30BF6501C5964B0004FCD53 /* ASLayoutManager.h */, - B30BF6511C5964B0004FCD53 /* ASLayoutManager.m */, + B30BF6511C5964B0004FCD53 /* ASLayoutManager.mm */, 257754951BEE44CD00737CA5 /* ASTextKitAttributes.h */, 257754941BEE44CD00737CA5 /* ASTextKitAttributes.mm */, 257754BA1BEE458E00737CA5 /* ASTextKitComponents.h */, @@ -1562,9 +1592,9 @@ 257754961BEE44CD00737CA5 /* ASTextKitContext.h */, 257754971BEE44CD00737CA5 /* ASTextKitContext.mm */, 257754BB1BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h */, - 257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.m */, + 257754B81BEE458E00737CA5 /* ASTextKitCoreTextAdditions.mm */, 257754981BEE44CD00737CA5 /* ASTextKitEntityAttribute.h */, - 257754991BEE44CD00737CA5 /* ASTextKitEntityAttribute.m */, + 257754991BEE44CD00737CA5 /* ASTextKitEntityAttribute.mm */, A32FEDD31C501B6A004F642A /* ASTextKitFontSizeAdjuster.h */, 9C8898BA1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm */, 257754931BEE44CD00737CA5 /* ASTextKitRenderer.h */, @@ -1580,7 +1610,7 @@ 257754A31BEE44CD00737CA5 /* ASTextKitTruncating.h */, 257754BC1BEE458E00737CA5 /* ASTextNodeTypes.h */, 257754B91BEE458E00737CA5 /* ASTextNodeWordKerner.h */, - 257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.m */, + 257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.mm */, ); name = TextKit; sourceTree = ""; @@ -1593,11 +1623,11 @@ 464052191A3F83C40061C0BA /* ASDataController.h */, 4640521A1A3F83C40061C0BA /* ASDataController.mm */, DE8BEABF1C2DF3FC00D57C12 /* ASDelegateProxy.h */, - DE8BEAC01C2DF3FC00D57C12 /* ASDelegateProxy.m */, + DE8BEAC01C2DF3FC00D57C12 /* ASDelegateProxy.mm */, E5B077FD1E69F4EB00C24B5B /* ASElementMap.h */, - E5B077FE1E69F4EB00C24B5B /* ASElementMap.m */, + E5B077FE1E69F4EB00C24B5B /* ASElementMap.mm */, AC6145401D8AFAE8003D62A2 /* ASSection.h */, - AC6145421D8AFD4F003D62A2 /* ASSection.m */, + AC6145421D8AFD4F003D62A2 /* ASSection.mm */, ); name = "Data Controller"; sourceTree = ""; @@ -1605,8 +1635,8 @@ 690ED5911E36D118000627C0 /* tvOS */ = { isa = PBXGroup; children = ( - 690ED5931E36D118000627C0 /* ASControlNode+tvOS.m */, - 690ED5951E36D118000627C0 /* ASImageNode+tvOS.m */, + 690ED5931E36D118000627C0 /* ASControlNode+tvOS.mm */, + 690ED5951E36D118000627C0 /* ASImageNode+tvOS.mm */, ); path = tvOS; sourceTree = ""; @@ -1633,7 +1663,7 @@ ACF6ED181B17843500DA7C62 /* ASAbsoluteLayoutSpec.h */, ACF6ED191B17843500DA7C62 /* ASAbsoluteLayoutSpec.mm */, 9C5586671BD549CB00B50E3A /* ASAsciiArtBoxCreator.h */, - 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */, + 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.mm */, ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutSpec.h */, ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutSpec.mm */, ACF6ED031B17843500DA7C62 /* ASCenterLayoutSpec.h */, @@ -1685,15 +1715,15 @@ CC583ABF1EF9BAB400134156 /* Common */ = { isa = PBXGroup; children = ( - CC583AC01EF9BAB400134156 /* ASDisplayNode+OCMock.m */, + CC583AC01EF9BAB400134156 /* ASDisplayNode+OCMock.mm */, CC583AC11EF9BAB400134156 /* ASTestCase.h */, - CC583AC21EF9BAB400134156 /* ASTestCase.m */, + CC583AC21EF9BAB400134156 /* ASTestCase.mm */, CC583AC31EF9BAB400134156 /* ASXCTExtensions.h */, CCE4F9BB1F0EA67F00062E4E /* debugbreak.h */, CC583AC41EF9BAB400134156 /* NSInvocation+ASTestHelpers.h */, - CC583AC51EF9BAB400134156 /* NSInvocation+ASTestHelpers.m */, + CC583AC51EF9BAB400134156 /* NSInvocation+ASTestHelpers.mm */, CC583AC61EF9BAB400134156 /* OCMockObject+ASAdditions.h */, - CC583AC71EF9BAB400134156 /* OCMockObject+ASAdditions.m */, + CC583AC71EF9BAB400134156 /* OCMockObject+ASAdditions.mm */, ); path = Common; sourceTree = ""; @@ -1712,13 +1742,13 @@ isa = PBXGroup; children = ( CCCCCCC31EC3EF060087FE10 /* ASTextDebugOption.h */, - CCCCCCC41EC3EF060087FE10 /* ASTextDebugOption.m */, + CCCCCCC41EC3EF060087FE10 /* ASTextDebugOption.mm */, CCCCCCC51EC3EF060087FE10 /* ASTextInput.h */, - CCCCCCC61EC3EF060087FE10 /* ASTextInput.m */, + CCCCCCC61EC3EF060087FE10 /* ASTextInput.mm */, CCCCCCC71EC3EF060087FE10 /* ASTextLayout.h */, - CCCCCCC81EC3EF060087FE10 /* ASTextLayout.m */, + CCCCCCC81EC3EF060087FE10 /* ASTextLayout.mm */, CCCCCCC91EC3EF060087FE10 /* ASTextLine.h */, - CCCCCCCA1EC3EF060087FE10 /* ASTextLine.m */, + CCCCCCCA1EC3EF060087FE10 /* ASTextLine.mm */, ); path = Component; sourceTree = ""; @@ -1727,9 +1757,9 @@ isa = PBXGroup; children = ( CCCCCCCC1EC3EF060087FE10 /* ASTextAttribute.h */, - CCCCCCCD1EC3EF060087FE10 /* ASTextAttribute.m */, + CCCCCCCD1EC3EF060087FE10 /* ASTextAttribute.mm */, CCCCCCCE1EC3EF060087FE10 /* ASTextRunDelegate.h */, - CCCCCCCF1EC3EF060087FE10 /* ASTextRunDelegate.m */, + CCCCCCCF1EC3EF060087FE10 /* ASTextRunDelegate.mm */, ); path = String; sourceTree = ""; @@ -1738,11 +1768,11 @@ isa = PBXGroup; children = ( CCCCCCD11EC3EF060087FE10 /* ASTextUtilities.h */, - CCCCCCD21EC3EF060087FE10 /* ASTextUtilities.m */, + CCCCCCD21EC3EF060087FE10 /* ASTextUtilities.mm */, CCCCCCE51EC3F0FC0087FE10 /* NSAttributedString+ASText.h */, - CCCCCCE61EC3F0FC0087FE10 /* NSAttributedString+ASText.m */, + CCCCCCE61EC3F0FC0087FE10 /* NSAttributedString+ASText.mm */, CCCCCCD31EC3EF060087FE10 /* NSParagraphStyle+ASText.h */, - CCCCCCD41EC3EF060087FE10 /* NSParagraphStyle+ASText.m */, + CCCCCCD41EC3EF060087FE10 /* NSParagraphStyle+ASText.mm */, ); path = Utility; sourceTree = ""; @@ -1761,7 +1791,7 @@ isa = PBXGroup; children = ( CCBD05DF1E4147B000D18509 /* ASIGListAdapterBasedDataSource.h */, - CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */, + CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.mm */, ); name = "Collection Data Adapter"; sourceTree = ""; @@ -1770,9 +1800,9 @@ isa = PBXGroup; children = ( CC034A111E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.h */, - CC034A121E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m */, + CC034A121E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.mm */, CCE04B201E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.h */, - CCE04B211E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.m */, + CCE04B211E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.mm */, ); name = "IGListKit Support"; sourceTree = ""; @@ -1781,9 +1811,9 @@ isa = PBXGroup; children = ( 764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */, - 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */, + 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.mm */, CCA282B61E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.h */, - CCA282B71E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.m */, + CCA282B71E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.mm */, ); path = Debug; sourceTree = ""; @@ -1792,7 +1822,7 @@ isa = PBXGroup; children = ( E5667E8B1F33871300FA6FC0 /* _ASCollectionGalleryLayoutInfo.h */, - E5667E8D1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.m */, + E5667E8D1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.mm */, E5775AFB1F13CE9F00CAC9BC /* _ASCollectionGalleryLayoutItem.h */, E5775AFD1F13CF7400CAC9BC /* _ASCollectionGalleryLayoutItem.mm */, E58E9E471E941DA5004CFC59 /* ASCollectionLayout.h */, @@ -1801,7 +1831,7 @@ E5775B031F16759F00CAC9BC /* ASCollectionLayoutCache.mm */, E5B5B9D01E9BAD9800A6B726 /* ASCollectionLayoutContext+Private.h */, E5855DEE1EBB4D83003639AE /* ASCollectionLayoutDefines.h */, - E5855DED1EBB4D83003639AE /* ASCollectionLayoutDefines.m */, + E5855DED1EBB4D83003639AE /* ASCollectionLayoutDefines.mm */, E5775AFF1F13D25400CAC9BC /* ASCollectionLayoutState+Private.h */, ); name = "Collection Layout"; @@ -1811,16 +1841,16 @@ isa = PBXGroup; children = ( E58E9E3D1E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.h */, - E58E9E3E1E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.m */, + E58E9E3E1E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.mm */, E5E2D72D1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h */, E5E2D72F1EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm */, E58E9E3F1E941D74004CFC59 /* ASCollectionLayoutContext.h */, - E58E9E401E941D74004CFC59 /* ASCollectionLayoutContext.m */, + E58E9E401E941D74004CFC59 /* ASCollectionLayoutContext.mm */, E58E9E411E941D74004CFC59 /* ASCollectionLayoutDelegate.h */, E5E281731E71C833006B67C2 /* ASCollectionLayoutState.h */, E5E281751E71C845006B67C2 /* ASCollectionLayoutState.mm */, E54E81FA1EB357BD00FFE8E1 /* ASPageTable.h */, - E54E81FB1EB357BD00FFE8E1 /* ASPageTable.m */, + E54E81FB1EB357BD00FFE8E1 /* ASPageTable.mm */, ); name = "Collection Layout"; sourceTree = ""; @@ -2226,8 +2256,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 057D02C71AC0A66700C7AC3C /* AppDelegate.m in Sources */, - 057D02C41AC0A66700C7AC3C /* main.m in Sources */, + 057D02C71AC0A66700C7AC3C /* AppDelegate.mm in Sources */, + 057D02C41AC0A66700C7AC3C /* main.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2235,83 +2265,83 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - CCEDDDD9200C518800FFCD0A /* ASConfigurationTests.m in Sources */, + CCEDDDD9200C518800FFCD0A /* ASConfigurationTests.mm in Sources */, AE440175210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm in Sources */, - E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.m in Sources */, - 4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.m in Sources */, - 29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m in Sources */, - CC583AD71EF9BDC100134156 /* NSInvocation+ASTestHelpers.m in Sources */, - CC051F1F1D7A286A006434CB /* ASCALayerTests.m in Sources */, - 242995D31B29743C00090100 /* ASBasicImageDownloaderTests.m in Sources */, - 296A0A351A951ABF005ACEAA /* ASBatchFetchingTests.m in Sources */, + E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.mm in Sources */, + 4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm in Sources */, + 29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.mm in Sources */, + CC583AD71EF9BDC100134156 /* NSInvocation+ASTestHelpers.mm in Sources */, + CC051F1F1D7A286A006434CB /* ASCALayerTests.mm in Sources */, + 242995D31B29743C00090100 /* ASBasicImageDownloaderTests.mm in Sources */, + 296A0A351A951ABF005ACEAA /* ASBatchFetchingTests.mm in Sources */, ACF6ED5C1B178DC700DA7C62 /* ASCenterLayoutSpecSnapshotTests.mm in Sources */, 9F06E5CD1B4CAF4200F015D8 /* ASCollectionViewTests.mm in Sources */, - 2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */, - CC3B208E1C3F7D0A00798563 /* ASWeakSetTests.m in Sources */, - F711994E1D20C21100568860 /* ASDisplayNodeExtrasTests.m in Sources */, - BB5FC3CE1F9BA689007F191E /* ASNavigationControllerTests.m in Sources */, + 2911485C1A77147A005D0878 /* ASControlNodeTests.mm in Sources */, + CC3B208E1C3F7D0A00798563 /* ASWeakSetTests.mm in Sources */, + F711994E1D20C21100568860 /* ASDisplayNodeExtrasTests.mm in Sources */, + BB5FC3CE1F9BA689007F191E /* ASNavigationControllerTests.mm in Sources */, ACF6ED5D1B178DC700DA7C62 /* ASDimensionTests.mm in Sources */, - BB5FC3D11F9C9389007F191E /* ASTabBarControllerTests.m in Sources */, + BB5FC3D11F9C9389007F191E /* ASTabBarControllerTests.mm in Sources */, 695BE2551DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm in Sources */, - CCA221D31D6FA7EF00AF6A0F /* ASViewControllerTests.m in Sources */, - 058D0A38195D057000B7D73C /* ASDisplayLayerTests.m in Sources */, - 2538B6F31BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m in Sources */, - CC583AD61EF9BDBE00134156 /* ASTestCase.m in Sources */, - 058D0A39195D057000B7D73C /* ASDisplayNodeAppearanceTests.m in Sources */, - CCB2F34D1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m in Sources */, - AE6987C11DD04E1000B9E458 /* ASPagerNodeTests.m in Sources */, + CCA221D31D6FA7EF00AF6A0F /* ASViewControllerTests.mm in Sources */, + 058D0A38195D057000B7D73C /* ASDisplayLayerTests.mm in Sources */, + 2538B6F31BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.mm in Sources */, + CC583AD61EF9BDBE00134156 /* ASTestCase.mm in Sources */, + 058D0A39195D057000B7D73C /* ASDisplayNodeAppearanceTests.mm in Sources */, + CCB2F34D1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.mm in Sources */, + AE6987C11DD04E1000B9E458 /* ASPagerNodeTests.mm in Sources */, 058D0A3A195D057000B7D73C /* ASDisplayNodeTests.mm in Sources */, 696FCB311D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm in Sources */, - CC583AD81EF9BDC300134156 /* OCMockObject+ASAdditions.m in Sources */, - 69FEE53D1D95A9AF0086F066 /* ASLayoutElementStyleTests.m in Sources */, - 4E9127691F64157600499623 /* ASRunLoopQueueTests.m in Sources */, - CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */, - CC54A81E1D7008B300296A24 /* ASDispatchTests.m in Sources */, + CC583AD81EF9BDC300134156 /* OCMockObject+ASAdditions.mm in Sources */, + 69FEE53D1D95A9AF0086F066 /* ASLayoutElementStyleTests.mm in Sources */, + 4E9127691F64157600499623 /* ASRunLoopQueueTests.mm in Sources */, + CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.mm in Sources */, + CC54A81E1D7008B300296A24 /* ASDispatchTests.mm in Sources */, F3F698D2211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm in Sources */, - CCE4F9B31F0D60AC00062E4E /* ASIntegerMapTests.m in Sources */, - 058D0A3B195D057000B7D73C /* ASDisplayNodeTestsHelper.m in Sources */, - 83A7D95E1D446A6E00BF333E /* ASWeakMapTests.m in Sources */, - 056D21551ABCEF50001107EF /* ASImageNodeSnapshotTests.m in Sources */, - AC026B581BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.m in Sources */, + CCE4F9B31F0D60AC00062E4E /* ASIntegerMapTests.mm in Sources */, + 058D0A3B195D057000B7D73C /* ASDisplayNodeTestsHelper.mm in Sources */, + 83A7D95E1D446A6E00BF333E /* ASWeakMapTests.mm in Sources */, + 056D21551ABCEF50001107EF /* ASImageNodeSnapshotTests.mm in Sources */, + AC026B581BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.mm in Sources */, ACF6ED5E1B178DC700DA7C62 /* ASInsetLayoutSpecSnapshotTests.mm in Sources */, - ACF6ED601B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.m in Sources */, - CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */, - 052EE0661A159FEF002C6279 /* ASMultiplexImageNodeTests.m in Sources */, - 058D0A3C195D057000B7D73C /* ASMutableAttributedStringBuilderTests.m in Sources */, - F325E48C21745F9E00AC93A4 /* ASButtonNodeTests.m in Sources */, - E586F96C1F9F9E2900ECE00E /* ASScrollNodeTests.m in Sources */, - CC8B05D81D73979700F54286 /* ASTextNodePerformanceTests.m in Sources */, - CC583AD91EF9BDC600134156 /* ASDisplayNode+OCMock.m in Sources */, - 697B315A1CFE4B410049936F /* ASEditableTextNodeTests.m in Sources */, + ACF6ED601B178DC700DA7C62 /* ASLayoutSpecSnapshotTestsHelper.mm in Sources */, + CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.mm in Sources */, + 052EE0661A159FEF002C6279 /* ASMultiplexImageNodeTests.mm in Sources */, + 058D0A3C195D057000B7D73C /* ASMutableAttributedStringBuilderTests.mm in Sources */, + F325E48C21745F9E00AC93A4 /* ASButtonNodeTests.mm in Sources */, + E586F96C1F9F9E2900ECE00E /* ASScrollNodeTests.mm in Sources */, + CC8B05D81D73979700F54286 /* ASTextNodePerformanceTests.mm in Sources */, + CC583AD91EF9BDC600134156 /* ASDisplayNode+OCMock.mm in Sources */, + 697B315A1CFE4B410049936F /* ASEditableTextNodeTests.mm in Sources */, ACF6ED611B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm in Sources */, - CC8B05D61D73836400F54286 /* ASPerformanceTestContext.m in Sources */, - CC0AEEA41D66316E005D1C78 /* ASUICollectionViewTests.m in Sources */, + CC8B05D61D73836400F54286 /* ASPerformanceTestContext.mm in Sources */, + CC0AEEA41D66316E005D1C78 /* ASUICollectionViewTests.mm in Sources */, CCE4F9B51F0DA4F300062E4E /* ASLayoutEngineTests.mm in Sources */, 69B225671D72535E00B25B22 /* ASDisplayNodeLayoutTests.mm in Sources */, - C057D9BD20B5453D00FC9112 /* ASTextNode2SnapshotTests.m in Sources */, + C057D9BD20B5453D00FC9112 /* ASTextNode2SnapshotTests.mm in Sources */, ACF6ED621B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm in Sources */, 7AB338691C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm in Sources */, - CCDD148B1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.m in Sources */, + CCDD148B1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.mm in Sources */, 1A6C00111FAB4EDD00D05926 /* ASCornerLayoutSpecSnapshotTests.mm in Sources */, 254C6B541BF8FF2A003EC431 /* ASTextKitTests.mm in Sources */, - 05EA6FE71AC0966E00E35788 /* ASSnapshotTestCase.m in Sources */, - CC35CEC620DD87280006448D /* ASCollectionsTests.m in Sources */, + 05EA6FE71AC0966E00E35788 /* ASSnapshotTestCase.mm in Sources */, + CC35CEC620DD87280006448D /* ASCollectionsTests.mm in Sources */, ACF6ED631B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm in Sources */, CCE4F9BA1F0DBB5000062E4E /* ASLayoutTestNode.mm in Sources */, - CCAA0B82206ADECB0057B336 /* ASRecursiveUnfairLockTests.m in Sources */, - 81E95C141D62639600336598 /* ASTextNodeSnapshotTests.m in Sources */, + CCAA0B82206ADECB0057B336 /* ASRecursiveUnfairLockTests.mm in Sources */, + 81E95C141D62639600336598 /* ASTextNodeSnapshotTests.mm in Sources */, 3C9C128519E616EF00E942A0 /* ASTableViewTests.mm in Sources */, - AEEC47E41C21D3D200EC1693 /* ASVideoNodeTests.m in Sources */, + AEEC47E41C21D3D200EC1693 /* ASVideoNodeTests.mm in Sources */, 254C6B521BF8FE6D003EC431 /* ASTextKitTruncationTests.mm in Sources */, - F325E490217460B100AC93A4 /* ASTextNode2Tests.m in Sources */, - 058D0A3D195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.m in Sources */, + F325E490217460B100AC93A4 /* ASTextNode2Tests.mm in Sources */, + 058D0A3D195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.mm in Sources */, CC3B20901C3F892D00798563 /* ASBridgedPropertiesTests.mm in Sources */, CCE4F9BE1F0ECE5200062E4E /* ASTLayoutFixture.mm in Sources */, - 058D0A40195D057000B7D73C /* ASTextNodeTests.m in Sources */, - DBC453221C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.m in Sources */, + 058D0A40195D057000B7D73C /* ASTextNodeTests.mm in Sources */, + DBC453221C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.mm in Sources */, 058D0A41195D057000B7D73C /* ASTextNodeWordKernerTests.mm in Sources */, - DBC452DE1C5C6A6A00B16017 /* ArrayDiffingTests.m in Sources */, - CC11F97A1DB181180024D77B /* ASNetworkImageNodeTests.m in Sources */, + DBC452DE1C5C6A6A00B16017 /* ArrayDiffingTests.mm in Sources */, + CC11F97A1DB181180024D77B /* ASNetworkImageNodeTests.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2319,80 +2349,79 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E5B225291F1790EE001E1431 /* ASHashing.m in Sources */, + E5B225291F1790EE001E1431 /* ASHashing.mm in Sources */, DEB8ED7C1DD003D300DBDE55 /* ASLayoutTransition.mm in Sources */, - CCA5F62E1EECC2A80060C137 /* ASAssert.m in Sources */, - 9F98C0261DBE29E000476D92 /* ASControlTargetAction.m in Sources */, + CCA5F62E1EECC2A80060C137 /* ASAssert.mm in Sources */, + 9F98C0261DBE29E000476D92 /* ASControlTargetAction.mm in Sources */, 9C70F2091CDABA36007D6C76 /* ASViewController.mm in Sources */, - 3917EBD51E9C2FC400D04A01 /* _ASCollectionReusableView.m in Sources */, - CCA282D11E9EBF6C0037E8B7 /* ASTipsWindow.m in Sources */, - CCCCCCE41EC3EF060087FE10 /* NSParagraphStyle+ASText.m in Sources */, - 8BBBAB8D1CEBAF1E00107FC6 /* ASDefaultPlaybackButton.m in Sources */, - B30BF6541C59D889004FCD53 /* ASLayoutManager.m in Sources */, + 3917EBD51E9C2FC400D04A01 /* _ASCollectionReusableView.mm in Sources */, + CCA282D11E9EBF6C0037E8B7 /* ASTipsWindow.mm in Sources */, + CCCCCCE41EC3EF060087FE10 /* NSParagraphStyle+ASText.mm in Sources */, + 8BBBAB8D1CEBAF1E00107FC6 /* ASDefaultPlaybackButton.mm in Sources */, + B30BF6541C59D889004FCD53 /* ASLayoutManager.mm in Sources */, 92DD2FE71BF4D0850074C9DD /* ASMapNode.mm in Sources */, - CCA282B91E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.m in Sources */, - 636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.m in Sources */, + CCA282B91E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.mm in Sources */, + 636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.mm in Sources */, B350623D1B010EFD0018CF92 /* _ASAsyncTransaction.mm in Sources */, 6947B0C51E36B5040007C478 /* ASStackPositionedLayout.mm in Sources */, - B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.m in Sources */, + B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.mm in Sources */, AC026B721BD57DBF00BBC17E /* _ASHierarchyChangeSet.mm in Sources */, - B35062421B010EFD0018CF92 /* _ASAsyncTransactionGroup.m in Sources */, - CCA282BD1E9EABDD0037E8B7 /* ASTipProvider.m in Sources */, + B35062421B010EFD0018CF92 /* _ASAsyncTransactionGroup.mm in Sources */, + CCA282BD1E9EABDD0037E8B7 /* ASTipProvider.mm in Sources */, 9019FBC01ED8061D00C45F72 /* ASYogaUtilities.mm in Sources */, B350624A1B010EFD0018CF92 /* _ASCoreAnimationExtras.mm in Sources */, 68EE0DC01C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */, B35062101B010EFD0018CF92 /* _ASDisplayLayer.mm in Sources */, - 9C55866B1BD54A1900B50E3A /* ASAsciiArtBoxCreator.m in Sources */, + 9C55866B1BD54A1900B50E3A /* ASAsciiArtBoxCreator.mm in Sources */, B35062121B010EFD0018CF92 /* _ASDisplayView.mm in Sources */, DEFAD8131CC48914000527C4 /* ASVideoNode.mm in Sources */, - CCA282C11E9EAE010037E8B7 /* ASTip.m in Sources */, + CCA282C11E9EAE010037E8B7 /* ASTip.mm in Sources */, B350624C1B010EFD0018CF92 /* _ASPendingState.mm in Sources */, 698371DC1E4379CD00437585 /* ASNodeController+Beta.mm in Sources */, - CC6AA2DB1E9F03B900978E87 /* ASDisplayNode+Ancestry.m in Sources */, + CC6AA2DB1E9F03B900978E87 /* ASDisplayNode+Ancestry.mm in Sources */, 509E68621B3AEDA5009B9150 /* ASAbstractLayoutController.mm in Sources */, 254C6B861BF94F8A003EC431 /* ASTextKitContext.mm in Sources */, - DBDB83971C6E879900D0098C /* ASPagerFlowLayout.m in Sources */, - E5B078001E69F4EB00C24B5B /* ASElementMap.m in Sources */, + DBDB83971C6E879900D0098C /* ASPagerFlowLayout.mm in Sources */, + E5B078001E69F4EB00C24B5B /* ASElementMap.mm in Sources */, 9C8898BC1C738BA800D6B02E /* ASTextKitFontSizeAdjuster.mm in Sources */, - 690ED59B1E36D118000627C0 /* ASImageNode+tvOS.m in Sources */, + 690ED59B1E36D118000627C0 /* ASImageNode+tvOS.mm in Sources */, 0FAFDF7620EC1C90003A51C0 /* ASLayout+IGListKit.mm in Sources */, - CCDC9B4E200991D10063C1F8 /* ASGraphicsContext.m in Sources */, - CCCCCCD81EC3EF060087FE10 /* ASTextInput.m in Sources */, + CCDC9B4E200991D10063C1F8 /* ASGraphicsContext.mm in Sources */, + CCCCCCD81EC3EF060087FE10 /* ASTextInput.mm in Sources */, 34EFC7621B701CA400AD841F /* ASBackgroundLayoutSpec.mm in Sources */, - DE8BEAC41C2DF3FC00D57C12 /* ASDelegateProxy.m in Sources */, + DE8BEAC41C2DF3FC00D57C12 /* ASDelegateProxy.mm in Sources */, B35062141B010EFD0018CF92 /* ASBasicImageDownloader.mm in Sources */, - B35062161B010EFD0018CF92 /* ASBatchContext.m in Sources */, + B35062161B010EFD0018CF92 /* ASBatchContext.mm in Sources */, AC47D9421B3B891B00AAEE9D /* ASCellNode.mm in Sources */, - E58E9E451E941D74004CFC59 /* ASCollectionLayoutContext.m in Sources */, + E58E9E451E941D74004CFC59 /* ASCollectionLayoutContext.mm in Sources */, 34EFC7641B701CC600AD841F /* ASCenterLayoutSpec.mm in Sources */, 18C2ED831B9B7DE800F627B3 /* ASCollectionNode.mm in Sources */, E55D86331CA8A14000A0C26F /* ASLayoutElement.mm in Sources */, - 68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */, - CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.m in Sources */, - CCED5E3F2020D36800395C40 /* ASNetworkImageLoadInfo.m in Sources */, - 68B8A4E41CBDB958007E4543 /* ASWeakProxy.m in Sources */, + 68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.mm in Sources */, + CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.mm in Sources */, + CCED5E3F2020D36800395C40 /* ASNetworkImageLoadInfo.mm in Sources */, + 68B8A4E41CBDB958007E4543 /* ASWeakProxy.mm in Sources */, E5775B041F16759F00CAC9BC /* ASCollectionLayoutCache.mm in Sources */, 9C70F20A1CDBE949007D6C76 /* ASTableNode.mm in Sources */, 69CB62AE1CB8165900024920 /* _ASDisplayViewAccessiblity.mm in Sources */, B35061F61B010EFD0018CF92 /* ASCollectionView.mm in Sources */, - CCA282C51E9EAE630037E8B7 /* ASLayerBackingTipProvider.m in Sources */, - 509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.m in Sources */, + CCA282C51E9EAE630037E8B7 /* ASLayerBackingTipProvider.mm in Sources */, + 509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.mm in Sources */, B35061F91B010EFD0018CF92 /* ASControlNode.mm in Sources */, - 8021EC1F1D2B00B100799119 /* UIImage+ASConvenience.m in Sources */, - CCAA0B80206ADBF30057B336 /* ASRecursiveUnfairLock.m in Sources */, + 8021EC1F1D2B00B100799119 /* UIImage+ASConvenience.mm in Sources */, + CCAA0B80206ADBF30057B336 /* ASRecursiveUnfairLock.mm in Sources */, CCBDDD0620C62A2D00CBA922 /* ASMainThreadDeallocation.mm in Sources */, B35062181B010EFD0018CF92 /* ASDataController.mm in Sources */, - CCB1F95A1EFB60A5009C7475 /* ASLog.m in Sources */, - 767E7F8E1C90191D0066C000 /* AsyncDisplayKit+Debug.m in Sources */, - CCEDDDCB200C2AC300FFCD0A /* ASConfigurationInternal.m in Sources */, - CCCCCCD61EC3EF060087FE10 /* ASTextDebugOption.m in Sources */, + CCB1F95A1EFB60A5009C7475 /* ASLog.mm in Sources */, + 767E7F8E1C90191D0066C000 /* AsyncDisplayKit+Debug.mm in Sources */, + CCEDDDCB200C2AC300FFCD0A /* ASConfigurationInternal.mm in Sources */, + CCCCCCD61EC3EF060087FE10 /* ASTextDebugOption.mm in Sources */, 34EFC75C1B701BD200AD841F /* ASDimension.mm in Sources */, B350624E1B010EFD0018CF92 /* ASDisplayNode+AsyncDisplay.mm in Sources */, - E5667E8E1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.m in Sources */, - 25E327591C16819500A2170C /* ASPagerNode.m in Sources */, + E5667E8E1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.mm in Sources */, + 25E327591C16819500A2170C /* ASPagerNode.mm in Sources */, 636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.mm in Sources */, B35062501B010EFD0018CF92 /* ASDisplayNode+DebugTiming.mm in Sources */, - DEC146B91C37A16A004A0EE7 /* ASCollectionInternal.m in Sources */, 254C6B891BF94F8A003EC431 /* ASTextKitRenderer+Positioning.mm in Sources */, 68355B341CB579B9001D4E68 /* ASImageNode+AnimatedImage.mm in Sources */, E5711A301C840C96009619D4 /* ASCollectionElement.mm in Sources */, @@ -2402,94 +2431,93 @@ B35061FF1B010EFD0018CF92 /* ASDisplayNodeExtras.mm in Sources */, B35062011B010EFD0018CF92 /* ASEditableTextNode.mm in Sources */, 254C6B881BF94F8A003EC431 /* ASTextKitRenderer.mm in Sources */, - CC3B208C1C3F7A5400798563 /* ASWeakSet.m in Sources */, - B350621C1B010EFD0018CF92 /* ASTableLayoutController.m in Sources */, + CC3B208C1C3F7A5400798563 /* ASWeakSet.mm in Sources */, + B350621C1B010EFD0018CF92 /* ASTableLayoutController.mm in Sources */, B350621E1B010EFD0018CF92 /* ASHighlightOverlayLayer.mm in Sources */, - 9CC606651D24DF9E006581A0 /* NSIndexSet+ASHelpers.m in Sources */, - CC0F885F1E4280B800576FED /* _ASCollectionViewCell.m in Sources */, - CC2F65EF1E5FFB1600DA57C9 /* ASMutableElementMap.m in Sources */, - B35062541B010EFD0018CF92 /* ASImageNode+CGExtras.m in Sources */, + 9CC606651D24DF9E006581A0 /* NSIndexSet+ASHelpers.mm in Sources */, + CC0F885F1E4280B800576FED /* _ASCollectionViewCell.mm in Sources */, + CC2F65EF1E5FFB1600DA57C9 /* ASMutableElementMap.mm in Sources */, + B35062541B010EFD0018CF92 /* ASImageNode+CGExtras.mm in Sources */, E58E9E4A1E941DA5004CFC59 /* ASCollectionLayout.mm in Sources */, 6947B0C01E36B4E30007C478 /* ASStackUnpositionedLayout.mm in Sources */, - 68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */, - E5855DEF1EBB4D83003639AE /* ASCollectionLayoutDefines.m in Sources */, + 68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.mm in Sources */, + E5855DEF1EBB4D83003639AE /* ASCollectionLayoutDefines.mm in Sources */, B35062031B010EFD0018CF92 /* ASImageNode.mm in Sources */, - 690BC8C220F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m in Sources */, + 690BC8C220F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.mm in Sources */, 254C6B821BF94F8A003EC431 /* ASTextKitComponents.mm in Sources */, 34EFC7601B701C8B00AD841F /* ASInsetLayoutSpec.mm in Sources */, - AC6145441D8AFD4F003D62A2 /* ASSection.m in Sources */, + AC6145441D8AFD4F003D62A2 /* ASSection.mm in Sources */, E5775AFE1F13CF7400CAC9BC /* _ASCollectionGalleryLayoutItem.mm in Sources */, - 34EFC75E1B701BF000AD841F /* ASInternalHelpers.m in Sources */, + 34EFC75E1B701BF000AD841F /* ASInternalHelpers.mm in Sources */, 34EFC7681B701CDE00AD841F /* ASLayout.mm in Sources */, DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */, - CCCCCCE01EC3EF060087FE10 /* ASTextRunDelegate.m in Sources */, - CCCCCCDA1EC3EF060087FE10 /* ASTextLayout.m in Sources */, - CCEDDDD1200C488000FFCD0A /* ASConfiguration.m in Sources */, - 254C6B841BF94F8A003EC431 /* ASTextNodeWordKerner.m in Sources */, + CCCCCCE01EC3EF060087FE10 /* ASTextRunDelegate.mm in Sources */, + CCCCCCDA1EC3EF060087FE10 /* ASTextLayout.mm in Sources */, + CCEDDDD1200C488000FFCD0A /* ASConfiguration.mm in Sources */, + 254C6B841BF94F8A003EC431 /* ASTextNodeWordKerner.mm in Sources */, E5E2D7301EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm in Sources */, 34EFC76B1B701CEB00AD841F /* ASLayoutSpec.mm in Sources */, CC3B20861C3F76D600798563 /* ASPendingStateController.mm in Sources */, 254C6B8C1BF94F8A003EC431 /* ASTextKitTailTruncater.mm in Sources */, - 6907C25A1DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m in Sources */, + 6907C25A1DC4ECFE00374C66 /* ASObjectDescriptionHelpers.mm in Sources */, B35062051B010EFD0018CF92 /* ASMultiplexImageNode.mm in Sources */, - B35062251B010EFD0018CF92 /* ASMutableAttributedStringBuilder.m in Sources */, + B35062251B010EFD0018CF92 /* ASMutableAttributedStringBuilder.mm in Sources */, B35062071B010EFD0018CF92 /* ASNetworkImageNode.mm in Sources */, 34EFC76D1B701CF100AD841F /* ASOverlayLayoutSpec.mm in Sources */, - 044285101BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.m in Sources */, - CCCCCCDE1EC3EF060087FE10 /* ASTextAttribute.m in Sources */, - CCA282B51E9EA7310037E8B7 /* ASTipsController.m in Sources */, + 044285101BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.mm in Sources */, + CCCCCCDE1EC3EF060087FE10 /* ASTextAttribute.mm in Sources */, + CCA282B51E9EA7310037E8B7 /* ASTipsController.mm in Sources */, B35062271B010EFD0018CF92 /* ASRangeController.mm in Sources */, - 0442850A1BAA63FE00D16268 /* ASBatchFetching.m in Sources */, - CC35CEC420DD7F600006448D /* ASCollections.m in Sources */, - 68FC85E61CE29B9400EDD713 /* ASNavigationController.m in Sources */, - CC4C2A791D88E3BF0039ACAB /* ASTraceEvent.m in Sources */, + 0442850A1BAA63FE00D16268 /* ASBatchFetching.mm in Sources */, + CC35CEC420DD7F600006448D /* ASCollections.mm in Sources */, + 68FC85E61CE29B9400EDD713 /* ASNavigationController.mm in Sources */, + CC4C2A791D88E3BF0039ACAB /* ASTraceEvent.mm in Sources */, 34EFC76F1B701CF700AD841F /* ASRatioLayoutSpec.mm in Sources */, 254C6B8B1BF94F8A003EC431 /* ASTextKitShadower.mm in Sources */, 254C6B851BF94F8A003EC431 /* ASTextKitAttributes.mm in Sources */, 90FC784F1E4BFE1B00383C5A /* ASDisplayNode+Yoga.mm in Sources */, - CCA282C91E9EB64B0037E8B7 /* ASDisplayNodeTipState.m in Sources */, - 509E68601B3AED8E009B9150 /* ASScrollDirection.m in Sources */, + CCA282C91E9EB64B0037E8B7 /* ASDisplayNodeTipState.mm in Sources */, + 509E68601B3AED8E009B9150 /* ASScrollDirection.mm in Sources */, B35062091B010EFD0018CF92 /* ASScrollNode.mm in Sources */, 69BCE3D91EC6513B007DCCAD /* ASDisplayNode+Layout.mm in Sources */, 8BDA5FC81CDBDF95007D13B2 /* ASVideoPlayerNode.mm in Sources */, - E54E81FD1EB357BD00FFE8E1 /* ASPageTable.m in Sources */, + E54E81FD1EB357BD00FFE8E1 /* ASPageTable.mm in Sources */, 34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */, 7AB338661C55B3420055FDE8 /* ASRelativeLayoutSpec.mm in Sources */, - CC7AF198200DAB2200A21BDE /* ASExperimentalFeatures.m in Sources */, - E5B2252E1F17E521001E1431 /* ASDispatch.m in Sources */, + CC7AF198200DAB2200A21BDE /* ASExperimentalFeatures.mm in Sources */, + E5B2252E1F17E521001E1431 /* ASDispatch.mm in Sources */, 696F01EE1DD2AF450049FBD5 /* ASEventLog.mm in Sources */, - 9C70F2051CDA4F06007D6C76 /* ASTraitCollection.m in Sources */, - 83A7D95B1D44547700BF333E /* ASWeakMap.m in Sources */, - CC034A0A1E60BEB400626263 /* ASDisplayNode+Convenience.m in Sources */, - E58E9E431E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.m in Sources */, + 9C70F2051CDA4F06007D6C76 /* ASTraitCollection.mm in Sources */, + 83A7D95B1D44547700BF333E /* ASWeakMap.mm in Sources */, + CC034A0A1E60BEB400626263 /* ASDisplayNode+Convenience.mm in Sources */, + E58E9E431E941D74004CFC59 /* ASCollectionFlowLayoutDelegate.mm in Sources */, DE84918E1C8FFF9F003D89E9 /* ASRunLoopQueue.mm in Sources */, - 68FC85E51CE29B7E00EDD713 /* ASTabBarController.m in Sources */, - CCCCCCDC1EC3EF060087FE10 /* ASTextLine.m in Sources */, + 68FC85E51CE29B7E00EDD713 /* ASTabBarController.mm in Sources */, + CCCCCCDC1EC3EF060087FE10 /* ASTextLine.mm in Sources */, 34EFC7741B701D0A00AD841F /* ASAbsoluteLayoutSpec.mm in Sources */, 1A6C000E1FAB4E2100D05926 /* ASCornerLayoutSpec.mm in Sources */, - CCCCCCE81EC3F0FC0087FE10 /* NSAttributedString+ASText.m in Sources */, + CCCCCCE81EC3F0FC0087FE10 /* NSAttributedString+ASText.mm in Sources */, 690C35621E055C5D00069B91 /* ASDimensionInternal.mm in Sources */, 909C4C761F09C98B00D6B76F /* ASTextNode2.mm in Sources */, - 68C2155A1DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */, - DB78412E1C6BCE1600A9E2B4 /* _ASTransitionContext.m in Sources */, + 68C2155A1DE10D330019C4BC /* ASCollectionViewLayoutInspector.mm in Sources */, + DB78412E1C6BCE1600A9E2B4 /* _ASTransitionContext.mm in Sources */, B350620B1B010EFD0018CF92 /* ASTableView.mm in Sources */, B350620E1B010EFD0018CF92 /* ASTextNode.mm in Sources */, - 68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */, - CC034A141E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m in Sources */, - 509E68661B3AEDD7009B9150 /* CoreGraphics+ASConvenience.m in Sources */, - 254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.m in Sources */, - 34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */, - 254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */, - CCCCCCE21EC3EF060087FE10 /* ASTextUtilities.m in Sources */, - CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.m in Sources */, + 68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.mm in Sources */, + CC034A141E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.mm in Sources */, + 254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.mm in Sources */, + 34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.mm in Sources */, + 254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.mm in Sources */, + CCCCCCE21EC3EF060087FE10 /* ASTextUtilities.mm in Sources */, + CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.mm in Sources */, CC56013C1F06E9A700DC4FBE /* ASIntegerMap.mm in Sources */, 697796611D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */, - B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.m in Sources */, - CCA282CD1E9EB73E0037E8B7 /* ASTipNode.m in Sources */, - CC84C7F320474C5300A3851B /* ASCGImageBuffer.m in Sources */, - 044284FD1BAA365100D16268 /* UICollectionViewLayout+ASConvenience.m in Sources */, - CC0F885B1E42807F00576FED /* ASCollectionViewFlowLayoutInspector.m in Sources */, - 690ED5981E36D118000627C0 /* ASControlNode+tvOS.m in Sources */, + B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.mm in Sources */, + CCA282CD1E9EB73E0037E8B7 /* ASTipNode.mm in Sources */, + CC84C7F320474C5300A3851B /* ASCGImageBuffer.mm in Sources */, + 044284FD1BAA365100D16268 /* UICollectionViewLayout+ASConvenience.mm in Sources */, + CC0F885B1E42807F00576FED /* ASCollectionViewFlowLayoutInspector.mm in Sources */, + 690ED5981E36D118000627C0 /* ASControlNode+tvOS.mm in Sources */, 254C6B8A1BF94F8A003EC431 /* ASTextKitRenderer+TextChecking.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/CHANGELOG.md b/CHANGELOG.md index 479ed1cad0..1900518e64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,7 @@ - Correct linePositionModifier behavior [Michael Schneider](https://github.com/maicki)[#1192] (https://github.com/TextureGroup/Texture/pull/1192) - Tweak a11y label aggregation behavior to enable container label overrides [Michael Schneider](https://github.com/maicki)[#1199] (https://github.com/TextureGroup/Texture/pull/1199) - Fix logic cleaning data if delegate / dataSource changes and bring over logic to ASTableView [Michael Schneider](https://github.com/maicki)[#1200] (https://github.com/TextureGroup/Texture/pull/1200) +- Standardize the code base on Objective-C++. We will still not leak any C++ into public headers, however. [Adlai Holler](https://github.com/Adlai-Holler) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASCGImageBuffer.m b/Source/ASCGImageBuffer.mm similarity index 99% rename from Source/ASCGImageBuffer.m rename to Source/ASCGImageBuffer.mm index 5e0c3dc921..6f05300e23 100644 --- a/Source/ASCGImageBuffer.m +++ b/Source/ASCGImageBuffer.mm @@ -1,5 +1,5 @@ // -// ASCGImageBuffer.m +// ASCGImageBuffer.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/ASCollections.m b/Source/ASCollections.mm similarity index 96% rename from Source/ASCollections.m rename to Source/ASCollections.mm index 4428d07389..592dee2e88 100644 --- a/Source/ASCollections.m +++ b/Source/ASCollections.mm @@ -1,12 +1,12 @@ // -// ASCollections.m +// ASCollections.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASCollections.h" +#import /** * A private allocator that signals to our retain callback to skip the retain. diff --git a/Source/ASConfiguration.m b/Source/ASConfiguration.mm similarity index 98% rename from Source/ASConfiguration.m rename to Source/ASConfiguration.mm index 7923f5837c..a973e75007 100644 --- a/Source/ASConfiguration.m +++ b/Source/ASConfiguration.mm @@ -1,5 +1,5 @@ // -// ASConfiguration.m +// ASConfiguration.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/ASConfigurationInternal.m b/Source/ASConfigurationInternal.mm similarity index 99% rename from Source/ASConfigurationInternal.m rename to Source/ASConfigurationInternal.mm index 4fb9685ea8..fabbfbf3fb 100644 --- a/Source/ASConfigurationInternal.m +++ b/Source/ASConfigurationInternal.mm @@ -1,5 +1,5 @@ // -// ASConfigurationInternal.m +// ASConfigurationInternal.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/ASDisplayNode+Convenience.m b/Source/ASDisplayNode+Convenience.mm similarity index 96% rename from Source/ASDisplayNode+Convenience.m rename to Source/ASDisplayNode+Convenience.mm index c5d2c981ed..42ae4e4a72 100644 --- a/Source/ASDisplayNode+Convenience.m +++ b/Source/ASDisplayNode+Convenience.mm @@ -1,5 +1,5 @@ // -// ASDisplayNode+Convenience.m +// ASDisplayNode+Convenience.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/ASExperimentalFeatures.m b/Source/ASExperimentalFeatures.mm similarity index 98% rename from Source/ASExperimentalFeatures.m rename to Source/ASExperimentalFeatures.mm index 01eaad0e84..eaa24387fb 100644 --- a/Source/ASExperimentalFeatures.m +++ b/Source/ASExperimentalFeatures.mm @@ -1,5 +1,5 @@ // -// ASExperimentalFeatures.m +// ASExperimentalFeatures.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/ASNavigationController.m b/Source/ASNavigationController.mm similarity index 99% rename from Source/ASNavigationController.m rename to Source/ASNavigationController.mm index 51c097f0b0..0e4abc3393 100644 --- a/Source/ASNavigationController.m +++ b/Source/ASNavigationController.mm @@ -1,5 +1,5 @@ // -// ASNavigationController.m +// ASNavigationController.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/ASNetworkImageLoadInfo.m b/Source/ASNetworkImageLoadInfo.mm similarity index 95% rename from Source/ASNetworkImageLoadInfo.m rename to Source/ASNetworkImageLoadInfo.mm index f0f0554430..4c3d553e74 100644 --- a/Source/ASNetworkImageLoadInfo.m +++ b/Source/ASNetworkImageLoadInfo.mm @@ -1,5 +1,5 @@ // -// ASNetworkImageLoadInfo.m +// ASNetworkImageLoadInfo.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/ASPagerFlowLayout.m b/Source/ASPagerFlowLayout.mm similarity index 99% rename from Source/ASPagerFlowLayout.m rename to Source/ASPagerFlowLayout.mm index 0a6ad673da..301cea244b 100644 --- a/Source/ASPagerFlowLayout.m +++ b/Source/ASPagerFlowLayout.mm @@ -1,5 +1,5 @@ // -// ASPagerFlowLayout.m +// ASPagerFlowLayout.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/ASPagerNode.m b/Source/ASPagerNode.mm similarity index 99% rename from Source/ASPagerNode.m rename to Source/ASPagerNode.mm index c857ad3261..28de250dde 100644 --- a/Source/ASPagerNode.m +++ b/Source/ASPagerNode.mm @@ -1,5 +1,5 @@ // -// ASPagerNode.m +// ASPagerNode.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/ASTabBarController.m b/Source/ASTabBarController.mm similarity index 98% rename from Source/ASTabBarController.m rename to Source/ASTabBarController.mm index 67a9ad964d..18ed4b4315 100644 --- a/Source/ASTabBarController.m +++ b/Source/ASTabBarController.mm @@ -1,5 +1,5 @@ // -// ASTabBarController.m +// ASTabBarController.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/ASVideoPlayerNode.h b/Source/ASVideoPlayerNode.h index 8d4cf87bcb..07e613a608 100644 --- a/Source/ASVideoPlayerNode.h +++ b/Source/ASVideoPlayerNode.h @@ -216,4 +216,4 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END -#endif +#endif // TARGET_OS_IOS diff --git a/Source/ASVisibilityProtocols.m b/Source/ASVisibilityProtocols.mm similarity index 95% rename from Source/ASVisibilityProtocols.m rename to Source/ASVisibilityProtocols.mm index 9ee52c433f..b13a683bea 100644 --- a/Source/ASVisibilityProtocols.m +++ b/Source/ASVisibilityProtocols.mm @@ -1,5 +1,5 @@ // -// ASVisibilityProtocols.m +// ASVisibilityProtocols.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/AsyncDisplayKit+IGListKitMethods.m b/Source/AsyncDisplayKit+IGListKitMethods.mm similarity index 100% rename from Source/AsyncDisplayKit+IGListKitMethods.m rename to Source/AsyncDisplayKit+IGListKitMethods.mm diff --git a/Source/Base/ASAssert.m b/Source/Base/ASAssert.mm similarity index 82% rename from Source/Base/ASAssert.m rename to Source/Base/ASAssert.mm index 73bee34ea9..0e2fc9902c 100644 --- a/Source/Base/ASAssert.m +++ b/Source/Base/ASAssert.mm @@ -1,5 +1,5 @@ // -// ASAssert.m +// ASAssert.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. @@ -39,19 +39,19 @@ static pthread_key_t ASMainThreadAssertionsDisabledKey() { } BOOL ASMainThreadAssertionsAreDisabled() { - return (pthread_getspecific(ASMainThreadAssertionsDisabledKey()) > 0); + return (nullptr != pthread_getspecific(ASMainThreadAssertionsDisabledKey())); } void ASPushMainThreadAssertionsDisabled() { let key = ASMainThreadAssertionsDisabledKey(); - let oldVal = pthread_getspecific(key); - pthread_setspecific(key, oldVal + 1); + let oldVal = (intptr_t)pthread_getspecific(key); + pthread_setspecific(key, (void *)(oldVal + 1)); } void ASPopMainThreadAssertionsDisabled() { let key = ASMainThreadAssertionsDisabledKey(); - let oldVal = pthread_getspecific(key); - pthread_setspecific(key, oldVal - 1); + let oldVal = (intptr_t)pthread_getspecific(key); + pthread_setspecific(key, (void *)(oldVal - 1)); ASDisplayNodeCAssert(oldVal > 0, @"Attempt to pop thread assertion-disabling without corresponding push."); } diff --git a/Source/Base/ASBaseDefines.h b/Source/Base/ASBaseDefines.h index 959e15d839..39c82b6748 100644 --- a/Source/Base/ASBaseDefines.h +++ b/Source/Base/ASBaseDefines.h @@ -12,6 +12,7 @@ #define AS_EXTERN FOUNDATION_EXTERN #define unowned __unsafe_unretained +// TODO: Remove these now that we're all-C++. #if defined(__cplusplus) # define var auto # define let const auto diff --git a/Source/Base/ASDisplayNode+Ancestry.m b/Source/Base/ASDisplayNode+Ancestry.mm similarity index 98% rename from Source/Base/ASDisplayNode+Ancestry.m rename to Source/Base/ASDisplayNode+Ancestry.mm index 33b53b18fc..7003064c70 100644 --- a/Source/Base/ASDisplayNode+Ancestry.m +++ b/Source/Base/ASDisplayNode+Ancestry.mm @@ -1,5 +1,5 @@ // -// ASDisplayNode+Ancestry.m +// ASDisplayNode+Ancestry.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Base/ASLog.m b/Source/Base/ASLog.mm similarity index 99% rename from Source/Base/ASLog.m rename to Source/Base/ASLog.mm index 8dcd8a8f34..270246454b 100644 --- a/Source/Base/ASLog.m +++ b/Source/Base/ASLog.mm @@ -1,5 +1,5 @@ // -// ASLog.m +// ASLog.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Debug/AsyncDisplayKit+Debug.m b/Source/Debug/AsyncDisplayKit+Debug.mm similarity index 99% rename from Source/Debug/AsyncDisplayKit+Debug.m rename to Source/Debug/AsyncDisplayKit+Debug.mm index 50dc802400..e5e4e7d081 100644 --- a/Source/Debug/AsyncDisplayKit+Debug.m +++ b/Source/Debug/AsyncDisplayKit+Debug.mm @@ -1,5 +1,5 @@ // -// AsyncDisplayKit+Debug.m +// AsyncDisplayKit+Debug.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Debug/AsyncDisplayKit+Tips.m b/Source/Debug/AsyncDisplayKit+Tips.mm similarity index 93% rename from Source/Debug/AsyncDisplayKit+Tips.m rename to Source/Debug/AsyncDisplayKit+Tips.mm index 19a955b68c..f1a3ec8d72 100644 --- a/Source/Debug/AsyncDisplayKit+Tips.m +++ b/Source/Debug/AsyncDisplayKit+Tips.mm @@ -1,5 +1,5 @@ // -// AsyncDisplayKit+Tips.m +// AsyncDisplayKit+Tips.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "AsyncDisplayKit+Tips.h" +#import #import @implementation ASDisplayNode (Tips) diff --git a/Source/Details/ASBatchContext.m b/Source/Details/ASBatchContext.mm similarity index 98% rename from Source/Details/ASBatchContext.m rename to Source/Details/ASBatchContext.mm index c05f58f00c..2eadb8fc22 100644 --- a/Source/Details/ASBatchContext.m +++ b/Source/Details/ASBatchContext.mm @@ -1,5 +1,5 @@ // -// ASBatchContext.m +// ASBatchContext.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASCollectionFlowLayoutDelegate.m b/Source/Details/ASCollectionFlowLayoutDelegate.mm similarity index 98% rename from Source/Details/ASCollectionFlowLayoutDelegate.m rename to Source/Details/ASCollectionFlowLayoutDelegate.mm index 746875155a..7a2796ca95 100644 --- a/Source/Details/ASCollectionFlowLayoutDelegate.m +++ b/Source/Details/ASCollectionFlowLayoutDelegate.mm @@ -1,5 +1,5 @@ // -// ASCollectionFlowLayoutDelegate.m +// ASCollectionFlowLayoutDelegate.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASCollectionLayoutContext.m b/Source/Details/ASCollectionLayoutContext.mm similarity index 98% rename from Source/Details/ASCollectionLayoutContext.m rename to Source/Details/ASCollectionLayoutContext.mm index 1ee98e038e..350be998b2 100644 --- a/Source/Details/ASCollectionLayoutContext.m +++ b/Source/Details/ASCollectionLayoutContext.mm @@ -1,5 +1,5 @@ // -// ASCollectionLayoutContext.m +// ASCollectionLayoutContext.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Details/ASCollectionViewLayoutController.m b/Source/Details/ASCollectionViewLayoutController.mm similarity index 99% rename from Source/Details/ASCollectionViewLayoutController.m rename to Source/Details/ASCollectionViewLayoutController.mm index 275fd23f6b..497cae9fb4 100644 --- a/Source/Details/ASCollectionViewLayoutController.m +++ b/Source/Details/ASCollectionViewLayoutController.mm @@ -1,5 +1,5 @@ // -// ASCollectionViewLayoutController.m +// ASCollectionViewLayoutController.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASCollectionViewLayoutInspector.m b/Source/Details/ASCollectionViewLayoutInspector.mm similarity index 98% rename from Source/Details/ASCollectionViewLayoutInspector.m rename to Source/Details/ASCollectionViewLayoutInspector.mm index 2abab8de02..04880923ae 100644 --- a/Source/Details/ASCollectionViewLayoutInspector.m +++ b/Source/Details/ASCollectionViewLayoutInspector.mm @@ -1,5 +1,5 @@ // -// ASCollectionViewLayoutInspector.m +// ASCollectionViewLayoutInspector.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASDelegateProxy.m b/Source/Details/ASDelegateProxy.mm similarity index 99% rename from Source/Details/ASDelegateProxy.m rename to Source/Details/ASDelegateProxy.mm index ba60c23b6b..bc51bb3e36 100644 --- a/Source/Details/ASDelegateProxy.m +++ b/Source/Details/ASDelegateProxy.mm @@ -1,5 +1,5 @@ // -// ASDelegateProxy.m +// ASDelegateProxy.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASElementMap.m b/Source/Details/ASElementMap.mm similarity index 99% rename from Source/Details/ASElementMap.m rename to Source/Details/ASElementMap.mm index edd036b05e..791344f62f 100644 --- a/Source/Details/ASElementMap.m +++ b/Source/Details/ASElementMap.mm @@ -1,5 +1,5 @@ // -// ASElementMap.m +// ASElementMap.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASElementMap.h" +#import #import #import #import diff --git a/Source/Details/ASGraphicsContext.m b/Source/Details/ASGraphicsContext.mm similarity index 99% rename from Source/Details/ASGraphicsContext.m rename to Source/Details/ASGraphicsContext.mm index 26255a58ae..b950613d0d 100644 --- a/Source/Details/ASGraphicsContext.m +++ b/Source/Details/ASGraphicsContext.mm @@ -1,12 +1,12 @@ // -// ASGraphicsContext.m +// ASGraphicsContext.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASGraphicsContext.h" +#import #import #import #import diff --git a/Source/Details/ASHashing.m b/Source/Details/ASHashing.mm similarity index 98% rename from Source/Details/ASHashing.m rename to Source/Details/ASHashing.mm index 2863e2dc58..17bf66bd82 100644 --- a/Source/Details/ASHashing.m +++ b/Source/Details/ASHashing.mm @@ -1,5 +1,5 @@ // -// ASHashing.m +// ASHashing.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Details/ASImageContainerProtocolCategories.m b/Source/Details/ASImageContainerProtocolCategories.mm similarity index 93% rename from Source/Details/ASImageContainerProtocolCategories.m rename to Source/Details/ASImageContainerProtocolCategories.mm index 1df6a9111f..c9316c32ab 100644 --- a/Source/Details/ASImageContainerProtocolCategories.m +++ b/Source/Details/ASImageContainerProtocolCategories.mm @@ -1,5 +1,5 @@ // -// ASImageContainerProtocolCategories.m +// ASImageContainerProtocolCategories.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASMutableAttributedStringBuilder.m b/Source/Details/ASMutableAttributedStringBuilder.mm similarity index 99% rename from Source/Details/ASMutableAttributedStringBuilder.m rename to Source/Details/ASMutableAttributedStringBuilder.mm index 65a2333711..b393fe1118 100644 --- a/Source/Details/ASMutableAttributedStringBuilder.m +++ b/Source/Details/ASMutableAttributedStringBuilder.mm @@ -1,5 +1,5 @@ // -// ASMutableAttributedStringBuilder.m +// ASMutableAttributedStringBuilder.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASObjectDescriptionHelpers.m b/Source/Details/ASObjectDescriptionHelpers.mm similarity index 99% rename from Source/Details/ASObjectDescriptionHelpers.m rename to Source/Details/ASObjectDescriptionHelpers.mm index db69a7bf1b..cbd6be0963 100644 --- a/Source/Details/ASObjectDescriptionHelpers.m +++ b/Source/Details/ASObjectDescriptionHelpers.mm @@ -1,5 +1,5 @@ // -// ASObjectDescriptionHelpers.m +// ASObjectDescriptionHelpers.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASPINRemoteImageDownloader.m b/Source/Details/ASPINRemoteImageDownloader.mm similarity index 99% rename from Source/Details/ASPINRemoteImageDownloader.m rename to Source/Details/ASPINRemoteImageDownloader.mm index f405771206..9307ee5618 100644 --- a/Source/Details/ASPINRemoteImageDownloader.m +++ b/Source/Details/ASPINRemoteImageDownloader.mm @@ -1,5 +1,5 @@ // -// ASPINRemoteImageDownloader.m +// ASPINRemoteImageDownloader.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASPageTable.m b/Source/Details/ASPageTable.mm similarity index 99% rename from Source/Details/ASPageTable.m rename to Source/Details/ASPageTable.mm index 22a96870b2..13baa95fda 100644 --- a/Source/Details/ASPageTable.m +++ b/Source/Details/ASPageTable.mm @@ -1,5 +1,5 @@ // -// ASPageTable.m +// ASPageTable.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Details/ASPhotosFrameworkImageRequest.m b/Source/Details/ASPhotosFrameworkImageRequest.mm similarity index 99% rename from Source/Details/ASPhotosFrameworkImageRequest.m rename to Source/Details/ASPhotosFrameworkImageRequest.mm index 942000bb6f..a7e0b41655 100644 --- a/Source/Details/ASPhotosFrameworkImageRequest.m +++ b/Source/Details/ASPhotosFrameworkImageRequest.mm @@ -1,5 +1,5 @@ // -// ASPhotosFrameworkImageRequest.m +// ASPhotosFrameworkImageRequest.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASRecursiveUnfairLock.m b/Source/Details/ASRecursiveUnfairLock.mm similarity index 99% rename from Source/Details/ASRecursiveUnfairLock.m rename to Source/Details/ASRecursiveUnfairLock.mm index 1013095ae3..9e4a29d47a 100644 --- a/Source/Details/ASRecursiveUnfairLock.m +++ b/Source/Details/ASRecursiveUnfairLock.mm @@ -1,5 +1,5 @@ // -// ASRecursiveUnfairLock.m +// ASRecursiveUnfairLock.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Details/ASScrollDirection.m b/Source/Details/ASScrollDirection.mm similarity index 98% rename from Source/Details/ASScrollDirection.m rename to Source/Details/ASScrollDirection.mm index 4edc8ec259..3dff6ba9b8 100644 --- a/Source/Details/ASScrollDirection.m +++ b/Source/Details/ASScrollDirection.mm @@ -1,5 +1,5 @@ // -// ASScrollDirection.m +// ASScrollDirection.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASTableLayoutController.m b/Source/Details/ASTableLayoutController.mm similarity index 98% rename from Source/Details/ASTableLayoutController.m rename to Source/Details/ASTableLayoutController.mm index 3ca3adee72..46429ca269 100644 --- a/Source/Details/ASTableLayoutController.m +++ b/Source/Details/ASTableLayoutController.mm @@ -1,5 +1,5 @@ // -// ASTableLayoutController.m +// ASTableLayoutController.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASTraceEvent.m b/Source/Details/ASTraceEvent.mm similarity index 99% rename from Source/Details/ASTraceEvent.m rename to Source/Details/ASTraceEvent.mm index 0325fbf901..c809865591 100644 --- a/Source/Details/ASTraceEvent.m +++ b/Source/Details/ASTraceEvent.mm @@ -1,5 +1,5 @@ // -// ASTraceEvent.m +// ASTraceEvent.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASTraitCollection.m b/Source/Details/ASTraitCollection.mm similarity index 99% rename from Source/Details/ASTraitCollection.m rename to Source/Details/ASTraitCollection.mm index 56c29c5cbe..8e49221782 100644 --- a/Source/Details/ASTraitCollection.m +++ b/Source/Details/ASTraitCollection.mm @@ -1,5 +1,5 @@ // -// ASTraitCollection.m +// ASTraitCollection.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASWeakProxy.m b/Source/Details/ASWeakProxy.mm similarity index 99% rename from Source/Details/ASWeakProxy.m rename to Source/Details/ASWeakProxy.mm index cfcb1aca5c..4a73408dd5 100644 --- a/Source/Details/ASWeakProxy.m +++ b/Source/Details/ASWeakProxy.mm @@ -1,5 +1,5 @@ // -// ASWeakProxy.m +// ASWeakProxy.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/ASWeakSet.m b/Source/Details/ASWeakSet.mm similarity index 99% rename from Source/Details/ASWeakSet.m rename to Source/Details/ASWeakSet.mm index 7d05dbed6e..6530271a5a 100644 --- a/Source/Details/ASWeakSet.m +++ b/Source/Details/ASWeakSet.mm @@ -1,5 +1,5 @@ // -// ASWeakSet.m +// ASWeakSet.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/CoreGraphics+ASConvenience.m b/Source/Details/CoreGraphics+ASConvenience.m deleted file mode 100644 index 0f78cf1bee..0000000000 --- a/Source/Details/CoreGraphics+ASConvenience.m +++ /dev/null @@ -1,11 +0,0 @@ -// -// CoreGraphics+ASConvenience.m -// Texture -// -// 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 -// - -#import - diff --git a/Source/Details/NSIndexSet+ASHelpers.m b/Source/Details/NSIndexSet+ASHelpers.mm similarity index 98% rename from Source/Details/NSIndexSet+ASHelpers.m rename to Source/Details/NSIndexSet+ASHelpers.mm index c38cb4c1b5..0eba0358f4 100644 --- a/Source/Details/NSIndexSet+ASHelpers.m +++ b/Source/Details/NSIndexSet+ASHelpers.mm @@ -1,5 +1,5 @@ // -// NSIndexSet+ASHelpers.m +// NSIndexSet+ASHelpers.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/NSMutableAttributedString+TextKitAdditions.m b/Source/Details/NSMutableAttributedString+TextKitAdditions.mm similarity index 96% rename from Source/Details/NSMutableAttributedString+TextKitAdditions.m rename to Source/Details/NSMutableAttributedString+TextKitAdditions.mm index 85c59b2af4..3f2ed9d35c 100644 --- a/Source/Details/NSMutableAttributedString+TextKitAdditions.m +++ b/Source/Details/NSMutableAttributedString+TextKitAdditions.mm @@ -1,5 +1,5 @@ // -// NSMutableAttributedString+TextKitAdditions.m +// NSMutableAttributedString+TextKitAdditions.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/Transactions/_ASAsyncTransactionContainer.m b/Source/Details/Transactions/_ASAsyncTransactionContainer.mm similarity index 99% rename from Source/Details/Transactions/_ASAsyncTransactionContainer.m rename to Source/Details/Transactions/_ASAsyncTransactionContainer.mm index 4a77b06705..ed44231ce2 100644 --- a/Source/Details/Transactions/_ASAsyncTransactionContainer.m +++ b/Source/Details/Transactions/_ASAsyncTransactionContainer.mm @@ -1,5 +1,5 @@ // -// _ASAsyncTransactionContainer.m +// _ASAsyncTransactionContainer.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/Transactions/_ASAsyncTransactionGroup.m b/Source/Details/Transactions/_ASAsyncTransactionGroup.mm similarity index 99% rename from Source/Details/Transactions/_ASAsyncTransactionGroup.m rename to Source/Details/Transactions/_ASAsyncTransactionGroup.mm index f9b1b9e017..ae651d1870 100644 --- a/Source/Details/Transactions/_ASAsyncTransactionGroup.m +++ b/Source/Details/Transactions/_ASAsyncTransactionGroup.mm @@ -1,5 +1,5 @@ // -// _ASAsyncTransactionGroup.m +// _ASAsyncTransactionGroup.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/UICollectionViewLayout+ASConvenience.m b/Source/Details/UICollectionViewLayout+ASConvenience.mm similarity index 95% rename from Source/Details/UICollectionViewLayout+ASConvenience.m rename to Source/Details/UICollectionViewLayout+ASConvenience.mm index 16a5054820..b7564d0a52 100644 --- a/Source/Details/UICollectionViewLayout+ASConvenience.m +++ b/Source/Details/UICollectionViewLayout+ASConvenience.mm @@ -1,5 +1,5 @@ // -// UICollectionViewLayout+ASConvenience.m +// UICollectionViewLayout+ASConvenience.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Details/_ASCollectionReusableView.m b/Source/Details/_ASCollectionReusableView.mm similarity index 96% rename from Source/Details/_ASCollectionReusableView.m rename to Source/Details/_ASCollectionReusableView.mm index 2576edae36..0ca4b8115c 100644 --- a/Source/Details/_ASCollectionReusableView.m +++ b/Source/Details/_ASCollectionReusableView.mm @@ -1,5 +1,5 @@ // -// _ASCollectionReusableView.m +// _ASCollectionReusableView.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,8 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "_ASCollectionReusableView.h" +#import + #import #import diff --git a/Source/Details/_ASCollectionViewCell.m b/Source/Details/_ASCollectionViewCell.mm similarity index 97% rename from Source/Details/_ASCollectionViewCell.m rename to Source/Details/_ASCollectionViewCell.mm index 837069e1be..bd36d56bf1 100644 --- a/Source/Details/_ASCollectionViewCell.m +++ b/Source/Details/_ASCollectionViewCell.mm @@ -1,5 +1,5 @@ // -// _ASCollectionViewCell.m +// _ASCollectionViewCell.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,8 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "_ASCollectionViewCell.h" +#import + #import #import #import diff --git a/Source/IGListAdapter+AsyncDisplayKit.m b/Source/IGListAdapter+AsyncDisplayKit.mm similarity index 89% rename from Source/IGListAdapter+AsyncDisplayKit.m rename to Source/IGListAdapter+AsyncDisplayKit.mm index 757a96d560..ec085da68e 100644 --- a/Source/IGListAdapter+AsyncDisplayKit.m +++ b/Source/IGListAdapter+AsyncDisplayKit.mm @@ -1,5 +1,5 @@ // -// IGListAdapter+AsyncDisplayKit.m +// IGListAdapter+AsyncDisplayKit.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -11,9 +11,9 @@ #if AS_IG_LIST_KIT -#import "IGListAdapter+AsyncDisplayKit.h" -#import "ASIGListAdapterBasedDataSource.h" -#import "ASAssert.h" +#import +#import +#import #import @implementation IGListAdapter (AsyncDisplayKit) diff --git a/Source/Layout/ASAsciiArtBoxCreator.m b/Source/Layout/ASAsciiArtBoxCreator.mm similarity index 99% rename from Source/Layout/ASAsciiArtBoxCreator.m rename to Source/Layout/ASAsciiArtBoxCreator.mm index 5b2488648e..78eb572ead 100644 --- a/Source/Layout/ASAsciiArtBoxCreator.m +++ b/Source/Layout/ASAsciiArtBoxCreator.mm @@ -1,5 +1,5 @@ // -// ASAsciiArtBoxCreator.m +// ASAsciiArtBoxCreator.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -10,7 +10,7 @@ #import #import -#import +#import static const NSUInteger kDebugBoxPadding = 2; diff --git a/Source/Private/ASBatchFetching.m b/Source/Private/ASBatchFetching.mm similarity index 99% rename from Source/Private/ASBatchFetching.m rename to Source/Private/ASBatchFetching.mm index 9ca28cb752..cf3c100eaa 100644 --- a/Source/Private/ASBatchFetching.m +++ b/Source/Private/ASBatchFetching.mm @@ -1,5 +1,5 @@ // -// ASBatchFetching.m +// ASBatchFetching.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASCollectionLayoutDefines.m b/Source/Private/ASCollectionLayoutDefines.mm similarity index 95% rename from Source/Private/ASCollectionLayoutDefines.m rename to Source/Private/ASCollectionLayoutDefines.mm index 0087af536a..e386575c5d 100644 --- a/Source/Private/ASCollectionLayoutDefines.m +++ b/Source/Private/ASCollectionLayoutDefines.mm @@ -1,5 +1,5 @@ // -// ASCollectionLayoutDefines.m +// ASCollectionLayoutDefines.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Private/ASCollectionViewFlowLayoutInspector.m b/Source/Private/ASCollectionViewFlowLayoutInspector.mm similarity index 99% rename from Source/Private/ASCollectionViewFlowLayoutInspector.m rename to Source/Private/ASCollectionViewFlowLayoutInspector.mm index b36e188268..8ba41ae424 100644 --- a/Source/Private/ASCollectionViewFlowLayoutInspector.m +++ b/Source/Private/ASCollectionViewFlowLayoutInspector.mm @@ -1,5 +1,5 @@ // -// ASCollectionViewFlowLayoutInspector.m +// ASCollectionViewFlowLayoutInspector.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASControlTargetAction.m b/Source/Private/ASControlTargetAction.mm similarity index 97% rename from Source/Private/ASControlTargetAction.m rename to Source/Private/ASControlTargetAction.mm index ea822db2fc..41cc113314 100644 --- a/Source/Private/ASControlTargetAction.m +++ b/Source/Private/ASControlTargetAction.mm @@ -1,5 +1,5 @@ // -// ASControlTargetAction.m +// ASControlTargetAction.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASDefaultPlayButton.m b/Source/Private/ASDefaultPlayButton.mm similarity index 98% rename from Source/Private/ASDefaultPlayButton.m rename to Source/Private/ASDefaultPlayButton.mm index 133db9a7e2..589bda90c2 100644 --- a/Source/Private/ASDefaultPlayButton.m +++ b/Source/Private/ASDefaultPlayButton.mm @@ -1,5 +1,5 @@ // -// ASDefaultPlayButton.m +// ASDefaultPlayButton.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASDefaultPlaybackButton.m b/Source/Private/ASDefaultPlaybackButton.mm similarity index 98% rename from Source/Private/ASDefaultPlaybackButton.m rename to Source/Private/ASDefaultPlaybackButton.mm index ecc276069c..deda7e8716 100644 --- a/Source/Private/ASDefaultPlaybackButton.m +++ b/Source/Private/ASDefaultPlaybackButton.mm @@ -1,5 +1,5 @@ // -// ASDefaultPlaybackButton.m +// ASDefaultPlaybackButton.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASDispatch.m b/Source/Private/ASDispatch.mm similarity index 94% rename from Source/Private/ASDispatch.m rename to Source/Private/ASDispatch.mm index f73281dfda..5c713db802 100644 --- a/Source/Private/ASDispatch.m +++ b/Source/Private/ASDispatch.mm @@ -1,5 +1,5 @@ // -// ASDispatch.m +// ASDispatch.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. @@ -7,6 +7,8 @@ // #import + +// Prefer C atomics in this file because ObjC blocks can't capture C++ atomics well. #import /** diff --git a/Source/Private/ASDisplayNodeCornerLayerDelegate.m b/Source/Private/ASDisplayNodeCornerLayerDelegate.mm similarity index 91% rename from Source/Private/ASDisplayNodeCornerLayerDelegate.m rename to Source/Private/ASDisplayNodeCornerLayerDelegate.mm index 8973570224..42838baba1 100644 --- a/Source/Private/ASDisplayNodeCornerLayerDelegate.m +++ b/Source/Private/ASDisplayNodeCornerLayerDelegate.mm @@ -1,5 +1,5 @@ // -// ASDisplayNodeCornerLayerDelegate.m +// ASDisplayNodeCornerLayerDelegate.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASDisplayNodeTipState.m b/Source/Private/ASDisplayNodeTipState.mm similarity index 94% rename from Source/Private/ASDisplayNodeTipState.m rename to Source/Private/ASDisplayNodeTipState.mm index 8050d27346..b5a4231998 100644 --- a/Source/Private/ASDisplayNodeTipState.m +++ b/Source/Private/ASDisplayNodeTipState.mm @@ -1,5 +1,5 @@ // -// ASDisplayNodeTipState.m +// ASDisplayNodeTipState.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASIGListAdapterBasedDataSource.m b/Source/Private/ASIGListAdapterBasedDataSource.mm similarity index 99% rename from Source/Private/ASIGListAdapterBasedDataSource.m rename to Source/Private/ASIGListAdapterBasedDataSource.mm index a489acf950..1bbf65c895 100644 --- a/Source/Private/ASIGListAdapterBasedDataSource.m +++ b/Source/Private/ASIGListAdapterBasedDataSource.mm @@ -1,5 +1,5 @@ // -// ASIGListAdapterBasedDataSource.m +// ASIGListAdapterBasedDataSource.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASImageNode+CGExtras.m b/Source/Private/ASImageNode+CGExtras.mm similarity index 99% rename from Source/Private/ASImageNode+CGExtras.m rename to Source/Private/ASImageNode+CGExtras.mm index acbd6857e1..c4f9fdcbc9 100644 --- a/Source/Private/ASImageNode+CGExtras.m +++ b/Source/Private/ASImageNode+CGExtras.mm @@ -1,5 +1,5 @@ // -// ASImageNode+CGExtras.m +// ASImageNode+CGExtras.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -9,7 +9,7 @@ #import -#import +#import // TODO rewrite these to be closer to the intended use -- take UIViewContentMode as param, CGRect destinationBounds, CGSize sourceSize. static CGSize _ASSizeFillWithAspectRatio(CGFloat aspectRatio, CGSize constraints); diff --git a/Source/Private/ASInternalHelpers.m b/Source/Private/ASInternalHelpers.mm similarity index 99% rename from Source/Private/ASInternalHelpers.m rename to Source/Private/ASInternalHelpers.mm index 81d1aa9971..a9926ccca4 100644 --- a/Source/Private/ASInternalHelpers.m +++ b/Source/Private/ASInternalHelpers.mm @@ -1,5 +1,5 @@ // -// ASInternalHelpers.m +// ASInternalHelpers.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -12,7 +12,7 @@ #import #import -#import +#import #import #import diff --git a/Source/Private/ASLayerBackingTipProvider.m b/Source/Private/ASLayerBackingTipProvider.mm similarity index 97% rename from Source/Private/ASLayerBackingTipProvider.m rename to Source/Private/ASLayerBackingTipProvider.mm index 9a5932faa8..19d1850ab7 100644 --- a/Source/Private/ASLayerBackingTipProvider.m +++ b/Source/Private/ASLayerBackingTipProvider.mm @@ -1,5 +1,5 @@ // -// ASLayerBackingTipProvider.m +// ASLayerBackingTipProvider.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASMutableElementMap.m b/Source/Private/ASMutableElementMap.mm similarity index 98% rename from Source/Private/ASMutableElementMap.m rename to Source/Private/ASMutableElementMap.mm index 97cfe34d41..0ef1f0170e 100644 --- a/Source/Private/ASMutableElementMap.m +++ b/Source/Private/ASMutableElementMap.mm @@ -1,5 +1,5 @@ // -// ASMutableElementMap.m +// ASMutableElementMap.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASMutableElementMap.h" +#import #import #import diff --git a/Source/Private/ASResponderChainEnumerator.m b/Source/Private/ASResponderChainEnumerator.mm similarity index 91% rename from Source/Private/ASResponderChainEnumerator.m rename to Source/Private/ASResponderChainEnumerator.mm index a127c64c1e..bb16e0fc57 100644 --- a/Source/Private/ASResponderChainEnumerator.m +++ b/Source/Private/ASResponderChainEnumerator.mm @@ -1,5 +1,5 @@ // -// ASResponderChainEnumerator.m +// ASResponderChainEnumerator.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASResponderChainEnumerator.h" +#import #import @implementation ASResponderChainEnumerator { diff --git a/Source/Private/ASSection.m b/Source/Private/ASSection.mm similarity index 97% rename from Source/Private/ASSection.m rename to Source/Private/ASSection.mm index 68b4ced300..16fd73fe10 100644 --- a/Source/Private/ASSection.m +++ b/Source/Private/ASSection.mm @@ -1,5 +1,5 @@ // -// ASSection.m +// ASSection.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASTip.m b/Source/Private/ASTip.mm similarity index 94% rename from Source/Private/ASTip.m rename to Source/Private/ASTip.mm index fde1bbc587..af1d299221 100644 --- a/Source/Private/ASTip.m +++ b/Source/Private/ASTip.mm @@ -1,5 +1,5 @@ // -// ASTip.m +// ASTip.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASTip.h" +#import #if AS_ENABLE_TIPS diff --git a/Source/Private/ASTipNode.m b/Source/Private/ASTipNode.mm similarity index 97% rename from Source/Private/ASTipNode.m rename to Source/Private/ASTipNode.mm index a4fe4bf4e5..dcca908b8a 100644 --- a/Source/Private/ASTipNode.m +++ b/Source/Private/ASTipNode.mm @@ -1,5 +1,5 @@ // -// ASTipNode.m +// ASTipNode.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASTipProvider.m b/Source/Private/ASTipProvider.mm similarity index 93% rename from Source/Private/ASTipProvider.m rename to Source/Private/ASTipProvider.mm index 7787997376..237e83cda0 100644 --- a/Source/Private/ASTipProvider.m +++ b/Source/Private/ASTipProvider.mm @@ -1,5 +1,5 @@ // -// ASTipProvider.m +// ASTipProvider.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASTipProvider.h" +#import #if AS_ENABLE_TIPS diff --git a/Source/Private/ASTipsController.m b/Source/Private/ASTipsController.mm similarity index 98% rename from Source/Private/ASTipsController.m rename to Source/Private/ASTipsController.mm index d12b3189bf..acc592130c 100644 --- a/Source/Private/ASTipsController.m +++ b/Source/Private/ASTipsController.mm @@ -1,5 +1,5 @@ // -// ASTipsController.m +// ASTipsController.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASTipsController.h" +#import #if AS_ENABLE_TIPS diff --git a/Source/Private/ASTipsWindow.m b/Source/Private/ASTipsWindow.mm similarity index 97% rename from Source/Private/ASTipsWindow.m rename to Source/Private/ASTipsWindow.mm index a330fc7d59..010932613a 100644 --- a/Source/Private/ASTipsWindow.m +++ b/Source/Private/ASTipsWindow.mm @@ -1,5 +1,5 @@ // -// ASTipsWindow.m +// ASTipsWindow.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,7 +7,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASTipsWindow.h" +#import #if AS_ENABLE_TIPS #import diff --git a/Source/Private/ASTwoDimensionalArrayUtils.m b/Source/Private/ASTwoDimensionalArrayUtils.mm similarity index 99% rename from Source/Private/ASTwoDimensionalArrayUtils.m rename to Source/Private/ASTwoDimensionalArrayUtils.mm index c9c2b658d8..8b4836fe89 100644 --- a/Source/Private/ASTwoDimensionalArrayUtils.m +++ b/Source/Private/ASTwoDimensionalArrayUtils.mm @@ -1,5 +1,5 @@ // -// ASTwoDimensionalArrayUtils.m +// ASTwoDimensionalArrayUtils.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/ASWeakMap.m b/Source/Private/ASWeakMap.mm similarity index 99% rename from Source/Private/ASWeakMap.m rename to Source/Private/ASWeakMap.mm index 42f192f9c6..3110b13d37 100644 --- a/Source/Private/ASWeakMap.m +++ b/Source/Private/ASWeakMap.mm @@ -1,5 +1,5 @@ // -// ASWeakMap.m +// ASWeakMap.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/TextExperiment/Component/ASTextDebugOption.m b/Source/Private/TextExperiment/Component/ASTextDebugOption.mm similarity index 99% rename from Source/Private/TextExperiment/Component/ASTextDebugOption.m rename to Source/Private/TextExperiment/Component/ASTextDebugOption.mm index 6b74b0990b..2565b903c9 100644 --- a/Source/Private/TextExperiment/Component/ASTextDebugOption.m +++ b/Source/Private/TextExperiment/Component/ASTextDebugOption.mm @@ -1,5 +1,5 @@ // -// ASTextDebugOption.m +// ASTextDebugOption.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Private/TextExperiment/Component/ASTextInput.m b/Source/Private/TextExperiment/Component/ASTextInput.mm similarity index 99% rename from Source/Private/TextExperiment/Component/ASTextInput.m rename to Source/Private/TextExperiment/Component/ASTextInput.mm index 07bc6cb6d5..1cdfe73858 100644 --- a/Source/Private/TextExperiment/Component/ASTextInput.m +++ b/Source/Private/TextExperiment/Component/ASTextInput.mm @@ -1,5 +1,5 @@ // -// ASTextInput.m +// ASTextInput.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/TextExperiment/Component/ASTextLayout.m b/Source/Private/TextExperiment/Component/ASTextLayout.mm similarity index 99% rename from Source/Private/TextExperiment/Component/ASTextLayout.m rename to Source/Private/TextExperiment/Component/ASTextLayout.mm index 98de735a1b..ec029d62e5 100644 --- a/Source/Private/TextExperiment/Component/ASTextLayout.m +++ b/Source/Private/TextExperiment/Component/ASTextLayout.mm @@ -1,5 +1,5 @@ // -// ASTextLayout.m +// ASTextLayout.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/TextExperiment/Component/ASTextLine.m b/Source/Private/TextExperiment/Component/ASTextLine.mm similarity index 99% rename from Source/Private/TextExperiment/Component/ASTextLine.m rename to Source/Private/TextExperiment/Component/ASTextLine.mm index 672b18c7a9..a01311d83c 100644 --- a/Source/Private/TextExperiment/Component/ASTextLine.m +++ b/Source/Private/TextExperiment/Component/ASTextLine.mm @@ -1,5 +1,5 @@ // -// ASTextLine.m +// ASTextLine.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/TextExperiment/String/ASTextAttribute.m b/Source/Private/TextExperiment/String/ASTextAttribute.mm similarity index 99% rename from Source/Private/TextExperiment/String/ASTextAttribute.m rename to Source/Private/TextExperiment/String/ASTextAttribute.mm index fb4b01b6f2..d1abadbe1f 100644 --- a/Source/Private/TextExperiment/String/ASTextAttribute.m +++ b/Source/Private/TextExperiment/String/ASTextAttribute.mm @@ -1,5 +1,5 @@ // -// ASTextAttribute.m +// ASTextAttribute.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/Private/TextExperiment/String/ASTextRunDelegate.m b/Source/Private/TextExperiment/String/ASTextRunDelegate.mm similarity index 98% rename from Source/Private/TextExperiment/String/ASTextRunDelegate.m rename to Source/Private/TextExperiment/String/ASTextRunDelegate.mm index aa4154a91c..1c179b1fea 100644 --- a/Source/Private/TextExperiment/String/ASTextRunDelegate.m +++ b/Source/Private/TextExperiment/String/ASTextRunDelegate.mm @@ -1,5 +1,5 @@ // -// ASTextRunDelegate.m +// ASTextRunDelegate.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Private/TextExperiment/Utility/ASTextUtilities.m b/Source/Private/TextExperiment/Utility/ASTextUtilities.mm similarity index 99% rename from Source/Private/TextExperiment/Utility/ASTextUtilities.m rename to Source/Private/TextExperiment/Utility/ASTextUtilities.mm index 624f73e924..8d0137718b 100644 --- a/Source/Private/TextExperiment/Utility/ASTextUtilities.m +++ b/Source/Private/TextExperiment/Utility/ASTextUtilities.mm @@ -1,5 +1,5 @@ // -// ASTextUtilities.m +// ASTextUtilities.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.m b/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.mm similarity index 99% rename from Source/Private/TextExperiment/Utility/NSAttributedString+ASText.m rename to Source/Private/TextExperiment/Utility/NSAttributedString+ASText.mm index 134effc161..39f628151c 100644 --- a/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.m +++ b/Source/Private/TextExperiment/Utility/NSAttributedString+ASText.mm @@ -1,5 +1,5 @@ // -// NSAttributedString+ASText.m +// NSAttributedString+ASText.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.m b/Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.mm similarity index 99% rename from Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.m rename to Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.mm index 94680d3f00..bc19fd234c 100644 --- a/Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.m +++ b/Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.mm @@ -1,5 +1,5 @@ // -// NSParagraphStyle+ASText.m +// NSParagraphStyle+ASText.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/Private/_ASCollectionGalleryLayoutInfo.m b/Source/Private/_ASCollectionGalleryLayoutInfo.mm similarity index 97% rename from Source/Private/_ASCollectionGalleryLayoutInfo.m rename to Source/Private/_ASCollectionGalleryLayoutInfo.mm index 8cca556bac..fec0b52872 100644 --- a/Source/Private/_ASCollectionGalleryLayoutInfo.m +++ b/Source/Private/_ASCollectionGalleryLayoutInfo.mm @@ -1,5 +1,5 @@ // -// _ASCollectionGalleryLayoutInfo.m +// _ASCollectionGalleryLayoutInfo.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Source/TextKit/ASLayoutManager.m b/Source/TextKit/ASLayoutManager.mm similarity index 98% rename from Source/TextKit/ASLayoutManager.m rename to Source/TextKit/ASLayoutManager.mm index 08370a4bfb..fbb3b49ea4 100644 --- a/Source/TextKit/ASLayoutManager.m +++ b/Source/TextKit/ASLayoutManager.mm @@ -1,5 +1,5 @@ // -// ASLayoutManager.m +// ASLayoutManager.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/TextKit/ASTextKitCoreTextAdditions.m b/Source/TextKit/ASTextKitCoreTextAdditions.mm similarity index 99% rename from Source/TextKit/ASTextKitCoreTextAdditions.m rename to Source/TextKit/ASTextKitCoreTextAdditions.mm index 9b8de67a63..57a1a71e23 100644 --- a/Source/TextKit/ASTextKitCoreTextAdditions.m +++ b/Source/TextKit/ASTextKitCoreTextAdditions.mm @@ -1,5 +1,5 @@ // -// ASTextKitCoreTextAdditions.m +// ASTextKitCoreTextAdditions.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/TextKit/ASTextKitEntityAttribute.m b/Source/TextKit/ASTextKitEntityAttribute.mm similarity index 96% rename from Source/TextKit/ASTextKitEntityAttribute.m rename to Source/TextKit/ASTextKitEntityAttribute.mm index fde0621cf5..4f460dfb7b 100644 --- a/Source/TextKit/ASTextKitEntityAttribute.m +++ b/Source/TextKit/ASTextKitEntityAttribute.mm @@ -1,5 +1,5 @@ // -// ASTextKitEntityAttribute.m +// ASTextKitEntityAttribute.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/TextKit/ASTextNodeWordKerner.m b/Source/TextKit/ASTextNodeWordKerner.mm similarity index 99% rename from Source/TextKit/ASTextNodeWordKerner.m rename to Source/TextKit/ASTextNodeWordKerner.mm index fc577d51a4..67e640557c 100644 --- a/Source/TextKit/ASTextNodeWordKerner.m +++ b/Source/TextKit/ASTextNodeWordKerner.mm @@ -1,5 +1,5 @@ // -// ASTextNodeWordKerner.m +// ASTextNodeWordKerner.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/UIImage+ASConvenience.m b/Source/UIImage+ASConvenience.mm similarity index 99% rename from Source/UIImage+ASConvenience.m rename to Source/UIImage+ASConvenience.mm index 557049d311..936514cf14 100644 --- a/Source/UIImage+ASConvenience.m +++ b/Source/UIImage+ASConvenience.mm @@ -1,5 +1,5 @@ // -// UIImage+ASConvenience.m +// UIImage+ASConvenience.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/UIResponder+AsyncDisplayKit.m b/Source/UIResponder+AsyncDisplayKit.mm similarity index 100% rename from Source/UIResponder+AsyncDisplayKit.m rename to Source/UIResponder+AsyncDisplayKit.mm diff --git a/Source/_ASTransitionContext.m b/Source/_ASTransitionContext.mm similarity index 99% rename from Source/_ASTransitionContext.m rename to Source/_ASTransitionContext.mm index a75a3ca434..40a3573c15 100644 --- a/Source/_ASTransitionContext.m +++ b/Source/_ASTransitionContext.mm @@ -1,5 +1,5 @@ // -// _ASTransitionContext.m +// _ASTransitionContext.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/tvOS/ASControlNode+tvOS.m b/Source/tvOS/ASControlNode+tvOS.mm similarity index 99% rename from Source/tvOS/ASControlNode+tvOS.m rename to Source/tvOS/ASControlNode+tvOS.mm index 8a878eb235..a823d9625c 100644 --- a/Source/tvOS/ASControlNode+tvOS.m +++ b/Source/tvOS/ASControlNode+tvOS.mm @@ -1,5 +1,5 @@ // -// ASControlNode+tvOS.m +// ASControlNode+tvOS.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Source/tvOS/ASImageNode+tvOS.m b/Source/tvOS/ASImageNode+tvOS.mm similarity index 98% rename from Source/tvOS/ASImageNode+tvOS.m rename to Source/tvOS/ASImageNode+tvOS.mm index 1bd1ef4599..fa760f1291 100644 --- a/Source/tvOS/ASImageNode+tvOS.m +++ b/Source/tvOS/ASImageNode+tvOS.mm @@ -1,5 +1,5 @@ // -// ASImageNode+tvOS.m +// ASImageNode+tvOS.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -12,6 +12,7 @@ #import #import +// TODO: Remove this – we don't need to link GLKit just to convert degrees to radians. #import #import diff --git a/Tests/ASAbsoluteLayoutSpecSnapshotTests.m b/Tests/ASAbsoluteLayoutSpecSnapshotTests.mm similarity index 98% rename from Tests/ASAbsoluteLayoutSpecSnapshotTests.m rename to Tests/ASAbsoluteLayoutSpecSnapshotTests.mm index 2715872cdc..a1b9b94596 100644 --- a/Tests/ASAbsoluteLayoutSpecSnapshotTests.m +++ b/Tests/ASAbsoluteLayoutSpecSnapshotTests.mm @@ -1,5 +1,5 @@ // -// ASAbsoluteLayoutSpecSnapshotTests.m +// ASAbsoluteLayoutSpecSnapshotTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASBasicImageDownloaderContextTests.m b/Tests/ASBasicImageDownloaderContextTests.mm similarity index 98% rename from Tests/ASBasicImageDownloaderContextTests.m rename to Tests/ASBasicImageDownloaderContextTests.mm index 8414abf007..701174b7dd 100644 --- a/Tests/ASBasicImageDownloaderContextTests.m +++ b/Tests/ASBasicImageDownloaderContextTests.mm @@ -1,5 +1,5 @@ // -// ASBasicImageDownloaderContextTests.m +// ASBasicImageDownloaderContextTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASBasicImageDownloaderTests.m b/Tests/ASBasicImageDownloaderTests.mm similarity index 98% rename from Tests/ASBasicImageDownloaderTests.m rename to Tests/ASBasicImageDownloaderTests.mm index 5eb6da503b..8268dfcd64 100644 --- a/Tests/ASBasicImageDownloaderTests.m +++ b/Tests/ASBasicImageDownloaderTests.mm @@ -1,5 +1,5 @@ // -// ASBasicImageDownloaderTests.m +// ASBasicImageDownloaderTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASBatchFetchingTests.m b/Tests/ASBatchFetchingTests.mm similarity index 99% rename from Tests/ASBatchFetchingTests.m rename to Tests/ASBatchFetchingTests.mm index 76cc6455ba..99b67f05c0 100644 --- a/Tests/ASBatchFetchingTests.m +++ b/Tests/ASBatchFetchingTests.mm @@ -1,5 +1,5 @@ // -// ASBatchFetchingTests.m +// ASBatchFetchingTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASButtonNodeTests.m b/Tests/ASButtonNodeTests.mm similarity index 98% rename from Tests/ASButtonNodeTests.m rename to Tests/ASButtonNodeTests.mm index eb6249e451..244edd1f0e 100644 --- a/Tests/ASButtonNodeTests.m +++ b/Tests/ASButtonNodeTests.mm @@ -1,5 +1,5 @@ // -// ASButtonNodeTests.m +// ASButtonNodeTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASCALayerTests.m b/Tests/ASCALayerTests.mm similarity index 99% rename from Tests/ASCALayerTests.m rename to Tests/ASCALayerTests.mm index 3527a272bb..2b30da28fc 100644 --- a/Tests/ASCALayerTests.m +++ b/Tests/ASCALayerTests.mm @@ -1,5 +1,5 @@ // -// ASCALayerTests.m +// ASCALayerTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASCollectionModernDataSourceTests.m b/Tests/ASCollectionModernDataSourceTests.mm similarity index 99% rename from Tests/ASCollectionModernDataSourceTests.m rename to Tests/ASCollectionModernDataSourceTests.mm index d13db9e6cd..5d0a77899a 100644 --- a/Tests/ASCollectionModernDataSourceTests.m +++ b/Tests/ASCollectionModernDataSourceTests.mm @@ -1,5 +1,5 @@ // -// ASCollectionModernDataSourceTests.m +// ASCollectionModernDataSourceTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASCollectionViewFlowLayoutInspectorTests.m b/Tests/ASCollectionViewFlowLayoutInspectorTests.mm similarity index 99% rename from Tests/ASCollectionViewFlowLayoutInspectorTests.m rename to Tests/ASCollectionViewFlowLayoutInspectorTests.mm index c90270df08..555fe21134 100644 --- a/Tests/ASCollectionViewFlowLayoutInspectorTests.m +++ b/Tests/ASCollectionViewFlowLayoutInspectorTests.mm @@ -1,5 +1,5 @@ // -// ASCollectionViewFlowLayoutInspectorTests.m +// ASCollectionViewFlowLayoutInspectorTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASCollectionsTests.m b/Tests/ASCollectionsTests.mm similarity index 98% rename from Tests/ASCollectionsTests.m rename to Tests/ASCollectionsTests.mm index 348798e6d3..ae0313d78c 100644 --- a/Tests/ASCollectionsTests.m +++ b/Tests/ASCollectionsTests.mm @@ -1,5 +1,5 @@ // -// ASCollectionsTests.m +// ASCollectionsTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASConfigurationTests.m b/Tests/ASConfigurationTests.mm similarity index 100% rename from Tests/ASConfigurationTests.m rename to Tests/ASConfigurationTests.mm diff --git a/Tests/ASControlNodeTests.m b/Tests/ASControlNodeTests.mm similarity index 99% rename from Tests/ASControlNodeTests.m rename to Tests/ASControlNodeTests.mm index 95207ce9d6..e1c0150a0d 100644 --- a/Tests/ASControlNodeTests.m +++ b/Tests/ASControlNodeTests.mm @@ -1,5 +1,5 @@ // -// ASControlNodeTests.m +// ASControlNodeTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASDispatchTests.m b/Tests/ASDispatchTests.mm similarity index 98% rename from Tests/ASDispatchTests.m rename to Tests/ASDispatchTests.mm index 64c3412f35..a90bce7ed8 100644 --- a/Tests/ASDispatchTests.m +++ b/Tests/ASDispatchTests.mm @@ -1,5 +1,5 @@ // -// ASDispatchTests.m +// ASDispatchTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASDisplayLayerTests.m b/Tests/ASDisplayLayerTests.mm similarity index 96% rename from Tests/ASDisplayLayerTests.m rename to Tests/ASDisplayLayerTests.mm index b65dc3fc4a..2e03eb6da2 100644 --- a/Tests/ASDisplayLayerTests.m +++ b/Tests/ASDisplayLayerTests.mm @@ -1,5 +1,5 @@ // -// ASDisplayLayerTests.m +// ASDisplayLayerTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -285,7 +285,7 @@ static _ASDisplayLayerTestDelegateClassModes _class_modes; - (void)checkDelegateDisplay:(BOOL)displaysAsynchronously { [_ASDisplayLayerTestDelegate setClassModes:_ASDisplayLayerTestDelegateClassModeDisplay]; - _ASDisplayLayerTestDelegate *asyncDelegate = [[_ASDisplayLayerTestDelegate alloc] initWithModes:_ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters]; + _ASDisplayLayerTestDelegate *asyncDelegate = [[_ASDisplayLayerTestDelegate alloc] initWithModes:_ASDisplayLayerTestDelegateMode(_ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters)]; _ASDisplayLayerTestLayer *layer = (_ASDisplayLayerTestLayer *)asyncDelegate.layer; layer.displaysAsynchronously = displaysAsynchronously; @@ -329,7 +329,7 @@ static _ASDisplayLayerTestDelegateClassModes _class_modes; - (void)checkDelegateDrawInContext:(BOOL)displaysAsynchronously { [_ASDisplayLayerTestDelegate setClassModes:_ASDisplayLayerTestDelegateClassModeDrawInContext]; - _ASDisplayLayerTestDelegate *asyncDelegate = [[_ASDisplayLayerTestDelegate alloc] initWithModes:_ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters]; + _ASDisplayLayerTestDelegate *asyncDelegate = [[_ASDisplayLayerTestDelegate alloc] initWithModes:_ASDisplayLayerTestDelegateMode(_ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters)]; _ASDisplayLayerTestLayer *layer = (_ASDisplayLayerTestLayer *)asyncDelegate.layer; layer.displaysAsynchronously = displaysAsynchronously; @@ -375,8 +375,8 @@ static _ASDisplayLayerTestDelegateClassModes _class_modes; - (void)checkDelegateDisplayAndDrawInContext:(BOOL)displaysAsynchronously { - [_ASDisplayLayerTestDelegate setClassModes:_ASDisplayLayerTestDelegateClassModeDisplay | _ASDisplayLayerTestDelegateClassModeDrawInContext]; - _ASDisplayLayerTestDelegate *asyncDelegate = [[_ASDisplayLayerTestDelegate alloc] initWithModes:_ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters]; + [_ASDisplayLayerTestDelegate setClassModes:_ASDisplayLayerTestDelegateClassModes(_ASDisplayLayerTestDelegateClassModeDisplay | _ASDisplayLayerTestDelegateClassModeDrawInContext)]; + _ASDisplayLayerTestDelegate *asyncDelegate = [[_ASDisplayLayerTestDelegate alloc] initWithModes:_ASDisplayLayerTestDelegateMode(_ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters)]; _ASDisplayLayerTestLayer *layer = (_ASDisplayLayerTestLayer *)asyncDelegate.layer; layer.displaysAsynchronously = displaysAsynchronously; @@ -451,7 +451,7 @@ static _ASDisplayLayerTestDelegateClassModes _class_modes; - (void)DISABLED_testTransaction { - _ASDisplayLayerTestDelegateMode delegateModes = _ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters; + auto delegateModes = _ASDisplayLayerTestDelegateMode(_ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters); [_ASDisplayLayerTestDelegate setClassModes:_ASDisplayLayerTestDelegateClassModeDisplay]; // Setup @@ -533,7 +533,7 @@ static _ASDisplayLayerTestDelegateClassModes _class_modes; - (void)checkSuspendResume:(BOOL)displaysAsynchronously { [_ASDisplayLayerTestDelegate setClassModes:_ASDisplayLayerTestDelegateClassModeDrawInContext]; - _ASDisplayLayerTestDelegate *asyncDelegate = [[_ASDisplayLayerTestDelegate alloc] initWithModes:_ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters]; + _ASDisplayLayerTestDelegate *asyncDelegate = [[_ASDisplayLayerTestDelegate alloc] initWithModes:_ASDisplayLayerTestDelegateMode(_ASDisplayLayerTestDelegateModeDidDisplay | _ASDisplayLayerTestDelegateModeDrawParameters)]; _ASDisplayLayerTestLayer *layer = (_ASDisplayLayerTestLayer *)asyncDelegate.layer; layer.displaysAsynchronously = displaysAsynchronously; diff --git a/Tests/ASDisplayNodeAppearanceTests.m b/Tests/ASDisplayNodeAppearanceTests.mm similarity index 95% rename from Tests/ASDisplayNodeAppearanceTests.m rename to Tests/ASDisplayNodeAppearanceTests.mm index 70f9265da7..3b8c1e9df7 100644 --- a/Tests/ASDisplayNodeAppearanceTests.m +++ b/Tests/ASDisplayNodeAppearanceTests.mm @@ -1,5 +1,5 @@ // -// ASDisplayNodeAppearanceTests.m +// ASDisplayNodeAppearanceTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -19,26 +19,26 @@ #import // helper functions -IMP class_replaceMethodWithBlock(Class class, SEL originalSelector, id block); -IMP class_replaceMethodWithBlock(Class class, SEL originalSelector, id block) +IMP class_replaceMethodWithBlock(Class theClass, SEL originalSelector, id block); +IMP class_replaceMethodWithBlock(Class theClass, SEL originalSelector, id block) { IMP newImplementation = imp_implementationWithBlock(block); - Method method = class_getInstanceMethod(class, originalSelector); - return class_replaceMethod(class, originalSelector, newImplementation, method_getTypeEncoding(method)); + Method method = class_getInstanceMethod(theClass, originalSelector); + return class_replaceMethod(theClass, originalSelector, newImplementation, method_getTypeEncoding(method)); } -static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(Class class, SEL originalSelector, void (^block)(id)) +static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(Class theClass, SEL originalSelector, void (^block)(id)) { __block IMP originalImp = NULL; void (^blockActualSwizzle)(id) = ^(id swizzedSelf){ block(swizzedSelf); ((void(*)(id, SEL))originalImp)(swizzedSelf, originalSelector); }; - originalImp = class_replaceMethodWithBlock(class, originalSelector, blockActualSwizzle); + originalImp = class_replaceMethodWithBlock(theClass, originalSelector, blockActualSwizzle); void (^cleanupBlock)(void) = ^{ // restore original method - Method method = class_getInstanceMethod(class, originalSelector); - class_replaceMethod(class, originalSelector, originalImp, method_getTypeEncoding(method)); + Method method = class_getInstanceMethod(theClass, originalSelector); + class_replaceMethod(theClass, originalSelector, originalImp, method_getTypeEncoding(method)); }; return cleanupBlock; }; diff --git a/Tests/ASDisplayNodeExtrasTests.m b/Tests/ASDisplayNodeExtrasTests.mm similarity index 98% rename from Tests/ASDisplayNodeExtrasTests.m rename to Tests/ASDisplayNodeExtrasTests.mm index 8635118388..77d904c2e6 100644 --- a/Tests/ASDisplayNodeExtrasTests.m +++ b/Tests/ASDisplayNodeExtrasTests.mm @@ -1,5 +1,5 @@ // -// ASDisplayNodeExtrasTests.m +// ASDisplayNodeExtrasTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASDisplayNodeImplicitHierarchyTests.m b/Tests/ASDisplayNodeImplicitHierarchyTests.mm similarity index 99% rename from Tests/ASDisplayNodeImplicitHierarchyTests.m rename to Tests/ASDisplayNodeImplicitHierarchyTests.mm index d856002bed..ea41a322b3 100644 --- a/Tests/ASDisplayNodeImplicitHierarchyTests.m +++ b/Tests/ASDisplayNodeImplicitHierarchyTests.mm @@ -1,5 +1,5 @@ // -// ASDisplayNodeImplicitHierarchyTests.m +// ASDisplayNodeImplicitHierarchyTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -11,6 +11,7 @@ #import #import + #import "ASDisplayNodeTestsHelper.h" @interface ASSpecTestDisplayNode : ASDisplayNode diff --git a/Tests/ASDisplayNodeSnapshotTests.m b/Tests/ASDisplayNodeSnapshotTests.mm similarity index 96% rename from Tests/ASDisplayNodeSnapshotTests.m rename to Tests/ASDisplayNodeSnapshotTests.mm index 8d67e3cd08..489727e3ba 100644 --- a/Tests/ASDisplayNodeSnapshotTests.m +++ b/Tests/ASDisplayNodeSnapshotTests.mm @@ -1,5 +1,5 @@ // -// ASDisplayNodeSnapshotTests.m +// ASDisplayNodeSnapshotTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASDisplayNodeTestsHelper.m b/Tests/ASDisplayNodeTestsHelper.mm similarity index 98% rename from Tests/ASDisplayNodeTestsHelper.m rename to Tests/ASDisplayNodeTestsHelper.mm index 3d625414e5..bc145b924d 100644 --- a/Tests/ASDisplayNodeTestsHelper.m +++ b/Tests/ASDisplayNodeTestsHelper.mm @@ -1,5 +1,5 @@ // -// ASDisplayNodeTestsHelper.m +// ASDisplayNodeTestsHelper.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASEditableTextNodeTests.m b/Tests/ASEditableTextNodeTests.mm similarity index 99% rename from Tests/ASEditableTextNodeTests.m rename to Tests/ASEditableTextNodeTests.mm index a7bbad223a..a359629014 100644 --- a/Tests/ASEditableTextNodeTests.m +++ b/Tests/ASEditableTextNodeTests.mm @@ -1,5 +1,5 @@ // -// ASEditableTextNodeTests.m +// ASEditableTextNodeTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASImageNodeSnapshotTests.m b/Tests/ASImageNodeSnapshotTests.mm similarity index 98% rename from Tests/ASImageNodeSnapshotTests.m rename to Tests/ASImageNodeSnapshotTests.mm index f9c0ca71f9..55cb5f866e 100644 --- a/Tests/ASImageNodeSnapshotTests.m +++ b/Tests/ASImageNodeSnapshotTests.mm @@ -1,5 +1,5 @@ // -// ASImageNodeSnapshotTests.m +// ASImageNodeSnapshotTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASIntegerMapTests.m b/Tests/ASIntegerMapTests.mm similarity index 99% rename from Tests/ASIntegerMapTests.m rename to Tests/ASIntegerMapTests.mm index a79086a614..d23e5bf49f 100644 --- a/Tests/ASIntegerMapTests.m +++ b/Tests/ASIntegerMapTests.mm @@ -1,5 +1,5 @@ // -// ASIntegerMapTests.m +// ASIntegerMapTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASLayoutElementStyleTests.m b/Tests/ASLayoutElementStyleTests.mm similarity index 99% rename from Tests/ASLayoutElementStyleTests.m rename to Tests/ASLayoutElementStyleTests.mm index 4afd67ec4c..f6f95066e8 100644 --- a/Tests/ASLayoutElementStyleTests.m +++ b/Tests/ASLayoutElementStyleTests.mm @@ -1,5 +1,5 @@ // -// ASLayoutElementStyleTests.m +// ASLayoutElementStyleTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASLayoutFlatteningTests.m b/Tests/ASLayoutFlatteningTests.mm similarity index 99% rename from Tests/ASLayoutFlatteningTests.m rename to Tests/ASLayoutFlatteningTests.mm index fb9870c03d..0a1fa02261 100644 --- a/Tests/ASLayoutFlatteningTests.m +++ b/Tests/ASLayoutFlatteningTests.mm @@ -1,5 +1,5 @@ // -// ASLayoutFlatteningTests.m +// ASLayoutFlatteningTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASLayoutSpecSnapshotTestsHelper.m b/Tests/ASLayoutSpecSnapshotTestsHelper.mm similarity index 97% rename from Tests/ASLayoutSpecSnapshotTestsHelper.m rename to Tests/ASLayoutSpecSnapshotTestsHelper.mm index d7385cda95..dec82d4c39 100644 --- a/Tests/ASLayoutSpecSnapshotTestsHelper.m +++ b/Tests/ASLayoutSpecSnapshotTestsHelper.mm @@ -1,5 +1,5 @@ // -// ASLayoutSpecSnapshotTestsHelper.m +// ASLayoutSpecSnapshotTestsHelper.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASLayoutSpecTests.m b/Tests/ASLayoutSpecTests.mm similarity index 99% rename from Tests/ASLayoutSpecTests.m rename to Tests/ASLayoutSpecTests.mm index 257e645499..ff13b66553 100644 --- a/Tests/ASLayoutSpecTests.m +++ b/Tests/ASLayoutSpecTests.mm @@ -1,5 +1,5 @@ // -// ASLayoutSpecTests.m +// ASLayoutSpecTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASMultiplexImageNodeTests.m b/Tests/ASMultiplexImageNodeTests.mm similarity index 99% rename from Tests/ASMultiplexImageNodeTests.m rename to Tests/ASMultiplexImageNodeTests.mm index 56e3b11199..caf86bb48e 100644 --- a/Tests/ASMultiplexImageNodeTests.m +++ b/Tests/ASMultiplexImageNodeTests.mm @@ -1,5 +1,5 @@ // -// ASMultiplexImageNodeTests.m +// ASMultiplexImageNodeTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -100,10 +100,10 @@ // First expect to be hit for the image directly, and fail to return it. OCMExpect([mockDataSource multiplexImageNode:imageNode imageForImageIdentifier:imageIdentifier]) - .andReturn(nil); + .andReturn((id)nil); // BUG: -imageForImageIdentifier is called twice in this case (where we return nil). OCMExpect([mockDataSource multiplexImageNode:imageNode imageForImageIdentifier:imageIdentifier]) - .andReturn(nil); + .andReturn((id)nil); // Then expect to be hit for the URL, which we'll return. OCMExpect([mockDataSource multiplexImageNode:imageNode URLForImageIdentifier:imageIdentifier]) .andReturn([self _testImageURL]); diff --git a/Tests/ASMutableAttributedStringBuilderTests.m b/Tests/ASMutableAttributedStringBuilderTests.mm similarity index 98% rename from Tests/ASMutableAttributedStringBuilderTests.m rename to Tests/ASMutableAttributedStringBuilderTests.mm index 9999b6d4b4..2415dfc626 100644 --- a/Tests/ASMutableAttributedStringBuilderTests.m +++ b/Tests/ASMutableAttributedStringBuilderTests.mm @@ -1,5 +1,5 @@ // -// ASMutableAttributedStringBuilderTests.m +// ASMutableAttributedStringBuilderTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASNavigationControllerTests.m b/Tests/ASNavigationControllerTests.mm similarity index 98% rename from Tests/ASNavigationControllerTests.m rename to Tests/ASNavigationControllerTests.mm index b964029b83..0f42652b01 100644 --- a/Tests/ASNavigationControllerTests.m +++ b/Tests/ASNavigationControllerTests.mm @@ -1,5 +1,5 @@ // -// ASNavigationControllerTests.m +// ASNavigationControllerTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASNetworkImageNodeTests.m b/Tests/ASNetworkImageNodeTests.mm similarity index 99% rename from Tests/ASNetworkImageNodeTests.m rename to Tests/ASNetworkImageNodeTests.mm index 20026a995b..6b60030ff9 100644 --- a/Tests/ASNetworkImageNodeTests.m +++ b/Tests/ASNetworkImageNodeTests.mm @@ -1,5 +1,5 @@ // -// ASNetworkImageNodeTests.m +// ASNetworkImageNodeTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASPagerNodeTests.m b/Tests/ASPagerNodeTests.mm similarity index 99% rename from Tests/ASPagerNodeTests.m rename to Tests/ASPagerNodeTests.mm index 76ea96c53b..416efaae3d 100644 --- a/Tests/ASPagerNodeTests.m +++ b/Tests/ASPagerNodeTests.mm @@ -1,5 +1,5 @@ // -// ASPagerNodeTests.m +// ASPagerNodeTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASPerformanceTestContext.m b/Tests/ASPerformanceTestContext.mm similarity index 96% rename from Tests/ASPerformanceTestContext.m rename to Tests/ASPerformanceTestContext.mm index 6064a8af9c..15c6787596 100644 --- a/Tests/ASPerformanceTestContext.m +++ b/Tests/ASPerformanceTestContext.mm @@ -1,5 +1,5 @@ // -// ASPerformanceTestContext.m +// ASPerformanceTestContext.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,10 +7,13 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import #import "ASPerformanceTestContext.h" + #import +#import +#import + @interface ASPerformanceTestResult () @property (nonatomic) NSTimeInterval timePer1000; @property (nonatomic) NSString *caseName; @@ -54,6 +57,11 @@ return self; } +- (NSDictionary *)results +{ + return _results; +} + - (void)dealloc { /** diff --git a/Tests/ASPhotosFrameworkImageRequestTests.m b/Tests/ASPhotosFrameworkImageRequestTests.mm similarity index 97% rename from Tests/ASPhotosFrameworkImageRequestTests.m rename to Tests/ASPhotosFrameworkImageRequestTests.mm index dc753bb927..fe1cb408b4 100644 --- a/Tests/ASPhotosFrameworkImageRequestTests.m +++ b/Tests/ASPhotosFrameworkImageRequestTests.mm @@ -1,5 +1,5 @@ // -// ASPhotosFrameworkImageRequestTests.m +// ASPhotosFrameworkImageRequestTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASRecursiveUnfairLockTests.m b/Tests/ASRecursiveUnfairLockTests.mm similarity index 99% rename from Tests/ASRecursiveUnfairLockTests.m rename to Tests/ASRecursiveUnfairLockTests.mm index 38ba7d57d8..3916b319e3 100644 --- a/Tests/ASRecursiveUnfairLockTests.m +++ b/Tests/ASRecursiveUnfairLockTests.mm @@ -1,5 +1,5 @@ // -// ASRecursiveUnfairLockTests.m +// ASRecursiveUnfairLockTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASRunLoopQueueTests.m b/Tests/ASRunLoopQueueTests.mm similarity index 99% rename from Tests/ASRunLoopQueueTests.m rename to Tests/ASRunLoopQueueTests.mm index 89eff024fe..5cb88df8be 100644 --- a/Tests/ASRunLoopQueueTests.m +++ b/Tests/ASRunLoopQueueTests.mm @@ -1,5 +1,5 @@ // -// ASRunLoopQueueTests.m +// ASRunLoopQueueTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASScrollNodeTests.m b/Tests/ASScrollNodeTests.mm similarity index 99% rename from Tests/ASScrollNodeTests.m rename to Tests/ASScrollNodeTests.mm index 12c85262a8..a58f3f415f 100644 --- a/Tests/ASScrollNodeTests.m +++ b/Tests/ASScrollNodeTests.mm @@ -1,5 +1,5 @@ // -// ASScrollNodeTests.m +// ASScrollNodeTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASSnapshotTestCase.m b/Tests/ASSnapshotTestCase.mm similarity index 98% rename from Tests/ASSnapshotTestCase.m rename to Tests/ASSnapshotTestCase.mm index 9fc4e8fd09..560c25988e 100644 --- a/Tests/ASSnapshotTestCase.m +++ b/Tests/ASSnapshotTestCase.mm @@ -1,5 +1,5 @@ // -// ASSnapshotTestCase.m +// ASSnapshotTestCase.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASTabBarControllerTests.m b/Tests/ASTabBarControllerTests.mm similarity index 98% rename from Tests/ASTabBarControllerTests.m rename to Tests/ASTabBarControllerTests.mm index b933222c9f..affde932b6 100644 --- a/Tests/ASTabBarControllerTests.m +++ b/Tests/ASTabBarControllerTests.mm @@ -1,5 +1,5 @@ // -// ASTabBarControllerTests.m +// ASTabBarControllerTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASTableViewThrashTests.m b/Tests/ASTableViewThrashTests.mm similarity index 99% rename from Tests/ASTableViewThrashTests.m rename to Tests/ASTableViewThrashTests.mm index df17ca4ba7..dbf94ba2be 100644 --- a/Tests/ASTableViewThrashTests.m +++ b/Tests/ASTableViewThrashTests.mm @@ -1,5 +1,5 @@ // -// ASTableViewThrashTests.m +// ASTableViewThrashTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASTextKitCoreTextAdditionsTests.m b/Tests/ASTextKitCoreTextAdditionsTests.mm similarity index 98% rename from Tests/ASTextKitCoreTextAdditionsTests.m rename to Tests/ASTextKitCoreTextAdditionsTests.mm index 4a17e0660d..09114a4adb 100644 --- a/Tests/ASTextKitCoreTextAdditionsTests.m +++ b/Tests/ASTextKitCoreTextAdditionsTests.mm @@ -1,5 +1,5 @@ // -// ASTextKitCoreTextAdditionsTests.m +// ASTextKitCoreTextAdditionsTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASTextNode2SnapshotTests.m b/Tests/ASTextNode2SnapshotTests.mm similarity index 99% rename from Tests/ASTextNode2SnapshotTests.m rename to Tests/ASTextNode2SnapshotTests.mm index aba895c323..579ad067c9 100644 --- a/Tests/ASTextNode2SnapshotTests.m +++ b/Tests/ASTextNode2SnapshotTests.mm @@ -1,5 +1,5 @@ // -// ASTextNode2SnapshotTests.m +// ASTextNode2SnapshotTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASTextNode2Tests.m b/Tests/ASTextNode2Tests.mm similarity index 99% rename from Tests/ASTextNode2Tests.m rename to Tests/ASTextNode2Tests.mm index 74e9399dd2..2bc513af02 100644 --- a/Tests/ASTextNode2Tests.m +++ b/Tests/ASTextNode2Tests.mm @@ -1,5 +1,5 @@ // -// ASTextNode2Tests.m +// ASTextNode2Tests.mm // TextureTests // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASTextNodePerformanceTests.m b/Tests/ASTextNodePerformanceTests.mm similarity index 99% rename from Tests/ASTextNodePerformanceTests.m rename to Tests/ASTextNodePerformanceTests.mm index ac22bf5bb8..ed055a7b03 100644 --- a/Tests/ASTextNodePerformanceTests.m +++ b/Tests/ASTextNodePerformanceTests.mm @@ -1,5 +1,5 @@ // -// ASTextNodePerformanceTests.m +// ASTextNodePerformanceTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASTextNodeSnapshotTests.m b/Tests/ASTextNodeSnapshotTests.mm similarity index 99% rename from Tests/ASTextNodeSnapshotTests.m rename to Tests/ASTextNodeSnapshotTests.mm index 068c3896b3..1b21ac35f2 100644 --- a/Tests/ASTextNodeSnapshotTests.m +++ b/Tests/ASTextNodeSnapshotTests.mm @@ -1,5 +1,5 @@ // -// ASTextNodeSnapshotTests.m +// ASTextNodeSnapshotTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASTextNodeTests.m b/Tests/ASTextNodeTests.mm similarity index 99% rename from Tests/ASTextNodeTests.m rename to Tests/ASTextNodeTests.mm index 441ca8f103..5b23270b50 100644 --- a/Tests/ASTextNodeTests.m +++ b/Tests/ASTextNodeTests.mm @@ -1,5 +1,5 @@ // -// ASTextNodeTests.m +// ASTextNodeTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASTraitCollectionTests.m b/Tests/ASTraitCollectionTests.mm similarity index 96% rename from Tests/ASTraitCollectionTests.m rename to Tests/ASTraitCollectionTests.mm index ab201b16d4..e6141d6c3a 100644 --- a/Tests/ASTraitCollectionTests.m +++ b/Tests/ASTraitCollectionTests.mm @@ -1,5 +1,5 @@ // -// ASTraitCollectionTests.m +// ASTraitCollectionTests.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/ASUICollectionViewTests.m b/Tests/ASUICollectionViewTests.mm similarity index 83% rename from Tests/ASUICollectionViewTests.m rename to Tests/ASUICollectionViewTests.mm index 8d8a9b9d38..6f99590a84 100644 --- a/Tests/ASUICollectionViewTests.m +++ b/Tests/ASUICollectionViewTests.mm @@ -1,5 +1,5 @@ // -// ASUICollectionViewTests.m +// ASUICollectionViewTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -138,29 +138,4 @@ XCTAssertThrowsSpecificNamed([cv insertSections:[NSIndexSet indexSetWithIndex:0]], NSException, NSInternalInconsistencyException); } -// If you put reloadData in a batch update, collection view will ignore it and perform the normal -// update validation i.e. throw an exception if your data source counts changed. -- (void)testThatPuttingReloadDataInABatchUpdateDoesntWork -{ - UICollectionViewLayout *layout = [[UICollectionViewLayout alloc] init]; - UICollectionView *cv = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 100, 100) collectionViewLayout:layout]; - id dataSource = [OCMockObject niceMockForProtocol:@protocol(UICollectionViewDataSource)]; - // Start data source at 1 section, 1 item - [[[dataSource stub] andReturnValue:[NSNumber numberWithInteger:1]] numberOfSectionsInCollectionView:cv]; - [[[dataSource expect] andReturnValue:[NSNumber numberWithInteger:1]] collectionView:cv numberOfItemsInSection:0]; - - cv.dataSource = dataSource; - - // Verify initial data. - XCTAssertEqual([cv numberOfSections], 1); - XCTAssertEqual([cv numberOfItemsInSection:0], 1); - [dataSource verify]; - - XCTAssertThrows([cv performBatchUpdates:^{ - // Change data source to 1 section, 2 items - [[[dataSource stub] andReturnValue:[NSNumber numberWithInteger:2]] collectionView:cv numberOfItemsInSection:0]; - [cv reloadData]; - } completion:nil]); -} - @end diff --git a/Tests/ASVideoNodeTests.m b/Tests/ASVideoNodeTests.mm similarity index 99% rename from Tests/ASVideoNodeTests.m rename to Tests/ASVideoNodeTests.mm index 727d5666b8..81515312d9 100644 --- a/Tests/ASVideoNodeTests.m +++ b/Tests/ASVideoNodeTests.mm @@ -1,5 +1,5 @@ // -// ASVideoNodeTests.m +// ASVideoNodeTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASViewControllerTests.m b/Tests/ASViewControllerTests.mm similarity index 99% rename from Tests/ASViewControllerTests.m rename to Tests/ASViewControllerTests.mm index df050da613..881175d95d 100644 --- a/Tests/ASViewControllerTests.m +++ b/Tests/ASViewControllerTests.mm @@ -1,5 +1,5 @@ // -// ASViewControllerTests.m +// ASViewControllerTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASWeakMapTests.m b/Tests/ASWeakMapTests.mm similarity index 98% rename from Tests/ASWeakMapTests.m rename to Tests/ASWeakMapTests.mm index 4158f0e88c..fd0c0835be 100644 --- a/Tests/ASWeakMapTests.m +++ b/Tests/ASWeakMapTests.mm @@ -1,5 +1,5 @@ // -// ASWeakMapTests.m +// ASWeakMapTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ASWeakSetTests.m b/Tests/ASWeakSetTests.mm similarity index 99% rename from Tests/ASWeakSetTests.m rename to Tests/ASWeakSetTests.mm index 6f64372e3d..31af91de0f 100644 --- a/Tests/ASWeakSetTests.m +++ b/Tests/ASWeakSetTests.mm @@ -1,5 +1,5 @@ // -// ASWeakSetTests.m +// ASWeakSetTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/ArrayDiffingTests.m b/Tests/ArrayDiffingTests.mm similarity index 99% rename from Tests/ArrayDiffingTests.m rename to Tests/ArrayDiffingTests.mm index 45010ffc07..5151449d79 100644 --- a/Tests/ArrayDiffingTests.m +++ b/Tests/ArrayDiffingTests.mm @@ -1,5 +1,5 @@ // -// ArrayDiffingTests.m +// ArrayDiffingTests.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/Common/ASDisplayNode+OCMock.m b/Tests/Common/ASDisplayNode+OCMock.mm similarity index 94% rename from Tests/Common/ASDisplayNode+OCMock.m rename to Tests/Common/ASDisplayNode+OCMock.mm index 051ae9e807..8776fd7bde 100644 --- a/Tests/Common/ASDisplayNode+OCMock.m +++ b/Tests/Common/ASDisplayNode+OCMock.mm @@ -1,5 +1,5 @@ // -// ASDisplayNode+OCMock.m +// ASDisplayNode+OCMock.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/Common/ASTestCase.m b/Tests/Common/ASTestCase.mm similarity index 99% rename from Tests/Common/ASTestCase.m rename to Tests/Common/ASTestCase.mm index 7e9d20bf2f..30b42bde4c 100644 --- a/Tests/Common/ASTestCase.m +++ b/Tests/Common/ASTestCase.mm @@ -1,5 +1,5 @@ // -// ASTestCase.m +// ASTestCase.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Tests/Common/NSInvocation+ASTestHelpers.m b/Tests/Common/NSInvocation+ASTestHelpers.mm similarity index 95% rename from Tests/Common/NSInvocation+ASTestHelpers.m rename to Tests/Common/NSInvocation+ASTestHelpers.mm index 5fe505c1f7..dc5a4279f7 100644 --- a/Tests/Common/NSInvocation+ASTestHelpers.m +++ b/Tests/Common/NSInvocation+ASTestHelpers.mm @@ -1,5 +1,5 @@ // -// NSInvocation+ASTestHelpers.m +// NSInvocation+ASTestHelpers.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. diff --git a/Tests/Common/OCMockObject+ASAdditions.m b/Tests/Common/OCMockObject+ASAdditions.mm similarity index 95% rename from Tests/Common/OCMockObject+ASAdditions.m rename to Tests/Common/OCMockObject+ASAdditions.mm index 3ed0930244..e6d3f711d3 100644 --- a/Tests/Common/OCMockObject+ASAdditions.m +++ b/Tests/Common/OCMockObject+ASAdditions.mm @@ -1,5 +1,5 @@ // -// OCMockObject+ASAdditions.m +// OCMockObject+ASAdditions.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. @@ -26,8 +26,8 @@ { // [OCProtocolMockObject respondsToSelector:] <-> [(self) swizzled_protocolMockRespondsToSelector:] Method orig = class_getInstanceMethod(OCMockObject.protocolMockObjectClass, @selector(respondsToSelector:)); - Method new = class_getInstanceMethod(self, @selector(swizzled_protocolMockRespondsToSelector:)); - method_exchangeImplementations(orig, new); + Method newMethod = class_getInstanceMethod(self, @selector(swizzled_protocolMockRespondsToSelector:)); + method_exchangeImplementations(orig, newMethod); // init <-> swizzled_init { @@ -39,8 +39,8 @@ // (class mock) description <-> swizzled_classMockDescription { Method orig = class_getInstanceMethod(OCMockObject.classMockObjectClass, @selector(description)); - Method new = class_getInstanceMethod(self, @selector(swizzled_classMockDescription)); - method_exchangeImplementations(orig, new); + Method newMethod = class_getInstanceMethod(self, @selector(swizzled_classMockDescription)); + method_exchangeImplementations(orig, newMethod); } } diff --git a/Tests/TestHost/AppDelegate.m b/Tests/TestHost/AppDelegate.m deleted file mode 100644 index bf5baf6f9e..0000000000 --- a/Tests/TestHost/AppDelegate.m +++ /dev/null @@ -1,21 +0,0 @@ -// -// AppDelegate.m -// Texture -// -// 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 -// - -#import "AppDelegate.h" -#import -#import - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - return YES; -} - -@end diff --git a/Source/Details/ASCollectionInternal.m b/Tests/TestHost/AppDelegate.mm similarity index 76% rename from Source/Details/ASCollectionInternal.m rename to Tests/TestHost/AppDelegate.mm index 0d50fe3463..91dc913326 100644 --- a/Source/Details/ASCollectionInternal.m +++ b/Tests/TestHost/AppDelegate.mm @@ -1,5 +1,5 @@ // -// ASCollectionInternal.m +// AppDelegate.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,3 +7,8 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // +#import "AppDelegate.h" + +@implementation AppDelegate + +@end diff --git a/Tests/TestHost/main.m b/Tests/TestHost/main.mm similarity index 97% rename from Tests/TestHost/main.m rename to Tests/TestHost/main.mm index 65850400e4..50a9e3ad6a 100644 --- a/Tests/TestHost/main.m +++ b/Tests/TestHost/main.mm @@ -1,5 +1,5 @@ // -// main.m +// main.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. diff --git a/Texture.podspec b/Texture.podspec index c64e8df22c..66a814c824 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -16,6 +16,10 @@ Pod::Spec.new do |spec| # Subspecs spec.subspec 'Core' do |core| + + # These will be lowered into subspecs in the future. Only here for ASVideoNode. + core.frameworks = ['AVFoundation', 'CoreMedia'] + core.compiler_flags = '-fno-exceptions' core.public_header_files = [ 'Source/*.h', @@ -28,8 +32,7 @@ Pod::Spec.new do |spec| ] core.source_files = [ - 'Source/**/*.{h,m,mm}', - 'Base/*.{h,m}', + 'Source/**/*.{h,mm}', # Most TextKit components are not public because the C++ content # in the headers will cause build errors when using @@ -57,7 +60,7 @@ Pod::Spec.new do |spec| end spec.subspec 'MapKit' do |map| - map.frameworks = 'MapKit' + map.frameworks = ['CoreLocation', 'MapKit'] map.xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) AS_USE_MAPKIT=1' } map.dependency 'Texture/Core' end From 706396f7d15bc38351676f4ed228e3e0fbab79f6 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Fri, 2 Nov 2018 14:04:41 -0700 Subject: [PATCH 42/60] Delete circle config from master now that I know how to get it to build my experimental branch --- .circleci/config.yml | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 1f2c6702b9..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,22 +0,0 @@ -# iOS CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/ios-migrating-from-1-2/ for more details -# -version: 2 -jobs: - build: - - # Limit to Testing branch - branches: - only: - - AHCircleCI - - # Specify the Xcode version to use - macos: - xcode: "9.4.1" - - steps: - - checkout - - run: - name: Build.sh all - command: ./build.sh all From ecfc7835da1066c5fd624e49d56087d288370742 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Sat, 3 Nov 2018 09:44:42 -0700 Subject: [PATCH 43/60] Add experiment flag to skip layoutIfNeeded in enterPreloadState for ASM nodes (#1201) --- Source/ASDisplayNode.mm | 3 ++- Source/ASExperimentalFeatures.h | 1 + Source/ASExperimentalFeatures.mm | 3 ++- Tests/ASConfigurationTests.mm | 40 +++++++++++++++++--------------- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 75604bc995..9047d7311f 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -3377,7 +3377,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { // - If it doesn't have a calculated or pending layout that fits its current bounds, a measurement pass will occur // (see -__layout and -_u_measureNodeWithBoundsIfNecessary:). This scenario is uncommon, // and running a measurement pass here is a fine trade-off because preloading any time after this point would be late. - if (self.automaticallyManagesSubnodes) { + + if (self.automaticallyManagesSubnodes && !ASActivateExperimentalFeature(ASExperimentalDidEnterPreloadSkipASMLayout)) { [self layoutIfNeeded]; } [self enumerateInterfaceStateDelegates:^(id del) { diff --git a/Source/ASExperimentalFeatures.h b/Source/ASExperimentalFeatures.h index 626975636c..b51523e1d8 100644 --- a/Source/ASExperimentalFeatures.h +++ b/Source/ASExperimentalFeatures.h @@ -24,6 +24,7 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { ASExperimentalCollectionTeardown = 1 << 6, // exp_collection_teardown ASExperimentalFramesetterCache = 1 << 7, // exp_framesetter_cache ASExperimentalClearDataDuringDeallocation = 1 << 8, // exp_clear_data_during_deallocation + ASExperimentalDidEnterPreloadSkipASMLayout = 1 << 9, // exp_did_enter_preload_skip_asm_layout ASExperimentalFeatureAll = 0xFFFFFFFF }; diff --git a/Source/ASExperimentalFeatures.mm b/Source/ASExperimentalFeatures.mm index eaa24387fb..68a6871f04 100644 --- a/Source/ASExperimentalFeatures.mm +++ b/Source/ASExperimentalFeatures.mm @@ -20,7 +20,8 @@ NSArray *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags @"exp_network_image_queue", @"exp_collection_teardown", @"exp_framesetter_cache", - @"exp_clear_data_during_deallocation"])); + @"exp_clear_data_during_deallocation", + @"exp_did_enter_preload_skip_asm_layout"])); if (flags == ASExperimentalFeatureAll) { return allNames; diff --git a/Tests/ASConfigurationTests.mm b/Tests/ASConfigurationTests.mm index d2f2b5a6cd..a563b92049 100644 --- a/Tests/ASConfigurationTests.mm +++ b/Tests/ASConfigurationTests.mm @@ -13,15 +13,16 @@ #import "ASConfigurationInternal.h" static ASExperimentalFeatures features[] = { - ASExperimentalGraphicsContexts, - ASExperimentalTextNode, - ASExperimentalInterfaceStateCoalescing, - ASExperimentalUnfairLock, - ASExperimentalLayerDefaults, - ASExperimentalNetworkImageQueue, - ASExperimentalCollectionTeardown, - ASExperimentalFramesetterCache, - ASExperimentalClearDataDuringDeallocation + ASExperimentalGraphicsContexts, + ASExperimentalTextNode, + ASExperimentalInterfaceStateCoalescing, + ASExperimentalUnfairLock, + ASExperimentalLayerDefaults, + ASExperimentalNetworkImageQueue, + ASExperimentalCollectionTeardown, + ASExperimentalFramesetterCache, + ASExperimentalClearDataDuringDeallocation, + ASExperimentalDidEnterPreloadSkipASMLayout }; @interface ASConfigurationTests : ASTestCase @@ -34,16 +35,17 @@ static ASExperimentalFeatures features[] = { + (NSArray *)names { return @[ - @"exp_graphics_contexts", - @"exp_text_node", - @"exp_interface_state_coalesce", - @"exp_unfair_lock", - @"exp_infer_layer_defaults", - @"exp_network_image_queue", - @"exp_collection_teardown", - @"exp_framesetter_cache", - @"exp_clear_data_during_deallocation" - ]; + @"exp_graphics_contexts", + @"exp_text_node", + @"exp_interface_state_coalesce", + @"exp_unfair_lock", + @"exp_infer_layer_defaults", + @"exp_network_image_queue", + @"exp_collection_teardown", + @"exp_framesetter_cache", + @"exp_clear_data_during_deallocation", + @"exp_did_enter_preload_skip_asm_layout", + ]; } - (ASExperimentalFeatures)allFeatures { From a34f45355e6017f871491efecf00f43e44967deb Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Sat, 3 Nov 2018 12:32:15 -0700 Subject: [PATCH 44/60] Revert #1023 (#1204) We will revert #1023. The current solution introduces problems if we are unlocking before calling _completePendingLayoutTransition. _completePendingLayoutTransition needs to be happening in one transaction if called from _u_measureNodeWithBoundsIfNecessary. --- Source/ASDisplayNode+Layout.mm | 248 ++++++++++++++++----------------- Source/ASDisplayNode.mm | 21 ++- 2 files changed, 134 insertions(+), 135 deletions(-) diff --git a/Source/ASDisplayNode+Layout.mm b/Source/ASDisplayNode+Layout.mm index 205d8b1ffd..f11dc1283f 100644 --- a/Source/ASDisplayNode+Layout.mm +++ b/Source/ASDisplayNode+Layout.mm @@ -296,125 +296,121 @@ ASLayoutElementStyleExtensibilityForwarding { ASAssertUnlocked(__instanceLock__); - BOOL isInLayoutPendingState = NO; - { - ASDN::MutexLocker l(__instanceLock__); - // Check if we are a subnode in a layout transition. - // In this case no measurement is needed as it's part of the layout transition - if ([self _locked_isLayoutTransitionInvalid]) { - return; - } - - CGSize boundsSizeForLayout = ASCeilSizeValues(bounds.size); - - // Prefer a newer and not yet applied _pendingDisplayNodeLayout over _calculatedDisplayNodeLayout - // If there is no such _pending, check if _calculated is valid to reuse (avoiding recalculation below). - BOOL pendingLayoutIsPreferred = NO; - if (_pendingDisplayNodeLayout.isValid(_layoutVersion)) { - NSUInteger calculatedVersion = _calculatedDisplayNodeLayout.version; - NSUInteger pendingVersion = _pendingDisplayNodeLayout.version; - if (pendingVersion > calculatedVersion) { - pendingLayoutIsPreferred = YES; // Newer _pending - } else if (pendingVersion == calculatedVersion - && !ASSizeRangeEqualToSizeRange(_pendingDisplayNodeLayout.constrainedSize, - _calculatedDisplayNodeLayout.constrainedSize)) { - pendingLayoutIsPreferred = YES; // _pending with a different constrained size - } - } - BOOL calculatedLayoutIsReusable = (_calculatedDisplayNodeLayout.isValid(_layoutVersion) - && (_calculatedDisplayNodeLayout.requestedLayoutFromAbove - || CGSizeEqualToSize(_calculatedDisplayNodeLayout.layout.size, boundsSizeForLayout))); - if (!pendingLayoutIsPreferred && calculatedLayoutIsReusable) { - return; - } - - as_activity_create_for_scope("Update node layout for current bounds"); - as_log_verbose(ASLayoutLog(), "Node %@, bounds size %@, calculatedSize %@, calculatedIsDirty %d", - self, - NSStringFromCGSize(boundsSizeForLayout), - NSStringFromCGSize(_calculatedDisplayNodeLayout->layout.size), - _calculatedDisplayNodeLayout->version < _layoutVersion); - // _calculatedDisplayNodeLayout is not reusable we need to transition to a new one - [self cancelLayoutTransition]; - - BOOL didCreateNewContext = NO; - ASLayoutElementContext *context = ASLayoutElementGetCurrentContext(); - if (context == nil) { - context = [[ASLayoutElementContext alloc] init]; - ASLayoutElementPushContext(context); - didCreateNewContext = YES; - } - - // Figure out previous and pending layouts for layout transition - ASDisplayNodeLayout nextLayout = _pendingDisplayNodeLayout; - #define layoutSizeDifferentFromBounds !CGSizeEqualToSize(nextLayout.layout.size, boundsSizeForLayout) - - // nextLayout was likely created by a call to layoutThatFits:, check if it is valid and can be applied. - // If our bounds size is different than it, or invalid, recalculate. Use #define to avoid nullptr-> - BOOL pendingLayoutApplicable = NO; - if (nextLayout.layout == nil) { - as_log_verbose(ASLayoutLog(), "No pending layout."); - } else if (!nextLayout.isValid(_layoutVersion)) { - as_log_verbose(ASLayoutLog(), "Pending layout is stale."); - } else if (layoutSizeDifferentFromBounds) { - as_log_verbose(ASLayoutLog(), "Pending layout size %@ doesn't match bounds size.", NSStringFromCGSize(nextLayout->layout.size)); - } else { - as_log_verbose(ASLayoutLog(), "Using pending layout %@.", nextLayout->layout); - pendingLayoutApplicable = YES; - } - - if (!pendingLayoutApplicable) { - as_log_verbose(ASLayoutLog(), "Measuring with previous constrained size."); - // Use the last known constrainedSize passed from a parent during layout (if never, use bounds). - NSUInteger version = _layoutVersion; - ASSizeRange constrainedSize = [self _locked_constrainedSizeForLayoutPass]; - ASLayout *layout = [self calculateLayoutThatFits:constrainedSize - restrictedToSize:self.style.size - relativeToParentSize:boundsSizeForLayout]; - nextLayout = ASDisplayNodeLayout(layout, constrainedSize, boundsSizeForLayout, version); - // Now that the constrained size of pending layout might have been reused, the layout is useless - // Release it and any orphaned subnodes it retains - _pendingDisplayNodeLayout.layout = nil; - } - - if (didCreateNewContext) { - ASLayoutElementPopContext(); - } - - // If our new layout's desired size for self doesn't match current size, ask our parent to update it. - // This can occur for either pre-calculated or newly-calculated layouts. - if (nextLayout.requestedLayoutFromAbove == NO - && CGSizeEqualToSize(boundsSizeForLayout, nextLayout.layout.size) == NO) { - as_log_verbose(ASLayoutLog(), "Layout size doesn't match bounds size. Requesting layout from above."); - // The layout that we have specifies that this node (self) would like to be a different size - // than it currently is. Because that size has been computed within the constrainedSize, we - // expect that calling setNeedsLayoutFromAbove will result in our parent resizing us to this. - // However, in some cases apps may manually interfere with this (setting a different bounds). - // In this case, we need to detect that we've already asked to be resized to match this - // particular ASLayout object, and shouldn't loop asking again unless we have a different ASLayout. - nextLayout.requestedLayoutFromAbove = YES; - - { - __instanceLock__.unlock(); - [self _u_setNeedsLayoutFromAbove]; - __instanceLock__.lock(); - } - - // Update the layout's version here because _u_setNeedsLayoutFromAbove calls __setNeedsLayout which in turn increases _layoutVersion - // Failing to do this will cause the layout to be invalid immediately - nextLayout.version = _layoutVersion; - } - - // Prepare to transition to nextLayout - ASDisplayNodeAssertNotNil(nextLayout.layout, @"nextLayout->layout should not be nil! %@", self); - _pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self - pendingLayout:nextLayout - previousLayout:_calculatedDisplayNodeLayout]; - isInLayoutPendingState = ASHierarchyStateIncludesLayoutPending(_hierarchyState); + ASDN::MutexLocker l(__instanceLock__); + // Check if we are a subnode in a layout transition. + // In this case no measurement is needed as it's part of the layout transition + if ([self _locked_isLayoutTransitionInvalid]) { + return; } + CGSize boundsSizeForLayout = ASCeilSizeValues(bounds.size); + + // Prefer a newer and not yet applied _pendingDisplayNodeLayout over _calculatedDisplayNodeLayout + // If there is no such _pending, check if _calculated is valid to reuse (avoiding recalculation below). + BOOL pendingLayoutIsPreferred = NO; + if (_pendingDisplayNodeLayout.isValid(_layoutVersion)) { + NSUInteger calculatedVersion = _calculatedDisplayNodeLayout.version; + NSUInteger pendingVersion = _pendingDisplayNodeLayout.version; + if (pendingVersion > calculatedVersion) { + pendingLayoutIsPreferred = YES; // Newer _pending + } else if (pendingVersion == calculatedVersion + && !ASSizeRangeEqualToSizeRange(_pendingDisplayNodeLayout.constrainedSize, + _calculatedDisplayNodeLayout.constrainedSize)) { + pendingLayoutIsPreferred = YES; // _pending with a different constrained size + } + } + BOOL calculatedLayoutIsReusable = (_calculatedDisplayNodeLayout.isValid(_layoutVersion) + && (_calculatedDisplayNodeLayout.requestedLayoutFromAbove + || CGSizeEqualToSize(_calculatedDisplayNodeLayout.layout.size, boundsSizeForLayout))); + if (!pendingLayoutIsPreferred && calculatedLayoutIsReusable) { + return; + } + + as_activity_create_for_scope("Update node layout for current bounds"); + as_log_verbose(ASLayoutLog(), "Node %@, bounds size %@, calculatedSize %@, calculatedIsDirty %d", + self, + NSStringFromCGSize(boundsSizeForLayout), + NSStringFromCGSize(_calculatedDisplayNodeLayout->layout.size), + _calculatedDisplayNodeLayout->version < _layoutVersion); + // _calculatedDisplayNodeLayout is not reusable we need to transition to a new one + [self cancelLayoutTransition]; + + BOOL didCreateNewContext = NO; + ASLayoutElementContext *context = ASLayoutElementGetCurrentContext(); + if (context == nil) { + context = [[ASLayoutElementContext alloc] init]; + ASLayoutElementPushContext(context); + didCreateNewContext = YES; + } + + // Figure out previous and pending layouts for layout transition + ASDisplayNodeLayout nextLayout = _pendingDisplayNodeLayout; + #define layoutSizeDifferentFromBounds !CGSizeEqualToSize(nextLayout.layout.size, boundsSizeForLayout) + + // nextLayout was likely created by a call to layoutThatFits:, check if it is valid and can be applied. + // If our bounds size is different than it, or invalid, recalculate. Use #define to avoid nullptr-> + BOOL pendingLayoutApplicable = NO; + if (nextLayout.layout == nil) { + as_log_verbose(ASLayoutLog(), "No pending layout."); + } else if (!nextLayout.isValid(_layoutVersion)) { + as_log_verbose(ASLayoutLog(), "Pending layout is stale."); + } else if (layoutSizeDifferentFromBounds) { + as_log_verbose(ASLayoutLog(), "Pending layout size %@ doesn't match bounds size.", NSStringFromCGSize(nextLayout->layout.size)); + } else { + as_log_verbose(ASLayoutLog(), "Using pending layout %@.", nextLayout->layout); + pendingLayoutApplicable = YES; + } + + if (!pendingLayoutApplicable) { + as_log_verbose(ASLayoutLog(), "Measuring with previous constrained size."); + // Use the last known constrainedSize passed from a parent during layout (if never, use bounds). + NSUInteger version = _layoutVersion; + ASSizeRange constrainedSize = [self _locked_constrainedSizeForLayoutPass]; + ASLayout *layout = [self calculateLayoutThatFits:constrainedSize + restrictedToSize:self.style.size + relativeToParentSize:boundsSizeForLayout]; + nextLayout = ASDisplayNodeLayout(layout, constrainedSize, boundsSizeForLayout, version); + // Now that the constrained size of pending layout might have been reused, the layout is useless + // Release it and any orphaned subnodes it retains + _pendingDisplayNodeLayout.layout = nil; + } + + if (didCreateNewContext) { + ASLayoutElementPopContext(); + } + + // If our new layout's desired size for self doesn't match current size, ask our parent to update it. + // This can occur for either pre-calculated or newly-calculated layouts. + if (nextLayout.requestedLayoutFromAbove == NO + && CGSizeEqualToSize(boundsSizeForLayout, nextLayout.layout.size) == NO) { + as_log_verbose(ASLayoutLog(), "Layout size doesn't match bounds size. Requesting layout from above."); + // The layout that we have specifies that this node (self) would like to be a different size + // than it currently is. Because that size has been computed within the constrainedSize, we + // expect that calling setNeedsLayoutFromAbove will result in our parent resizing us to this. + // However, in some cases apps may manually interfere with this (setting a different bounds). + // In this case, we need to detect that we've already asked to be resized to match this + // particular ASLayout object, and shouldn't loop asking again unless we have a different ASLayout. + nextLayout.requestedLayoutFromAbove = YES; + + { + __instanceLock__.unlock(); + [self _u_setNeedsLayoutFromAbove]; + __instanceLock__.lock(); + } + + // Update the layout's version here because _u_setNeedsLayoutFromAbove calls __setNeedsLayout which in turn increases _layoutVersion + // Failing to do this will cause the layout to be invalid immediately + nextLayout.version = _layoutVersion; + } + + // Prepare to transition to nextLayout + ASDisplayNodeAssertNotNil(nextLayout.layout, @"nextLayout->layout should not be nil! %@", self); + _pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self + pendingLayout:nextLayout + previousLayout:_calculatedDisplayNodeLayout]; + // If a parent is currently executing a layout transition, perform our layout application after it. - if (isInLayoutPendingState == NO) { + if (ASHierarchyStateIncludesLayoutPending(_hierarchyState) == NO) { // If no transition, apply our new layout immediately (common case). [self _completePendingLayoutTransition]; } @@ -872,18 +868,12 @@ ASLayoutElementStyleExtensibilityForwarding */ - (void)_completePendingLayoutTransition { - ASAssertUnlocked(__instanceLock__); - - ASLayoutTransition *pendingLayoutTransition; - { - ASDN::MutexLocker l(__instanceLock__); - pendingLayoutTransition = _pendingLayoutTransition; - if (pendingLayoutTransition != nil) { - [self _locked_setCalculatedDisplayNodeLayout:pendingLayoutTransition.pendingLayout]; - } - } + __instanceLock__.lock(); + ASLayoutTransition *pendingLayoutTransition = _pendingLayoutTransition; + __instanceLock__.unlock(); if (pendingLayoutTransition != nil) { + [self _setCalculatedDisplayNodeLayout:pendingLayoutTransition.pendingLayout]; [self _completeLayoutTransition:pendingLayoutTransition]; [self _pendingLayoutTransitionDidComplete]; } @@ -903,7 +893,8 @@ ASLayoutElementStyleExtensibilityForwarding // Trampoline to the main thread if necessary if (ASDisplayNodeThreadIsMain() || layoutTransition.isSynchronous == NO) { // Committing the layout transition will result in subnode insertions and removals, both of which must be called without the lock held - ASAssertUnlocked(__instanceLock__); + // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 + // ASAssertUnlocked(__instanceLock__); [layoutTransition commitTransition]; } else { // Subnode insertions and removals need to happen always on the main thread if at least one subnode is already loaded @@ -963,7 +954,8 @@ ASLayoutElementStyleExtensibilityForwarding #endif // Subclass hook - ASAssertUnlocked(__instanceLock__); + // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 + // ASAssertUnlocked(__instanceLock__); [self calculatedLayoutDidChange]; // Grab lock after calling out to subclass diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 9047d7311f..34ff77b941 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -2215,7 +2215,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { - (void)_insertSubnode:(ASDisplayNode *)subnode atSubnodeIndex:(NSInteger)subnodeIndex sublayerIndex:(NSInteger)sublayerIndex andRemoveSubnode:(ASDisplayNode *)oldSubnode { ASDisplayNodeAssertThreadAffinity(self); - ASAssertUnlocked(__instanceLock__); + // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 + // ASAssertUnlocked(__instanceLock__); as_log_verbose(ASNodeLog(), "Insert subnode %@ at index %zd of %@ and remove subnode %@", subnode, subnodeIndex, self, oldSubnode); @@ -2431,7 +2432,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { - (void)_insertSubnode:(ASDisplayNode *)subnode belowSubnode:(ASDisplayNode *)below { ASDisplayNodeAssertThreadAffinity(self); - ASAssertUnlocked(__instanceLock__); + // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 + // ASAssertUnlocked(__instanceLock__); if (subnode == nil) { ASDisplayNodeFailAssert(@"Cannot insert a nil subnode"); @@ -2495,7 +2497,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { - (void)_insertSubnode:(ASDisplayNode *)subnode aboveSubnode:(ASDisplayNode *)above { ASDisplayNodeAssertThreadAffinity(self); - ASAssertUnlocked(__instanceLock__); + // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 + // ASAssertUnlocked(__instanceLock__); if (subnode == nil) { ASDisplayNodeFailAssert(@"Cannot insert a nil subnode"); @@ -2557,7 +2560,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { - (void)_insertSubnode:(ASDisplayNode *)subnode atIndex:(NSInteger)idx { ASDisplayNodeAssertThreadAffinity(self); - ASAssertUnlocked(__instanceLock__); + // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 + // ASAssertUnlocked(__instanceLock__); if (subnode == nil) { ASDisplayNodeFailAssert(@"Cannot insert a nil subnode"); @@ -2594,7 +2598,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { - (void)_removeSubnode:(ASDisplayNode *)subnode { ASDisplayNodeAssertThreadAffinity(self); - ASAssertUnlocked(__instanceLock__); + // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 + // ASAssertUnlocked(__instanceLock__); // Don't call self.supernode here because that will retain/autorelease the supernode. This method -_removeSupernode: is often called while tearing down a node hierarchy, and the supernode in question might be in the middle of its -dealloc. The supernode is never messaged, only compared by value, so this is safe. // The particular issue that triggers this edge case is when a node calls -removeFromSupernode on a subnode from within its own -dealloc method. @@ -2620,7 +2625,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { - (void)_removeFromSupernode { ASDisplayNodeAssertThreadAffinity(self); - ASAssertUnlocked(__instanceLock__); + // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 + // ASAssertUnlocked(__instanceLock__); __instanceLock__.lock(); __weak ASDisplayNode *supernode = _supernode; @@ -2634,7 +2640,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { - (void)_removeFromSupernodeIfEqualTo:(ASDisplayNode *)supernode { ASDisplayNodeAssertThreadAffinity(self); - ASAssertUnlocked(__instanceLock__); + // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 + // ASAssertUnlocked(__instanceLock__); __instanceLock__.lock(); From a3194f8757507ce1132403d46a12ab4cd4810124 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 4 Nov 2018 09:26:57 -0800 Subject: [PATCH 45/60] Allow configuring imageCache when initializing ASPINRemoteImageDownloader. (#1197) * Allow configuring imageCache along with NSURLSessionConfiguration when initializing ASPINRemoteImageDownloader. * Update CHANGELOG.md * Update Source/Details/ASPINRemoteImageDownloader.m Co-Authored-By: wiseoldduck * Put class linkage tests behind #if DEBUG * Remove silly nil check * Add non-nil assert * Update documentation --- CHANGELOG.md | 1 + Source/Details/ASPINRemoteImageDownloader.h | 20 ++++- Source/Details/ASPINRemoteImageDownloader.mm | 93 +++++++++++--------- 3 files changed, 69 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1900518e64..56a9b9117c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master * Add your own contributions to the next release on the line below this with your name. +- [ASPINRemoteImageManager] Allow specifying an image cache when configuring ASPINRemoteImageManager. [Kevin Smith](https://github.com/wiseoldduck). [#1197](https://github.com/TextureGroup/Texture/pull/1197) - [ASTextNode2] Newline character support and truncated line sizing improvement. [Kevin Smith](https://github.com/wiseoldduck). [#1193](https://github.com/TextureGroup/Texture/pull/1193) - [ASScrollNode] A11y support for ASScrollNode. [Max Wang](https://github.com/wsdwsd0829). [#1188](https://github.com/TextureGroup/Texture/pull/1188) - [ASDisplayNode.m] Make sure node is loaded before enter visible. [Max Wang](https://github.com/wsdwsd0829). [#886](https://github.com/TextureGroup/Texture/pull/886) diff --git a/Source/Details/ASPINRemoteImageDownloader.h b/Source/Details/ASPINRemoteImageDownloader.h index 618dc15842..cbbe8574cb 100644 --- a/Source/Details/ASPINRemoteImageDownloader.h +++ b/Source/Details/ASPINRemoteImageDownloader.h @@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN @class PINRemoteImageManager; +@protocol PINRemoteImageCaching; @interface ASPINRemoteImageDownloader : NSObject @@ -28,7 +29,6 @@ NS_ASSUME_NONNULL_BEGIN */ + (ASPINRemoteImageDownloader *)sharedDownloader NS_RETURNS_RETAINED; - /** * Sets the default NSURLSessionConfiguration that will be used by @c ASNetworkImageNodes and @c ASMultiplexImageNodes * while loading images off the network. This must be specified early in the application lifecycle before @@ -39,15 +39,27 @@ NS_ASSUME_NONNULL_BEGIN */ + (void)setSharedImageManagerWithConfiguration:(nullable NSURLSessionConfiguration *)configuration; +/** + * Sets the default NSURLSessionConfiguration that will be used by @c ASNetworkImageNodes and @c ASMultiplexImageNodes + * while loading images off the network. This must be specified early in the application lifecycle before + * `sharedDownloader` is accessed. + * + * @param configuration The session configuration that will be used by `sharedDownloader` + * @param imageCache The cache to be used by PINRemoteImage - nil will set up a default cache: PINCache + * if it is available, PINRemoteImageBasicCache (NSCache) if not. + * + */ ++ (void)setSharedImageManagerWithConfiguration:(nullable NSURLSessionConfiguration *)configuration + imageCache:(nullable id)imageCache; + /** * Sets a custom preconfigured PINRemoteImageManager that will be used by @c ASNetworkImageNodes and @c ASMultiplexImageNodes * while loading images off the network. This must be specified early in the application lifecycle before - * `sharedDownloader` is accessed. If nil is passed in as the PINRemoteImageManager, it will create - * a default image manager with a nil session configuration. + * `sharedDownloader` is accessed. * * @param preconfiguredPINRemoteImageManager The preconfigured remote image manager that will be used by `sharedDownloader` */ -+ (void)setSharedPreconfiguredRemoteImageManager:(nullable PINRemoteImageManager *)preconfiguredPINRemoteImageManager; ++ (void)setSharedPreconfiguredRemoteImageManager:(PINRemoteImageManager *)preconfiguredPINRemoteImageManager; /** * The shared instance of a @c PINRemoteImageManager used by all @c ASPINRemoteImageDownloaders diff --git a/Source/Details/ASPINRemoteImageDownloader.mm b/Source/Details/ASPINRemoteImageDownloader.mm index 9307ee5618..16a7795bae 100644 --- a/Source/Details/ASPINRemoteImageDownloader.mm +++ b/Source/Details/ASPINRemoteImageDownloader.mm @@ -75,7 +75,7 @@ @implementation ASPINRemoteImageManager //Share image cache with sharedImageManager image cache. -- (id )defaultImageCache ++ (id )defaultImageCache { static dispatch_once_t onceToken; static id cache = nil; @@ -106,7 +106,6 @@ static PINRemoteImageManager *sharedPINRemoteImageManager = nil; + (ASPINRemoteImageDownloader *)sharedDownloader NS_RETURNS_RETAINED { - static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ sharedDownloader = [[ASPINRemoteImageDownloader alloc] init]; @@ -116,56 +115,68 @@ static PINRemoteImageManager *sharedPINRemoteImageManager = nil; + (void)setSharedImageManagerWithConfiguration:(nullable NSURLSessionConfiguration *)configuration { - NSAssert(sharedDownloader == nil, @"Singleton has been created and session can no longer be configured."); - NSAssert1(sharedPINRemoteImageManager == nil, @"An instance of %@ has been set. Either configuration or preconfigured image manager can be set at a time and only once.", [[sharedPINRemoteImageManager class] description]); - __unused PINRemoteImageManager *sharedManager = [self sharedPINRemoteImageManagerWithConfiguration:configuration preconfiguredPINRemoteImageManager:nil]; + PINRemoteImageManager *sharedManager = [self PINRemoteImageManagerWithConfiguration:configuration imageCache:nil]; + [self setSharedPreconfiguredRemoteImageManager:sharedManager]; } -+ (void)setSharedPreconfiguredRemoteImageManager:(nullable PINRemoteImageManager *)preconfiguredPINRemoteImageManager ++ (void)setSharedImageManagerWithConfiguration:(nullable NSURLSessionConfiguration *)configuration + imageCache:(nullable id)imageCache { - NSAssert(sharedDownloader == nil, @"Singleton has been created and session can no longer be configured."); - NSAssert1(sharedPINRemoteImageManager == nil, @"An instance of %@ has been set. Either configuration or preconfigured image manager can be set at a time and only once.", [[sharedPINRemoteImageManager class] description]); - __unused PINRemoteImageManager *sharedManager = [self sharedPINRemoteImageManagerWithConfiguration:nil preconfiguredPINRemoteImageManager:preconfiguredPINRemoteImageManager]; + PINRemoteImageManager *sharedManager = [self PINRemoteImageManagerWithConfiguration:configuration imageCache:imageCache]; + [self setSharedPreconfiguredRemoteImageManager:sharedManager]; } -+ (PINRemoteImageManager *)sharedPINRemoteImageManagerWithConfiguration:(NSURLSessionConfiguration *)configuration preconfiguredPINRemoteImageManager:(PINRemoteImageManager *)preconfiguredPINRemoteImageManager -{ - NSAssert(!(configuration != nil && preconfiguredPINRemoteImageManager != nil), @"Either configuration or preconfigured image manager can be set at a time."); - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ +static dispatch_once_t shared_init_predicate; - if (preconfiguredPINRemoteImageManager) { - sharedPINRemoteImageManager = preconfiguredPINRemoteImageManager; - } else { -#if PIN_ANIMATED_AVAILABLE - // Check that Carthage users have linked both PINRemoteImage & PINCache by testing for one file each - if (!(NSClassFromString(@"PINRemoteImageManager"))) { - NSException *e = [NSException - exceptionWithName:@"FrameworkSetupException" - reason:@"Missing the path to the PINRemoteImage framework." - userInfo:nil]; - @throw e; - } - if (!(NSClassFromString(@"PINCache"))) { - NSException *e = [NSException - exceptionWithName:@"FrameworkSetupException" - reason:@"Missing the path to the PINCache framework." - userInfo:nil]; - @throw e; - } - sharedPINRemoteImageManager = [[ASPINRemoteImageManager alloc] initWithSessionConfiguration:configuration - alternativeRepresentationProvider:[self sharedDownloader]]; -#else - sharedPINRemoteImageManager = [[ASPINRemoteImageManager alloc] initWithSessionConfiguration:configuration]; -#endif - } ++ (void)setSharedPreconfiguredRemoteImageManager:(PINRemoteImageManager *)preconfiguredPINRemoteImageManager +{ + NSAssert(preconfiguredPINRemoteImageManager != nil, @"setSharedPreconfiguredRemoteImageManager requires a non-nil parameter"); + NSAssert(sharedDownloader == nil, @"Singleton has been created and session can no longer be configured."); + NSAssert1(sharedPINRemoteImageManager == nil, @"An instance of %@ has been set. Either configuration or preconfigured image manager can be set at a time and only once.", [[sharedPINRemoteImageManager class] description]); + + dispatch_once(&shared_init_predicate, ^{ + sharedPINRemoteImageManager = preconfiguredPINRemoteImageManager; }); - return sharedPINRemoteImageManager; +} + ++ (PINRemoteImageManager *)PINRemoteImageManagerWithConfiguration:(nullable NSURLSessionConfiguration *)configuration imageCache:(nullable id)imageCache +{ + PINRemoteImageManager *manager = nil; +#if DEBUG + // Check that Carthage users have linked both PINRemoteImage & PINCache by testing for one file each + if (!(NSClassFromString(@"PINRemoteImageManager"))) { + NSException *e = [NSException + exceptionWithName:@"FrameworkSetupException" + reason:@"Missing the path to the PINRemoteImage framework." + userInfo:nil]; + @throw e; + } + if (!(NSClassFromString(@"PINCache"))) { + NSException *e = [NSException + exceptionWithName:@"FrameworkSetupException" + reason:@"Missing the path to the PINCache framework." + userInfo:nil]; + @throw e; + } +#endif +#if PIN_ANIMATED_AVAILABLE + manager = [[ASPINRemoteImageManager alloc] initWithSessionConfiguration:configuration + alternativeRepresentationProvider:[self sharedDownloader] + imageCache:imageCache]; +#else + manager = [[ASPINRemoteImageManager alloc] initWithSessionConfiguration:configuration + alternativeRepresentationProvider:nil + imageCache:imageCache]; +#endif + return manager; } - (PINRemoteImageManager *)sharedPINRemoteImageManager { - return [ASPINRemoteImageDownloader sharedPINRemoteImageManagerWithConfiguration:nil preconfiguredPINRemoteImageManager:nil]; + dispatch_once(&shared_init_predicate, ^{ + sharedPINRemoteImageManager = [ASPINRemoteImageDownloader PINRemoteImageManagerWithConfiguration:nil imageCache:nil]; + }); + return sharedPINRemoteImageManager; } - (BOOL)sharedImageManagerSupportsMemoryRemoval From aad0b5d18bacb4ab174574d21f51cb7a6e382393 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Sun, 4 Nov 2018 09:34:39 -0800 Subject: [PATCH 46/60] Add -Wno-implicit-retain-self to podspec + smaller cleanups (#1209) --- Texture.podspec | 2 +- examples/ASDKgram/Sample.xcodeproj/project.pbxproj | 4 ++++ examples/ASDKgram/Sample/AppDelegate.m | 9 +++++---- examples/ASDKgram/Sample/Info.plist | 4 +--- examples/ASDKgram/Sample/PhotoFeedBaseController.m | 5 +++++ .../ASDKgram/Sample/PhotoFeedListKitViewController.m | 12 ++++++++++++ 6 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Texture.podspec b/Texture.podspec index 66a814c824..fa34201dbd 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |spec| # These will be lowered into subspecs in the future. Only here for ASVideoNode. core.frameworks = ['AVFoundation', 'CoreMedia'] - core.compiler_flags = '-fno-exceptions' + core.compiler_flags = '-fno-exceptions -Wno-implicit-retain-self' core.public_header_files = [ 'Source/*.h', 'Source/Details/**/*.h', diff --git a/examples/ASDKgram/Sample.xcodeproj/project.pbxproj b/examples/ASDKgram/Sample.xcodeproj/project.pbxproj index 08713d5b1b..97ef0f3c5e 100644 --- a/examples/ASDKgram/Sample.xcodeproj/project.pbxproj +++ b/examples/ASDKgram/Sample.xcodeproj/project.pbxproj @@ -401,6 +401,7 @@ CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -443,6 +444,7 @@ CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -470,6 +472,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -489,6 +492,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; diff --git a/examples/ASDKgram/Sample/AppDelegate.m b/examples/ASDKgram/Sample/AppDelegate.m index 019c6a71b2..9058c8f100 100644 --- a/examples/ASDKgram/Sample/AppDelegate.m +++ b/examples/ASDKgram/Sample/AppDelegate.m @@ -39,18 +39,23 @@ // ASDK Home Feed viewController & navController PhotoFeedNodeController *asdkHomeFeedVC = [[PhotoFeedNodeController alloc] init]; UINavigationController *asdkHomeFeedNavCtrl = [[UINavigationController alloc] initWithRootViewController:asdkHomeFeedVC]; + asdkHomeFeedNavCtrl.navigationBar.barStyle = UIBarStyleBlack; asdkHomeFeedNavCtrl.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"ASDK" image:[UIImage imageNamed:@"home"] tag:0]; asdkHomeFeedNavCtrl.hidesBarsOnSwipe = YES; // ListKit Home Feed viewController & navController PhotoFeedListKitViewController *listKitHomeFeedVC = [[PhotoFeedListKitViewController alloc] init]; UINavigationController *listKitHomeFeedNavCtrl = [[UINavigationController alloc] initWithRootViewController:listKitHomeFeedVC]; + listKitHomeFeedNavCtrl.navigationBar.barStyle = UIBarStyleBlack; listKitHomeFeedNavCtrl.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"ListKit" image:[UIImage imageNamed:@"home"] tag:0]; listKitHomeFeedNavCtrl.hidesBarsOnSwipe = YES; + + // UIKit Home Feed viewController & navController PhotoFeedViewController *uikitHomeFeedVC = [[PhotoFeedViewController alloc] init]; UINavigationController *uikitHomeFeedNavCtrl = [[UINavigationController alloc] initWithRootViewController:uikitHomeFeedVC]; + uikitHomeFeedNavCtrl.navigationBar.barStyle = UIBarStyleBlack; uikitHomeFeedNavCtrl.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"UIKit" image:[UIImage imageNamed:@"home"] tag:0]; uikitHomeFeedNavCtrl.hidesBarsOnSwipe = YES; @@ -70,10 +75,6 @@ [[UINavigationBar appearance] setBarTintColor:[UIColor darkBlueColor]]; [[UINavigationBar appearance] setTranslucent:NO]; - // iOS8 hides the status bar in landscape orientation, this forces the status bar hidden status to NO - [application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; - [application setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; - #if WEAVER WVDebugger *debugger = [WVDebugger defaultInstance]; [debugger enableLayoutElementDebuggingWithApplication:application]; diff --git a/examples/ASDKgram/Sample/Info.plist b/examples/ASDKgram/Sample/Info.plist index 22adc008a5..7641b2f1a3 100644 --- a/examples/ASDKgram/Sample/Info.plist +++ b/examples/ASDKgram/Sample/Info.plist @@ -30,8 +30,6 @@ armv7 - UIStatusBarStyle - UIStatusBarStyleLightContent UISupportedInterfaceOrientations UIInterfaceOrientationPortrait @@ -46,6 +44,6 @@ UIInterfaceOrientationLandscapeRight UIViewControllerBasedStatusBarAppearance - + diff --git a/examples/ASDKgram/Sample/PhotoFeedBaseController.m b/examples/ASDKgram/Sample/PhotoFeedBaseController.m index 473f2fc2e3..d94a34e922 100644 --- a/examples/ASDKgram/Sample/PhotoFeedBaseController.m +++ b/examples/ASDKgram/Sample/PhotoFeedBaseController.m @@ -75,6 +75,11 @@ return UIStatusBarStyleLightContent; } +- (BOOL)prefersStatusBarHidden +{ + return NO; +} + - (CGSize)imageSizeForScreenWidth { CGRect screenRect = [[UIScreen mainScreen] bounds]; diff --git a/examples/ASDKgram/Sample/PhotoFeedListKitViewController.m b/examples/ASDKgram/Sample/PhotoFeedListKitViewController.m index 950458e197..997e9451b8 100644 --- a/examples/ASDKgram/Sample/PhotoFeedListKitViewController.m +++ b/examples/ASDKgram/Sample/PhotoFeedListKitViewController.m @@ -28,6 +28,8 @@ UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; ASCollectionNode *node = [[ASCollectionNode alloc] initWithCollectionViewLayout:layout]; if (self = [super initWithNode:node]) { + self.navigationItem.title = @"ListKit"; + CGRect screenRect = [[UIScreen mainScreen] bounds]; CGFloat screenScale = [[UIScreen mainScreen] scale]; CGSize screenWidthImageSize = CGSizeMake(screenRect.size.width * screenScale, screenRect.size.width * screenScale); @@ -81,6 +83,16 @@ return _spinner; } +- (UIStatusBarStyle)preferredStatusBarStyle +{ + return UIStatusBarStyleLightContent; +} + +- (BOOL)prefersStatusBarHidden +{ + return NO; +} + #pragma mark - IGListAdapterDataSource - (NSArray> *)objectsForListAdapter:(IGListAdapter *)listAdapter From c7d1465abaccf93a7f5464e8b386168d2f666b88 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Sun, 4 Nov 2018 11:34:21 -0800 Subject: [PATCH 47/60] Generate the changelog at release time rather than updating in each PR (#1031) --- .github_changelog_generator | 3 + CHANGELOG.md | 846 ++++++++++++++++++++++++++---------- Dangerfile | 7 +- README.md | 4 + RELEASE.md | 16 + 5 files changed, 643 insertions(+), 233 deletions(-) create mode 100644 .github_changelog_generator create mode 100644 RELEASE.md diff --git a/.github_changelog_generator b/.github_changelog_generator new file mode 100644 index 0000000000..a5410c8d8e --- /dev/null +++ b/.github_changelog_generator @@ -0,0 +1,3 @@ +issues=false +since-tag=2.3 +future-release=2.8 diff --git a/CHANGELOG.md b/CHANGELOG.md index 56a9b9117c..e4b300da5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,237 +1,625 @@ -## master -* Add your own contributions to the next release on the line below this with your name. -- [ASPINRemoteImageManager] Allow specifying an image cache when configuring ASPINRemoteImageManager. [Kevin Smith](https://github.com/wiseoldduck). [#1197](https://github.com/TextureGroup/Texture/pull/1197) -- [ASTextNode2] Newline character support and truncated line sizing improvement. [Kevin Smith](https://github.com/wiseoldduck). [#1193](https://github.com/TextureGroup/Texture/pull/1193) -- [ASScrollNode] A11y support for ASScrollNode. [Max Wang](https://github.com/wsdwsd0829). [#1188](https://github.com/TextureGroup/Texture/pull/1188) -- [ASDisplayNode.m] Make sure node is loaded before enter visible. [Max Wang](https://github.com/wsdwsd0829). [#886](https://github.com/TextureGroup/Texture/pull/886) -- [ASTextNode2] Add improved support for all line-break modes in experimental text node. [Kevin Smith](https://github.com/wiseoldduck). [#1150](https://github.com/TextureGroup/Texture/pull/1150) -- [ASExperimentalFeatures.m] Fix mismatch name in experimental features. [Max Wang](https://github.com/wsdwsd0829). [#1159](https://github.com/TextureGroup/Texture/pull/1159) -- [ASCollectionViewLayoutController] Set default tuning parameters before view is loaded. [Max Wang](https://github.com/wsdwsd0829). [#1158](https://github.com/TextureGroup/Texture/pull/1158) -- [ASPhotosFrameworkImageRequestTests] Guard photo library with macro for tests. [Max Wang](https://github.com/wsdwsd0829). [#1147](https://github.com/TextureGroup/Texture/pull/1147) -- [ASDisplayNode] Do not cancel display when in exit hierarchy but let interface state changing to handle it. [Max Wang](https://github.com/wsdwsd0829). [#1110](https://github.com/TextureGroup/Texture/pull/1110) -- [Breaking][ASDisplayNode] Make interface state delegate protocol required. [Max Wang](https://github.com/wsdwsd0829). [#1112](https://github.com/TextureGroup/Texture/pull/1112) -- [ASCollectionView] Fix reording of cells manually for iOS 9 & 10. [Max Wang](https://github.com/wsdwsd0829). [#1081](https://github.com/TextureGroup/Texture/pull/1081) -- [ASDisplayNode] Allow add/remove interface state delegates on background thread. [Max Wang](https://github.com/wsdwsd0829). [#1090](https://github.com/TextureGroup/Texture/pull/1090) -- [License] Simplify the Texture license to be pure Apache 2 (removing ASDK-Licenses).[Scott Goodson](https://github.com/appleguy) [#1077](https://github.com/TextureGroup/Texture/pull/1077) -- [ASNetworkImageNode] Allow delegate methods to be called on background thread. [Max Wang](https://github.com/wsdwsd0829). [#1007](https://github.com/TextureGroup/Texture/pull/1007) -- [ASLayoutTransition] Add support for preserving order after node moves during transitions. (This order defines the z-order as well.) [Kevin Smith](https://github.com/wiseoldduck) [#1006] -- [ASDisplayNode] Adds support for multiple interface state delegates. [Garrett Moon](https://github.com/garrettmoon) [#979](https://github.com/TextureGroup/Texture/pull/979) -- [ASDataController] Add capability to renew supplementary views (update map) when size change from zero to non-zero.[Max Wang](https://github.com/wsdwsd0829) [#842](https://github.com/TextureGroup/Texture/pull/842) -- Make `ASPerformMainThreadDeallocation` visible in C. [Adlai Holler](https://github.com/Adlai-Holler) -- Add snapshot test for astextnode2. [Max Wang](https://github.com/wsdwsd0829) [#935](https://github.com/TextureGroup/Texture/pull/935) -- Internal housekeeping on the async transaction (rendering) system. [Adlai Holler](https://github.com/Adlai-Holler) -- Add new protocol `ASLocking` that extends `NSLocking` with `tryLock`, and allows taking multiple locks safely. [Adlai Holler](https://github.com/Adlai-Holler) -- Make the main thread ivar deallocation system available to other classes. Plus a little optimization. See `ASMainThreadDeallocation.h`. [Adlai Holler](https://github.com/Adlai-Holler) [#959](https://github.com/TextureGroup/Texture/pull/959) -- Reduce usage of autorelease pools. [Adlai Holler](https://github.com/Adlai-Holler) [#968](https://github.com/TextureGroup/Texture/pull/968) -- Clean up unused/unneeded header macros. [Adlai Holler](https://github.com/Adlai-Holler) -- Clean up C-function `extern` decorators. [Adlai Holler](https://github.com/Adlai-Holler) -- Add an experiment to reduce work involved in collection teardown. [Adlai Holler](https://github.com/Adlai-Holler) -- Optimize layout flattening, particularly reducing retain/release operations. [Adlai Holler](https://github.com/Adlai-Holler) -- Create a method to transfer strong C-arrays into immutable NSArrays, reducing retain/release traffic. [Adlai Holler](https://github.com/Adlai-Holler) -- Remove yoga layout spec, which has been superseded by tighter Yoga integration (`ASDisplayNode+Yoga.h`) -- Properly consider node for responder methods [Michael Schneider](https://github.com/maicki) -- Introduce let / var macros and some further cleanup. [Michael Schneider](https://github.com/maicki) [#1012](https://github.com/TextureGroup/Texture/pull/1012) -- [IGListKit] Adds missing UIScrollViewDelegate method to DataSource proxy [Sergey Pronin](https://github.com/wannabehero) -- Fix misleading/scary stack trace shown when an assertion occurs during node measurement [Huy Nguyen](https://github.com/nguyenhuy) [#1022](https://github.com/TextureGroup/Texture/pull/1022) -- Fix build on 32-bit simulator in Xcode 9.3 and later, caused by `Thread-local storage is not supported on this architecture.` [Adlai Holler](https://github.com/Adlai-Holler) -- Enable locking assertions (and add some more) to improve and enforce locking safety within the framework [Huy Nguyen](https://github.com/nguyenhuy) [#1024](https://github.com/TextureGroup/Texture/pull/1024) -- Split MapKit, Photos, and AssetsLibrary dependent code into separate subspecs to improve binary size and start time when they're not needed. The default subspec includes all three for backwards compatibility, but this **will change in 3.0**. When using non-Cocoapods build environments, define `AS_USE_PHOTOS, AS_USE_MAPKIT, AS_USE_ASSETS_LIBRARY` to 1 respectively to signal their use. [Adlai Holler](https://github.com/Adlai-Holler) -- Optimization: Removed an NSMutableArray in flattened layouts. [Adlai Holler](https://github.com/Adlai-Holler) -- Reduced binary size by disabling exception support (which we don't use.) [Adlai Holler](https://github.com/Adlai-Holler) -- Create and set delegate for clip corner layers within ASDisplayNode [Michael Schneider](https://github.com/maicki) [#1029](https://github.com/TextureGroup/Texture/pull/1029) -- Improve locking situation in ASVideoPlayerNode [Michael Schneider](https://github.com/maicki) [#1042](https://github.com/TextureGroup/Texture/pull/1042) -- Optimize ASDisplayNode -> ASNodeController reference by removing weak proxy and objc associated objects. [Adlai Holler](https://github.com/Adlai-Holler) -- Remove CA transaction signpost injection because it causes more transactions and is too chatty. [Adlai Holler](https://github.com/Adlai-Holler) -- Optimize display node accessibility by not creating attributed & non-attributed copies of hint, label, and value. [Adlai Holler](https://github.com/Adlai-Holler) -- Add an experimental feature that reuses CTFramesetter objects in ASTextNode2 to improve performance. [Adlai Holler](https://github.com/Adlai-Holler) -- Add NS_DESIGNATED_INITIALIZER to ASViewController initWithNode: [Michael Schneider](https://github.com/maicki) [#1054](https://github.com/TextureGroup/Texture/pull/1054) -- Optimize text stack by removing unneeded copying. [Adlai Holler](https://github.com/Adlai-Holler) -- Renamed `accessibleElements` to `accessibilityElements` and removed the re-definition of the property in ASDisplayView. [Jia Wern Lim](https://github.com/jiawernlim) -- Remove double scaling of lineHeightMultiple & paragraphSpacing attributes in ASTextKitFontSizeAdjuster. [Eric Jensen](https://github.com/ejensen) -- Add a delegate callback for when the framework has initialized. [Adlai Holler](https://github.com/Adlai-Holler) -- Improve TextNode2 by skipping an unneeded copy during measurement. [Adlai Holler](https://github.com/Adlai-Holler) -- Improve locking around clearContents [Michael Schneider](https://github.com/maicki) -- Unlock before cleanup and calling out to subclass hooks for animated images. [Michael Schneider](https://github.com/maicki) [#1087](https://github.com/TextureGroup/Texture/pull/1087) -- [ASDisplayNode] Fix interface state update for layer backed nodes when layer thrashes (interface coaleascing case).[Max Wang](https://github.com/wsdwsd0829). [#1111](https://github.com/TextureGroup/Texture/pull/1111) -- [ASPINRemoteImageManager] Add a new API for setting a preconfigured PINRemoteImageManager. [Ernest Ma](https://github.com/ernestmama) [#1124](https://github.com/TextureGroup/Texture/pull/1124) -- Small optimization to the layout spec & yoga layout systems by eliminating array copies. [Adlai Holler](https://github.com/Adlai-Holler) -- Optimize layout process by removing `ASRectMap`. [Adlai Holler](https://github.com/Adlai-Holler) -- Remove necessity to use view to access rangeController in ASTableNode, ASCollectionNode. [Michael Schneider](https://github.com/maicki) -- Remove display node's reliance on shared_ptr. [Adlai Holler](https://github.com/Adlai-Holler) -- [ASCollectionView] Fix a crash that is caused by clearing a collection view's data while it's still being used. [Huy Nguyen](https://github.com/nguyenhuy) [#1154](https://github.com/TextureGroup/Texture/pull/1154) -- Clean up timing of layout tree flattening/ copying of unflattened tree for Weaver. [Michael Zuccarino](https://github.com/mikezucc) [#1157](https://github.com/TextureGroup/Texture/pull/1157) -- Fix crash setting attributed text on multiple threads [Michael Schneider](https://github.com/maicki) -- [ASTextNode2] Ignore certain text alignments while calculating intrinsic size [Huy Nguyen](https://github.com/nguyenhuy) [#1166](https://github.com/TextureGroup/Texture/pull/1166) -- Fix mismatch in UIAccessibilityAction selector method [Michael Schneider](https://github.com/maicki) [#1169](https://github.com/TextureGroup/Texture/pull/1169) -- [ASDisplayNode] Expose default Texture-set accessibility values as properties. [Jia Wern Lim](https://github.com/jiawernlim) [#1170](https://github.com/TextureGroup/Texture/pull/1170) -- ASTableNode init method match checks from ASCollectionNode [Michael Schneider](https://github.com/maicki) [#1171] -- Add NSLocking conformance to ASNodeController [Michael Schneider](https://github.com/maicki)[#1179] (https://github.com/TextureGroup/Texture/pull/1179) -- Don’t handle touches on additional attributed message if passthrough is enabled [Michael Schneider](https://github.com/maicki)[#1184] (https://github.com/TextureGroup/Texture/pull/1184) -- Yoga integration improvements [Michael Schneider](https://github.com/maicki)[#1187] (https://github.com/TextureGroup/Texture/pull/1187) -- Correct linePositionModifier behavior [Michael Schneider](https://github.com/maicki)[#1192] (https://github.com/TextureGroup/Texture/pull/1192) -- Tweak a11y label aggregation behavior to enable container label overrides [Michael Schneider](https://github.com/maicki)[#1199] (https://github.com/TextureGroup/Texture/pull/1199) -- Fix logic cleaning data if delegate / dataSource changes and bring over logic to ASTableView [Michael Schneider](https://github.com/maicki)[#1200] (https://github.com/TextureGroup/Texture/pull/1200) -- Standardize the code base on Objective-C++. We will still not leak any C++ into public headers, however. [Adlai Holler](https://github.com/Adlai-Holler) +# Change Log -## 2.7 -- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) -- [ASTextNode2] Upgrade lock safety by protecting all ivars (including rarely-changed ones). -- User FLT_EPSILON in ASCeilPixelValue and ASFloorPixelValue to help with floating point precision errors when computing layouts for 3x devices. [Ricky Cancro](https://github.com/rcancro) [#838](https://github.com/TextureGroup/Texture/pull/864) -- Disable interface colescing and match to pre-colescing interface update behavior [Max Wang](https://github.com/wsdwsd0829) [#862](https://github.com/TextureGroup/Texture/pull/862) -- [ASDisplayNode] Add safeAreaInsets, layoutMargins and related properties to ASDisplayNode, with full support for older OS versions [Yevgen Pogribnyi](https://github.com/ypogribnyi) [#685](https://github.com/TextureGroup/Texture/pull/685) -- [ASPINRemoteImageDownloader] Allow cache to provide animated image. [Max Wang](https://github.com/wsdwsd0829) [#850](https://github.com/TextureGroup/Texture/pull/850) -- [tvOS] Fixes errors when building against tvOS SDK [Alex Hill](https://github.com/alexhillc) [#728](https://github.com/TextureGroup/Texture/pull/728) -- [ASDisplayNode] Add unit tests for layout z-order changes (with an open issue to fix). -- [ASWrapperCellNode] Introduce a new class allowing more control of UIKit passthrough cells. -- [ASDisplayNode] Consolidate main thread initialization and allow apps to invoke it manually instead of +load. -- [ASRunloopQueue] Introduce new runloop queue(ASCATransactionQueue) to coalesce Interface state update calls for view controller transitions. -- [ASRangeController] Fix stability of "minimum" rangeMode if the app has more than one layout before scrolling. -- **Important** ASDisplayNode's cornerRadius is a new thread-safe bridged property that should be preferred over CALayer's. Use the latter at your own risk! [Huy Nguyen](https://github.com/nguyenhuy) [#749](https://github.com/TextureGroup/Texture/pull/749). -- [ASCellNode] Adds mapping for UITableViewCell focusStyle [Alex Hill](https://github.com/alexhillc) [#727](https://github.com/TextureGroup/Texture/pull/727) -- [ASNetworkImageNode] Fix capturing self in the block while loading image in ASNetworkImageNode. [Denis Mororozov](https://github.com/morozkin) [#777](https://github.com/TextureGroup/Texture/pull/777) -- [ASTraitCollection] Add new properties of UITraitCollection to ASTraitCollection. [Yevgen Pogribnyi](https://github.com/ypogribnyi) -- [ASRectMap] Replace implementation of ASRectTable with a simpler one based on unordered_map.[Scott Goodson](https://github.com/appleguy) [#719](https://github.com/TextureGroup/Texture/pull/719) -- [ASCollectionView] Add missing flags for ASCollectionDelegate [Ilya Zheleznikov](https://github.com/ilyailya) [#718](https://github.com/TextureGroup/Texture/pull/718) -- [ASNetworkImageNode] Deprecates .URLs in favor of .URL [Garrett Moon](https://github.com/garrettmoon) [#699](https://github.com/TextureGroup/Texture/pull/699) -- [iOS11] Update project settings and fix errors [Eke](https://github.com/Eke) [#676](https://github.com/TextureGroup/Texture/pull/676) -- [ASCornerLayoutSpec] New layout spec class for declarative corner element layout. [#657](https://github.com/TextureGroup/Texture/pull/657) [huangkun](https://github.com/huang-kun) -- [ASDisplayNode layout] Fix an issue that causes a pending layout to be applied multiple times. [Huy Nguyen](https://github.com/nguyenhuy) [#695](https://github.com/TextureGroup/Texture/pull/695) -- [ASDisplayNode layout] Fix an issue that sometimes causes a node's pending layout to not be applied. [Huy Nguyen](https://github.com/nguyenhuy) [#792](https://github.com/TextureGroup/Texture/pull/792) -- [ASScrollNode] Ensure the node respects the given size range while calculating its layout. [#637](https://github.com/TextureGroup/Texture/pull/637) [Huy Nguyen](https://github.com/nguyenhuy) -- [ASScrollNode] Invalidate the node's calculated layout if its scrollable directions changed. Also add unit tests for the class. [#637](https://github.com/TextureGroup/Texture/pull/637) [Huy Nguyen](https://github.com/nguyenhuy) -- Add new unit testing to the layout engine. [Adlai Holler](https://github.com/Adlai-Holler) [#424](https://github.com/TextureGroup/Texture/pull/424) -- [Automatic Subnode Management] Nodes with ASM enabled now insert/delete their subnodes as soon as they enter preload state, so subnodes can start preloading right away. [Huy Nguyen](https://github.com/nguyenhuy) [#706](https://github.com/TextureGroup/Texture/pull/706) -- [ASCollectionNode] Added support for interactive item movement. [Adlai Holler](https://github.com/Adlai-Holler) -- Added an experimental "no-copy" rendering API. See ASGraphicsContext.h for info. [Adlai Holler](https://github.com/Adlai-Holler) -- Dropped support for iOS 8. [Adlai Holler](https://github.com/Adlai-Holler) -- Added a configuration API – a unified place to turn on/off experimental Texture features. See `ASConfiguration.h` for info. [Adlai Holler](https://github.com/Adlai-Holler) -- **Breaking** Changes to ASNetworkImageNode: [Adlai Holler](https://github.com/Adlai-Holler) - - Modified `ASImageDownloaderCompletion` to add an optional `id userInfo` field. Your custom downloader can pass `nil`. - - Modified the last argument to `-[ASNetworkImageNodeDelegate imageNode:didLoadImage:info:]` method from a struct to an object of new class `ASNetworkImageLoadInfo` which includes other metadata about the load operation. -- Removed +load static initializer from ASDisplayNode. [Adlai Holler](https://github.com/Adlai-Holler) -- Optimized ASNetworkImageNode loading and resolved edge cases where the image provided to the delegate was not the image that was loaded. [Adlai Holler](https://github.com/Adlai-Holler) [#778](https://github.com/TextureGroup/Texture/pull/778/) -- Make `ASCellNode` tint color apply to table view cell accessories. [Vladyslav Chapaev](https://github.com/ShogunPhyched) [#764](https://github.com/TextureGroup/Texture/pull/764) -- Fix ASTextNode2 is accessing backgroundColor off main while sizing / layout is happening. [Michael Schneider](https://github.com/maicki) [#794](https://github.com/TextureGroup/Texture/pull/778/) -- Pass scrollViewWillEndDragging delegation through in ASIGListAdapterDataSource for IGListKit integration. [#796](https://github.com/TextureGro -- up/Texture/pull/796) -- Fix UIResponder handling with view backing ASDisplayNode. [Michael Schneider](https://github.com/maicki) [#789](https://github.com/TextureGroup/Texture/pull/789/) -- Optimized thread-local storage by replacing pthread_specific with C11 thread-local variables. [Adlai Holler](https://github.com/Adlai-Holler) [#811](https://github.com/TextureGroup/Texture/pull/811/) -- Fixed a thread-sanitizer warning in ASTextNode. [Adlai Holler](https://github.com/Adlai-Holler) [#830](https://github.com/TextureGroup/Texture/pull/830/) -- Fix ASTextNode2 handling background color incorrectly. [Adlai Holler](https://github.com/Adlai-Holler) [#831](https://github.com/TextureGroup/Texture/pull/831/) -- [NoCopyRendering] Improved performance & fixed image memory not being tagged in Instruments. [Adlai Holler](https://github.com/Adlai-Holler) [#833](https://github.com/TextureGroup/Texture/pull/833/) -- Use `NS_RETURNS_RETAINED` macro to make our methods a tiny bit faster. [Adlai Holler](https://github.com/Adlai-Holler) [#843](https://github.com/TextureGroup/Texture/pull/843/) -- `ASDisplayNode, ASLayoutSpec, and ASLayoutElementStyle` now conform to `NSLocking`. They act as recursive locks. Useful locking macros have been added as `ASThread.h`. Subclasses / client code can lock these objects but should be careful as usual when dealing with locks. [Adlai Holler](https://github.com/Adlai-Holler) -- Introduces `ASRecursiveUnfairLock` as an experiment to improve locking performance. [Adlai Holler](https://github.com/Adlai-Holler) -- Adds an experiment to shorten init time. [Adlai Holler](https://github.com/Adlai-Holler) -- Adds a check that Texture is compiled with stdc++11 as specified by the podfile. gnu++11 can cause subtle issues that are currently being investigated. [Adlai Holler](https://github.com/Adlai-Holler) -- Adds an experiment to call ASNetworkImageNode callbacks off main. [Garrett Moon](https://github.com/garrettmoon) -- Prevent UITextView from updating contentOffset while deallocating [Michael Schneider](https://github.com/maicki) -- [ASCollectionNode/ASTableNode] Fix a crash occurs while remeasuring cell nodes. [Huy Nguyen](https://github.com/nguyenhuy) [#917](https://github.com/TextureGroup/Texture/pull/917) -- Fix an issue where ASConfigurationDelegate would not call out for "control" users. If set, it now receives events whenever an experimental feature decision point occurs, whether it's enabled or not. [Adlai Holler](https://github.com/Adlai-Holler) -- [ASDisplayNode] Fix an issue that causes a node to sometimes return an outdated calculated size or size range. [Huy Nguyen](https://github.com/nguyenhuy) [#808](https://github.com/TextureGroup/Texture/pull/808) -- Add an experimental deallocation queue implementation that's more efficient. [Adlai Holler](https://github.com/Adlai-Holler) -- Standardize property declaration style. [Adlai Holler](https://github.com/Adlai-Holler) -- [ASTableView] Fix an issue that causes table view to use one of a cell's invalid layouts instead of generating a new one. [Huy Nguyen](https://github.com/nguyenhuy) [#942](https://github.com/TextureGroup/Texture/pull/942) +## [2.8](https://github.com/TextureGroup/Texture/tree/2.8) (2018-11-04) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.7...2.8) -## 2.6 -- [Xcode 9] Updated to require Xcode 9 (to fix warnings) [Garrett Moon](https://github.com/garrettmoon) -- [ASCollectionView] Improve performance and behavior of rotation / bounds changes. [Scott Goodson](https://github.com/appleguy) [#431](https://github.com/TextureGroup/Texture/pull/431) -- [ASCollectionView] Improve index space translation of Flow Layout Delegate methods. [Scott Goodson](https://github.com/appleguy) -- [Animated Image] Adds support for animated WebP as well as improves GIF handling. [#605](https://github.com/TextureGroup/Texture/pull/605) [Garrett Moon](https://github.com/garrettmoon) -- [ASCollectionView] Check if batch fetching is needed if batch fetching parameter has been changed. [#624](https://github.com/TextureGroup/Texture/pull/624) [Garrett Moon](https://github.com/garrettmoon) -- [ASNetworkImageNode] New delegate callback to tell the consumer whether the image was loaded from cache or download. [Adlai Holler](https://github.com/Adlai-Holler) -- [Layout] Fixes a deadlock in layout. [#638](https://github.com/TextureGroup/Texture/pull/638) [Garrett Moon](https://github.com/garrettmoon) -- Updated to be backwards compatible with Xcode 8. [Adlai Holler](https://github.com/Adlai-Holler) -- [API CHANGES] `ASPerformMainThreadDeallocation` and `ASPerformBackgroundDeallocation` functions take `id *` instead of `id` and they're now more reliable. Also, in Swift, `ASDeallocQueue.sharedDeallocationQueue() -> ASDeallocQueue.sharedDeallocationQueue`. [Adlai Holler](https://github.com/Adlai-Holler) [#651](https://github.com/TextureGroup/Texture/pull/651) -- [Collection/Table] Added direct support for mapping section indexes between data spaces. [Adlai Holler](https://github.com/Adlai-Holler) [#651](https://github.com/TextureGroup/Texture/pull/660) +**Merged pull requests:** -## 2.5.1 -- [ASVideoNode] Fix unreleased time observer. [Flo Vouin](https://github.com/flovouin) -- [PINCache] Set a default .byteLimit to reduce disk usage and startup time. [#595](https://github.com/TextureGroup/Texture/pull/595) [Scott Goodson](https://github.com/appleguy) -- [ASNetworkImageNode] Fix deadlock in GIF handling. [#582](https://github.com/TextureGroup/Texture/pull/582) [Garrett Moon](https://github.com/garrettmoon) -- [ASDisplayNode] Add attributed versions of a11y label, hint and value. [#554](https://github.com/TextureGroup/Texture/pull/554) [Alexander HĂ¼llmandel](https://github.com/fruitcoder) -- [ASCornerRounding] Introduce .cornerRoundingType: CALayer, Precomposited, or Clip Corners. [Scott Goodson](https://github.com/appleguy) [#465](https://github.com/TextureGroup/Texture/pull/465) -- [Yoga] Add insertYogaNode:atIndex: method. Improve handling of relayouts. [Scott Goodson](https://github.com/appleguy) +- Add -Wno-implicit-retain-self to podspec + smaller cleanups \#trivial [\#1209](https://github.com/TextureGroup/Texture/pull/1209) ([maicki](https://github.com/maicki)) +- Address compiler warnings \#trivial [\#1207](https://github.com/TextureGroup/Texture/pull/1207) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Convert the codebase to Objective-C++ [\#1206](https://github.com/TextureGroup/Texture/pull/1206) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add tests for accessibility [\#1205](https://github.com/TextureGroup/Texture/pull/1205) ([wiseoldduck](https://github.com/wiseoldduck)) +- Revert \#1023 \#trivial [\#1204](https://github.com/TextureGroup/Texture/pull/1204) ([maicki](https://github.com/maicki)) +- Follow up cleanup \#trivial [\#1203](https://github.com/TextureGroup/Texture/pull/1203) ([maicki](https://github.com/maicki)) +- Add experiment flag to skip layoutIfNeeded in enterPreloadState for ASM nodes \#trivial [\#1201](https://github.com/TextureGroup/Texture/pull/1201) ([maicki](https://github.com/maicki)) +- Fix logic cleaning data if delegate / dataSource changes and bring over logic to ASTableView [\#1200](https://github.com/TextureGroup/Texture/pull/1200) ([maicki](https://github.com/maicki)) +- Tweak a11y label aggregation behavior to enable container label overrides [\#1199](https://github.com/TextureGroup/Texture/pull/1199) ([maicki](https://github.com/maicki)) +- Fix shadowed var warning \(and add clarity\) \#trivial [\#1198](https://github.com/TextureGroup/Texture/pull/1198) ([wiseoldduck](https://github.com/wiseoldduck)) +- Allow configuring imageCache when initializing ASPINRemoteImageDownloader. [\#1197](https://github.com/TextureGroup/Texture/pull/1197) ([wiseoldduck](https://github.com/wiseoldduck)) +- ASTextNode2 to consider both width and height when determining if it is calculating an intrinsic size [\#1196](https://github.com/TextureGroup/Texture/pull/1196) ([ernestmama](https://github.com/ernestmama)) +- Remove extraneous ";" \#trivial [\#1194](https://github.com/TextureGroup/Texture/pull/1194) ([wiseoldduck](https://github.com/wiseoldduck)) +- Newline character support and truncated line sizing improvement. [\#1193](https://github.com/TextureGroup/Texture/pull/1193) ([wiseoldduck](https://github.com/wiseoldduck)) +- Correct linePositionModifier behavior [\#1192](https://github.com/TextureGroup/Texture/pull/1192) ([maicki](https://github.com/maicki)) +- Move AS\_TEXT\_ALERT\_UNIMPLEMENTED\_FEATURE into ASTextNodeCommon \#trivial [\#1191](https://github.com/TextureGroup/Texture/pull/1191) ([maicki](https://github.com/maicki)) +- A11y for scrollnode [\#1188](https://github.com/TextureGroup/Texture/pull/1188) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Yoga integration improvements [\#1187](https://github.com/TextureGroup/Texture/pull/1187) ([maicki](https://github.com/maicki)) +- Remove unnecessary ASWeakProxy import \#trivial [\#1186](https://github.com/TextureGroup/Texture/pull/1186) ([maicki](https://github.com/maicki)) +- Directly use \_\_instanceLock\_\_ to lock / unlock without having to create and destroy a MutextUnlocker \#trivial [\#1185](https://github.com/TextureGroup/Texture/pull/1185) ([maicki](https://github.com/maicki)) +- Don’t handle touches on additional attributed message if passthrough is enabled [\#1184](https://github.com/TextureGroup/Texture/pull/1184) ([maicki](https://github.com/maicki)) +- Set the default values for showsVerticalScrollIndicator and showsHorizontalScrollIndicator \#trivial [\#1181](https://github.com/TextureGroup/Texture/pull/1181) ([maicki](https://github.com/maicki)) +- Move import of stdatomic to ASRecursiveUnfairLock implementation file \#trivial [\#1180](https://github.com/TextureGroup/Texture/pull/1180) ([maicki](https://github.com/maicki)) +- Add NSLocking conformance to ASNodeController [\#1179](https://github.com/TextureGroup/Texture/pull/1179) ([maicki](https://github.com/maicki)) +- Only initialize framework once, avoid multiple across tests \#trivial [\#1178](https://github.com/TextureGroup/Texture/pull/1178) ([maicki](https://github.com/maicki)) +- Expose a way to determine if a text node will truncate for a given constrained size \#trivial [\#1177](https://github.com/TextureGroup/Texture/pull/1177) ([maicki](https://github.com/maicki)) +- Fix define spaces \#trivial [\#1176](https://github.com/TextureGroup/Texture/pull/1176) ([maicki](https://github.com/maicki)) +- Expose test\_resetWithConfiguration: for testing \#trivial [\#1175](https://github.com/TextureGroup/Texture/pull/1175) ([maicki](https://github.com/maicki)) +- Add way to suppress invalid CollectionUpdateExceptions \#trivial [\#1173](https://github.com/TextureGroup/Texture/pull/1173) ([maicki](https://github.com/maicki)) +- Use interface state to manage image loading \#trivial [\#1172](https://github.com/TextureGroup/Texture/pull/1172) ([maicki](https://github.com/maicki)) +- ASTableNode init method match checks from ASCollectionNode [\#1171](https://github.com/TextureGroup/Texture/pull/1171) ([maicki](https://github.com/maicki)) +- \[ASDisplayNode\] Expose default Texture-set accessibility values as properties [\#1170](https://github.com/TextureGroup/Texture/pull/1170) ([jiawernlim](https://github.com/jiawernlim)) +- Fix mismatch in UIAccessibilityAction selector method [\#1169](https://github.com/TextureGroup/Texture/pull/1169) ([maicki](https://github.com/maicki)) +- Small fix in ASTextKitRenderer \#trivial [\#1167](https://github.com/TextureGroup/Texture/pull/1167) ([nguyenhuy](https://github.com/nguyenhuy)) +- ASTextNode2 to ignore certain text alignments while calculating intrinsic size [\#1166](https://github.com/TextureGroup/Texture/pull/1166) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update Jekyll to 3.6.3 [\#1165](https://github.com/TextureGroup/Texture/pull/1165) ([nguyenhuy](https://github.com/nguyenhuy)) +- Migrate placeholder example project from 1.0 to 2.x [\#1164](https://github.com/TextureGroup/Texture/pull/1164) ([ay8s](https://github.com/ay8s)) +- Update documentation of ASNetworkImageNodeDelegate \#trivial [\#1163](https://github.com/TextureGroup/Texture/pull/1163) ([nguyenhuy](https://github.com/nguyenhuy)) +- Mismatch name experimental features [\#1159](https://github.com/TextureGroup/Texture/pull/1159) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Set default tuning params [\#1158](https://github.com/TextureGroup/Texture/pull/1158) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Clean up timing of layout tree flattening/ copying of unflattened tree for Weaver [\#1157](https://github.com/TextureGroup/Texture/pull/1157) ([mikezucc](https://github.com/mikezucc)) +- Only clear ASCollectionView's data during deallocation [\#1154](https://github.com/TextureGroup/Texture/pull/1154) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASTextNode2\] Add improved support for all line-break modes in experimental text node. [\#1150](https://github.com/TextureGroup/Texture/pull/1150) ([wiseoldduck](https://github.com/wiseoldduck)) +- Guard photo library with macro for tests [\#1147](https://github.com/TextureGroup/Texture/pull/1147) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Rollout ASDeallocQueueV2 \#trivial [\#1143](https://github.com/TextureGroup/Texture/pull/1143) ([ernestmama](https://github.com/ernestmama)) +- Fix crash setting attributed text on multiple threads [\#1141](https://github.com/TextureGroup/Texture/pull/1141) ([maicki](https://github.com/maicki)) +- Add missing NS\_NOESCAPE attributes in overwritten methods \#trivial [\#1139](https://github.com/TextureGroup/Texture/pull/1139) ([ejensen](https://github.com/ejensen)) +- Add missing comma in ASExperimentalFeatures \#trivial [\#1137](https://github.com/TextureGroup/Texture/pull/1137) ([nguyenhuy](https://github.com/nguyenhuy)) +- Add ASExperimentalSkipClearData \#trivial [\#1136](https://github.com/TextureGroup/Texture/pull/1136) ([maicki](https://github.com/maicki)) +- Fix RemoteImageDownloader name mismatch \#trivial [\#1134](https://github.com/TextureGroup/Texture/pull/1134) ([ernestmama](https://github.com/ernestmama)) +- Fix compilation warnings \#trivial [\#1132](https://github.com/TextureGroup/Texture/pull/1132) ([ejensen](https://github.com/ejensen)) +- Remove reliance on shared\_ptr for ASDisplayNodeLayouts [\#1131](https://github.com/TextureGroup/Texture/pull/1131) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Make yoga & layout specs faster by eliminating some copies [\#1128](https://github.com/TextureGroup/Texture/pull/1128) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove ASRectMap, which is not worth its own weight [\#1127](https://github.com/TextureGroup/Texture/pull/1127) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASPINRemoteImageDownloader\] Fix +setSharedPreconfiguredRemoteImageManager:'s doc \#trivial [\#1126](https://github.com/TextureGroup/Texture/pull/1126) ([nguyenhuy](https://github.com/nguyenhuy)) +- Add a method for setting preconfigured PINRemoteImageManager [\#1124](https://github.com/TextureGroup/Texture/pull/1124) ([ernestmama](https://github.com/ernestmama)) +- Don't copy onDidLoadBlocks \#trivial [\#1123](https://github.com/TextureGroup/Texture/pull/1123) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove use of NSHashTable for interface state delegates \#trivial [\#1122](https://github.com/TextureGroup/Texture/pull/1122) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix typos and minor code cleanups \#trivial [\#1120](https://github.com/TextureGroup/Texture/pull/1120) ([nguyenhuy](https://github.com/nguyenhuy)) +- Don't setNeedsDisplay on text node 2 measure \#trivial [\#1116](https://github.com/TextureGroup/Texture/pull/1116) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Don't copy container during ASTextNode2 measure [\#1115](https://github.com/TextureGroup/Texture/pull/1115) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Make interface state delegate non optional [\#1112](https://github.com/TextureGroup/Texture/pull/1112) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Interface state not update correctly during layer thrash. [\#1111](https://github.com/TextureGroup/Texture/pull/1111) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Fix layer backed nodes not update properly [\#1110](https://github.com/TextureGroup/Texture/pull/1110) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- changelog fix: let / var macros did not make it to 2.7 [\#1109](https://github.com/TextureGroup/Texture/pull/1109) ([jozsefmihalicza](https://github.com/jozsefmihalicza)) +- Improve locking around clearContents [\#1107](https://github.com/TextureGroup/Texture/pull/1107) ([maicki](https://github.com/maicki)) +- Add missing argument for calling image download completion block \#trivial [\#1106](https://github.com/TextureGroup/Texture/pull/1106) ([maicki](https://github.com/maicki)) +- Fix URL for blog about Pinterest [\#1105](https://github.com/TextureGroup/Texture/pull/1105) ([muukii](https://github.com/muukii)) +- Remove necessity to use view to access rangeController in ASTableNode, ASCollectionNode [\#1103](https://github.com/TextureGroup/Texture/pull/1103) ([maicki](https://github.com/maicki)) +- Add a -textureDidInitialize delegate callback [\#1100](https://github.com/TextureGroup/Texture/pull/1100) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Reuse interface state delegates when calling out \#trivial [\#1099](https://github.com/TextureGroup/Texture/pull/1099) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add an explicit cast to satisfy strict compilers \#trivial [\#1098](https://github.com/TextureGroup/Texture/pull/1098) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix a couple typos. [\#1092](https://github.com/TextureGroup/Texture/pull/1092) ([jtbthethird](https://github.com/jtbthethird)) +- \#trivial Shouldn't hold the lock while adding subnodes [\#1091](https://github.com/TextureGroup/Texture/pull/1091) ([garrettmoon](https://github.com/garrettmoon)) +- Allow to add interface state delegate in background. [\#1090](https://github.com/TextureGroup/Texture/pull/1090) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Fix Typo [\#1089](https://github.com/TextureGroup/Texture/pull/1089) ([jtbthethird](https://github.com/jtbthethird)) +- Add subnode should not be called with the lock held. \#trivial [\#1088](https://github.com/TextureGroup/Texture/pull/1088) ([garrettmoon](https://github.com/garrettmoon)) +- Unlock before cleanup and calling out to subclass hooks for animated images. [\#1087](https://github.com/TextureGroup/Texture/pull/1087) ([maicki](https://github.com/maicki)) +- Fix collection editing [\#1081](https://github.com/TextureGroup/Texture/pull/1081) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Fix compiler error in ASLocking \#trivial [\#1079](https://github.com/TextureGroup/Texture/pull/1079) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update showcase to add Wishpoke [\#1078](https://github.com/TextureGroup/Texture/pull/1078) ([dhatuna](https://github.com/dhatuna)) +- \[License\] Simplify the Texture license to be pure Apache 2 \(removing ASDK-Licenses\). [\#1077](https://github.com/TextureGroup/Texture/pull/1077) ([appleguy](https://github.com/appleguy)) +- Fix multiple documentation issues \#trivial [\#1073](https://github.com/TextureGroup/Texture/pull/1073) ([maicki](https://github.com/maicki)) +- Refactored `accessibleElements` to `accessibilityElements` [\#1069](https://github.com/TextureGroup/Texture/pull/1069) ([jiawernlim](https://github.com/jiawernlim)) +- Readability improvements in ASDataController \#trivial [\#1067](https://github.com/TextureGroup/Texture/pull/1067) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove direct ivar access on non-self object to fix mocking case \#trivial [\#1066](https://github.com/TextureGroup/Texture/pull/1066) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Reduce copying in ASTextNode2 stack [\#1065](https://github.com/TextureGroup/Texture/pull/1065) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add an experimental framesetter cache in ASTextNode2 [\#1063](https://github.com/TextureGroup/Texture/pull/1063) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove extra string/attributed string creation in accessibility props [\#1062](https://github.com/TextureGroup/Texture/pull/1062) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove objc association & weak proxy from node -\> controller pointer [\#1061](https://github.com/TextureGroup/Texture/pull/1061) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove CATransaction signposts [\#1060](https://github.com/TextureGroup/Texture/pull/1060) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASTextNode2\] Simplify allocWithZone: + initialize implementation \#trivial [\#1059](https://github.com/TextureGroup/Texture/pull/1059) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASTextNode\] Fixes in ASTextKitFontSizeAdjuster [\#1056](https://github.com/TextureGroup/Texture/pull/1056) ([ejensen](https://github.com/ejensen)) +- Revert "Optimize drawing code + add examples how to round corners \(\#996\) [\#1055](https://github.com/TextureGroup/Texture/pull/1055) ([maicki](https://github.com/maicki)) +- Add NS\_DESIGNATED\_INITIALIZER to ASViewController initWithNode: [\#1054](https://github.com/TextureGroup/Texture/pull/1054) ([maicki](https://github.com/maicki)) +- Fix headers in markdown [\#1053](https://github.com/TextureGroup/Texture/pull/1053) ([Un3qual](https://github.com/Un3qual)) +- Avoid setting frame on a node's backing store while holding its lock [\#1048](https://github.com/TextureGroup/Texture/pull/1048) ([nguyenhuy](https://github.com/nguyenhuy)) +- \#trivial Add a comment about tiling mode and issue \#1046 [\#1047](https://github.com/TextureGroup/Texture/pull/1047) ([wiseoldduck](https://github.com/wiseoldduck)) +- Add documentation for rounding corners within Texture \#trivial [\#1044](https://github.com/TextureGroup/Texture/pull/1044) ([maicki](https://github.com/maicki)) +- Improve locking situation in ASVideoPlayerNode [\#1042](https://github.com/TextureGroup/Texture/pull/1042) ([maicki](https://github.com/maicki)) +- Revert unreleased layout debug method name change from \#1030 \#trivial [\#1039](https://github.com/TextureGroup/Texture/pull/1039) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Pin OCMock version to 3.4.1 because 3.4.2 has issues [\#1038](https://github.com/TextureGroup/Texture/pull/1038) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix & update ASCollectionNode constrained size doc. \#trivial [\#1037](https://github.com/TextureGroup/Texture/pull/1037) ([ay8s](https://github.com/ay8s)) +- Fix warning for ASLayout method override for the designated initializer of the superclass '-init' not found \#trivial [\#1036](https://github.com/TextureGroup/Texture/pull/1036) ([maicki](https://github.com/maicki)) +- Fix the bug I introduced in \#1030 \#trivial [\#1035](https://github.com/TextureGroup/Texture/pull/1035) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Turn off exceptions to reduce binary size \(-600KB for arm64\) [\#1033](https://github.com/TextureGroup/Texture/pull/1033) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Turn lock-checking on only when assertions are enabled \#trivial [\#1032](https://github.com/TextureGroup/Texture/pull/1032) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove NSMutableArray for retaining sublayout elements [\#1030](https://github.com/TextureGroup/Texture/pull/1030) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Create and set delegate for clip corner layers within ASDisplayNode [\#1029](https://github.com/TextureGroup/Texture/pull/1029) ([maicki](https://github.com/maicki)) +- Split framework dependencies into separate subspecs [\#1028](https://github.com/TextureGroup/Texture/pull/1028) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove misleading comment and add assertion \#trivial [\#1027](https://github.com/TextureGroup/Texture/pull/1027) ([wiseoldduck](https://github.com/wiseoldduck)) +- Address warnings in Xcode \>= 9.3 about using %zd for NSInteger \#trivial [\#1026](https://github.com/TextureGroup/Texture/pull/1026) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix 32-bit simulator build on Xcode \>= 9.3 [\#1025](https://github.com/TextureGroup/Texture/pull/1025) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Stricter locking assertions [\#1024](https://github.com/TextureGroup/Texture/pull/1024) ([nguyenhuy](https://github.com/nguyenhuy)) +- Make sure -\_completePendingLayoutTransition is called without the node's instance lock \#trivial [\#1023](https://github.com/TextureGroup/Texture/pull/1023) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fix misleading/scary stack trace shown when an assertion occurs during node measurement [\#1022](https://github.com/TextureGroup/Texture/pull/1022) ([nguyenhuy](https://github.com/nguyenhuy)) +- Add an introduction for ASCornerLayoutSpec in layout2-layoutspec-types.md \#trivial [\#1021](https://github.com/TextureGroup/Texture/pull/1021) ([huang-kun](https://github.com/huang-kun)) +- Add showsHorizontal\(Vertical\)ScrollIndicator property applying from pending state \#trivial [\#1016](https://github.com/TextureGroup/Texture/pull/1016) ([maicki](https://github.com/maicki)) +- \[IGListKit\] Adds missing UIScrollViewDelegate method to DataSource proxy [\#1015](https://github.com/TextureGroup/Texture/pull/1015) ([wannabehero](https://github.com/wannabehero)) +- Introduce let / var macros and some further cleanup [\#1012](https://github.com/TextureGroup/Texture/pull/1012) ([maicki](https://github.com/maicki)) +- Properly consider node for responder methods [\#1008](https://github.com/TextureGroup/Texture/pull/1008) ([maicki](https://github.com/maicki)) +- Background image load api [\#1007](https://github.com/TextureGroup/Texture/pull/1007) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Add move detection and support to ASLayoutTransition [\#1006](https://github.com/TextureGroup/Texture/pull/1006) ([wiseoldduck](https://github.com/wiseoldduck)) +- Fix warnings and a memory leak \#trivial [\#1003](https://github.com/TextureGroup/Texture/pull/1003) ([maicki](https://github.com/maicki)) +- Rewrite Swift Example [\#1002](https://github.com/TextureGroup/Texture/pull/1002) ([maicki](https://github.com/maicki)) +- Remove yoga layout spec, which has been superseded [\#999](https://github.com/TextureGroup/Texture/pull/999) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Optimize drawing code + add examples how to round corners [\#996](https://github.com/TextureGroup/Texture/pull/996) ([maicki](https://github.com/maicki)) +- Fix typo in containers-asviewcontroller.md [\#989](https://github.com/TextureGroup/Texture/pull/989) ([muukii](https://github.com/muukii)) +- Create transfer-array method and use it [\#987](https://github.com/TextureGroup/Texture/pull/987) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add missing instance variables in ASTextNode and warnings cleanup \#trivial [\#984](https://github.com/TextureGroup/Texture/pull/984) ([maicki](https://github.com/maicki)) +- Optimize layout flattening [\#982](https://github.com/TextureGroup/Texture/pull/982) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Changed lost images to existing one. \#trivial [\#981](https://github.com/TextureGroup/Texture/pull/981) ([tataevr](https://github.com/tataevr)) +- \[texturegroup.org\] Use valid link for Upgrade to 2.0 beta 1 page \#trivial [\#980](https://github.com/TextureGroup/Texture/pull/980) ([mikezucc](https://github.com/mikezucc)) +- Adds support for having multiple interface state delegates. [\#979](https://github.com/TextureGroup/Texture/pull/979) ([garrettmoon](https://github.com/garrettmoon)) +- Create an experiment to remove extra collection teardown step [\#975](https://github.com/TextureGroup/Texture/pull/975) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove unused/unneeded header macros [\#973](https://github.com/TextureGroup/Texture/pull/973) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Standardize "extern" decls on AS\_EXTERN [\#972](https://github.com/TextureGroup/Texture/pull/972) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- ASConfiguration version check only when have json dict [\#971](https://github.com/TextureGroup/Texture/pull/971) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Pointer check [\#970](https://github.com/TextureGroup/Texture/pull/970) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Reduce usage of autorelease pools [\#968](https://github.com/TextureGroup/Texture/pull/968) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Update showcase to include Apollo for Reddit [\#967](https://github.com/TextureGroup/Texture/pull/967) ([christianselig](https://github.com/christianselig)) +- Fix crash when call needsMainThreadDeallocation on NSProxy instances \#trivial [\#965](https://github.com/TextureGroup/Texture/pull/965) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fix name typo \#trivial [\#963](https://github.com/TextureGroup/Texture/pull/963) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Generalize the main thread ivar deallocation system [\#959](https://github.com/TextureGroup/Texture/pull/959) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add support for acquiring multiple locks at once [\#958](https://github.com/TextureGroup/Texture/pull/958) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Clean up async transaction system a bit [\#955](https://github.com/TextureGroup/Texture/pull/955) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Added 'Waplog' to showcase. [\#953](https://github.com/TextureGroup/Texture/pull/953) ([malikkuru](https://github.com/malikkuru)) +- Make ASPerformMainThreadDeallocation visible in C [\#952](https://github.com/TextureGroup/Texture/pull/952) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Cut 2.7 release [\#949](https://github.com/TextureGroup/Texture/pull/949) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fixed removing node from supernode after layout transition [\#937](https://github.com/TextureGroup/Texture/pull/937) ([atitovdev](https://github.com/atitovdev)) +- add ASTextNode2 snapshot test [\#935](https://github.com/TextureGroup/Texture/pull/935) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- \[ASTextNode\] One more check variables before calling delegate method \#trivial [\#922](https://github.com/TextureGroup/Texture/pull/922) ([Flatout73](https://github.com/Flatout73)) +- Assert node did load before did enter visible way 1 [\#886](https://github.com/TextureGroup/Texture/pull/886) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Renew supplementary node on relayout [\#842](https://github.com/TextureGroup/Texture/pull/842) ([wsdwsd0829](https://github.com/wsdwsd0829)) -## 2.5 +## [2.7](https://github.com/TextureGroup/Texture/tree/2.7) (2018-05-29) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.6...2.7) -- [ASCollectionNode] Add -isProcessingUpdates and -onDidFinishProcessingUpdates: APIs. [#522](https://github.com/TextureGroup/Texture/pull/522) [Scott Goodson](https://github.com/appleguy) -- [Accessibility] Add .isAccessibilityContainer property, allowing automatic aggregation of children's a11y labels. [#468][Scott Goodson](https://github.com/appleguy) -- [ASImageNode] Enabled .clipsToBounds by default, fixing the use of .cornerRadius and clipping of GIFs. [Scott Goodson](https://github.com/appleguy) [#466](https://github.com/TextureGroup/Texture/pull/466) -- Fix an issue in layout transition that causes it to unexpectedly use the old layout [Huy Nguyen](https://github.com/nguyenhuy) [#464](https://github.com/TextureGroup/Texture/pull/464) -- Add -[ASDisplayNode detailedLayoutDescription] property to aid debugging. [Adlai Holler](https://github.com/Adlai-Holler) [#476](https://github.com/TextureGroup/Texture/pull/476) -- Fix an issue that causes calculatedLayoutDidChange being called needlessly. [Huy Nguyen](https://github.com/nguyenhuy) [#490](https://github.com/TextureGroup/Texture/pull/490) -- Negate iOS 11 automatic estimated table row heights. [Christian Selig](https://github.com/christianselig) [#485](https://github.com/TextureGroup/Texture/pull/485) -- Add content inset and offset bridging properties to ASTableNode and ASCollectionNode. Deprecate related properties and methods in ASTableView and ASCollectionView [Huy Nguyen](https://github.com/nguyenhuy) [#460](https://github.com/TextureGroup/Texture/pull/460) [#560](https://github.com/TextureGroup/Texture/pull/560) -- Remove re-entrant access to self.view when applying initial pending state. [Adlai Holler](https://github.com/Adlai-Holler) [#510](https://github.com/TextureGroup/Texture/pull/510) -- Small improvements in ASCollectionLayout [Huy Nguyen](https://github.com/nguyenhuy) [#509](https://github.com/TextureGroup/Texture/pull/509) [#513](https://github.com/TextureGroup/Texture/pull/513) [#562]((https://github.com/TextureGroup/Texture/pull/562) -- Fix retain cycle between ASImageNode and PINAnimatedImage [Phil Larson](https://github.com/plarson) [#520](https://github.com/TextureGroup/Texture/pull/520) -- Change the API for disabling logging from a compiler flag to a runtime C function ASDisableLogging(). [Adlai Holler](https://github.com/Adlai-Holler) [#528](https://github.com/TextureGroup/Texture/pull/528) -- Table and collection views to consider content inset when calculating (default) element size range [Huy Nguyen](https://github.com/nguyenhuy) [#525](https://github.com/TextureGroup/Texture/pull/525) -- [ASEditableTextNode] added -editableTextNodeShouldBeginEditing to ASEditableTextNodeDelegate to mirror the corresponding method from UITextViewDelegate. [Yan S.](https://github.com/yans) [#535](https://github.com/TextureGroup/Texture/pull/535) -- [Breaking] Remove APIs that have been deprecated since 2.0 and/or for at least 6 months [Huy Nguyen](https://github.com/nguyenhuy) [#529](https://github.com/TextureGroup/Texture/pull/529) -- [ASDisplayNode] Ensure `-displayWillStartAsynchronously:` and `-displayDidFinish` are invoked on rasterized subnodes. [Eric Scheers](https://github.com/smeis) [#532](https://github.com/TextureGroup/Texture/pull/532) -- Fixed a memory corruption issue in the ASImageNode display system. [Adlai Holler](https://github.com/Adlai-Holler) [#555](https://github.com/TextureGroup/Texture/pull/555) -- [Breaking] Rename ASCollectionGalleryLayoutSizeProviding to ASCollectionGalleryLayoutPropertiesProviding. Besides a fixed item size, it now can provide interitem and line spacings, as well as section inset [Huy Nguyen](https://github.com/nguyenhuy) [#496](https://github.com/TextureGroup/Texture/pull/496) [#533](https://github.com/TextureGroup/Texture/pull/533) -- Deprecate `-[ASDisplayNode displayWillStart]` in favor of `-displayWillStartAsynchronously:` [Huy Nguyen](https://github.com/nguyenhuy) [#536](https:/ -/github.com/TextureGroup/Texture/pull/536) -- Add support for URLs on ASNetworkImageNode. [Garrett Moon](https://github.com/garrettmoon) -- [ASImageNode] Always dealloc images in a background queue [Huy Nguyen](https://github.com/nguyenhuy) [#561](https://github.com/TextureGroup/Texture/pull/561) -- Mark ASRunLoopQueue as drained if it contains only NULLs [Cesar Estebanez](https://github.com/cesteban) [#558](https://github.com/TextureGroup/Texture/pull/558) -- Fix crashes caused by failing to unlock or destroy a static mutex while the app is being terminated [Huy Nguyen](https://github.com/nguyenhuy) +**Merged pull requests:** -## 2.4 -- Fix an issue where inserting/deleting sections could lead to inconsistent supplementary element behavior. [Adlai Holler](https://github.com/Adlai-Holler) -- Overhaul logging and add activity tracing support. [Adlai Holler](https://github.com/Adlai-Holler) -- Fix a crash where scrolling a table view after entering editing mode could lead to bad internal states in the table. [Huy Nguyen](https://github.com/nguyenhuy) [#416](https://github.com/TextureGroup/Texture/pull/416/) -- Fix a crash in collection view that occurs if batch updates are performed while scrolling [Huy Nguyen](https://github.com/nguyenhuy) [#378](https://github.com/TextureGroup/Texture/issues/378) -- Some improvements in ASCollectionView [Huy Nguyen](https://github.com/nguyenhuy) [#407](https://github.com/TextureGroup/Texture/pull/407) -- Small refactors in ASDataController [Huy Nguyen](https://github.com/TextureGroup/Texture/pull/443) [#443](https://github.com/TextureGroup/Texture/pull/443) -- [ASCollectionView] Add delegate bridging and index space translation for missing UICollectionViewLayout properties. [Scott Goodson](https://github.com/appleguy) -- [ASTextNode2] Add initial implementation for link handling. [Scott Goodson](https://github.com/appleguy) [#396](https://github.com/TextureGroup/Texture/pull/396) -- [ASTextNode2] Provide compile flag to globally enable new implementation of ASTextNode: ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE. [Scott Goodson](https://github.com/appleguy) [#396](https://github.com/TextureGroup/Texture/pull/410) -- Add ASCollectionGalleryLayoutDelegate - an async collection layout that makes same-size collections (e.g photo galleries, pagers, etc) fast and lightweight! [Huy Nguyen](https://github.com/nguyenhuy/) [#76](https://github.com/TextureGroup/Texture/pull/76) [#451](https://github.com/TextureGroup/Texture/pull/451) -- Fix an issue that causes infinite layout loop in ASDisplayNode after [#428](https://github.com/TextureGroup/Texture/pull/428) [Huy Nguyen](https://github.com/nguyenhuy) [#455](https://github.com/TextureGroup/Texture/pull/455) -- Rename ASCellNode.viewModel to ASCellNode.nodeModel to reduce collisions with subclass properties implemented by clients. [Adlai Holler](https://github.com/Adlai-Holler) [#504](https://github.com/TextureGroup/Texture/pull/504) +- Update AppIcon in showcase [\#946](https://github.com/TextureGroup/Texture/pull/946) ([muukii](https://github.com/muukii)) +- Update tip-1-nodeBlocks.md [\#943](https://github.com/TextureGroup/Texture/pull/943) ([sagarbhosale](https://github.com/sagarbhosale)) +- \[ASTableView\] Generate a new cell layout if existing ones are invalid [\#942](https://github.com/TextureGroup/Texture/pull/942) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update to unsplash [\#938](https://github.com/TextureGroup/Texture/pull/938) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASTextNode2\] Simplify compare-assign check & lock \_pointScaleFactors accessor \#trivial [\#934](https://github.com/TextureGroup/Texture/pull/934) ([appleguy](https://github.com/appleguy)) +- Create a new dealloc queue that is more efficient [\#931](https://github.com/TextureGroup/Texture/pull/931) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASImageNode+AnimatedImage\] Fix early return when animatedImage is nil in setAnimatedImage \#trivial [\#925](https://github.com/TextureGroup/Texture/pull/925) ([flovouin](https://github.com/flovouin)) +- Remove assert. fix \#878 \#914 [\#924](https://github.com/TextureGroup/Texture/pull/924) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Always call out to delegate for experiments, whether enabled or not [\#923](https://github.com/TextureGroup/Texture/pull/923) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASTextNode2\] Upgrade lock safety by protecting all ivars \(including rarely-changed ones\). [\#918](https://github.com/TextureGroup/Texture/pull/918) ([appleguy](https://github.com/appleguy)) +- \[ASCollectionNode/ASTableNode\] Fix a crash occurs while remeasuring cell nodes [\#917](https://github.com/TextureGroup/Texture/pull/917) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASDisplayNode\] Improve thread-safety of didExitHierarchy \#trivial [\#916](https://github.com/TextureGroup/Texture/pull/916) ([nguyenhuy](https://github.com/nguyenhuy)) +- Prevent UITextView from updating contentOffset while deallocating [\#915](https://github.com/TextureGroup/Texture/pull/915) ([maicki](https://github.com/maicki)) +- Fix ASDKgram-Swift to avoid 'error parsing JSON within PhotoModel Init' [\#913](https://github.com/TextureGroup/Texture/pull/913) ([kenstir](https://github.com/kenstir)) +- \#trivial Add forgotten experiment into Schemas/configuration.json [\#912](https://github.com/TextureGroup/Texture/pull/912) ([garrettmoon](https://github.com/garrettmoon)) +- \#trivial Fix the C++ assertion [\#911](https://github.com/TextureGroup/Texture/pull/911) ([garrettmoon](https://github.com/garrettmoon)) +- Add 'iDiva - Beauty & Wedding tips' to Showcase [\#909](https://github.com/TextureGroup/Texture/pull/909) ([sudhanshutil](https://github.com/sudhanshutil)) +- Issue ASNetworkImageNode callbacks off main thread [\#908](https://github.com/TextureGroup/Texture/pull/908) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASTextNode\] Fix a deadlock that could occur when enabling experimental ASTextNode2 via ASConfiguration [\#903](https://github.com/TextureGroup/Texture/pull/903) ([appleguy](https://github.com/appleguy)) +- \[Docs\] Add new lightning talk from Buffer \#trivial [\#902](https://github.com/TextureGroup/Texture/pull/902) ([ay8s](https://github.com/ay8s)) +- Request std=c++11 dialect again, and add warning [\#900](https://github.com/TextureGroup/Texture/pull/900) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASTextNode\] Check variables before calling delegate method \#trivial [\#898](https://github.com/TextureGroup/Texture/pull/898) ([Jauzee](https://github.com/Jauzee)) +- ASDKFastImageNamed UIImage initializer nullability \#trivial [\#897](https://github.com/TextureGroup/Texture/pull/897) ([alexhillc](https://github.com/alexhillc)) +- \#trivial Fixes an issue where playback may not start [\#896](https://github.com/TextureGroup/Texture/pull/896) ([garrettmoon](https://github.com/garrettmoon)) +- Update configuration schema \#trivial [\#893](https://github.com/TextureGroup/Texture/pull/893) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- replace ` with code in containers-overview.md [\#884](https://github.com/TextureGroup/Texture/pull/884) ([everettjf](https://github.com/everettjf)) +- \[Docs\] Fix typos in layout specs section \#trivial [\#883](https://github.com/TextureGroup/Texture/pull/883) ([morozkin](https://github.com/morozkin)) +- Match interfacestate update sequence to uikit [\#882](https://github.com/TextureGroup/Texture/pull/882) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Add experiment to skip creating UIViews altogether for constants [\#881](https://github.com/TextureGroup/Texture/pull/881) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix ASDISPLAYNODE\_ASSERTIONS\_ENABLED and ASDefaultPlaybackButton warnings \#trivial [\#880](https://github.com/TextureGroup/Texture/pull/880) ([maicki](https://github.com/maicki)) +- Fix macro definition for AS\_KDEBUG\_ENABLE producing warning \#trivial [\#879](https://github.com/TextureGroup/Texture/pull/879) ([andrewrohn](https://github.com/andrewrohn)) +- Fix pager node for interface coalescing [\#877](https://github.com/TextureGroup/Texture/pull/877) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Standardize Property Declaration Style in Core Classes [\#870](https://github.com/TextureGroup/Texture/pull/870) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[NoCopyRendering\] In non-VM case, use calloc to get a zerod buffer \#trivial [\#869](https://github.com/TextureGroup/Texture/pull/869) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Check in Xcode 9.3 "workspace checks" file [\#868](https://github.com/TextureGroup/Texture/pull/868) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove Redundant Atomic Store from Recursive Unfair Lock in Recursive Case \#trivial [\#867](https://github.com/TextureGroup/Texture/pull/867) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Update Podspec [\#866](https://github.com/TextureGroup/Texture/pull/866) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[Issue 838\] Update ASCeilPixelValue and ASRoundPixelValue [\#864](https://github.com/TextureGroup/Texture/pull/864) ([rcancro](https://github.com/rcancro)) +- Disable interface coalescing [\#862](https://github.com/TextureGroup/Texture/pull/862) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Introduce ASRecursiveUnfairLock and tests [\#858](https://github.com/TextureGroup/Texture/pull/858) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Make NSIndexSet+ASHelpers.h reference local \#trivial [\#857](https://github.com/TextureGroup/Texture/pull/857) ([dmaclach](https://github.com/dmaclach)) +- Make ASBatchContext lock-free \#trivial [\#854](https://github.com/TextureGroup/Texture/pull/854) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASNetworkImageNode\] Replace NSUUID sentinel with integer \#trivial [\#852](https://github.com/TextureGroup/Texture/pull/852) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Make objects conform to NSLocking [\#851](https://github.com/TextureGroup/Texture/pull/851) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Make cache support animated image [\#850](https://github.com/TextureGroup/Texture/pull/850) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- \[bugfix\] Align timing of interface coalescing and range update. \#trivial [\#847](https://github.com/TextureGroup/Texture/pull/847) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Update layout2-layout-element-properties.md [\#844](https://github.com/TextureGroup/Texture/pull/844) ([arielelkin](https://github.com/arielelkin)) +- Use NS\_RETURNS\_RETAINED macro to save time [\#843](https://github.com/TextureGroup/Texture/pull/843) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Handle nil backgroundColor in ASTextNode2 \#trivial [\#841](https://github.com/TextureGroup/Texture/pull/841) ([maicki](https://github.com/maicki)) +- Put back VM flag in ASCGImageBuffer [\#839](https://github.com/TextureGroup/Texture/pull/839) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Order items in XCode project navigator by name [\#835](https://github.com/TextureGroup/Texture/pull/835) ([OleksiyA](https://github.com/OleksiyA)) +- \[NoCopyRendering\] Use vm instead of malloc [\#833](https://github.com/TextureGroup/Texture/pull/833) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASTextNode2\] Fix background color drawing [\#831](https://github.com/TextureGroup/Texture/pull/831) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix Text Node Thread Sanitizer Warning [\#830](https://github.com/TextureGroup/Texture/pull/830) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- access view first before checking canBecome/Resign responder in becomeResponder methods [\#829](https://github.com/TextureGroup/Texture/pull/829) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- \[\#trivial\] fixes rendered image quality on networked image nodes whic… [\#826](https://github.com/TextureGroup/Texture/pull/826) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASTextNode\] Fix locking, add test for issue \#trivial [\#825](https://github.com/TextureGroup/Texture/pull/825) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[\#trivial\] I don't think we need this extra locked method. [\#824](https://github.com/TextureGroup/Texture/pull/824) ([garrettmoon](https://github.com/garrettmoon)) +- \#trivial Hopefully made this a bit more readable. [\#823](https://github.com/TextureGroup/Texture/pull/823) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASTextNode\] Avoid acquiring instance lock multiple times \#trivial [\#820](https://github.com/TextureGroup/Texture/pull/820) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Showcase\] Fix mensXP showcase and attach Vingle-Tech-Talk Medium [\#818](https://github.com/TextureGroup/Texture/pull/818) ([GeekTree0101](https://github.com/GeekTree0101)) +- \[ASDisplayNode\] Add unit tests for layout z-order changes \(with an open issue to fix\). [\#816](https://github.com/TextureGroup/Texture/pull/816) ([appleguy](https://github.com/appleguy)) +- \[ASDKGram Example\] image\_url has been changed from URL string to Array by 5… [\#813](https://github.com/TextureGroup/Texture/pull/813) ([kaar3k](https://github.com/kaar3k)) +- Replace pthread specifics with C11 thread-local variables [\#811](https://github.com/TextureGroup/Texture/pull/811) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Upgrade dangerfile [\#810](https://github.com/TextureGroup/Texture/pull/810) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASDisplayNode\] Fix an issue that causes a node to sometimes return an outdated calculated size or size range [\#808](https://github.com/TextureGroup/Texture/pull/808) ([nguyenhuy](https://github.com/nguyenhuy)) +- Avoid triggering main thread assertions in collection/table dealloc \#trivial [\#803](https://github.com/TextureGroup/Texture/pull/803) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Update IGListKit dependency to allow for updated versions [\#802](https://github.com/TextureGroup/Texture/pull/802) ([johntmcintosh](https://github.com/johntmcintosh)) +- \[ASDisplayNode\] Consolidate main thread initialization and allow apps to invoke it manually instead of +load. [\#798](https://github.com/TextureGroup/Texture/pull/798) ([appleguy](https://github.com/appleguy)) +- \[ASWrapperCellNode\] Introduce a new class allowing more control of UIKit passthrough cells. [\#797](https://github.com/TextureGroup/Texture/pull/797) ([appleguy](https://github.com/appleguy)) +- Add missing scrollViewWillEndDragging passthrough delegate [\#796](https://github.com/TextureGroup/Texture/pull/796) ([xezero](https://github.com/xezero)) +- Fix ASTextNode2 is accessing backgroundColor off main while sizing / layout is happening [\#794](https://github.com/TextureGroup/Texture/pull/794) ([maicki](https://github.com/maicki)) +- \[ASTableNode & ASCollectionNode\] Keepalive reference for node if their view is necessarily alive \(has a superview\). [\#793](https://github.com/TextureGroup/Texture/pull/793) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- \[ASDisplayNode layout\] Fix an issue that sometimes causes a node's pending layout to not be applied [\#792](https://github.com/TextureGroup/Texture/pull/792) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASRangeController\] Fix stability of "minimum" rangeMode if the app has more than one layout before scrolling. [\#790](https://github.com/TextureGroup/Texture/pull/790) ([appleguy](https://github.com/appleguy)) +- Fix UIResponder handling with view backing ASDisplayNode [\#789](https://github.com/TextureGroup/Texture/pull/789) ([maicki](https://github.com/maicki)) +- New runloop queue to coalesce Interface state update calls. [\#788](https://github.com/TextureGroup/Texture/pull/788) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- \[Graphics contexts\] Retain the reference color space \#trivial [\#784](https://github.com/TextureGroup/Texture/pull/784) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Get CatDealsCollectionView example running again \#trivial [\#783](https://github.com/TextureGroup/Texture/pull/783) ([maicki](https://github.com/maicki)) +- Improve nullable annotations for \_ASDisplayLayer and \_ASDisplayView \#trivial [\#780](https://github.com/TextureGroup/Texture/pull/780) ([maicki](https://github.com/maicki)) +- \[ASDisplayNode\] Force a layout pass on a visible node as soon as it enters preload state [\#779](https://github.com/TextureGroup/Texture/pull/779) ([nguyenhuy](https://github.com/nguyenhuy)) +- Improve ASNetworkImageNode delegate callout behavior [\#778](https://github.com/TextureGroup/Texture/pull/778) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix capturing self in the block while loading image in ASNetworkImageNode [\#777](https://github.com/TextureGroup/Texture/pull/777) ([morozkin](https://github.com/morozkin)) +- Fix synchronous state of node if +viewClass or +layerClass is overwritten \#trivial [\#776](https://github.com/TextureGroup/Texture/pull/776) ([maicki](https://github.com/maicki)) +- Add support for providing additional info to network image node delegate [\#775](https://github.com/TextureGroup/Texture/pull/775) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Expose asyncdisplaykit\_node in \_ASDisplayView same as in \_ASDisplayLayer \#trivial [\#773](https://github.com/TextureGroup/Texture/pull/773) ([maicki](https://github.com/maicki)) +- Improve no-copy rendering experiment, remove +load method [\#771](https://github.com/TextureGroup/Texture/pull/771) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix typos in layout2-layoutspec-types.md \#trivial [\#770](https://github.com/TextureGroup/Texture/pull/770) ([morozkin](https://github.com/morozkin)) +- Update PINCache [\#769](https://github.com/TextureGroup/Texture/pull/769) ([justinswart](https://github.com/justinswart)) +- Fix misprint \#trivial [\#768](https://github.com/TextureGroup/Texture/pull/768) ([Flatout73](https://github.com/Flatout73)) +- NoCopyRendering experiment: Fix possible memory leak if image node rendering is canceled \#trivial [\#765](https://github.com/TextureGroup/Texture/pull/765) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Node tint color [\#764](https://github.com/TextureGroup/Texture/pull/764) ([ShogunPhyched](https://github.com/ShogunPhyched)) +- Revert "Faster collection operations" [\#759](https://github.com/TextureGroup/Texture/pull/759) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASPrimitiveTraitCollection\] Always treat preferredContentSize as a potential nil \#trivial [\#757](https://github.com/TextureGroup/Texture/pull/757) ([ypogribnyi](https://github.com/ypogribnyi)) +- Update subclassing.md [\#753](https://github.com/TextureGroup/Texture/pull/753) ([janechoi6](https://github.com/janechoi6)) +- \[ASDisplayNode\] Don't force a layout pass on a visible node that enters preload state [\#751](https://github.com/TextureGroup/Texture/pull/751) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fix the dangerfile [\#750](https://github.com/TextureGroup/Texture/pull/750) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASDisplayNode\] Always return the thread-safe cornerRadius property, even in slow CALayer rounding mode [\#749](https://github.com/TextureGroup/Texture/pull/749) ([nguyenhuy](https://github.com/nguyenhuy)) +- Faster collection operations [\#748](https://github.com/TextureGroup/Texture/pull/748) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Create a centralized configuration API [\#747](https://github.com/TextureGroup/Texture/pull/747) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Update dangerfile for 2018 \#trivial [\#746](https://github.com/TextureGroup/Texture/pull/746) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Raise deployment target to iOS 9 [\#743](https://github.com/TextureGroup/Texture/pull/743) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add an experimental "no-copy" renderer [\#741](https://github.com/TextureGroup/Texture/pull/741) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fixed: completeBatchFetching is called on a background thread [\#731](https://github.com/TextureGroup/Texture/pull/731) ([aaronr93](https://github.com/aaronr93)) +- \[tvOS\] Fixes errors when building against tvOS SDK [\#728](https://github.com/TextureGroup/Texture/pull/728) ([alexhillc](https://github.com/alexhillc)) +- \[ASCellNode\] focusStyle mapping [\#727](https://github.com/TextureGroup/Texture/pull/727) ([alexhillc](https://github.com/alexhillc)) +- \[ASDisplayNode\] Provide safeAreaInsets and layoutMargins bridge [\#685](https://github.com/TextureGroup/Texture/pull/685) ([ypogribnyi](https://github.com/ypogribnyi)) +- \[ASTraitCollection\] Add missing properties to ASTraitCollection [\#625](https://github.com/TextureGroup/Texture/pull/625) ([ypogribnyi](https://github.com/ypogribnyi)) -## 2.3.4 -- [Yoga] Rewrite YOGA_TREE_CONTIGUOUS mode with improved behavior and cleaner integration [Scott Goodson](https://github.com/appleguy) -- [ASTraitCollection] Convert ASPrimitiveTraitCollection from lock to atomic. [Scott Goodson](https://github.com/appleguy) -- Add a synchronous mode to ASCollectionNode, for colletion view data source debugging. [Hannah Troisi](https://github.com/hannahmbanana) -- [ASDisplayNode+Layout] Add check for orphaned nodes after layout transition to clean up. #336. [Scott Goodson](https://github.com/appleguy) -- Fixed an issue where GIFs with placeholders never had their placeholders uncover the GIF. [Garrett Moon](https://github.com/garrettmoon) -- [Yoga] Implement ASYogaLayoutSpec, a simplified integration strategy for Yoga-powered layout calculation. [Scott Goodson](https://github.com/appleguy) -- Fixed an issue where calls to setNeedsDisplay and setNeedsLayout would stop working on loaded nodes. [Garrett Moon](https://github.com/garrettmoon) -- Migrated unit tests to OCMock 3.4 (from 2.2) and improved the multiplex image node tests. [Adlai Holler](https://github.com/Adlai-Holler) -- Fix CollectionNode double-load issue. This should significantly improve performance in cases where a collection node has content immediately available on first layout i.e. not fetched from the network. [Adlai Holler](https://github.com/Adlai-Holler) -- Overhaul layout flattening algorithm [Huy Nguyen](https://github.com/nguyenhuy) [#395](https://github.com/TextureGroup/Texture/pull/395). +## [2.6](https://github.com/TextureGroup/Texture/tree/2.6) (2018-01-12) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.5.1...2.6) -## 2.3.3 -- [ASTextKitFontSizeAdjuster] Replace use of NSAttributedString's boundingRectWithSize:options:context: with NSLayoutManager's boundingRectForGlyphRange:inTextContainer: [Ricky Cancro](https://github.com/rcancro) -- Add support for IGListKit post-removal-of-IGListSectionType, in preparation for IGListKit 3.0.0 release. [Adlai Holler](https://github.com/Adlai-Holler) [#49](https://github.com/TextureGroup/Texture/pull/49) -- Fix `__has_include` check in ASLog.h [Philipp Smorygo](Philipp.Smorygo@jetbrains.com) -- Fix potential deadlock in ASControlNode [Garrett Moon](https://github.com/garrettmoon) -- [Yoga Beta] Improvements to the experimental support for Yoga layout [Scott Goodson](appleguy) -- Make cell node `indexPath` and `supplementaryElementKind` atomic so you can read from any thread. [Adlai-Holler](https://github.com/Adlai-Holler) [#49](https://github.com/TextureGroup/Texture/pull/74) -- Update the rasterization API and un-deprecate it. [Adlai Holler](https://github.com/Adlai-Holler)[#82](https://github.com/TextureGroup/Texture/pull/49) -- Simplified & optimized hashing code. [Adlai Holler](https://github.com/Adlai-Holler) [#86](https://github.com/TextureGroup/Texture/pull/86) -- Improve the performance & safety of ASDisplayNode subnodes. [Adlai Holler](https://github.com/Adlai-Holler) [#223](https://github.com/TextureGroup/Texture/pull/223) -- Move more properties from ASTableView, ASCollectionView to their respective node classes. [Adlai Holler](https://github.com/Adlai-Holler) -- Remove finalLayoutElement [Michael Schneider](https://github.com/maicki)[#96](https://github.com/TextureGroup/Texture/pull/96) -- Add ASPageTable - A map table for fast retrieval of objects within a certain page [Huy Nguyen](https://github.com/nguyenhuy) -- Add new public `-supernodes`, `-supernodesIncludingSelf`, and `-supernodeOfClass:includingSelf:` methods. [Adlai Holler](https://github.com/Adlai-Holler)[#246](https://github.com/TextureGroup/Texture/pull/246) -- Improve our handling supernode traversal to avoid loading layers and fix assertion failures you might hit in debug. [Adlai Holler](https://github.com/Adlai-Holler)[#246](https://github.com/TextureGroup/Texture/pull/246) -- [ASDisplayNode] Pass drawParameter in rendering context callbacks [Michael Schneider](https://github.com/maicki)[#248](https://github.com/TextureGroup/Texture/pull/248) -- [ASTextNode] Move to class method of drawRect:withParameters:isCancelled:isRasterizing: for drawing [Michael Schneider](https://github.com/maicki)[#232](https://github.com/TextureGroup/Texture/pull/232) -- [ASDisplayNode] Remove instance:-drawRect:withParameters:isCancelled:isRasterizing: (https://github.com/maicki)[#232](https://github.com/TextureGroup/Texture/pull/232) -- [ASTextNode] Add an experimental new implementation. See `+[ASTextNode setExperimentOptions:]`. [Adlai Holler](https://github.com/Adlai-Holler)[#259](https://github.com/TextureGroup/Texture/pull/259) -- [ASVideoNode] Added error reporing to ASVideoNode and it's delegate [#260](https://github.com/TextureGroup/Texture/pull/260) -- [ASCollectionNode] Fixed conversion of item index paths between node & view. [Adlai Holler](https://github.com/Adlai-Holler) [#262](https://github.com/TextureGroup/Texture/pull/262) -- [Layout] Extract layout implementation code into it's own subcategories [Michael Schneider](https://github.com/maicki)[#272](https://github.com/TextureGroup/Texture/pull/272) -- [Fix] Fix a potential crash when cell nodes that need layout are deleted during the same runloop. [Adlai Holler](https://github.com/Adlai-Holler) [#279](https://github.com/TextureGroup/Texture/pull/279) -- [Batch fetching] Add ASBatchFetchingDelegate that takes scroll velocity and remaining time into account [Huy Nguyen](https://github.com/nguyenhuy) [#281](https://github.com/TextureGroup/Texture/pull/281) -- [Fix] Fix a major regression in our image node contents caching. [Adlai Holler](https://github.com/Adlai-Holler) [#287](https://github.com/TextureGroup/Texture/pull/287) -- [Fix] Fixed a bug where ASVideoNodeDelegate error reporting callback would crash an app because of not responding to selector. [Sergey Petrachkov](https://github.com/Petrachkov) [#291](https://github.com/TextureGroup/Texture/issues/291) -- [IGListKit] Add IGListKit headers to public section of Xcode project [Michael Schneider](https://github.com/maicki)[#286](https://github.com/TextureGroup/Texture/pull/286) -- [Layout] Ensure -layout and -layoutDidFinish are called only if a node is loaded. [Huy Nguyen](https://github.com/nguyenhuy) [#285](https://github.com/TextureGroup/Texture/pull/285) -- [Layout Debugger] Small changes needed for the coming layout debugger [Huy Nguyen](https://github.com/nguyenhuy) [#337](https://github.com/TextureGroup/Texture/pull/337) +**Merged pull requests:** + +- Add MensXP to Showcase [\#739](https://github.com/TextureGroup/Texture/pull/739) ([sudhanshutil](https://github.com/sudhanshutil)) +- Enable collection node interactive moves [\#735](https://github.com/TextureGroup/Texture/pull/735) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add Blendle to our showcase page [\#721](https://github.com/TextureGroup/Texture/pull/721) ([nguyenhuy](https://github.com/nguyenhuy)) +- \#trivial Fixes image nodes being stuck not being able to download image [\#720](https://github.com/TextureGroup/Texture/pull/720) ([garrettmoon](https://github.com/garrettmoon)) +- Reimplement ASRectTable using unordered\_map to avoid obscure NSMapTable exception. [\#719](https://github.com/TextureGroup/Texture/pull/719) ([appleguy](https://github.com/appleguy)) +- Add missing flags for ASCollectionDelegate [\#718](https://github.com/TextureGroup/Texture/pull/718) ([ilyailya](https://github.com/ilyailya)) +- Add support for toggling logs off and back on at runtime [\#714](https://github.com/TextureGroup/Texture/pull/714) ([johntmcintosh](https://github.com/johntmcintosh)) +- \[Update Showcase\] Update Showcase, add Vingle very community [\#711](https://github.com/TextureGroup/Texture/pull/711) ([GeekTree0101](https://github.com/GeekTree0101)) +- \[ASCollectionElement\] Check for nil elements on ASTableView as well. [\#710](https://github.com/TextureGroup/Texture/pull/710) ([cesteban](https://github.com/cesteban)) +- Ensure an ASM enabled node applies its pending layout when enters preload state [\#706](https://github.com/TextureGroup/Texture/pull/706) ([nguyenhuy](https://github.com/nguyenhuy)) +- The ASDKgram example doesn't compile. [\#700](https://github.com/TextureGroup/Texture/pull/700) ([onato](https://github.com/onato)) +- Revert Adds support for specifying a quality indexed array of URLs [\#699](https://github.com/TextureGroup/Texture/pull/699) ([garrettmoon](https://github.com/garrettmoon)) +- Correct Synchronous Concurrency Talk Link [\#698](https://github.com/TextureGroup/Texture/pull/698) ([ay8s](https://github.com/ay8s)) +- \[ASDisplayNode+Layout\] Ensure a pending layout is applied once [\#695](https://github.com/TextureGroup/Texture/pull/695) ([nguyenhuy](https://github.com/nguyenhuy)) +- Add missing \ tags in Layout API Sizing docs [\#691](https://github.com/TextureGroup/Texture/pull/691) ([richardhenry](https://github.com/richardhenry)) +- Fix bug that breaks ASNodeController docs page [\#690](https://github.com/TextureGroup/Texture/pull/690) ([richardhenry](https://github.com/richardhenry)) +- Add a recent talk by @smeis at CocoaHeadsNL [\#687](https://github.com/TextureGroup/Texture/pull/687) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update subtree-rasterization.md [\#679](https://github.com/TextureGroup/Texture/pull/679) ([WymzeeLabs](https://github.com/WymzeeLabs)) +- Update layer-backing.md [\#678](https://github.com/TextureGroup/Texture/pull/678) ([WymzeeLabs](https://github.com/WymzeeLabs)) +- \[iOS11\] Update project settings and fix errors [\#676](https://github.com/TextureGroup/Texture/pull/676) ([Eke](https://github.com/Eke)) +- Fix swift sample. [\#669](https://github.com/TextureGroup/Texture/pull/669) ([rwinzhang](https://github.com/rwinzhang)) +- Bugfix/fix yoga logging aligning api changes [\#668](https://github.com/TextureGroup/Texture/pull/668) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- Make it possible to map between sections even if they're empty [\#660](https://github.com/TextureGroup/Texture/pull/660) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASCornerLayoutSpec\] New layout spec class for declarative corner element layout. [\#657](https://github.com/TextureGroup/Texture/pull/657) ([huang-kun](https://github.com/huang-kun)) +- Update layout2-layoutspec-types.md [\#655](https://github.com/TextureGroup/Texture/pull/655) ([TBXark](https://github.com/TBXark)) +- \[Minor Breaking API\] Make deallocation queues more reliable [\#651](https://github.com/TextureGroup/Texture/pull/651) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Make the framework backwards compatible with Xcode 8 [\#650](https://github.com/TextureGroup/Texture/pull/650) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Disable this test for now, it's too flakey and no one has time to inv… [\#649](https://github.com/TextureGroup/Texture/pull/649) ([garrettmoon](https://github.com/garrettmoon)) +- \[Documentation\] Update Inversion Docs [\#647](https://github.com/TextureGroup/Texture/pull/647) ([GeekTree0101](https://github.com/GeekTree0101)) +- Have ASNetworkImageNode report whether images were cached or not [\#639](https://github.com/TextureGroup/Texture/pull/639) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix a layout deadlock caused by holding the lock and going up the tree. [\#638](https://github.com/TextureGroup/Texture/pull/638) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASScrollNode\] Fix small bugs and add unit tests [\#637](https://github.com/TextureGroup/Texture/pull/637) ([nguyenhuy](https://github.com/nguyenhuy)) +- A couple performance tweaks for animated images \#trivial [\#634](https://github.com/TextureGroup/Texture/pull/634) ([garrettmoon](https://github.com/garrettmoon)) +- \[Documentation\] Update "Getting Started" page [\#633](https://github.com/TextureGroup/Texture/pull/633) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Tests\] Add test scrollToPageAtIndex ASPagerNode [\#629](https://github.com/TextureGroup/Texture/pull/629) ([remirobert](https://github.com/remirobert)) +- \[Tests\] Introducing tests for the ASTabBarController [\#628](https://github.com/TextureGroup/Texture/pull/628) ([remirobert](https://github.com/remirobert)) +- \[Tests\] Introducing tests for the ASNavigationController [\#627](https://github.com/TextureGroup/Texture/pull/627) ([remirobert](https://github.com/remirobert)) +- \[ASCollectionView\] Call -invalidateFlowLayoutDelegateMetrics when rotating. \#trivial [\#616](https://github.com/TextureGroup/Texture/pull/616) ([appleguy](https://github.com/appleguy)) +- Add unit tests for the layout engine [\#424](https://github.com/TextureGroup/Texture/pull/424) ([Adlai-Holler](https://github.com/Adlai-Holler)) + +## [2.5.1](https://github.com/TextureGroup/Texture/tree/2.5.1) (2017-10-24) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.5...2.5.1) + +**Merged pull requests:** + +- Dispatch batch update to main \#trivial [\#626](https://github.com/TextureGroup/Texture/pull/626) ([garrettmoon](https://github.com/garrettmoon)) +- Check if we need to do a batch update [\#624](https://github.com/TextureGroup/Texture/pull/624) ([garrettmoon](https://github.com/garrettmoon)) +- Fix naming conflict with YYText \#trivial [\#623](https://github.com/TextureGroup/Texture/pull/623) ([maicki](https://github.com/maicki)) +- Fix "This block and function declaration is not a prototype" warning. [\#619](https://github.com/TextureGroup/Texture/pull/619) ([mbesnili](https://github.com/mbesnili)) +- update Pinterest CDN URL in example code [\#613](https://github.com/TextureGroup/Texture/pull/613) ([derekargueta](https://github.com/derekargueta)) +- \[ASTextKitComponents\] Make sure Main Thread Checker isn't triggered during background calculations \#trivial [\#612](https://github.com/TextureGroup/Texture/pull/612) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASTextKitComponents\] Temporary components can be deallocated off main \#trivial [\#610](https://github.com/TextureGroup/Texture/pull/610) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update layout2-layoutspec-types.md [\#608](https://github.com/TextureGroup/Texture/pull/608) ([olcayertas](https://github.com/olcayertas)) +- Don't set download results if no longer in preload range. [\#606](https://github.com/TextureGroup/Texture/pull/606) ([garrettmoon](https://github.com/garrettmoon)) +- Animated WebP support [\#605](https://github.com/TextureGroup/Texture/pull/605) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASVideoNode\] Time observer fix [\#604](https://github.com/TextureGroup/Texture/pull/604) ([flovouin](https://github.com/flovouin)) +- Add assertion in dealloc that it is on main in ASTextKitComponents \#trivial [\#603](https://github.com/TextureGroup/Texture/pull/603) ([maicki](https://github.com/maicki)) +- ASTextKitComponents needs to be deallocated on main [\#598](https://github.com/TextureGroup/Texture/pull/598) ([maicki](https://github.com/maicki)) +- update faq toc links to match the generated html id \#trivial [\#597](https://github.com/TextureGroup/Texture/pull/597) ([romankl](https://github.com/romankl)) +- \[PINCache\] Set a default .byteLimit to reduce disk usage & startup time. [\#595](https://github.com/TextureGroup/Texture/pull/595) ([appleguy](https://github.com/appleguy)) +- Move clearing out of ASTextKitComponents property delegates into ASTextKitComponents dealloc \#trivial [\#591](https://github.com/TextureGroup/Texture/pull/591) ([maicki](https://github.com/maicki)) +- Clear ivar after scheduling for main thread deallocation \#trivial [\#590](https://github.com/TextureGroup/Texture/pull/590) ([maicki](https://github.com/maicki)) +- Use Nil for "no class" instead of nil \#trivial [\#589](https://github.com/TextureGroup/Texture/pull/589) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Update showcase.md [\#587](https://github.com/TextureGroup/Texture/pull/587) ([hannahmbanana](https://github.com/hannahmbanana)) +- Rolling back CI to known version for now [\#585](https://github.com/TextureGroup/Texture/pull/585) ([garrettmoon](https://github.com/garrettmoon)) +- Use node lock instead of separate one to avoid deadlocks. [\#582](https://github.com/TextureGroup/Texture/pull/582) ([garrettmoon](https://github.com/garrettmoon)) +- \[\_ASPendingState\] Make sure accessibility strings are not nil before allocating attributed strings for them \#trivial [\#581](https://github.com/TextureGroup/Texture/pull/581) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASTextNode\] Implement an example comparing ASTextNode 1 & 2 behavior. [\#570](https://github.com/TextureGroup/Texture/pull/570) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- \[ASCollectionView\] Fix index space translation of Flow Layout Delegate methods. [\#467](https://github.com/TextureGroup/Texture/pull/467) ([appleguy](https://github.com/appleguy)) +- \[ASCollectionView\] Improve performance and behavior of rotation / bounds changes. [\#431](https://github.com/TextureGroup/Texture/pull/431) ([appleguy](https://github.com/appleguy)) + +## [2.5](https://github.com/TextureGroup/Texture/tree/2.5) (2017-09-26) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/v2.5...2.5) + +**Merged pull requests:** + +- Fix crashes caused by failing to unlock or destroy a static mutex while the app is being terminated [\#577](https://github.com/TextureGroup/Texture/pull/577) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update yoga version [\#569](https://github.com/TextureGroup/Texture/pull/569) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- \[ASDKgram Example\] fix crash on startup [\#566](https://github.com/TextureGroup/Texture/pull/566) ([hannahmbanana](https://github.com/hannahmbanana)) +- Added attributed versions of accessibilityLabel, accessibilityHint, accessibilityValue [\#554](https://github.com/TextureGroup/Texture/pull/554) ([fruitcoder](https://github.com/fruitcoder)) +- \[Yoga\] Add insertYogaNode:atIndex: method. Improve handling of relayouts. [\#469](https://github.com/TextureGroup/Texture/pull/469) ([appleguy](https://github.com/appleguy)) +- \[ASCornerRounding\] Introduce .cornerRoundingType: CALayer, Precomposited, or Clip Corners. [\#465](https://github.com/TextureGroup/Texture/pull/465) ([appleguy](https://github.com/appleguy)) +- \[ASElementMap\] Fix indexPath's section or item is actually negative \#trivial [\#457](https://github.com/TextureGroup/Texture/pull/457) ([Anyewuya](https://github.com/Anyewuya)) + +## [v2.5](https://github.com/TextureGroup/Texture/tree/v2.5) (2017-09-14) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.4...v2.5) + +**Merged pull requests:** + +- Fix -\[ASPagerNode view\] triggering pendingState + nodeLoaded assert \#trivial [\#564](https://github.com/TextureGroup/Texture/pull/564) ([samhsiung](https://github.com/samhsiung)) +- \[ASCollectionLayout\] Exclude content inset on scrollable directions from viewport size [\#562](https://github.com/TextureGroup/Texture/pull/562) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASImageNode\] Always dealloc images in a background queue [\#561](https://github.com/TextureGroup/Texture/pull/561) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASCollectionNode\]\[ASTableNode\] Add content inset bridging property [\#560](https://github.com/TextureGroup/Texture/pull/560) ([nguyenhuy](https://github.com/nguyenhuy)) +- Mark ASRunLoopQueue as drained if it contains only NULLs [\#558](https://github.com/TextureGroup/Texture/pull/558) ([cesteban](https://github.com/cesteban)) +- Adds support for specifying a quality indexed array of URLs [\#557](https://github.com/TextureGroup/Texture/pull/557) ([garrettmoon](https://github.com/garrettmoon)) +- Make ASWeakMapEntry Value Atomic [\#555](https://github.com/TextureGroup/Texture/pull/555) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASDisplayNode\] Deprecate -displayWillStart in favor of -displayWillStartAsynchronously: [\#536](https://github.com/TextureGroup/Texture/pull/536) ([nguyenhuy](https://github.com/nguyenhuy)) +- SEP-491 prerequisite: add textViewShouldBeginEditing: to ASEditableTextNodeDelegate [\#535](https://github.com/TextureGroup/Texture/pull/535) ([yans](https://github.com/yans)) +- \[Gallery layout\] Include the caller in properties providing methods [\#533](https://github.com/TextureGroup/Texture/pull/533) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASDisplayNode\] Notify rasterized subnodes that render pass has completed [\#532](https://github.com/TextureGroup/Texture/pull/532) ([smeis](https://github.com/smeis)) +- \[Cleanup\] Remove deprecated APIs [\#529](https://github.com/TextureGroup/Texture/pull/529) ([nguyenhuy](https://github.com/nguyenhuy)) +- Add a function to disable all logging at runtime [\#528](https://github.com/TextureGroup/Texture/pull/528) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[Table and collection views\] Consider content inset when calculating \(default\) element size range [\#525](https://github.com/TextureGroup/Texture/pull/525) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASCollectionNode\] Add -isProcessingUpdates and -onDidFinishProcessingUpdates: APIs. [\#522](https://github.com/TextureGroup/Texture/pull/522) ([appleguy](https://github.com/appleguy)) +- ASImageNode+AnimatedImage playbackReadyCallback retain cycle [\#520](https://github.com/TextureGroup/Texture/pull/520) ([plarson](https://github.com/plarson)) +- \[CI\] BuildKite to ignore all markdown files [\#517](https://github.com/TextureGroup/Texture/pull/517) ([nguyenhuy](https://github.com/nguyenhuy)) +- ASCollectionLayout improvements [\#513](https://github.com/TextureGroup/Texture/pull/513) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update changelog and podspec for 2.4 [\#512](https://github.com/TextureGroup/Texture/pull/512) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- ASCollectionLayout to return a zero content size if its state is unavailable [\#509](https://github.com/TextureGroup/Texture/pull/509) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update corner-rounding.md [\#482](https://github.com/TextureGroup/Texture/pull/482) ([oferRounds](https://github.com/oferRounds)) +- \[Accessibility\] Add .isAccessibilityContainer property, allowing automatic aggregation of children's a11y labels. [\#468](https://github.com/TextureGroup/Texture/pull/468) ([appleguy](https://github.com/appleguy)) +- \[ASImageNode\] Enable .clipsToBounds by default \(fix .cornerRadius, GIFs overflow\). [\#466](https://github.com/TextureGroup/Texture/pull/466) ([appleguy](https://github.com/appleguy)) + +## [2.4](https://github.com/TextureGroup/Texture/tree/2.4) (2017-08-15) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.3.4...2.4) + +**Merged pull requests:** + +- Avoid re-entrant call to self.view when applying initial pending state [\#510](https://github.com/TextureGroup/Texture/pull/510) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[examples/ASCollectionView\] Register supplementary kinds \#trivial [\#508](https://github.com/TextureGroup/Texture/pull/508) ([nguyenhuy](https://github.com/nguyenhuy)) +- Rename the field again to nodeModel [\#504](https://github.com/TextureGroup/Texture/pull/504) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Rename -\[ASCellNode viewModel\] to -\[ASCellNode nodeViewModel\] to avoid collisions [\#499](https://github.com/TextureGroup/Texture/pull/499) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fixed typo `UIKIt` [\#497](https://github.com/TextureGroup/Texture/pull/497) ([nixzhu](https://github.com/nixzhu)) +- Improvements in ASCollectionGalleryLayoutDelegate [\#496](https://github.com/TextureGroup/Texture/pull/496) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Showcase\] Update showcase - add blog post link to ClassDojo icon \#trivial [\#493](https://github.com/TextureGroup/Texture/pull/493) ([Kaspik](https://github.com/Kaspik)) +- \[ASCoreAnimationExtras\] Update documentation for resizbale images \#trivial [\#492](https://github.com/TextureGroup/Texture/pull/492) ([Kaspik](https://github.com/Kaspik)) +- \[ASStackLayoutSpec\] Fix interitem spacing not being reset on new lines and add snapshot tests \#trivial [\#491](https://github.com/TextureGroup/Texture/pull/491) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Layout Transition\] Avoid calling didComplete method if pending layout transition is nil [\#490](https://github.com/TextureGroup/Texture/pull/490) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[LayoutTransition\] Call \_locked\_constrainedSizeForLayoutPass with the lock actually held \#trivial [\#488](https://github.com/TextureGroup/Texture/pull/488) ([nguyenhuy](https://github.com/nguyenhuy)) +- iOS 11 UITableView automatic height estimation fix [\#485](https://github.com/TextureGroup/Texture/pull/485) ([christianselig](https://github.com/christianselig)) +- Update scroll-node.md [\#484](https://github.com/TextureGroup/Texture/pull/484) ([oferRounds](https://github.com/oferRounds)) +- Update adoption-guide-2-0-beta1.md [\#483](https://github.com/TextureGroup/Texture/pull/483) ([oferRounds](https://github.com/oferRounds)) +- Update subclassing.md [\#479](https://github.com/TextureGroup/Texture/pull/479) ([oferRounds](https://github.com/oferRounds)) +- Invalidate layouts more aggressively when transitioning with animation [\#476](https://github.com/TextureGroup/Texture/pull/476) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Update image-modification-block.md [\#474](https://github.com/TextureGroup/Texture/pull/474) ([oferRounds](https://github.com/oferRounds)) +- \[ASStackLayoutSpec\] Flex wrap fix and lineSpacing property [\#472](https://github.com/TextureGroup/Texture/pull/472) ([flovouin](https://github.com/flovouin)) +- \[ASNodeController\] Add -nodeDidLayout callback. Allow switching retain behavior at runtime. [\#470](https://github.com/TextureGroup/Texture/pull/470) ([appleguy](https://github.com/appleguy)) +- \[Layout transition\] Invalidate calculated layout if transitioning using the same size range [\#464](https://github.com/TextureGroup/Texture/pull/464) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASTableNode\]\[ASCollectionNode\] Add content offset bridging property [\#460](https://github.com/TextureGroup/Texture/pull/460) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASDisplayNode\] Fix infinite layout loop [\#455](https://github.com/TextureGroup/Texture/pull/455) ([nguyenhuy](https://github.com/nguyenhuy)) +- Add ASPagerNode+Beta to umbrella header \#trivial [\#454](https://github.com/TextureGroup/Texture/pull/454) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASPagerNode\] Remove unused flow layout reference \#trivial [\#452](https://github.com/TextureGroup/Texture/pull/452) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASCollectionLayout\] Add ASCollectionGalleryLayoutSizeProviding [\#451](https://github.com/TextureGroup/Texture/pull/451) ([nguyenhuy](https://github.com/nguyenhuy)) +- fix SIMULATE\_WEB\_RESPONSE not imported \#449 [\#450](https://github.com/TextureGroup/Texture/pull/450) ([wsdwsd0829](https://github.com/wsdwsd0829)) +- \[ASDataController \] Merge willUpdateWithChangeSet and didUpdateWithChangeSet delegate methods \#trivial [\#445](https://github.com/TextureGroup/Texture/pull/445) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASDataController\] Clean up [\#443](https://github.com/TextureGroup/Texture/pull/443) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASDataController\] Avoid asking for size ranges of soon-to-be-delete elements during relayouts [\#442](https://github.com/TextureGroup/Texture/pull/442) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASCollectionView\] Add delegate bridging and index space translation for missing UICollectionViewLayout properties. [\#440](https://github.com/TextureGroup/Texture/pull/440) ([appleguy](https://github.com/appleguy)) +- \[ASDisplayNode\] Fix some gaps in the bridging of new contents\* properties. [\#435](https://github.com/TextureGroup/Texture/pull/435) ([appleguy](https://github.com/appleguy)) +- \[ASDisplayNode\] Allow setting stretchable contents on nodes; add bridged properties. \#trivial [\#429](https://github.com/TextureGroup/Texture/pull/429) ([appleguy](https://github.com/appleguy)) +- Use a sentinel NSUInteger for node layout data \#trivial [\#428](https://github.com/TextureGroup/Texture/pull/428) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Workaround clang4.0 \ initialization \#trivial [\#426](https://github.com/TextureGroup/Texture/pull/426) ([bkase](https://github.com/bkase)) +- Add missing import in ASDisplayNode+AsyncDisplay \#trivial [\#423](https://github.com/TextureGroup/Texture/pull/423) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASCollectionElement\] Add checks for nil element, prior to other PRs landing. [\#421](https://github.com/TextureGroup/Texture/pull/421) ([appleguy](https://github.com/appleguy)) +- \[ASDataController\] Apply new visible map inside batch updates block [\#420](https://github.com/TextureGroup/Texture/pull/420) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASVideoPlayerNode\] Check that the video player's delegate implements the didTapFullScreenButtonNode method before calling it \#trivial [\#418](https://github.com/TextureGroup/Texture/pull/418) ([tnev](https://github.com/tnev)) +- \[ASDataController\] Fix a crash in table view caused by executing an empty change set during layoutSubviews [\#416](https://github.com/TextureGroup/Texture/pull/416) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASDisplayNode+Layout\] In layoutThatFits:, check and use \_pending layout if valid. [\#413](https://github.com/TextureGroup/Texture/pull/413) ([appleguy](https://github.com/appleguy)) +- Integrate Weaver into ASDKGram [\#412](https://github.com/TextureGroup/Texture/pull/412) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASDisplayNode\] -didEnterPreloadState does not need to call -layoutIfNeeded \#trivial [\#411](https://github.com/TextureGroup/Texture/pull/411) ([appleguy](https://github.com/appleguy)) +- \[ASTextNode2\] Provide compiler flag to enable ASTextNode2 for all usages. [\#410](https://github.com/TextureGroup/Texture/pull/410) ([appleguy](https://github.com/appleguy)) +- \[Yoga\] Refine the handling of measurement functions when Yoga is used. [\#408](https://github.com/TextureGroup/Texture/pull/408) ([appleguy](https://github.com/appleguy)) +- \[ASCollectionView\] Small improvements [\#407](https://github.com/TextureGroup/Texture/pull/407) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Documentation\] Improve description of synchronous concurrency with screenshot and video link. [\#406](https://github.com/TextureGroup/Texture/pull/406) ([appleguy](https://github.com/appleguy)) +- Introduce ASIntegerMap, improve our changeset handling \#trivial [\#405](https://github.com/TextureGroup/Texture/pull/405) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix issue where supplementary elements don't track section changes [\#404](https://github.com/TextureGroup/Texture/pull/404) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Overhaul our logging, add activity tracing support. [\#399](https://github.com/TextureGroup/Texture/pull/399) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASTextNode2\] Add initial implementation for link handling. [\#396](https://github.com/TextureGroup/Texture/pull/396) ([appleguy](https://github.com/appleguy)) +- Introduce ASCollectionGalleryLayoutDelegate [\#76](https://github.com/TextureGroup/Texture/pull/76) ([nguyenhuy](https://github.com/nguyenhuy)) + +## [2.3.4](https://github.com/TextureGroup/Texture/tree/2.3.4) (2017-06-30) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.3.3...2.3.4) + +**Merged pull requests:** + +- Update to the latest betas of PINRemoteImage and PINCache [\#403](https://github.com/TextureGroup/Texture/pull/403) ([garrettmoon](https://github.com/garrettmoon)) +- A bit of minor cleanup \#trivial [\#402](https://github.com/TextureGroup/Texture/pull/402) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASLayout\] Revisit the flattening algorithm [\#395](https://github.com/TextureGroup/Texture/pull/395) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASLayout\] If a layout has no sublayouts, don't bother initializing its rect table [\#394](https://github.com/TextureGroup/Texture/pull/394) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASLayout\] Fix documentation of retainSublayoutLayoutElements \#trivial [\#393](https://github.com/TextureGroup/Texture/pull/393) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fix compiling ASDimension if Yoga enabled \#trivial [\#389](https://github.com/TextureGroup/Texture/pull/389) ([maicki](https://github.com/maicki)) +- comments to reflect code \#trivial [\#388](https://github.com/TextureGroup/Texture/pull/388) ([benjamin-chang](https://github.com/benjamin-chang)) +- \[ASCellNode\] Remove unnecessary frame setting \#trivial [\#387](https://github.com/TextureGroup/Texture/pull/387) ([nguyenhuy](https://github.com/nguyenhuy)) +- Horrible spelling mistake \#trivial [\#384](https://github.com/TextureGroup/Texture/pull/384) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fix for Video Table Example Building [\#383](https://github.com/TextureGroup/Texture/pull/383) ([ay8s](https://github.com/ay8s)) +- ASDimensionMake to be more lenient \#trivial [\#382](https://github.com/TextureGroup/Texture/pull/382) ([nguyenhuy](https://github.com/nguyenhuy)) +- Gate orphaned node detector behind YOGA flag \#trivial [\#380](https://github.com/TextureGroup/Texture/pull/380) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Event Log\] Log ASM flag when modify subnodes \#trivial [\#379](https://github.com/TextureGroup/Texture/pull/379) ([nguyenhuy](https://github.com/nguyenhuy)) +- Add new workspaces for tests for different integrations \#trivial [\#377](https://github.com/TextureGroup/Texture/pull/377) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix imageModificationBlock doc \#trivial [\#376](https://github.com/TextureGroup/Texture/pull/376) ([maicki](https://github.com/maicki)) +- Fix double-load issue with ASCollectionNode [\#372](https://github.com/TextureGroup/Texture/pull/372) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- FIXED Typo in Layout Transition Documentation [\#371](https://github.com/TextureGroup/Texture/pull/371) ([martinjkelly](https://github.com/martinjkelly)) +- \[Yoga\] Delete YOGA\_TREE\_CONTIGOUS gating and permanently enable. \#trivial [\#370](https://github.com/TextureGroup/Texture/pull/370) ([appleguy](https://github.com/appleguy)) +- \[Yoga\] Minimize number of nodes that have MeasureFunc set on them. [\#369](https://github.com/TextureGroup/Texture/pull/369) ([appleguy](https://github.com/appleguy)) +- Improve System Trace Implementation \#trivial [\#368](https://github.com/TextureGroup/Texture/pull/368) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Updates ASDKGram to use IGListKit 3.0.0 [\#367](https://github.com/TextureGroup/Texture/pull/367) ([ay8s](https://github.com/ay8s)) +- Update link to AsyncDisplayKit 2.0 Launch Talk [\#363](https://github.com/TextureGroup/Texture/pull/363) ([appleguy](https://github.com/appleguy)) +- \[ASTableView\] Use ASTableView tableNode property instead of calling ASViewToDisplayNode \#trivial [\#361](https://github.com/TextureGroup/Texture/pull/361) ([maicki](https://github.com/maicki)) +- Add section-object support to new tests, improve test confinement. \#trivial [\#360](https://github.com/TextureGroup/Texture/pull/360) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[Docs\] Update 'Corner Rounding' document for Texture 2 [\#359](https://github.com/TextureGroup/Texture/pull/359) ([ArchimboldiMao](https://github.com/ArchimboldiMao)) +- Add support for keeping letting cell nodes update to new view models when reloaded. \#trivial [\#357](https://github.com/TextureGroup/Texture/pull/357) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add first-pass view model support to collection node. \#trivial [\#356](https://github.com/TextureGroup/Texture/pull/356) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASTraitCollection\] Convert ASPrimitiveTraitCollection from lock to atomic. [\#355](https://github.com/TextureGroup/Texture/pull/355) ([appleguy](https://github.com/appleguy)) +- Improve collection node testing, reveal double-load issue. \#trivial [\#352](https://github.com/TextureGroup/Texture/pull/352) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix title in changelog [\#350](https://github.com/TextureGroup/Texture/pull/350) ([levi](https://github.com/levi)) +- Add a Flag to Disable Main Thread Assertions \#trivial [\#348](https://github.com/TextureGroup/Texture/pull/348) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Migrate to Latest OCMock, Demonstrate Improved Unit Testing [\#347](https://github.com/TextureGroup/Texture/pull/347) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Upgrade ASLayoutElementContext to an Object \#trivial [\#344](https://github.com/TextureGroup/Texture/pull/344) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[Yoga\] Rewrite YOGA\_TREE\_CONTIGUOUS mode with improved behavior and cleaner integration [\#343](https://github.com/TextureGroup/Texture/pull/343) ([appleguy](https://github.com/appleguy)) +- Fix internal Linter warnings \#trivial [\#340](https://github.com/TextureGroup/Texture/pull/340) ([maicki](https://github.com/maicki)) +- Small changes required by the coming layout debugger [\#337](https://github.com/TextureGroup/Texture/pull/337) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASDataController\] Add event logging for transaction queue flush duration \#trivial [\#334](https://github.com/TextureGroup/Texture/pull/334) ([hannahmbanana](https://github.com/hannahmbanana)) +- \[ASCollectionView\] synchronous mode [\#332](https://github.com/TextureGroup/Texture/pull/332) ([hannahmbanana](https://github.com/hannahmbanana)) +- \[Performance\] Convert ASLayoutElementSize to atomic \#trivial [\#331](https://github.com/TextureGroup/Texture/pull/331) ([hannahmbanana](https://github.com/hannahmbanana)) +- \[Yoga\] Refer to proper path name and use module import [\#306](https://github.com/TextureGroup/Texture/pull/306) ([weibel](https://github.com/weibel)) +- \[ASImageNode\] Add documentation for image effects \#trivial [\#263](https://github.com/TextureGroup/Texture/pull/263) ([maicki](https://github.com/maicki)) + +## [2.3.3](https://github.com/TextureGroup/Texture/tree/2.3.3) (2017-06-06) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.3.2...2.3.3) + +**Merged pull requests:** + +- Updating to 2.3.3 \#trivial [\#338](https://github.com/TextureGroup/Texture/pull/338) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASDisplayNode+Layout\] Add check for orphaned nodes after layout transition to clean up. [\#336](https://github.com/TextureGroup/Texture/pull/336) ([appleguy](https://github.com/appleguy)) +- Update PINRemoteImage [\#328](https://github.com/TextureGroup/Texture/pull/328) ([garrettmoon](https://github.com/garrettmoon)) +- Fix typo \#trivial [\#327](https://github.com/TextureGroup/Texture/pull/327) ([vitalybaev](https://github.com/vitalybaev)) +- Fixes an issue with GIFs that would always be covered by their placeh… [\#326](https://github.com/TextureGroup/Texture/pull/326) ([garrettmoon](https://github.com/garrettmoon)) +- Replace NSMutableSet with NSHashTable when Appropriate \#trivial [\#321](https://github.com/TextureGroup/Texture/pull/321) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[Cleanup\] Small fixes to improve conformance for strict compiler settings \#trivial [\#320](https://github.com/TextureGroup/Texture/pull/320) ([appleguy](https://github.com/appleguy)) +- Rejigger Cell Visibility Tracking [\#317](https://github.com/TextureGroup/Texture/pull/317) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Clean Up ASAsyncTransaction \#trivial [\#316](https://github.com/TextureGroup/Texture/pull/316) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Clean Up ASDisplayLayer \#trivial [\#315](https://github.com/TextureGroup/Texture/pull/315) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASDisplayNode\] Revise assertion to log until Issue \#145 is addressed. \#trivial [\#313](https://github.com/TextureGroup/Texture/pull/313) ([appleguy](https://github.com/appleguy)) +- \[Docs\] Fixed typo in carthage project name \#trivial [\#310](https://github.com/TextureGroup/Texture/pull/310) ([george-gw](https://github.com/george-gw)) +- Fix non layout [\#309](https://github.com/TextureGroup/Texture/pull/309) ([garrettmoon](https://github.com/garrettmoon)) +- Catch Invalid Layer Bounds in a Nonfatal Assertion \#trivial [\#308](https://github.com/TextureGroup/Texture/pull/308) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASCollectionNode\] Fix missing properties and layoutInspector \#trivial [\#305](https://github.com/TextureGroup/Texture/pull/305) ([flovouin](https://github.com/flovouin)) +- \[Examples\] Fixed crash on SocialAppLayout-Inverted + behaviour comments [\#304](https://github.com/TextureGroup/Texture/pull/304) ([dimazen](https://github.com/dimazen)) +- IGListKit related headers need to be in the module all time now \#trivial [\#300](https://github.com/TextureGroup/Texture/pull/300) ([maicki](https://github.com/maicki)) +- \[ASDisplayNode\] Remove assertion in calculateSizeThatFits: and log an event \#trivial [\#299](https://github.com/TextureGroup/Texture/pull/299) ([maicki](https://github.com/maicki)) +- ASBatchFetching to not round scroll velocity \#trivial [\#294](https://github.com/TextureGroup/Texture/pull/294) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[ASVideoNodeDelegate\] fix for \#291 crash [\#292](https://github.com/TextureGroup/Texture/pull/292) ([SergeyPetrachkov](https://github.com/SergeyPetrachkov)) +- Fix Alignment of Hashed Structs [\#287](https://github.com/TextureGroup/Texture/pull/287) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[IGListKit\] Add IGListKit headers to public section of Xcode project [\#286](https://github.com/TextureGroup/Texture/pull/286) ([maicki](https://github.com/maicki)) +- Only call -layout and -layoutDidFinish if the node is already loaded [\#285](https://github.com/TextureGroup/Texture/pull/285) ([nguyenhuy](https://github.com/nguyenhuy)) +- \[Batch Fetching\] Add ASBatchFetchingDelegate [\#281](https://github.com/TextureGroup/Texture/pull/281) ([nguyenhuy](https://github.com/nguyenhuy)) +- Ignore Relayout Requests for Deleted Cell Nodes [\#279](https://github.com/TextureGroup/Texture/pull/279) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Remove Unused Node Code \#trivial [\#278](https://github.com/TextureGroup/Texture/pull/278) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix Documentation Warnings \#trivial [\#276](https://github.com/TextureGroup/Texture/pull/276) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[Examples\] Fix LayoutSpecExamples and LayoutSpecExamples-Swift: image URLs were still pointing to asyncdisplaykit.org [\#275](https://github.com/TextureGroup/Texture/pull/275) ([cesteban](https://github.com/cesteban)) +- \[Layout\] Extract layout implementation code into it's own subcategories [\#272](https://github.com/TextureGroup/Texture/pull/272) ([maicki](https://github.com/maicki)) +- Fix Release Builds \#trivial [\#271](https://github.com/TextureGroup/Texture/pull/271) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[Yoga\] Implement ASYogaLayoutSpec, a simplified integration strategy for Yoga. [\#270](https://github.com/TextureGroup/Texture/pull/270) ([appleguy](https://github.com/appleguy)) +- Simplify Layout Transition State \#trivial [\#269](https://github.com/TextureGroup/Texture/pull/269) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Store ASLayoutElementContext in Thread-Local Storage \#trivial [\#268](https://github.com/TextureGroup/Texture/pull/268) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[Examples\] Fix a couple of examples due to API changes recently \#trivial [\#267](https://github.com/TextureGroup/Texture/pull/267) ([maicki](https://github.com/maicki)) +- Fix Collection Item Index Path Conversion [\#262](https://github.com/TextureGroup/Texture/pull/262) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- added error reporting callback to ASVideoNode [\#260](https://github.com/TextureGroup/Texture/pull/260) ([SergeyPetrachkov](https://github.com/SergeyPetrachkov)) +- Add Experimental Text Node Implementation [\#259](https://github.com/TextureGroup/Texture/pull/259) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add missing import and define in ASLog \#trivial [\#257](https://github.com/TextureGroup/Texture/pull/257) ([nguyenhuy](https://github.com/nguyenhuy)) +- Simplify Override Checking, Only Do It When Assertions Are Enabled \#trivial [\#253](https://github.com/TextureGroup/Texture/pull/253) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASTextKitFontSizeAdjuster\] Replace use of boundingRectWithSize:options:context: with boundingRectForGlyphRange: inTextContainer: [\#251](https://github.com/TextureGroup/Texture/pull/251) ([rcancro](https://github.com/rcancro)) +- Improve Ancestry Handling, Avoid Assertion Failure [\#246](https://github.com/TextureGroup/Texture/pull/246) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[Yoga\] Increment Yoga version to current, 1.5.0. [\#91](https://github.com/TextureGroup/Texture/pull/91) ([appleguy](https://github.com/appleguy)) +- \[example/CustomCollectionView\] Implement MosaicCollectionLayoutDelegate [\#28](https://github.com/TextureGroup/Texture/pull/28) ([nguyenhuy](https://github.com/nguyenhuy)) + +## [2.3.2](https://github.com/TextureGroup/Texture/tree/2.3.2) (2017-05-09) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.3.1...2.3.2) + +**Merged pull requests:** + +- \[ASDisplayNode\] Pass drawParameter in rendering context callbacks [\#248](https://github.com/TextureGroup/Texture/pull/248) ([maicki](https://github.com/maicki)) +- Assert only once we know URL has changed [\#247](https://github.com/TextureGroup/Texture/pull/247) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASImageNode\] Move to class method of displayWithParameters:isCancelled: for drawing [\#244](https://github.com/TextureGroup/Texture/pull/244) ([maicki](https://github.com/maicki)) +- Don't Use Associated Objects for Drawing Priority \#trivial [\#239](https://github.com/TextureGroup/Texture/pull/239) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASDimension\] Remove warning about float precision using CGFloat and … \#trivial [\#237](https://github.com/TextureGroup/Texture/pull/237) ([amegias](https://github.com/amegias)) +- \[ASImageNode\] Move debug label and will- / didDisplayNodeContentWithRenderingContext out of drawing method \#trivial [\#235](https://github.com/TextureGroup/Texture/pull/235) ([maicki](https://github.com/maicki)) +- Fixes assertion on startup in social app layout example [\#233](https://github.com/TextureGroup/Texture/pull/233) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASTextNode\] Move to class method of drawRect:withParameters:isCancelled:isRasterizing: for drawing [\#232](https://github.com/TextureGroup/Texture/pull/232) ([maicki](https://github.com/maicki)) +- \[ASImageNode\] Remove unneeded pointer star \#trivial [\#231](https://github.com/TextureGroup/Texture/pull/231) ([maicki](https://github.com/maicki)) +- \[ASTwoDimensionalArrayUtils\] Fix extern C function definition to fix compiler issue. \#trivial [\#229](https://github.com/TextureGroup/Texture/pull/229) ([appleguy](https://github.com/appleguy)) +- Move Last Few Properties from ASTableView,ASCollectionView to Node [\#225](https://github.com/TextureGroup/Texture/pull/225) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix Issues in the Project File \#trivial [\#224](https://github.com/TextureGroup/Texture/pull/224) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Improve Our Handling of Subnodes [\#223](https://github.com/TextureGroup/Texture/pull/223) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Extract ASLayoutElement and ASLayoutElementStylability into categories \#trivial [\#131](https://github.com/TextureGroup/Texture/pull/131) ([maicki](https://github.com/maicki)) +- \[Layout\] Remove finalLayoutElement [\#96](https://github.com/TextureGroup/Texture/pull/96) ([maicki](https://github.com/maicki)) +- \[Docs\] Add workaround for setting a custom lineSpacing and maxNumberOfLines to ASTextNode docs [\#92](https://github.com/TextureGroup/Texture/pull/92) ([maicki](https://github.com/maicki)) +- \[ASDisplayNode\] Implement a std::atomic-based flag system for superb performance [\#89](https://github.com/TextureGroup/Texture/pull/89) ([appleguy](https://github.com/appleguy)) +- \[Yoga\] Ensure that calculated layout is nil'd in invalidate\*Layout [\#87](https://github.com/TextureGroup/Texture/pull/87) ([appleguy](https://github.com/appleguy)) +- Simplify Hashing Code [\#86](https://github.com/TextureGroup/Texture/pull/86) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Fix site header [\#84](https://github.com/TextureGroup/Texture/pull/84) ([levi](https://github.com/levi)) +- Tighten Rasterization API, Undeprecate It [\#82](https://github.com/TextureGroup/Texture/pull/82) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Implement ASPageTable [\#81](https://github.com/TextureGroup/Texture/pull/81) ([nguyenhuy](https://github.com/nguyenhuy)) +- Make Cell Node Properties Atomic [\#74](https://github.com/TextureGroup/Texture/pull/74) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- \[ASNodeController+Beta\] Provide an option to allow nodes to own their controllers. [\#61](https://github.com/TextureGroup/Texture/pull/61) ([appleguy](https://github.com/appleguy)) +- \[Yoga Beta\] Improvements to the experimental support for Yoga layout. [\#59](https://github.com/TextureGroup/Texture/pull/59) ([appleguy](https://github.com/appleguy)) +- Fix issue with swipe to delete cell gesture. \#trivial [\#46](https://github.com/TextureGroup/Texture/pull/46) ([rewcraig](https://github.com/rewcraig)) +- Fix CustomCollectionView-Swift sample [\#22](https://github.com/TextureGroup/Texture/pull/22) ([george-gw](https://github.com/george-gw)) +- Automatically resume ASVideoNode after returning from background [\#13](https://github.com/TextureGroup/Texture/pull/13) ([plarson](https://github.com/plarson)) + +## [2.3.1](https://github.com/TextureGroup/Texture/tree/2.3.1) (2017-04-27) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.2.1...2.3.1) + +**Merged pull requests:** + +- Don't run tests for the docs directory. [\#79](https://github.com/TextureGroup/Texture/pull/79) ([garrettmoon](https://github.com/garrettmoon)) +- Fix SCSS build [\#78](https://github.com/TextureGroup/Texture/pull/78) ([levi](https://github.com/levi)) +- Fix documentation warning on ASCollectionLayoutState.h \#trivial [\#77](https://github.com/TextureGroup/Texture/pull/77) ([garrettmoon](https://github.com/garrettmoon)) +- ASLayoutSpec to use more default implementations \#trivial [\#73](https://github.com/TextureGroup/Texture/pull/73) ([nguyenhuy](https://github.com/nguyenhuy)) +- Update the CI to the new ruby version [\#71](https://github.com/TextureGroup/Texture/pull/71) ([garrettmoon](https://github.com/garrettmoon)) +- Missing a word [\#68](https://github.com/TextureGroup/Texture/pull/68) ([djblake](https://github.com/djblake)) +- Update license v2 [\#67](https://github.com/TextureGroup/Texture/pull/67) ([garrettmoon](https://github.com/garrettmoon)) +- \[ASCollectionView\] Prevent prefetching from being enabled to eliminate overhead. [\#65](https://github.com/TextureGroup/Texture/pull/65) ([appleguy](https://github.com/appleguy)) +- \[CGPointNull\] Rename globally exported C function to avoid collisions \#trivial [\#62](https://github.com/TextureGroup/Texture/pull/62) ([appleguy](https://github.com/appleguy)) +- \[RTL\] Bridge the UISemanticContentAttribute property for more convenient RTL support. [\#60](https://github.com/TextureGroup/Texture/pull/60) ([appleguy](https://github.com/appleguy)) +- Fixes a potential deadlock; it's not safe to message likely super nod… [\#56](https://github.com/TextureGroup/Texture/pull/56) ([garrettmoon](https://github.com/garrettmoon)) +- Fix \_\_has\_include check in ASLog.h \#trivial [\#55](https://github.com/TextureGroup/Texture/pull/55) ([fsmorygo](https://github.com/fsmorygo)) +- GLKit workaround \#trivial [\#54](https://github.com/TextureGroup/Texture/pull/54) ([stephenkopylov](https://github.com/stephenkopylov)) +- Layout debugger proposal [\#52](https://github.com/TextureGroup/Texture/pull/52) ([nguyenhuy](https://github.com/nguyenhuy)) +- Fixes header check to accept the 'new' header for modified files. [\#50](https://github.com/TextureGroup/Texture/pull/50) ([garrettmoon](https://github.com/garrettmoon)) +- Remove References to IGListSectionType, Now that It's Gone [\#49](https://github.com/TextureGroup/Texture/pull/49) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Move doc stylesheets to sass [\#47](https://github.com/TextureGroup/Texture/pull/47) ([levi](https://github.com/levi)) +- Fixes for Dangerfile header checks [\#45](https://github.com/TextureGroup/Texture/pull/45) ([garrettmoon](https://github.com/garrettmoon)) +- Enforce header file changes [\#44](https://github.com/TextureGroup/Texture/pull/44) ([garrettmoon](https://github.com/garrettmoon)) +- Use \_ASCollectionReusableView inside ASIGListSupplementaryViewSourceMethods [\#40](https://github.com/TextureGroup/Texture/pull/40) ([plarson](https://github.com/plarson)) +- Bump Cartfile versions to match podspec [\#37](https://github.com/TextureGroup/Texture/pull/37) ([dymv](https://github.com/dymv)) +- \[Site\] Remove hero drop shadow [\#35](https://github.com/TextureGroup/Texture/pull/35) ([levi](https://github.com/levi)) +- Add announcement banner to documentation site [\#31](https://github.com/TextureGroup/Texture/pull/31) ([levi](https://github.com/levi)) +- \[ASCollectionLayout\] Manually set size to measured cells [\#24](https://github.com/TextureGroup/Texture/pull/24) ([nguyenhuy](https://github.com/nguyenhuy)) +- Create a Pluggable "Tips" System to Help in Development [\#19](https://github.com/TextureGroup/Texture/pull/19) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Add danger [\#18](https://github.com/TextureGroup/Texture/pull/18) ([garrettmoon](https://github.com/garrettmoon)) +- Fix Case where Network Image Node Stays Locked [\#17](https://github.com/TextureGroup/Texture/pull/17) ([Adlai-Holler](https://github.com/Adlai-Holler)) +- Update the homepage URL [\#10](https://github.com/TextureGroup/Texture/pull/10) ([garrettmoon](https://github.com/garrettmoon)) + +## [2.2.1](https://github.com/TextureGroup/Texture/tree/2.2.1) (2017-04-14) +[Full Changelog](https://github.com/TextureGroup/Texture/compare/2.3...2.2.1) + +**Merged pull requests:** + +- Add blog post [\#9](https://github.com/TextureGroup/Texture/pull/9) ([garrettmoon](https://github.com/garrettmoon)) + + + +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file diff --git a/Dangerfile b/Dangerfile index 60c90dfe2e..14679294da 100644 --- a/Dangerfile +++ b/Dangerfile @@ -18,10 +18,9 @@ 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 -# Changelog entries are required for changes to source files. -no_changelog_entry = !git.modified_files.include?("CHANGELOG.md") -if has_changes_in_source_directory && no_changelog_entry && !declared_trivial - warn("Any source code changes should have an entry in CHANGELOG.md or have #trivial in their title.") +# 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) diff --git a/README.md b/README.md index 64e7f4ab33..4b939fac5a 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,10 @@ As the framework has grown, many features have been added that can save develope We use Slack for real-time debugging, community updates, and general talk about Texture. [Signup](http://asdk-slack-auto-invite.herokuapp.com) yourself or email textureframework@gmail.com to get an invite. +## Release process + +For the release process see the [RELEASE] (https://github.com/texturegroup/texture/blob/master/RELEASE.md) file. + ## Contributing We welcome any contributions. See the [CONTRIBUTING](https://github.com/texturegroup/texture/blob/master/CONTRIBUTING.md) file for how to get involved. diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000000..99ed83bfc1 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,16 @@ +# Release Process +This document describes the process for a public Texture release. + +### Preparation +- Install [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator): `sudo gem install github_changelog_generator` +- 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` +- Update `spec.version` within `Texture.podspec`. +- 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. +- Update `future-release` within `.github_changelog_generator` to the next version. + +### 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 From e745aded7dd01603f15860ea14c6b4f23635446c Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Sun, 4 Nov 2018 16:28:48 -0800 Subject: [PATCH 48/60] [ASImageNode] Fix a threading issue which can cause a display completion block to never be executed (#1148) - Clear _displayCompletionBlock while we still have the node's instance lock. Because it may not be the same block by the time the lock is reacquired. In other words, it can happen that another thread sets a new display block after this thread releases the lock but before it reacquires it. And we don't want to clear out the new block. - Reduce a lock/unlock pair which should help perf a tiny bit. --- Source/ASImageNode.mm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Source/ASImageNode.mm b/Source/ASImageNode.mm index d5739f1a49..1ace8c74b1 100644 --- a/Source/ASImageNode.mm +++ b/Source/ASImageNode.mm @@ -533,8 +533,15 @@ static ASDN::StaticMutex& cacheLock = *new ASDN::StaticMutex; [super displayDidFinish]; __instanceLock__.lock(); - void (^displayCompletionBlock)(BOOL canceled) = _displayCompletionBlock; UIImage *image = _image; + void (^displayCompletionBlock)(BOOL canceled) = _displayCompletionBlock; + BOOL shouldPerformDisplayCompletionBlock = (image && displayCompletionBlock); + + // Clear the ivar now. The block is retained and will be executed shortly. + if (shouldPerformDisplayCompletionBlock) { + _displayCompletionBlock = nil; + } + BOOL hasDebugLabel = (_debugLabelNode != nil); __instanceLock__.unlock(); @@ -556,13 +563,8 @@ static ASDN::StaticMutex& cacheLock = *new ASDN::StaticMutex; } // If we've got a block to perform after displaying, do it. - if (image && displayCompletionBlock) { - + if (shouldPerformDisplayCompletionBlock) { displayCompletionBlock(NO); - - __instanceLock__.lock(); - _displayCompletionBlock = nil; - __instanceLock__.unlock(); } } From 87615b0ec2daf9d6cef3427f9be45caa872da55e Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Sun, 4 Nov 2018 18:22:28 -0800 Subject: [PATCH 49/60] Cleanup Dangerfile (#1212) `has_changes_in_source_directory` and `declared_trivial` are not longer needed after after PR #1031. --- Dangerfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Dangerfile b/Dangerfile index 14679294da..147d389069 100644 --- a/Dangerfile +++ b/Dangerfile @@ -1,11 +1,6 @@ require 'open-uri' source_pattern = /(\.m|\.mm|\.h)$/ - -# Sometimes it's a README fix, or something like that - which isn't relevant for -# including in a project's CHANGELOG for example -declared_trivial = github.pr_title.include? "#trivial" -has_changes_in_source_directory = !git.modified_files.grep(/Source/).empty? modified_source_files = git.modified_files.grep(source_pattern) has_modified_source_files = !modified_source_files.empty? From 5909e27e371887f48af5f596f20f5e643ee14562 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Mon, 5 Nov 2018 13:16:36 -0800 Subject: [PATCH 50/60] Fix shouldTruncateForConstrainedSize in ASTextNode2 (#1214) --- Source/ASTextNode2.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 9feb18afd6..6946ec95a3 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -1142,7 +1142,7 @@ static NSAttributedString *DefaultTruncationAttributedString() - (BOOL)shouldTruncateForConstrainedSize:(ASSizeRange)constrainedSize { - return ASLockedSelf([self locked_textLayoutForSize:constrainedSize.max].truncatedLine == nil); + return ASLockedSelf([self locked_textLayoutForSize:constrainedSize.max].truncatedLine != nil); } - (ASTextLayout *)locked_textLayoutForSize:(CGSize)size From 5c9815f46d1c9580b08828c6676b386395e0d25b Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Mon, 5 Nov 2018 13:26:36 -0800 Subject: [PATCH 51/60] ASThread: Remove Locker, Unlocker, and SharedMutex (#1213) * ASThread: Remove Locker, Unlocker, and SharedMutex * Remove extra line * Kick the CI * Move C++ down * Fix thing --- Source/ASDisplayNode.mm | 73 ++++++------ Source/ASImageNode.mm | 6 +- Source/ASTextNode2.mm | 6 +- Source/ASVideoNode.mm | 12 +- Source/Details/ASBasicImageDownloader.mm | 6 +- Source/Details/ASMainSerialQueue.mm | 11 +- Source/Details/ASThread.h | 143 +---------------------- Source/Private/ASLayoutTransition.mm | 18 +-- Source/TextKit/ASTextKitContext.mm | 8 +- 9 files changed, 77 insertions(+), 206 deletions(-) diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 34ff77b941..8923762659 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -416,12 +416,13 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__); - (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body { - ASDN::MutexLocker l(__instanceLock__); + ASDN::UniqueLock l(__instanceLock__); if ([self _locked_isNodeLoaded]) { ASDisplayNodeAssertThreadAffinity(self); - ASDN::MutexUnlocker l(__instanceLock__); + l.unlock(); body(self); + return; } else if (_onDidLoadBlocks == nil) { _onDidLoadBlocks = [NSMutableArray arrayWithObject:body]; } else { @@ -601,7 +602,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__); - (UIView *)view { - ASDN::MutexLocker l(__instanceLock__); + ASDN::UniqueLock l(__instanceLock__); ASDisplayNodeAssert(!_flags.layerBacked, @"Call to -view undefined on layer-backed nodes"); BOOL isLayerBacked = _flags.layerBacked; @@ -626,30 +627,28 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__); // in the background on a loaded node, which isn't currently supported. if (_pendingViewState.hasSetNeedsLayout) { // Need to unlock before calling setNeedsLayout to avoid deadlocks. - // MutexUnlocker will re-lock at the end of scope. - ASDN::MutexUnlocker u(__instanceLock__); + l.unlock(); [self __setNeedsLayout]; + l.lock(); } [self _locked_applyPendingStateToViewOrLayer]; - { - // The following methods should not be called with a lock - ASDN::MutexUnlocker u(__instanceLock__); + // The following methods should not be called with a lock + l.unlock(); - // No need for the lock as accessing the subviews or layers are always happening on main - [self _addSubnodeViewsAndLayers]; - - // A subclass hook should never be called with a lock - [self _didLoad]; - } + // No need for the lock as accessing the subviews or layers are always happening on main + [self _addSubnodeViewsAndLayers]; + + // A subclass hook should never be called with a lock + [self _didLoad]; return _view; } - (CALayer *)layer { - ASDN::MutexLocker l(__instanceLock__); + ASDN::UniqueLock l(__instanceLock__); if (_layer != nil) { return _layer; } @@ -661,31 +660,30 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__); // Loading a layer needs to happen on the main thread ASDisplayNodeAssertMainThread(); [self _locked_loadViewOrLayer]; + CALayer *layer = _layer; // FIXME: Ideally we'd call this as soon as the node receives -setNeedsLayout // but automatic subnode management would require us to modify the node tree // in the background on a loaded node, which isn't currently supported. if (_pendingViewState.hasSetNeedsLayout) { // Need to unlock before calling setNeedsLayout to avoid deadlocks. - // MutexUnlocker will re-lock at the end of scope. - ASDN::MutexUnlocker u(__instanceLock__); + l.unlock(); [self __setNeedsLayout]; + l.lock(); } [self _locked_applyPendingStateToViewOrLayer]; - { - // The following methods should not be called with a lock - ASDN::MutexUnlocker u(__instanceLock__); + // The following methods should not be called with a lock + l.unlock(); - // No need for the lock as accessing the subviews or layers are always happening on main - [self _addSubnodeViewsAndLayers]; - - // A subclass hook should never be called with a lock - [self _didLoad]; - } + // No need for the lock as accessing the subviews or layers are always happening on main + [self _addSubnodeViewsAndLayers]; + + // A subclass hook should never be called with a lock + [self _didLoad]; - return _layer; + return layer; } // Returns nil if the layer is not an _ASDisplayLayer; will not create the layer if nil. @@ -1033,7 +1031,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__); BOOL loaded = NO; { - ASDN::MutexLocker l(__instanceLock__); + ASDN::UniqueLock l(__instanceLock__); loaded = [self _locked_isNodeLoaded]; CGRect bounds = _threadSafeBounds; @@ -1055,10 +1053,9 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__); // This method will confirm that the layout is up to date (and update if needed). // Importantly, it will also APPLY the layout to all of our subnodes if (unless parent is transitioning). - { - ASDN::MutexUnlocker u(__instanceLock__); - [self _u_measureNodeWithBoundsIfNecessary:bounds]; - } + l.unlock(); + [self _u_measureNodeWithBoundsIfNecessary:bounds]; + l.lock(); [self _locked_layoutPlaceholderIfNecessary]; } @@ -1121,7 +1118,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__); { __ASDisplayNodeCheckForLayoutMethodOverrides; - ASDN::MutexLocker l(__instanceLock__); + ASDN::UniqueLock l(__instanceLock__); #if YOGA // There are several cases where Yoga could arrive here: @@ -1138,11 +1135,13 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__); if ([self shouldHaveYogaMeasureFunc] == NO) { // If we're a yoga root, tree node, or leaf with no measure func (e.g. spacer), then // initiate a new Yoga calculation pass from root. - ASDN::MutexUnlocker ul(__instanceLock__); + as_activity_create_for_scope("Yoga layout calculation"); if (self.yogaLayoutInProgress == NO) { ASYogaLog("Calculating yoga layout from root %@, %@", self, NSStringFromASSizeRange(constrainedSize)); + l.unlock(); [self calculateLayoutFromYogaRoot:constrainedSize]; + l.lock(); } else { ASYogaLog("Reusing existing yoga layout %@", _yogaCalculatedLayout); } @@ -3546,15 +3545,15 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { ASDisplayNodeAssertMainThread(); ASAssertUnlocked(__instanceLock__); - ASDN::MutexLocker l(__instanceLock__); + ASDN::UniqueLock l(__instanceLock__); // FIXME: Ideally we'd call this as soon as the node receives -setNeedsLayout // but automatic subnode management would require us to modify the node tree // in the background on a loaded node, which isn't currently supported. if (_pendingViewState.hasSetNeedsLayout) { // Need to unlock before calling setNeedsLayout to avoid deadlocks. - // MutexUnlocker will re-lock at the end of scope. - ASDN::MutexUnlocker u(__instanceLock__); + l.unlock(); [self __setNeedsLayout]; + l.lock(); } [self _locked_applyPendingViewState]; diff --git a/Source/ASImageNode.mm b/Source/ASImageNode.mm index 1ace8c74b1..bed6655608 100644 --- a/Source/ASImageNode.mm +++ b/Source/ASImageNode.mm @@ -434,12 +434,12 @@ typedef void (^ASImageNodeDrawParametersBlock)(ASWeakMapEntry *entry); static ASWeakMap *cache = nil; // Allocate cacheLock on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) -static ASDN::StaticMutex& cacheLock = *new ASDN::StaticMutex; +static auto *cacheLock = new ASDN::Mutex; + (ASWeakMapEntry *)contentsForkey:(ASImageNodeContentsKey *)key drawParameters:(id)drawParameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled { { - ASDN::StaticMutexLocker l(cacheLock); + ASDN::MutexLocker l(*cacheLock); if (!cache) { cache = [[ASWeakMap alloc] init]; } @@ -456,7 +456,7 @@ static ASDN::StaticMutex& cacheLock = *new ASDN::StaticMutex; } { - ASDN::StaticMutexLocker l(cacheLock); + ASDN::MutexLocker l(*cacheLock); return [cache setObject:contents forKey:key]; } } diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 6946ec95a3..f3ec51fa35 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -55,14 +55,14 @@ */ static NS_RETURNS_RETAINED ASTextLayout *ASTextNodeCompatibleLayoutWithContainerAndText(ASTextContainer *container, NSAttributedString *text) { // Allocate layoutCacheLock on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) - static ASDN::StaticMutex& layoutCacheLock = *new ASDN::StaticMutex; + static auto *layoutCacheLock = new ASDN::Mutex; static NSCache *textLayoutCache; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ textLayoutCache = [[NSCache alloc] init]; }); - layoutCacheLock.lock(); + layoutCacheLock->lock(); ASTextCacheValue *cacheValue = [textLayoutCache objectForKey:text]; if (cacheValue == nil) { @@ -72,7 +72,7 @@ static NS_RETURNS_RETAINED ASTextLayout *ASTextNodeCompatibleLayoutWithContainer // Lock the cache item for the rest of the method. Only after acquiring can we release the NSCache. ASDN::MutexLocker lock(cacheValue->_m); - layoutCacheLock.unlock(); + layoutCacheLock->unlock(); CGRect containerBounds = (CGRect){ .size = container.size }; { diff --git a/Source/ASVideoNode.mm b/Source/ASVideoNode.mm index 4cb4ba8c5f..fe368a12ca 100644 --- a/Source/ASVideoNode.mm +++ b/Source/ASVideoNode.mm @@ -10,6 +10,7 @@ #import #import #import +#import #import #import #import @@ -322,7 +323,7 @@ static NSString * const kRate = @"rate"; - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - ASLockScopeSelf(); + ASDN::UniqueLock l(__instanceLock__); if (object == _currentPlayerItem) { if ([keyPath isEqualToString:kStatus]) { @@ -330,8 +331,9 @@ static NSString * const kRate = @"rate"; if (self.playerState != ASVideoNodePlayerStatePlaying) { self.playerState = ASVideoNodePlayerStateReadyToPlay; if (_shouldBePlaying && ASInterfaceStateIncludesVisible(self.interfaceState)) { - ASUnlockScope(self); + l.unlock(); [self play]; + l.lock(); } } // If we don't yet have a placeholder image update it now that we should have data available for it @@ -354,8 +356,10 @@ static NSString * const kRate = @"rate"; [self.delegate videoNodeDidRecoverFromStall:self]; } - ASUnlockScope(self); + l.unlock(); [self play]; // autoresume after buffer catches up + // NOTE: Early return without re-locking. + return; } } else if ([keyPath isEqualToString:kplaybackBufferEmpty]) { if (_shouldBePlaying && [change[NSKeyValueChangeNewKey] boolValue] == YES && ASInterfaceStateIncludesVisible(self.interfaceState)) { @@ -373,6 +377,8 @@ static NSString * const kRate = @"rate"; } } } + + // NOTE: Early return above. } - (void)tapped diff --git a/Source/Details/ASBasicImageDownloader.mm b/Source/Details/ASBasicImageDownloader.mm index 24ccf95bfd..c13fc728bc 100644 --- a/Source/Details/ASBasicImageDownloader.mm +++ b/Source/Details/ASBasicImageDownloader.mm @@ -39,11 +39,11 @@ NSString * const kASBasicImageDownloaderContextCompletionBlock = @"kASBasicImage static NSMutableDictionary *currentRequests = nil; // Allocate currentRequestsLock on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) -static ASDN::StaticMutex& currentRequestsLock = *new ASDN::StaticMutex; +static auto *currentRequestsLock = new ASDN::Mutex; + (ASBasicImageDownloaderContext *)contextForURL:(NSURL *)URL { - ASDN::StaticMutexLocker l(currentRequestsLock); + ASDN::MutexLocker l(*currentRequestsLock); if (!currentRequests) { currentRequests = [[NSMutableDictionary alloc] init]; } @@ -57,7 +57,7 @@ static ASDN::StaticMutex& currentRequestsLock = *new ASDN::StaticMutex; + (void)cancelContextWithURL:(NSURL *)URL { - ASDN::StaticMutexLocker l(currentRequestsLock); + ASDN::MutexLocker l(*currentRequestsLock); if (currentRequests) { [currentRequests removeObjectForKey:URL]; } diff --git a/Source/Details/ASMainSerialQueue.mm b/Source/Details/ASMainSerialQueue.mm index 42d937ad47..3a5fa00f85 100644 --- a/Source/Details/ASMainSerialQueue.mm +++ b/Source/Details/ASMainSerialQueue.mm @@ -40,19 +40,21 @@ - (void)performBlockOnMainThread:(dispatch_block_t)block { - ASDN::MutexLocker l(_serialQueueLock); + + ASDN::UniqueLock l(_serialQueueLock); [_blocks addObject:block]; { - ASDN::MutexUnlocker u(_serialQueueLock); + l.unlock(); [self runBlocks]; + l.lock(); } } - (void)runBlocks { dispatch_block_t mainThread = ^{ + ASDN::UniqueLock l(self->_serialQueueLock); do { - ASDN::MutexLocker l(self->_serialQueueLock); dispatch_block_t block; if (self->_blocks.count > 0) { block = _blocks[0]; @@ -61,8 +63,9 @@ break; } { - ASDN::MutexUnlocker u(self->_serialQueueLock); + l.unlock(); block(); + l.lock(); } } while (true); }; diff --git a/Source/Details/ASThread.h b/Source/Details/ASThread.h index bdcfd26189..701e6c10a1 100644 --- a/Source/Details/ASThread.h +++ b/Source/Details/ASThread.h @@ -95,7 +95,6 @@ ASDISPLAYNODE_INLINE void _ASUnlockScopeCleanup(id __strong *lockPtr) #ifdef __cplusplus -#define TIME_LOCKER 0 /** * Enable this flag to collect information on the owning thread and ownership level of a mutex. * These properties are useful to determine if a mutex has been acquired and in case of a recursive mutex, how many times that happened. @@ -112,11 +111,8 @@ ASDISPLAYNODE_INLINE void _ASUnlockScopeCleanup(id __strong *lockPtr) #define CHECK_LOCKING_SAFETY 0 #endif -#if TIME_LOCKER -#import -#endif - #include +#include // This MUST always execute, even when assertions are disabled. Otherwise all lock operations become no-ops! // (To be explicit, do not turn this into an NSAssert, assert(), or any other kind of statement where the @@ -143,106 +139,6 @@ ASDISPLAYNODE_INLINE void _ASUnlockScopeCleanup(id __strong *lockPtr) namespace ASDN { - template - class Locker - { - T &_l; - -#if TIME_LOCKER - CFTimeInterval _ti; - const char *_name; -#endif - - public: -#if !TIME_LOCKER - - Locker (T &l) noexcept : _l (l) { - _l.lock (); - } - - ~Locker () { - _l.unlock (); - } - - // non-copyable. - Locker(const Locker&) = delete; - Locker &operator=(const Locker&) = delete; - -#else - - Locker (T &l, const char *name = NULL) noexcept : _l (l), _name(name) { - _ti = CACurrentMediaTime(); - _l.lock (); - } - - ~Locker () { - _l.unlock (); - if (_name) { - printf(_name, NULL); - printf(" dt:%f\n", CACurrentMediaTime() - _ti); - } - } - -#endif - - }; - - template - class SharedLocker - { - std::shared_ptr _l; - -#if TIME_LOCKER - CFTimeInterval _ti; - const char *_name; -#endif - - public: -#if !TIME_LOCKER - - SharedLocker (std::shared_ptr const& l) noexcept : _l (l) { - ASDisplayNodeCAssertTrue(_l != nullptr); - _l->lock (); - } - - ~SharedLocker () { - _l->unlock (); - } - - // non-copyable. - SharedLocker(const SharedLocker&) = delete; - SharedLocker &operator=(const SharedLocker&) = delete; - -#else - - SharedLocker (std::shared_ptr const& l, const char *name = NULL) noexcept : _l (l), _name(name) { - _ti = CACurrentMediaTime(); - _l->lock (); - } - - ~SharedLocker () { - _l->unlock (); - if (_name) { - printf(_name, NULL); - printf(" dt:%f\n", CACurrentMediaTime() - _ti); - } - } - -#endif - - }; - - template - class Unlocker - { - T &_l; - public: - Unlocker (T &l) noexcept : _l (l) { _l.unlock (); } - ~Unlocker () {_l.lock ();} - Unlocker(Unlocker&) = delete; - Unlocker &operator=(Unlocker&) = delete; - }; - // Set once in Mutex constructor. Linker fails if this is a member variable. ?? static BOOL gMutex_unfair; @@ -414,41 +310,8 @@ namespace ASDN { RecursiveMutex () : Mutex (true) {} }; - typedef Locker MutexLocker; - typedef SharedLocker MutexSharedLocker; - typedef Unlocker MutexUnlocker; - - /** - If you are creating a static mutex, use StaticMutex. This avoids expensive constructor overhead at startup (or worse, ordering - issues between different static objects). It also avoids running a destructor on app exit time (needless expense). - - Note that you can, but should not, use StaticMutex for non-static objects. It will leak its mutex on destruction, - so avoid that! - */ - struct StaticMutex - { - StaticMutex () : _m (PTHREAD_MUTEX_INITIALIZER) {} - - // non-copyable. - StaticMutex(const StaticMutex&) = delete; - StaticMutex &operator=(const StaticMutex&) = delete; - - void lock () { - AS_POSIX_ASSERT_NOERR(pthread_mutex_lock (this->mutex())); - } - - void unlock () { - AS_POSIX_ASSERT_NOERR(pthread_mutex_unlock (this->mutex())); - } - - pthread_mutex_t *mutex () { return &_m; } - - private: - pthread_mutex_t _m; - }; - - typedef Locker StaticMutexLocker; - typedef Unlocker StaticMutexUnlocker; + typedef std::lock_guard MutexLocker; + typedef std::unique_lock UniqueLock; } // namespace ASDN diff --git a/Source/Private/ASLayoutTransition.mm b/Source/Private/ASLayoutTransition.mm index 1e482afa63..b7d9cda441 100644 --- a/Source/Private/ASLayoutTransition.mm +++ b/Source/Private/ASLayoutTransition.mm @@ -81,7 +81,7 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) { - (BOOL)isSynchronous { - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); return !ASLayoutCanTransitionAsynchronous(_pendingLayout.layout); } @@ -93,7 +93,7 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) { - (void)applySubnodeInsertionsAndMoves { - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); [self calculateSubnodeOperationsIfNeeded]; // Create an activity even if no subnodes affected. @@ -131,7 +131,7 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) { - (void)applySubnodeRemovals { as_activity_scope(as_activity_create("Apply subnode removals", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); [self calculateSubnodeOperationsIfNeeded]; if (_removedSubnodes.count == 0) { @@ -151,7 +151,7 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) { - (void)calculateSubnodeOperationsIfNeeded { - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); if (_calculatedSubnodeOperations) { return; } @@ -206,27 +206,27 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) { - (NSArray *)currentSubnodesWithTransitionContext:(_ASTransitionContext *)context { - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); return _node.subnodes; } - (NSArray *)insertedSubnodesWithTransitionContext:(_ASTransitionContext *)context { - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); [self calculateSubnodeOperationsIfNeeded]; return _insertedSubnodes; } - (NSArray *)removedSubnodesWithTransitionContext:(_ASTransitionContext *)context { - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); [self calculateSubnodeOperationsIfNeeded]; return _removedSubnodes; } - (ASLayout *)transitionContext:(_ASTransitionContext *)context layoutForKey:(NSString *)key { - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); if ([key isEqualToString:ASTransitionContextFromLayoutKey]) { return _previousLayout.layout; } else if ([key isEqualToString:ASTransitionContextToLayoutKey]) { @@ -238,7 +238,7 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) { - (ASSizeRange)transitionContext:(_ASTransitionContext *)context constrainedSizeForKey:(NSString *)key { - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); if ([key isEqualToString:ASTransitionContextFromLayoutKey]) { return _previousLayout.constrainedSize; } else if ([key isEqualToString:ASTransitionContextToLayoutKey]) { diff --git a/Source/TextKit/ASTextKitContext.mm b/Source/TextKit/ASTextKitContext.mm index 0995a66f66..fa0fb88344 100644 --- a/Source/TextKit/ASTextKitContext.mm +++ b/Source/TextKit/ASTextKitContext.mm @@ -32,9 +32,9 @@ { if (self = [super init]) { // Concurrently initialising TextKit components crashes (rdar://18448377) so we use a global lock. - // Allocate __staticMutex on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) - static ASDN::StaticMutex& __staticMutex = *new ASDN::StaticMutex; - ASDN::StaticMutexLocker l(__staticMutex); + // Allocate mutex on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) + static auto *mutex = new ASDN::Mutex; + ASDN::MutexLocker l(*mutex); __instanceLock__ = std::make_shared(); @@ -66,7 +66,7 @@ NSTextStorage *, NSTextContainer *))block { - ASDN::MutexSharedLocker l(__instanceLock__); + ASDN::MutexLocker l(*__instanceLock__); if (block) { block(_layoutManager, _textStorage, _textContainer); } From e392f832f42897da41a7c0106709b55427efcea4 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Tue, 6 Nov 2018 08:31:09 -0800 Subject: [PATCH 52/60] Rework ASTraitCollection to Fix Warnings and Remove Boilerplate (#1211) * Clean up trait collection to fix a ton of warnings and remove code * Support Xcode 9 (iOS 11 SDK) * Hack harder --- AsyncDisplayKit.xcodeproj/project.pbxproj | 4 - Source/Base/ASAssert.h | 1 + Source/Base/ASBaseDefines.h | 12 + Source/Details/ASTraitCollection.h | 107 +---- Source/Details/ASTraitCollection.mm | 468 +++++----------------- Tests/ASTraitCollectionTests.mm | 30 -- 6 files changed, 123 insertions(+), 499 deletions(-) delete mode 100644 Tests/ASTraitCollectionTests.mm diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 2cfec88415..7566729fb7 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -101,7 +101,6 @@ 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 */; }; - 4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm */; }; 4E9127691F64157600499623 /* ASRunLoopQueueTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4E9127681F64157600499623 /* ASRunLoopQueueTests.mm */; }; 509E68601B3AED8E009B9150 /* ASScrollDirection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E111B371BD7007741D0 /* ASScrollDirection.mm */; }; 509E68611B3AEDA0009B9150 /* ASAbstractLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E171B37339C007741D0 /* ASAbstractLayoutController.h */; }; @@ -672,7 +671,6 @@ 3917EBD21E9C2FC400D04A01 /* _ASCollectionReusableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASCollectionReusableView.h; sourceTree = ""; }; 3917EBD31E9C2FC400D04A01 /* _ASCollectionReusableView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASCollectionReusableView.mm; sourceTree = ""; }; 3C9C128419E616EF00E942A0 /* ASTableViewTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASTableViewTests.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTraitCollectionTests.mm; sourceTree = ""; }; 464052191A3F83C40061C0BA /* ASDataController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASDataController.h; sourceTree = ""; }; 4640521A1A3F83C40061C0BA /* ASDataController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDataController.mm; sourceTree = ""; }; 4640521B1A3F83C40061C0BA /* ASTableLayoutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTableLayoutController.h; sourceTree = ""; }; @@ -1359,7 +1357,6 @@ 058D0A37195D057000B7D73C /* ASTextNodeWordKernerTests.mm */, CCE4F9BC1F0ECE5200062E4E /* ASTLayoutFixture.h */, CCE4F9BD1F0ECE5200062E4E /* ASTLayoutFixture.mm */, - 4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm */, CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.mm */, AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.mm */, CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.mm */, @@ -2268,7 +2265,6 @@ CCEDDDD9200C518800FFCD0A /* ASConfigurationTests.mm in Sources */, AE440175210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm in Sources */, E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.mm in Sources */, - 4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.mm in Sources */, 29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.mm in Sources */, CC583AD71EF9BDC100134156 /* NSInvocation+ASTestHelpers.mm in Sources */, CC051F1F1D7A286A006434CB /* ASCALayerTests.mm in Sources */, diff --git a/Source/Base/ASAssert.h b/Source/Base/ASAssert.h index e838c86dd1..f00ce967d6 100644 --- a/Source/Base/ASAssert.h +++ b/Source/Base/ASAssert.h @@ -63,6 +63,7 @@ #define ASDisplayNodeCAssertPositiveReal(description, num) ASDisplayNodeCAssert(num >= 0 && num <= CGFLOAT_MAX, @"%@ must be a real positive integer: %f.", description, (CGFloat)num) #define ASDisplayNodeCAssertInfOrPositiveReal(description, num) ASDisplayNodeCAssert(isinf(num) || (num >= 0 && num <= CGFLOAT_MAX), @"%@ must be infinite or a real positive integer: %f.", description, (CGFloat)num) +#define ASDisplayNodeCAssertPermanent(object) ASDisplayNodeCAssert(CFGetRetainCount((__bridge CFTypeRef)(object)) == CFGetRetainCount(kCFNull), @"Expected %s to be a permanent object.", #object) #define ASDisplayNodeErrorDomain @"ASDisplayNodeErrorDomain" #define ASDisplayNodeNonFatalErrorCode 1 diff --git a/Source/Base/ASBaseDefines.h b/Source/Base/ASBaseDefines.h index 39c82b6748..65335e275e 100644 --- a/Source/Base/ASBaseDefines.h +++ b/Source/Base/ASBaseDefines.h @@ -21,6 +21,18 @@ # define let const __auto_type #endif +/** + * Hack to support building for iOS with Xcode 9. UIUserInterfaceStyle was previously tvOS-only, + * and it was added to iOS 12. Xcode 9 (iOS 11 SDK) will flat-out refuse to build anything that + * references this enum targeting iOS, even if it's guarded with the right availability macros, + * because it thinks the entire platform isn't compatible with the enum. + */ +#if TARGET_OS_TV || (defined(__IPHONE_12_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0) +#define AS_BUILD_UIUSERINTERFACESTYLE 1 +#else +#define AS_BUILD_UIUSERINTERFACESTYLE 0 +#endif + #ifdef __GNUC__ # define ASDISPLAYNODE_GNUC(major, minor) \ (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) diff --git a/Source/Details/ASTraitCollection.h b/Source/Details/ASTraitCollection.h index f1aa8ab187..9ecf433ecc 100644 --- a/Source/Details/ASTraitCollection.h +++ b/Source/Details/ASTraitCollection.h @@ -18,34 +18,6 @@ NS_ASSUME_NONNULL_BEGIN -#pragma mark - ASPrimitiveContentSizeCategory - -/** - * ASPrimitiveContentSizeCategory is a UIContentSizeCategory that can be used inside a struct. - * - * We need an unretained pointer because ARC can't manage struct memory. - * - * WARNING: DO NOT cast UIContentSizeCategory values to ASPrimitiveContentSizeCategory directly. - * Use ASPrimitiveContentSizeCategoryMake(UIContentSizeCategory) instead. - * This is because we make some assumptions about the lifetime of the object it points to. - * Also note that cast from ASPrimitiveContentSizeCategory to UIContentSizeCategory is always safe. - */ -typedef __unsafe_unretained UIContentSizeCategory ASPrimitiveContentSizeCategory; - -/** - * Safely casts from UIContentSizeCategory to ASPrimitiveContentSizeCategory. - * - * The UIKit documentation doesn't specify if we can receive a copy of the UIContentSizeCategory constant. While getting - * copies is fine with ARC, usage of unretained pointers requires us to ensure the lifetime of the object it points to. - * Manual retain&release of the UIContentSizeCategory object is not an option because it would require us to do that - * everywhere ASPrimitiveTraitCollection is used. This is error-prone and can lead to crashes and memory leaks. So, we - * explicitly limit possible values of ASPrimitiveContentSizeCategory to the predetermined set of global constants with - * known lifetime. - * - * @return a pointer to one of the UIContentSizeCategory constants. - */ -AS_EXTERN ASPrimitiveContentSizeCategory ASPrimitiveContentSizeCategoryMake(UIContentSizeCategory sizeCategory); - #pragma mark - ASPrimitiveTraitCollection /** @@ -56,7 +28,9 @@ AS_EXTERN ASPrimitiveContentSizeCategory ASPrimitiveContentSizeCategoryMake(UICo * If you use ASPrimitiveTraitCollection, please do make sure to initialize it with ASPrimitiveTraitCollectionMakeDefault() * or ASPrimitiveTraitCollectionFromUITraitCollection(UITraitCollection*). */ -typedef struct ASPrimitiveTraitCollection { +#pragma clang diagnostic push +#pragma clang diagnostic warning "-Wpadded" +typedef struct { UIUserInterfaceSizeClass horizontalSizeClass; UIUserInterfaceSizeClass verticalSizeClass; @@ -66,14 +40,16 @@ typedef struct ASPrimitiveTraitCollection { UIUserInterfaceIdiom userInterfaceIdiom; UIForceTouchCapability forceTouchCapability; UITraitEnvironmentLayoutDirection layoutDirection API_AVAILABLE(ios(10.0)); -#if TARGET_OS_TV - UIUserInterfaceStyle userInterfaceStyle; +#if AS_BUILD_UIUSERINTERFACESTYLE + UIUserInterfaceStyle userInterfaceStyle API_AVAILABLE(tvos(10.0), ios(12.0)); #endif - ASPrimitiveContentSizeCategory preferredContentSizeCategory; + // NOTE: This must be a constant. We will assert. + unowned UIContentSizeCategory preferredContentSizeCategory API_AVAILABLE(ios(10.0)); CGSize containerSize; } ASPrimitiveTraitCollection; +#pragma clang diagnostic pop /** * Creates ASPrimitiveTraitCollection with default values. @@ -164,52 +140,21 @@ AS_EXTERN void ASTraitCollectionPropagateDown(id element, ASPri AS_SUBCLASSING_RESTRICTED @interface ASTraitCollection : NSObject -@property (nonatomic, readonly) UIUserInterfaceSizeClass horizontalSizeClass; -@property (nonatomic, readonly) UIUserInterfaceSizeClass verticalSizeClass; +@property (readonly) UIUserInterfaceSizeClass horizontalSizeClass; +@property (readonly) UIUserInterfaceSizeClass verticalSizeClass; -@property (nonatomic, readonly) CGFloat displayScale; -@property (nonatomic, readonly) UIDisplayGamut displayGamut API_AVAILABLE(ios(10.0)); +@property (readonly) CGFloat displayScale; +@property (readonly) UIDisplayGamut displayGamut API_AVAILABLE(ios(10.0)); -@property (nonatomic, readonly) UIUserInterfaceIdiom userInterfaceIdiom; -@property (nonatomic, readonly) UIForceTouchCapability forceTouchCapability; -@property (nonatomic, readonly) UITraitEnvironmentLayoutDirection layoutDirection API_AVAILABLE(ios(10.0)); -#if TARGET_OS_TV -@property (nonatomic, readonly) UIUserInterfaceStyle userInterfaceStyle; +@property (readonly) UIUserInterfaceIdiom userInterfaceIdiom; +@property (readonly) UIForceTouchCapability forceTouchCapability; +@property (readonly) UITraitEnvironmentLayoutDirection layoutDirection API_AVAILABLE(ios(10.0)); +#if AS_BUILD_UIUSERINTERFACESTYLE +@property (readonly) UIUserInterfaceStyle userInterfaceStyle API_AVAILABLE(tvos(10.0), ios(12.0)); #endif +@property (readonly) UIContentSizeCategory preferredContentSizeCategory API_AVAILABLE(ios(10.0)); -@property (nonatomic, readonly) UIContentSizeCategory preferredContentSizeCategory; - -@property (nonatomic, readonly) CGSize containerSize; - -+ (ASTraitCollection *)traitCollectionWithUITraitCollection:(UITraitCollection *)traitCollection - containerSize:(CGSize)windowSize NS_RETURNS_RETAINED; - -+ (ASTraitCollection *)traitCollectionWithUITraitCollection:(UITraitCollection *)traitCollection - containerSize:(CGSize)windowSize - fallbackContentSizeCategory:(UIContentSizeCategory)fallbackContentSizeCategory NS_RETURNS_RETAINED; - -#if TARGET_OS_TV -+ (ASTraitCollection *)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass - verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass - displayScale:(CGFloat)displayScale - displayGamut:(UIDisplayGamut)displayGamut - userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom - forceTouchCapability:(UIForceTouchCapability)forceTouchCapability - layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection - userInterfaceStyle:(UIUserInterfaceStyle)userInterfaceStyle - preferredContentSizeCategory:(UIContentSizeCategory)preferredContentSizeCategory - containerSize:(CGSize)windowSize NS_RETURNS_RETAINED; -#else -+ (ASTraitCollection *)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass - verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass - displayScale:(CGFloat)displayScale - displayGamut:(UIDisplayGamut)displayGamut - userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom - forceTouchCapability:(UIForceTouchCapability)forceTouchCapability - layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection - preferredContentSizeCategory:(UIContentSizeCategory)preferredContentSizeCategory - containerSize:(CGSize)windowSize NS_RETURNS_RETAINED; -#endif +@property (readonly) CGSize containerSize; - (BOOL)isEqualToTraitCollection:(ASTraitCollection *)traitCollection; @@ -226,18 +171,4 @@ AS_SUBCLASSING_RESTRICTED @end -@interface ASTraitCollection (Deprecated) - -- (instancetype)init ASDISPLAYNODE_DEPRECATED_MSG("The default constructor of this class is going to become unavailable. Use other constructors instead."); - -+ (ASTraitCollection *)traitCollectionWithDisplayScale:(CGFloat)displayScale - userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom - horizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass - verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass - forceTouchCapability:(UIForceTouchCapability)forceTouchCapability - containerSize:(CGSize)windowSize - NS_RETURNS_RETAINED ASDISPLAYNODE_DEPRECATED_MSG("Use full version of this method instead."); - -@end - NS_ASSUME_NONNULL_END diff --git a/Source/Details/ASTraitCollection.mm b/Source/Details/ASTraitCollection.mm index 8e49221782..7058501aac 100644 --- a/Source/Details/ASTraitCollection.mm +++ b/Source/Details/ASTraitCollection.mm @@ -8,68 +8,11 @@ // #import +#import #import #import #import -#pragma mark - ASPrimitiveContentSizeCategory - -// UIContentSizeCategoryUnspecified is available only in iOS 10.0 and later. -// This is used for compatibility with older iOS versions. -ASDISPLAYNODE_INLINE UIContentSizeCategory AS_UIContentSizeCategoryUnspecified() { - if (AS_AVAILABLE_IOS(10)) { - return UIContentSizeCategoryUnspecified; - } else { - return @"_UICTContentSizeCategoryUnspecified"; - } -} - -ASDISPLAYNODE_INLINE UIContentSizeCategory _Nonnull AS_safeContentSizeCategory(UIContentSizeCategory _Nullable sizeCategory) { - return sizeCategory ? sizeCategory : AS_UIContentSizeCategoryUnspecified(); -} - -ASPrimitiveContentSizeCategory ASPrimitiveContentSizeCategoryMake(UIContentSizeCategory sizeCategory) { - if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraSmall]) { - return UIContentSizeCategoryExtraSmall; - } - if ([sizeCategory isEqualToString:UIContentSizeCategorySmall]) { - return UIContentSizeCategorySmall; - } - if ([sizeCategory isEqualToString:UIContentSizeCategoryMedium]) { - return UIContentSizeCategoryMedium; - } - if ([sizeCategory isEqualToString:UIContentSizeCategoryLarge]) { - return UIContentSizeCategoryLarge; - } - if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraLarge]) { - return UIContentSizeCategoryExtraLarge; - } - if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraExtraLarge]) { - return UIContentSizeCategoryExtraExtraLarge; - } - if ([sizeCategory isEqualToString:UIContentSizeCategoryExtraExtraExtraLarge]) { - return UIContentSizeCategoryExtraExtraExtraLarge; - } - - if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityMedium]) { - return UIContentSizeCategoryAccessibilityMedium; - } - if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityLarge]) { - return UIContentSizeCategoryAccessibilityLarge; - } - if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraLarge]) { - return UIContentSizeCategoryAccessibilityExtraLarge; - } - if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraLarge]) { - return UIContentSizeCategoryAccessibilityExtraExtraLarge; - } - if ([sizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraExtraLarge]) { - return UIContentSizeCategoryAccessibilityExtraExtraExtraLarge; - } - - return AS_UIContentSizeCategoryUnspecified(); -} - #pragma mark - ASPrimitiveTraitCollection void ASTraitCollectionPropagateDown(id element, ASPrimitiveTraitCollection traitCollection) { @@ -83,14 +26,21 @@ void ASTraitCollectionPropagateDown(id element, ASPrimitiveTrai } ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() { - return (ASPrimitiveTraitCollection) { - // Default values can be defined in here - .displayGamut = UIDisplayGamutUnspecified, - .userInterfaceIdiom = UIUserInterfaceIdiomUnspecified, - .layoutDirection = UITraitEnvironmentLayoutDirectionUnspecified, - .preferredContentSizeCategory = ASPrimitiveContentSizeCategoryMake(AS_UIContentSizeCategoryUnspecified()), - .containerSize = CGSizeZero, - }; + ASPrimitiveTraitCollection tc; + tc.horizontalSizeClass = UIUserInterfaceSizeClassUnspecified; + tc.verticalSizeClass = UIUserInterfaceSizeClassUnspecified; + tc.containerSize = CGSizeZero; + if (AS_AVAILABLE_IOS(10)) { + tc.displayGamut = UIDisplayGamutUnspecified; + tc.preferredContentSizeCategory = UIContentSizeCategoryUnspecified; + tc.layoutDirection = UITraitEnvironmentLayoutDirectionUnspecified; + } +#if AS_BUILD_UIUSERINTERFACESTYLE + if (AS_AVAILABLE_IOS_TVOS(12, 10)) { + tc.userInterfaceStyle = UIUserInterfaceStyleUnspecified; + } +#endif + return tc; } ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITraitCollection *traitCollection) { @@ -104,38 +54,19 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra environmentTraitCollection.displayGamut = traitCollection.displayGamut; environmentTraitCollection.layoutDirection = traitCollection.layoutDirection; - // preferredContentSizeCategory is also available on older iOS versions, but only via UIApplication class. - // It should be noted that [UIApplication sharedApplication] is unavailable because Texture is built with only extension-safe API. - environmentTraitCollection.preferredContentSizeCategory = ASPrimitiveContentSizeCategoryMake(traitCollection.preferredContentSizeCategory); - - #if TARGET_OS_TV - environmentTraitCollection.userInterfaceStyle = traitCollection.userInterfaceStyle; - #endif - } else { - environmentTraitCollection.displayGamut = UIDisplayGamutSRGB; // We're on iOS 9 or lower, so this is not a P3 device. + ASDisplayNodeCAssertPermanent(traitCollection.preferredContentSizeCategory); + environmentTraitCollection.preferredContentSizeCategory = traitCollection.preferredContentSizeCategory; } +#if AS_BUILD_UIUSERINTERFACESTYLE + if (AS_AVAILABLE_IOS_TVOS(12, 10)) { + environmentTraitCollection.userInterfaceStyle = traitCollection.userInterfaceStyle; + } +#endif return environmentTraitCollection; } BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTraitCollection lhs, ASPrimitiveTraitCollection rhs) { - UIContentSizeCategory leftSizeCategory = AS_safeContentSizeCategory(lhs.preferredContentSizeCategory); - UIContentSizeCategory rightSizeCategory = AS_safeContentSizeCategory(rhs.preferredContentSizeCategory); - - return - lhs.verticalSizeClass == rhs.verticalSizeClass && - lhs.horizontalSizeClass == rhs.horizontalSizeClass && - lhs.displayScale == rhs.displayScale && - lhs.displayGamut == rhs.displayGamut && - lhs.userInterfaceIdiom == rhs.userInterfaceIdiom && - lhs.forceTouchCapability == rhs.forceTouchCapability && - lhs.layoutDirection == rhs.layoutDirection && - #if TARGET_OS_TV - lhs.userInterfaceStyle == rhs.userInterfaceStyle && - #endif - - [leftSizeCategory isEqualToString:rightSizeCategory] && // Simple pointer comparison should be sufficient here - - CGSizeEqualToSize(lhs.containerSize, rhs.containerSize); + return !memcmp(&lhs, &rhs, sizeof(ASPrimitiveTraitCollection)); } // Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline @@ -179,6 +110,7 @@ ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUIUserInterfaceSizeClass(UIUserInt } // Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline +API_AVAILABLE(ios(10)) ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUIDisplayGamut(UIDisplayGamut displayGamut) { switch (displayGamut) { case UIDisplayGamutSRGB: @@ -191,6 +123,7 @@ ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUIDisplayGamut(UIDisplayGamut disp } // Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline +API_AVAILABLE(ios(10)) ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentLayoutDirection(UITraitEnvironmentLayoutDirection layoutDirection) { switch (layoutDirection) { case UITraitEnvironmentLayoutDirectionLeftToRight: @@ -202,8 +135,9 @@ ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentLayoutDirection( } } -#if TARGET_OS_TV // Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline +#if AS_BUILD_UIUSERINTERFACESTYLE +API_AVAILABLE(tvos(10.0), ios(12.0)) ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUIUserInterfaceStyle(UIUserInterfaceStyle userInterfaceStyle) { switch (userInterfaceStyle) { case UIUserInterfaceStyleLight: @@ -221,181 +155,83 @@ NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection trai [props addObject:@{ @"verticalSizeClass": AS_NSStringFromUIUserInterfaceSizeClass(traits.verticalSizeClass) }]; [props addObject:@{ @"horizontalSizeClass": AS_NSStringFromUIUserInterfaceSizeClass(traits.horizontalSizeClass) }]; [props addObject:@{ @"displayScale": [NSString stringWithFormat: @"%.0lf", (double)traits.displayScale] }]; - [props addObject:@{ @"displayGamut": AS_NSStringFromUIDisplayGamut(traits.displayGamut) }]; [props addObject:@{ @"userInterfaceIdiom": AS_NSStringFromUIUserInterfaceIdiom(traits.userInterfaceIdiom) }]; [props addObject:@{ @"forceTouchCapability": AS_NSStringFromUIForceTouchCapability(traits.forceTouchCapability) }]; - [props addObject:@{ @"layoutDirection": AS_NSStringFromUITraitEnvironmentLayoutDirection(traits.layoutDirection) }]; - #if TARGET_OS_TV +#if AS_BUILD_UIUSERINTERFACESTYLE + if (AS_AVAILABLE_IOS_TVOS(12, 10)) { [props addObject:@{ @"userInterfaceStyle": AS_NSStringFromUIUserInterfaceStyle(traits.userInterfaceStyle) }]; - #endif - [props addObject:@{ @"preferredContentSizeCategory": AS_safeContentSizeCategory(traits.preferredContentSizeCategory) }]; + } +#endif + if (AS_AVAILABLE_IOS(10)) { + [props addObject:@{ @"layoutDirection": AS_NSStringFromUITraitEnvironmentLayoutDirection(traits.layoutDirection) }]; + [props addObject:@{ @"preferredContentSizeCategory": traits.preferredContentSizeCategory }]; + [props addObject:@{ @"displayGamut": AS_NSStringFromUIDisplayGamut(traits.displayGamut) }]; + } [props addObject:@{ @"containerSize": NSStringFromCGSize(traits.containerSize) }]; return ASObjectDescriptionMakeWithoutObject(props); } #pragma mark - ASTraitCollection -@implementation ASTraitCollection - -#if TARGET_OS_TV - -- (instancetype)initWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass - verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass - displayScale:(CGFloat)displayScale - displayGamut:(UIDisplayGamut)displayGamut - userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom - forceTouchCapability:(UIForceTouchCapability)forceTouchCapability - layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection - userInterfaceStyle:(UIUserInterfaceStyle)userInterfaceStyle - preferredContentSizeCategory:(UIContentSizeCategory _Nonnull)preferredContentSizeCategory - containerSize:(CGSize)windowSize -{ - self = [super init]; - if (self) { - _horizontalSizeClass = horizontalSizeClass; - _verticalSizeClass = verticalSizeClass; - _displayScale = displayScale; - _displayGamut = displayGamut; - _userInterfaceIdiom = userInterfaceIdiom; - _forceTouchCapability = forceTouchCapability; - _layoutDirection = layoutDirection; - _userInterfaceStyle = userInterfaceStyle; - _preferredContentSizeCategory = AS_safeContentSizeCategory(preferredContentSizeCategory); // guard against misuse - _containerSize = windowSize; - } - return self; +@implementation ASTraitCollection { + ASPrimitiveTraitCollection _prim; } -+ (instancetype)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass - verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass - displayScale:(CGFloat)displayScale - displayGamut:(UIDisplayGamut)displayGamut - userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom - forceTouchCapability:(UIForceTouchCapability)forceTouchCapability - layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection - userInterfaceStyle:(UIUserInterfaceStyle)userInterfaceStyle - preferredContentSizeCategory:(UIContentSizeCategory _Nonnull)preferredContentSizeCategory - containerSize:(CGSize)windowSize NS_RETURNS_RETAINED -{ - return [[self alloc] initWithHorizontalSizeClass:horizontalSizeClass - verticalSizeClass:verticalSizeClass - displayScale:displayScale - displayGamut:displayGamut - userInterfaceIdiom:userInterfaceIdiom - forceTouchCapability:forceTouchCapability - layoutDirection:layoutDirection - userInterfaceStyle:userInterfaceStyle - preferredContentSizeCategory:preferredContentSizeCategory - containerSize:windowSize]; -} - -#else - -- (instancetype)initWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass - verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass - displayScale:(CGFloat)displayScale - displayGamut:(UIDisplayGamut)displayGamut - userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom - forceTouchCapability:(UIForceTouchCapability)forceTouchCapability - layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection - preferredContentSizeCategory:(UIContentSizeCategory _Nonnull)preferredContentSizeCategory - containerSize:(CGSize)windowSize -{ - self = [super init]; - if (self) { - _horizontalSizeClass = horizontalSizeClass; - _verticalSizeClass = verticalSizeClass; - _displayScale = displayScale; - _displayGamut = displayGamut; - _userInterfaceIdiom = userInterfaceIdiom; - _forceTouchCapability = forceTouchCapability; - _layoutDirection = layoutDirection; - _preferredContentSizeCategory = AS_safeContentSizeCategory(preferredContentSizeCategory); // guard against misuse - _containerSize = windowSize; - } - return self; -} - -+ (instancetype)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass - verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass - displayScale:(CGFloat)displayScale - displayGamut:(UIDisplayGamut)displayGamut - userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom - forceTouchCapability:(UIForceTouchCapability)forceTouchCapability - layoutDirection:(UITraitEnvironmentLayoutDirection)layoutDirection - preferredContentSizeCategory:(UIContentSizeCategory _Nonnull)preferredContentSizeCategory - containerSize:(CGSize)windowSize NS_RETURNS_RETAINED -{ - return [[self alloc] initWithHorizontalSizeClass:horizontalSizeClass - verticalSizeClass:verticalSizeClass - displayScale:displayScale - displayGamut:displayGamut - userInterfaceIdiom:userInterfaceIdiom - forceTouchCapability:forceTouchCapability - layoutDirection:layoutDirection - preferredContentSizeCategory:preferredContentSizeCategory - containerSize:windowSize]; -} - -#endif - -+ (instancetype)traitCollectionWithUITraitCollection:(UITraitCollection *)traitCollection - containerSize:(CGSize)windowSize NS_RETURNS_RETAINED -{ - return [self traitCollectionWithUITraitCollection:traitCollection - containerSize:windowSize - fallbackContentSizeCategory:AS_UIContentSizeCategoryUnspecified()]; -} - - -+ (instancetype)traitCollectionWithUITraitCollection:(UITraitCollection *)traitCollection - containerSize:(CGSize)windowSize - fallbackContentSizeCategory:(UIContentSizeCategory _Nonnull)fallbackContentSizeCategory NS_RETURNS_RETAINED -{ - UIDisplayGamut displayGamut; - UITraitEnvironmentLayoutDirection layoutDirection; - UIContentSizeCategory sizeCategory; - #if TARGET_OS_TV - UIUserInterfaceStyle userInterfaceStyle; - #endif ++ (ASTraitCollection *)traitCollectionWithASPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traits NS_RETURNS_RETAINED { + ASTraitCollection *tc = [[ASTraitCollection alloc] init]; if (AS_AVAILABLE_IOS(10)) { - displayGamut = traitCollection.displayGamut; - layoutDirection = traitCollection.layoutDirection; - sizeCategory = traitCollection.preferredContentSizeCategory; - #if TARGET_OS_TV - userInterfaceStyle = traitCollection.userInterfaceStyle; - #endif - } else { - displayGamut = UIDisplayGamutSRGB; // We're on iOS 9 or lower, so this is not a P3 device. - layoutDirection = UITraitEnvironmentLayoutDirectionUnspecified; - sizeCategory = fallbackContentSizeCategory; - #if TARGET_OS_TV - userInterfaceStyle = UIUserInterfaceStyleUnspecified; - #endif + ASDisplayNodeCAssertPermanent(traits.preferredContentSizeCategory); } + tc->_prim = traits; + return tc; +} -#if TARGET_OS_TV - return [self traitCollectionWithHorizontalSizeClass:traitCollection.horizontalSizeClass - verticalSizeClass:traitCollection.verticalSizeClass - displayScale:traitCollection.displayScale - displayGamut:displayGamut - userInterfaceIdiom:traitCollection.userInterfaceIdiom - forceTouchCapability:traitCollection.forceTouchCapability - layoutDirection:layoutDirection - userInterfaceStyle:userInterfaceStyle - preferredContentSizeCategory:sizeCategory - containerSize:windowSize]; -#else - return [self traitCollectionWithHorizontalSizeClass:traitCollection.horizontalSizeClass - verticalSizeClass:traitCollection.verticalSizeClass - displayScale:traitCollection.displayScale - displayGamut:displayGamut - userInterfaceIdiom:traitCollection.userInterfaceIdiom - forceTouchCapability:traitCollection.forceTouchCapability - layoutDirection:layoutDirection - preferredContentSizeCategory:sizeCategory - containerSize:windowSize]; +- (ASPrimitiveTraitCollection)primitiveTraitCollection { + return _prim; +} +- (UIUserInterfaceSizeClass)horizontalSizeClass +{ + return _prim.horizontalSizeClass; +} +-(UIUserInterfaceSizeClass)verticalSizeClass +{ + return _prim.verticalSizeClass; +} +- (CGFloat)displayScale +{ + return _prim.displayScale; +} +- (UIDisplayGamut)displayGamut +{ + return _prim.displayGamut; +} +- (UIForceTouchCapability)forceTouchCapability +{ + return _prim.forceTouchCapability; +} +- (UITraitEnvironmentLayoutDirection)layoutDirection +{ + return _prim.layoutDirection; +} +#if AS_BUILD_UIUSERINTERFACESTYLE +- (UIUserInterfaceStyle)userInterfaceStyle +{ + return _prim.userInterfaceStyle; +} #endif +- (UIContentSizeCategory)preferredContentSizeCategory +{ + return _prim.preferredContentSizeCategory; +} +- (NSUInteger)hash { + return ASHashBytes(&_prim, sizeof(ASPrimitiveTraitCollection)); +} + +- (BOOL)isEqual:(id)object { + if (!object || ![object isKindOfClass:ASTraitCollection.class]) { + return NO; + } + return [self isEqualToTraitCollection:object]; } - (BOOL)isEqualToTraitCollection:(ASTraitCollection *)traitCollection @@ -407,129 +243,7 @@ NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection trai if (self == traitCollection) { return YES; } - - return - self.horizontalSizeClass == traitCollection.horizontalSizeClass && - self.verticalSizeClass == traitCollection.verticalSizeClass && - self.displayScale == traitCollection.displayScale && - self.displayGamut == traitCollection.displayGamut && - self.userInterfaceIdiom == traitCollection.userInterfaceIdiom && - self.forceTouchCapability == traitCollection.forceTouchCapability && - self.layoutDirection == traitCollection.layoutDirection && - #if TARGET_OS_TV - self.userInterfaceStyle == traitCollection.userInterfaceStyle && - #endif - [self.preferredContentSizeCategory isEqualToString:traitCollection.preferredContentSizeCategory] && - CGSizeEqualToSize(self.containerSize, traitCollection.containerSize); -} - -@end - -@implementation ASTraitCollection (PrimitiveTraits) - -+ (instancetype)traitCollectionWithASPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traits NS_RETURNS_RETAINED -{ -#if TARGET_OS_TV - return [self traitCollectionWithHorizontalSizeClass:traits.horizontalSizeClass - verticalSizeClass:traits.verticalSizeClass - displayScale:traits.displayScale - displayGamut:traits.displayGamut - userInterfaceIdiom:traits.userInterfaceIdiom - forceTouchCapability:traits.forceTouchCapability - layoutDirection:traits.layoutDirection - userInterfaceStyle:traits.userInterfaceStyle - preferredContentSizeCategory:AS_safeContentSizeCategory(traits.preferredContentSizeCategory) - containerSize:traits.containerSize]; -#else - return [self traitCollectionWithHorizontalSizeClass:traits.horizontalSizeClass - verticalSizeClass:traits.verticalSizeClass - displayScale:traits.displayScale - displayGamut:traits.displayGamut - userInterfaceIdiom:traits.userInterfaceIdiom - forceTouchCapability:traits.forceTouchCapability - layoutDirection:traits.layoutDirection - preferredContentSizeCategory:AS_safeContentSizeCategory(traits.preferredContentSizeCategory) - containerSize:traits.containerSize]; -#endif -} - -- (ASPrimitiveTraitCollection)primitiveTraitCollection -{ - return (ASPrimitiveTraitCollection) { - .horizontalSizeClass = self.horizontalSizeClass, - .verticalSizeClass = self.verticalSizeClass, - .displayScale = self.displayScale, - .displayGamut = self.displayGamut, - .userInterfaceIdiom = self.userInterfaceIdiom, - .forceTouchCapability = self.forceTouchCapability, - .layoutDirection = self.layoutDirection, -#if TARGET_OS_TV - .userInterfaceStyle = self.userInterfaceStyle, -#endif - .preferredContentSizeCategory = ASPrimitiveContentSizeCategoryMake(self.preferredContentSizeCategory), - .containerSize = self.containerSize, - }; -} - -@end - -@implementation ASTraitCollection (Deprecated) - -- (instancetype)init -{ -#if TARGET_OS_TV - return [self initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified - verticalSizeClass:UIUserInterfaceSizeClassUnspecified - displayScale:0 - displayGamut:UIDisplayGamutUnspecified - userInterfaceIdiom:UIUserInterfaceIdiomUnspecified - forceTouchCapability:UIForceTouchCapabilityUnknown - layoutDirection:UITraitEnvironmentLayoutDirectionUnspecified - userInterfaceStyle:UIUserInterfaceStyleUnspecified - preferredContentSizeCategory:AS_UIContentSizeCategoryUnspecified() - containerSize:CGSizeZero]; -#else - return [self initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified - verticalSizeClass:UIUserInterfaceSizeClassUnspecified - displayScale:0 - displayGamut:UIDisplayGamutUnspecified - userInterfaceIdiom:UIUserInterfaceIdiomUnspecified - forceTouchCapability:UIForceTouchCapabilityUnknown - layoutDirection:UITraitEnvironmentLayoutDirectionUnspecified - preferredContentSizeCategory:AS_UIContentSizeCategoryUnspecified() - containerSize:CGSizeZero]; -#endif -} - -+ (ASTraitCollection *)traitCollectionWithDisplayScale:(CGFloat)displayScale - userInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom - horizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass - verticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass - forceTouchCapability:(UIForceTouchCapability)forceTouchCapability - containerSize:(CGSize)windowSize NS_RETURNS_RETAINED -{ -#if TARGET_OS_TV - return [self traitCollectionWithHorizontalSizeClass:horizontalSizeClass - verticalSizeClass:verticalSizeClass - displayScale:displayScale - displayGamut:UIDisplayGamutUnspecified - userInterfaceIdiom:userInterfaceIdiom - forceTouchCapability:forceTouchCapability - layoutDirection:UITraitEnvironmentLayoutDirectionUnspecified - userInterfaceStyle:UIUserInterfaceStyleUnspecified - preferredContentSizeCategory:AS_UIContentSizeCategoryUnspecified() - containerSize:windowSize]; -#else - return [self traitCollectionWithHorizontalSizeClass:horizontalSizeClass - verticalSizeClass:verticalSizeClass - displayScale:displayScale - displayGamut:UIDisplayGamutUnspecified - userInterfaceIdiom:userInterfaceIdiom - forceTouchCapability:forceTouchCapability - layoutDirection:UITraitEnvironmentLayoutDirectionUnspecified - preferredContentSizeCategory:AS_UIContentSizeCategoryUnspecified() - containerSize:windowSize]; -#endif + return ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(_prim, traitCollection->_prim); } @end diff --git a/Tests/ASTraitCollectionTests.mm b/Tests/ASTraitCollectionTests.mm deleted file mode 100644 index e6141d6c3a..0000000000 --- a/Tests/ASTraitCollectionTests.mm +++ /dev/null @@ -1,30 +0,0 @@ -// -// ASTraitCollectionTests.mm -// Texture -// -// Copyright (c) Pinterest, Inc. All rights reserved. -// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 -// - -#import -#import - -@interface ASTraitCollectionTests : XCTestCase - -@end - -@implementation ASTraitCollectionTests - -- (void)testPrimitiveContentSizeCategoryLifetime -{ - ASPrimitiveContentSizeCategory primitiveContentSize; - @autoreleasepool { - // Make sure the compiler won't optimize string alloc/dealloc - NSString *contentSizeCategory = [NSString stringWithCString:"UICTContentSizeCategoryL" encoding:NSUTF8StringEncoding]; - primitiveContentSize = ASPrimitiveContentSizeCategoryMake(contentSizeCategory); - } - - XCTAssertEqual(primitiveContentSize, UIContentSizeCategoryLarge); -} - -@end From 7edaeab839a6196025dc07c1a7c6d3ee9c4cb6e7 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Wed, 7 Nov 2018 07:01:19 -0800 Subject: [PATCH 53/60] Fix warning using __builtin_popcount (#1218) --- Source/ASConfigurationInternal.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ASConfigurationInternal.mm b/Source/ASConfigurationInternal.mm index fabbfbf3fb..596719000c 100644 --- a/Source/ASConfigurationInternal.mm +++ b/Source/ASConfigurationInternal.mm @@ -74,7 +74,7 @@ return NO; } - NSAssert(__builtin_popcount(requested) == 1, @"Cannot activate multiple features at once with this method."); + NSAssert(__builtin_popcountl(requested) == 1, @"Cannot activate multiple features at once with this method."); // We need to call out, whether it's enabled or not. // A/B testing requires even "control" users to be activated. From 4cfc333d81689c74d5838d4514dd012a4098ad08 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Wed, 7 Nov 2018 10:47:48 -0800 Subject: [PATCH 54/60] Clean up our mutex, fix try_lock not hooking into assert mechanism (#1219) * Clean up our mutex * Placement new import * Privatize --- Source/Details/ASThread.h | 283 +++++++++++++++++--------------------- 1 file changed, 130 insertions(+), 153 deletions(-) diff --git a/Source/Details/ASThread.h b/Source/Details/ASThread.h index 701e6c10a1..80091abf3e 100644 --- a/Source/Details/ASThread.h +++ b/Source/Details/ASThread.h @@ -9,11 +9,8 @@ #import -#import #import #import -#import -#import #import #import @@ -82,7 +79,7 @@ ASDISPLAYNODE_INLINE void _ASLockScopeUnownedCleanup(id __unsafe_unre #define ASSynthesizeLockingMethodsWithMutex(mutex) \ - (void)lock { mutex.lock(); } \ - (void)unlock { mutex.unlock(); } \ -- (BOOL)tryLock { return mutex.tryLock(); } +- (BOOL)tryLock { return (BOOL)mutex.try_lock(); } #define ASSynthesizeLockingMethodsWithObject(object) \ - (void)lock { [object lock]; } \ @@ -95,155 +92,118 @@ ASDISPLAYNODE_INLINE void _ASUnlockScopeCleanup(id __strong *lockPtr) #ifdef __cplusplus -/** - * Enable this flag to collect information on the owning thread and ownership level of a mutex. - * These properties are useful to determine if a mutex has been acquired and in case of a recursive mutex, how many times that happened. - * - * This flag also enable locking assertions (e.g ASAssertUnlocked(node)). - * The assertions are useful when you want to indicate and enforce the locking policy/expectation of methods. - * To determine when and which methods acquired a (recursive) mutex (to debug deadlocks, for example), - * put breakpoints at some assertions. When the breakpoints hit, walk through stack trace frames - * and check ownership count of the mutex. - */ -#if ASDISPLAYNODE_ASSERTIONS_ENABLED -#define CHECK_LOCKING_SAFETY 1 -#else -#define CHECK_LOCKING_SAFETY 0 -#endif - #include #include +#include +#include -// This MUST always execute, even when assertions are disabled. Otherwise all lock operations become no-ops! -// (To be explicit, do not turn this into an NSAssert, assert(), or any other kind of statement where the -// evaluation of x_ can be compiled out.) -#define AS_POSIX_ASSERT_NOERR(x_) ({ \ - __unused int res = (x_); \ - ASDisplayNodeCAssert(res == 0, @"Expected %s to return 0, got %d instead. Error: %s", #x_, res, strerror(res)); \ -}) - -/** - * Assert if the current thread owns a mutex. - * This assertion is useful when you want to indicate and enforce the locking policy/expectation of methods. - * To determine when and which methods acquired a (recursive) mutex (to debug deadlocks, for example), - * put breakpoints at some of these assertions. When the breakpoints hit, walk through stack trace frames - * and check ownership count of the mutex. - */ -#if CHECK_LOCKING_SAFETY -#define ASAssertUnlocked(lock) ASDisplayNodeAssertFalse(lock.locked()) -#define ASAssertLocked(lock) ASDisplayNodeAssert(lock.locked(), @"Lock must be held by current thread") -#else -#define ASAssertUnlocked(lock) -#define ASAssertLocked(lock) -#endif +// These macros are here for legacy reasons. We may get rid of them later. +#define ASAssertLocked(m) m.AssertHeld() +#define ASAssertUnlocked(m) m.AssertNotHeld() namespace ASDN { // Set once in Mutex constructor. Linker fails if this is a member variable. ?? - static BOOL gMutex_unfair; - + static bool gMutex_unfair; + // Silence unguarded availability warnings in here, because // perf is critical and we will check availability once // and not again. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability" - struct Mutex + class Mutex { - /// Constructs a non-recursive mutex (the default). + public: + /// Constructs a plain mutex (the default). Mutex () : Mutex (false) {} ~Mutex () { - if (gMutex_unfair) { - // nop - } else { - AS_POSIX_ASSERT_NOERR(pthread_mutex_destroy (&_m)); + // Manually destroy since unions can't do it. + switch (_type) { + case Plain: + _plain.~mutex(); + break; + case Recursive: + _recursive.~recursive_mutex(); + break; + case Unfair: + // nop + break; + case RecursiveUnfair: + // nop + break; } -#if CHECK_LOCKING_SAFETY - _owner = 0; - _count = 0; -#endif } Mutex (const Mutex&) = delete; Mutex &operator=(const Mutex&) = delete; - bool tryLock() { - if (gMutex_unfair) { - if (_recursive) { - return ASRecursiveUnfairLockTryLock(&_runfair); - } else { - return os_unfair_lock_trylock(&_unfair); - } - } else { - let result = pthread_mutex_trylock(&_m); - if (result == 0) { - return true; - } else if (result == EBUSY) { - return false; - } else { - ASDisplayNodeCFailAssert(@"Locking error: %s", strerror(result)); - return true; // if we return false we may enter an infinite loop. - } + bool try_lock() { + bool success = false; + switch (_type) { + case Plain: + success = _plain.try_lock(); + break; + case Recursive: + success = _recursive.try_lock(); + break; + case Unfair: + success = os_unfair_lock_trylock(&_unfair); + break; + case RecursiveUnfair: + success = ASRecursiveUnfairLockTryLock(&_runfair); + break; } + if (success) { + DidLock(); + } + return success; + } + + void lock() { + switch (_type) { + case Plain: + _plain.lock(); + break; + case Recursive: + _recursive.lock(); + break; + case Unfair: + os_unfair_lock_lock(&_unfair); + break; + case RecursiveUnfair: + ASRecursiveUnfairLockLock(&_runfair); + break; + } + DidLock(); + } + + void unlock() { + WillUnlock(); + switch (_type) { + case Plain: + _plain.unlock(); + break; + case Recursive: + _recursive.unlock(); + break; + case Unfair: + os_unfair_lock_unlock(&_unfair); + break; + case RecursiveUnfair: + ASRecursiveUnfairLockUnlock(&_runfair); + break; + } + } + + void AssertHeld() { + ASDisplayNodeCAssert(_owner == std::this_thread::get_id(), @"Thread should hold lock"); + } + + void AssertNotHeld() { + ASDisplayNodeCAssert(_owner != std::this_thread::get_id(), @"Thread should not hold lock"); } - void lock() { - if (gMutex_unfair) { - if (_recursive) { - ASRecursiveUnfairLockLock(&_runfair); - } else { - os_unfair_lock_lock(&_unfair); - } - } else { - AS_POSIX_ASSERT_NOERR(pthread_mutex_lock(&_m)); - } -#if CHECK_LOCKING_SAFETY - mach_port_t thread_id = pthread_mach_thread_np(pthread_self()); - if (thread_id != _owner) { - // New owner. Since this mutex can't be acquired by another thread if there is an existing owner, _owner and _count must be 0. - ASDisplayNodeCAssertTrue(0 == _owner); - ASDisplayNodeCAssertTrue(0 == _count); - _owner = thread_id; - } else { - // Existing owner tries to reacquire this (recursive) mutex. _count must already be positive. - ASDisplayNodeCAssertTrue(_count > 0); - } - ++_count; -#endif - } - - void unlock () { -#if CHECK_LOCKING_SAFETY - mach_port_t thread_id = pthread_mach_thread_np(pthread_self()); - // Unlocking a mutex on an unowning thread causes undefined behaviour. Assert and fail early. - ASDisplayNodeCAssertTrue(thread_id == _owner); - // Current thread owns this mutex. _count must be positive. - ASDisplayNodeCAssertTrue(_count > 0); - --_count; - if (0 == _count) { - // Current thread is no longer the owner. - _owner = 0; - } -#endif - if (gMutex_unfair) { - if (_recursive) { - ASRecursiveUnfairLockUnlock(&_runfair); - } else { - os_unfair_lock_unlock(&_unfair); - } - } else { - AS_POSIX_ASSERT_NOERR(pthread_mutex_unlock(&_m)); - } - } - - pthread_mutex_t *mutex () { return &_m; } - -#if CHECK_LOCKING_SAFETY - bool locked() { - return _count > 0 && pthread_mach_thread_np(pthread_self()) == _owner; - } -#endif - protected: explicit Mutex (bool recursive) { // Check if we can use unfair lock and store in static var. @@ -254,44 +214,60 @@ namespace ASDN { } }); - _recursive = recursive; - - if (gMutex_unfair) { - if (recursive) { + if (recursive) { + if (gMutex_unfair) { + _type = RecursiveUnfair; _runfair = AS_RECURSIVE_UNFAIR_LOCK_INIT; } else { - _unfair = OS_UNFAIR_LOCK_INIT; + _type = Recursive; + new (&_recursive) std::recursive_mutex(); } } else { - if (!recursive) { - AS_POSIX_ASSERT_NOERR(pthread_mutex_init (&_m, NULL)); + if (gMutex_unfair) { + _type = Unfair; + _unfair = OS_UNFAIR_LOCK_INIT; } else { - // Fall back to recursive mutex. - static pthread_mutexattr_t attr; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - AS_POSIX_ASSERT_NOERR(pthread_mutexattr_init (&attr)); - AS_POSIX_ASSERT_NOERR(pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE)); - }); - AS_POSIX_ASSERT_NOERR(pthread_mutex_init(&_m, &attr)); + _type = Plain; + new (&_plain) std::mutex(); } } -#if CHECK_LOCKING_SAFETY - _owner = 0; - _count = 0; -#endif } private: - BOOL _recursive; + enum Type { + Plain, + Recursive, + Unfair, + RecursiveUnfair + }; + + void WillUnlock() { +#if ASDISPLAYNODE_ASSERTIONS_ENABLED + if (--_count == 0) { + _owner = std::thread::id(); + } +#endif + } + + void DidLock() { +#if ASDISPLAYNODE_ASSERTIONS_ENABLED + if (++_count == 1) { + // New owner. + _owner = std::this_thread::get_id(); + } +#endif + } + + Type _type; union { os_unfair_lock _unfair; ASRecursiveUnfairLock _runfair; - pthread_mutex_t _m; + std::mutex _plain; + std::recursive_mutex _recursive; }; -#if CHECK_LOCKING_SAFETY - mach_port_t _owner; - uint32_t _count; +#if ASDISPLAYNODE_ASSERTIONS_ENABLED + std::thread::id _owner; + int _count; #endif }; #pragma clang diagnostic pop // ignored "-Wunguarded-availability" @@ -305,8 +281,9 @@ namespace ASDN { http://www.zaval.org/resources/library/butenhof1.html http://www.fieryrobot.com/blog/2008/10/14/recursive-locks-will-kill-you/ */ - struct RecursiveMutex : Mutex + class RecursiveMutex : public Mutex { + public: RecursiveMutex () : Mutex (true) {} }; From 56e69eac7875a3f4b830d92e10fd29a40e4a46f6 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Thu, 8 Nov 2018 13:07:46 -0800 Subject: [PATCH 55/60] Initialize mutex assertion variables (#1226) --- Source/Details/ASThread.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Details/ASThread.h b/Source/Details/ASThread.h index 80091abf3e..d5896fd13b 100644 --- a/Source/Details/ASThread.h +++ b/Source/Details/ASThread.h @@ -266,8 +266,8 @@ namespace ASDN { std::recursive_mutex _recursive; }; #if ASDISPLAYNODE_ASSERTIONS_ENABLED - std::thread::id _owner; - int _count; + std::thread::id _owner = std::thread::id(); + int _count = 0; #endif }; #pragma clang diagnostic pop // ignored "-Wunguarded-availability" From 53368a5cb6b735033d8637fa4ef30ed85493fae8 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Fri, 9 Nov 2018 07:31:28 -0800 Subject: [PATCH 56/60] Remove CHECK_LOCKING_SAFETY check (#1225) Locking assertions are always active now --- Source/ASDisplayNode.mm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 8923762659..58e7518bcf 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -2108,12 +2108,6 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { // NOTE: This method must be dealloc-safe (should not retain self). - (ASDisplayNode *)supernode { -#if CHECK_LOCKING_SAFETY - if (__instanceLock__.locked()) { - NSLog(@"WARNING: Accessing supernode while holding recursive instance lock of this node is worrisome. It's likely that you will soon try to acquire the supernode's lock, and this can easily cause deadlocks."); - } -#endif - ASDN::MutexLocker l(__instanceLock__); return _supernode; } From fd047d681eb4867081a61df9a444309ed91cf56d Mon Sep 17 00:00:00 2001 From: Andrew Yates Date: Sat, 10 Nov 2018 08:41:58 -0800 Subject: [PATCH 57/60] Make ASEditableTextNode accessible to VoiceOver (#1162) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make ASEditableTextNode accessible to VoiceOver * Update CHANGELOG * Make ASEditableTextNode an accessibility container * Remove initial fix * Changelog * Correct changelog entry * Remove isAccessibilityElement as it’s a container * Add isNodeLoaded checks * Remove Changelog Changes --- Source/ASEditableTextNode.mm | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Source/ASEditableTextNode.mm b/Source/ASEditableTextNode.mm index 962a2e96e2..0adc8b0adb 100644 --- a/Source/ASEditableTextNode.mm +++ b/Source/ASEditableTextNode.mm @@ -842,4 +842,38 @@ [_delegate editableTextNodeDidFinishEditing:self]; } +#pragma mark - UIAccessibilityContainer + +- (NSInteger)accessibilityElementCount +{ + if (!self.isNodeLoaded) { + ASDisplayNodeFailAssert(@"Cannot access accessibilityElementCount since ASEditableTextNode is not loaded"); + return 0; + } + return 1; +} + +- (NSArray *)accessibilityElements +{ + if (!self.isNodeLoaded) { + ASDisplayNodeFailAssert(@"Cannot access accessibilityElements since ASEditableTextNode is not loaded"); + return @[]; + } + return @[self.textView]; +} + +- (id)accessibilityElementAtIndex:(NSInteger)index +{ + if (!self.isNodeLoaded) { + ASDisplayNodeFailAssert(@"Cannot access accessibilityElementAtIndex: since ASEditableTextNode is not loaded"); + return nil; + } + return self.textView; +} + +- (NSInteger)indexOfAccessibilityElement:(id)element +{ + return 0; +} + @end From 39f25f661e1450dce4501855b6eab4d947a97928 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Sun, 11 Nov 2018 08:43:07 -0800 Subject: [PATCH 58/60] ASCATransactionQueue interface trashing improvements (#1216) * ASCATransactionQueue interface trashing improvements * Use weakSelf --- Source/ASRunLoopQueue.mm | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/Source/ASRunLoopQueue.mm b/Source/ASRunLoopQueue.mm index 0463c6221b..fd88cafd80 100644 --- a/Source/ASRunLoopQueue.mm +++ b/Source/ASRunLoopQueue.mm @@ -191,7 +191,7 @@ static void runLoopSourceCallback(void *info) { #if ASRunLoopQueueLoggingEnabled - (void)checkRunLoop { - NSLog(@"<%@> - Jobs: %ld", self, _internalQueue.size()); + NSLog(@"<%@> - Jobs: %ld", self, _internalQueue.count); } #endif @@ -323,10 +323,8 @@ ASSynthesizeLockingMethodsWithMutex(_internalQueueLock) CFRunLoopRef _runLoop; CFRunLoopSourceRef _runLoopSource; CFRunLoopObserverRef _preTransactionObserver; - CFRunLoopObserverRef _postTransactionObserver; NSPointerArray *_internalQueue; ASDN::RecursiveMutex _internalQueueLock; - BOOL _CATransactionCommitInProgress; // In order to not pollute the top-level activities, each queue has 1 root activity. os_activity_t _rootActivity; @@ -343,9 +341,6 @@ ASSynthesizeLockingMethodsWithMutex(_internalQueueLock) // CoreAnimation commit order is 2000000, the goal of this is to process shortly beforehand // but after most other scheduled work on the runloop has processed. static int const kASASCATransactionQueueOrder = 1000000; -// This will mark the end of current loop and any node enqueued between kASASCATransactionQueueOrder -// and kASASCATransactionQueuePostOrder will apply interface change immediately. -static int const kASASCATransactionQueuePostOrder = 3000000; + (ASCATransactionQueue *)sharedQueue NS_RETURNS_RETAINED { @@ -377,17 +372,13 @@ static int const kASASCATransactionQueuePostOrder = 3000000; // __unsafe_unretained allows us to avoid flagging the memory cycle detector. __unsafe_unretained __typeof__(self) weakSelf = self; void (^handlerBlock) (CFRunLoopObserverRef observer, CFRunLoopActivity activity) = ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { + while (weakSelf->_internalQueue.count > 0) { [weakSelf processQueue]; - }; - void (^postHandlerBlock) (CFRunLoopObserverRef observer, CFRunLoopActivity activity) = ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { - ASDN::MutexLocker l(_internalQueueLock); - _CATransactionCommitInProgress = NO; + } }; _preTransactionObserver = CFRunLoopObserverCreateWithHandler(NULL, kCFRunLoopBeforeWaiting, true, kASASCATransactionQueueOrder, handlerBlock); - _postTransactionObserver = CFRunLoopObserverCreateWithHandler(NULL, kCFRunLoopBeforeWaiting, true, kASASCATransactionQueuePostOrder, postHandlerBlock); CFRunLoopAddObserver(_runLoop, _preTransactionObserver, kCFRunLoopCommonModes); - CFRunLoopAddObserver(_runLoop, _postTransactionObserver, kCFRunLoopCommonModes); // It is not guaranteed that the runloop will turn if it has no scheduled work, and this causes processing of // the queue to stop. Attaching a custom loop source to the run loop and signal it if new work needs to be done @@ -416,19 +407,14 @@ static int const kASASCATransactionQueuePostOrder = 3000000; if (CFRunLoopObserverIsValid(_preTransactionObserver)) { CFRunLoopObserverInvalidate(_preTransactionObserver); } - if (CFRunLoopObserverIsValid(_postTransactionObserver)) { - CFRunLoopObserverInvalidate(_postTransactionObserver); - } CFRelease(_preTransactionObserver); - CFRelease(_postTransactionObserver); _preTransactionObserver = nil; - _postTransactionObserver = nil; } #if ASRunLoopQueueLoggingEnabled - (void)checkRunLoop { - NSLog(@"<%@> - Jobs: %ld", self, _internalQueue.size()); + NSLog(@"<%@> - Jobs: %ld", self, _internalQueue.count); } #endif @@ -441,11 +427,6 @@ static int const kASASCATransactionQueuePostOrder = 3000000; { ASDN::MutexLocker l(_internalQueueLock); - // Mark the queue will end coalescing shortly until after CATransactionCommit. - // This will give the queue a chance to apply any further interfaceState changes/enqueue - // immediately within current runloop instead of pushing the work to next runloop cycle. - _CATransactionCommitInProgress = YES; - NSInteger internalQueueCount = _internalQueue.count; // Early-exit if the queue is empty. if (internalQueueCount == 0) { @@ -502,7 +483,7 @@ static int const kASASCATransactionQueuePostOrder = 3000000; return; } - if (!self.enabled || _CATransactionCommitInProgress) { + if (!self.enabled) { [object prepareForCATransactionCommit]; return; } From ce78fa00dfe95dcdf49b13e3aee086608668a020 Mon Sep 17 00:00:00 2001 From: Orkhan Huseynov <32098320+orkhan-huseynov@users.noreply.github.com> Date: Mon, 12 Nov 2018 20:23:41 +0400 Subject: [PATCH 59/60] Update image-node.md (#1230) typo fix --- docs/_docs/image-node.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_docs/image-node.md b/docs/_docs/image-node.md index d7b1057ed7..4fcc2da69b 100755 --- a/docs/_docs/image-node.md +++ b/docs/_docs/image-node.md @@ -6,7 +6,7 @@ prevPage: text-node.html nextPage: network-image-node.html --- -`ASImageNode` is the Texture equivalent to `UIImageView`. The most basic difference is that images are decoded asynchronously by default. Of course, there are more advanced improvments as well such as GIF support and `imageModificationBlock`s. +`ASImageNode` is the Texture equivalent to `UIImageView`. The most basic difference is that images are decoded asynchronously by default. Of course, there are more advanced improvements as well such as GIF support and `imageModificationBlock`s. ### Basic Usage From 771c068ad67a2ecde7f0da2bf727e0326d156c54 Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 13 Nov 2018 08:20:20 -0800 Subject: [PATCH 60/60] Correct block self references to strongSelf (#1231) --- Source/ASNetworkImageNode.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/ASNetworkImageNode.mm b/Source/ASNetworkImageNode.mm index b7f4ed8eac..f1ec760287 100644 --- a/Source/ASNetworkImageNode.mm +++ b/Source/ASNetworkImageNode.mm @@ -729,17 +729,17 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); void (^calloutBlock)(ASNetworkImageNode *inst); if (newImage) { - if (self->_delegateFlags.delegateDidLoadImageWithInfo) { + if (strongSelf->_delegateFlags.delegateDidLoadImageWithInfo) { calloutBlock = ^(ASNetworkImageNode *strongSelf) { let info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:imageSource downloadIdentifier:downloadIdentifier userInfo:userInfo]; [delegate imageNode:strongSelf didLoadImage:newImage info:info]; }; - } else if (self->_delegateFlags.delegateDidLoadImage) { + } else if (strongSelf->_delegateFlags.delegateDidLoadImage) { calloutBlock = ^(ASNetworkImageNode *strongSelf) { [delegate imageNode:strongSelf didLoadImage:newImage]; }; } - } else if (error && self->_delegateFlags.delegateDidFailWithError) { + } else if (error && strongSelf->_delegateFlags.delegateDidFailWithError) { calloutBlock = ^(ASNetworkImageNode *strongSelf) { [delegate imageNode:strongSelf didFailWithError:error]; }; @@ -753,7 +753,7 @@ static std::atomic_bool _useMainThreadDelegateCallbacks(true); } }); } else { - calloutBlock(self); + calloutBlock(strongSelf); } } });