Skip to content

Commit

Permalink
[ASTextNode2] Add initial implementation for link handling. (TextureG…
Browse files Browse the repository at this point in the history
…roup#396)

* [ASTextNode2] Add initial implementation for link handling.

This is a fairly basic first step to achieving feature parity between ASTextNode2
and ASTextNode. It does not yet do the 9-box detection of links, and there is
other code from ASTextNode that could be shared to improve this.

However, in the interest of getting a shippable implementation running as soon
as possible, I'm hoping to quickly refine this. Then we can continue improving
it based on the original ASTextNode with the benefit of testing UI against it.

* [ASTextNode2] Refine implementation of link handling.
  • Loading branch information
appleguy authored and bernieperez committed Apr 25, 2018
1 parent f8474c0 commit 583684a
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## master

* Add your own contributions to the next release on the line below this with your name.
- [ASTextNode2] Add initial implementation for link handling. [Scott Goodson](https://github.com/appleguy) [#396](https://github.com/TextureGroup/Texture/pull/396)

##2.3.4
- [Yoga] Rewrite YOGA_TREE_CONTIGUOUS mode with improved behavior and cleaner integration [Scott Goodson](https://github.com/appleguy)
Expand Down
86 changes: 84 additions & 2 deletions Source/Private/ASTextNode2.mm
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,52 @@ - (id)_linkAttributeValueAtPoint:(CGPoint)point
inAdditionalTruncationMessage:(out BOOL *)inAdditionalTruncationMessageOut
forHighlighting:(BOOL)highlighting
{
AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE();
ASDN::MutexLocker l(__instanceLock__);

// TODO: The copy and application of size shouldn't be required, but it is currently.
// 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];
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]) {
*inAdditionalTruncationMessageOut = YES;
return nil;
}

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];
if (value == nil) {
// Didn't find any links specified with this attribute.
continue;
}

// If highlighting, check with delegate first. If not implemented, assume YES.
if (highlighting
&& [_delegate respondsToSelector:@selector(textNode:shouldHighlightLinkAttribute:value:atPoint:)]
&& ![_delegate textNode:(ASTextNode *)self shouldHighlightLinkAttribute:attributeName value:value atPoint:point]) {
value = nil;
attributeName = nil;
}

if (value != nil || attributeName != nil) {
*rangeOut = NSIntersectionRange(visibleRange, effectiveRange);

if (attributeNameOut != NULL) {
*attributeNameOut = attributeName;
}

return value;
}
}

return nil;
}

Expand Down Expand Up @@ -560,8 +605,13 @@ - (void)setHighlightRange:(NSRange)highlightRange animated:(BOOL)animated

- (void)_setHighlightRange:(NSRange)highlightRange forAttributeName:(NSString *)highlightedAttributeName value:(id)highlightedAttributeValue animated:(BOOL)animated
{
// Set these so that link tapping works.
_highlightedLinkAttributeName = highlightedAttributeName;
_highlightedLinkAttributeValue = highlightedAttributeValue;

AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE();
// Much of the code from original ASTextNode is probably usable here.

return;
}

Expand Down Expand Up @@ -665,7 +715,39 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
ASDisplayNodeAssertMainThread();

[super touchesBegan:touches withEvent:event];
AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE();

CGPoint point = [[touches anyObject] locationInView:self.view];

NSRange range = NSMakeRange(0, 0);
NSString *linkAttributeName = nil;
BOOL inAdditionalTruncationMessage = NO;

id linkAttributeValue = [self _linkAttributeValueAtPoint:point
attributeName:&linkAttributeName
range:&range
inAdditionalTruncationMessage:&inAdditionalTruncationMessage
forHighlighting:YES];

NSUInteger lastCharIndex = NSIntegerMax;
BOOL linkCrossesVisibleRange = (lastCharIndex > range.location) && (lastCharIndex < NSMaxRange(range) - 1);

if (inAdditionalTruncationMessage) {
NSRange visibleRange = NSMakeRange(0, 0);
{
ASDN::MutexLocker l(__instanceLock__);
// TODO: The copy and application of size shouldn't be required, but it is currently.
// 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];
visibleRange = layout.visibleRange;
}
NSRange truncationMessageRange = [self _additionalTruncationMessageRangeWithVisibleRange:visibleRange];
[self _setHighlightRange:truncationMessageRange forAttributeName:ASTextNodeTruncationTokenAttributeName value:nil animated:YES];
} else if (range.length && !linkCrossesVisibleRange && linkAttributeValue != nil && linkAttributeName != nil) {
[self _setHighlightRange:range forAttributeName:linkAttributeName value:linkAttributeValue animated:YES];
}

return;
}

Expand Down

0 comments on commit 583684a

Please sign in to comment.