Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implemented A anchor support.

When encountering a <a name="anchor">text</a> this causes a DTAnchorAttribute to be added to the text. DTAttributedTextView now has a method to scroll to thusly named anchors.
  • Loading branch information...
commit bcac40798944b6096b1465c3747b4e5963de1e90 1 parent 384f2d5
@Cocoanetics authored
View
8 Core/Source/DTAttributedTextView.h
@@ -23,4 +23,12 @@
@property (nonatomic, unsafe_unretained) IBOutlet id <DTAttributedTextContentViewDelegate> textDelegate;
+
+/**
+ Scrolls the receiver to the anchor with the given name to the top.
+ @param anchorName The name of the href anchor.
+ @param animated `YES` if the movement should be animated.
+ */
+- (void)scrollToAnchorNamed:(NSString *)anchorName animated:(BOOL)animated;
+
@end
View
20 Core/Source/DTAttributedTextView.m
@@ -85,6 +85,25 @@ - (Class)classForContentView
return [DTAttributedTextContentView class];
}
+#pragma mark External Methods
+- (void)scrollToAnchorNamed:(NSString *)anchorName animated:(BOOL)animated
+{
+ NSRange range = [self.contentView.attributedString rangeOfAnchorNamed:anchorName];
+
+ if (range.length != NSNotFound)
+ {
+ // get the line of the first index of the anchor range
+ DTCoreTextLayoutLine *line = [self.contentView.layoutFrame lineContainingIndex:range.location];
+
+ // make sure we don't scroll too far
+ CGFloat maxScrollPos = self.contentSize.height - self.bounds.size.height + self.contentInset.bottom + self.contentInset.top;
+ CGFloat scrollPos = MIN(line.frame.origin.y, maxScrollPos);
+
+ // scroll
+ [self setContentOffset:CGPointMake(0, scrollPos) animated:animated];
+ }
+}
+
#pragma mark Notifications
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
@@ -95,7 +114,6 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
}
}
-
#pragma mark Properties
- (DTAttributedTextContentView *)contentView
{
View
1  Core/Source/DTCoreTextConstants.h
@@ -30,6 +30,7 @@ extern NSString *DTDefaultStyleSheet;
extern NSString *DTTextListsAttribute;
extern NSString *DTAttachmentParagraphSpacingAttribute;
extern NSString *DTLinkAttribute;
+extern NSString *DTAnchorAttribute;
extern NSString *DTGUIDAttribute;
extern NSString *DTHeaderLevelAttribute;
extern NSString *DTPreserveNewlinesAttribute;
View
1  Core/Source/DTCoreTextConstants.m
@@ -27,6 +27,7 @@
NSString *DTTextListsAttribute = @"DTTextLists";
NSString *DTAttachmentParagraphSpacingAttribute = @"DTAttachmentParagraphSpacing";
NSString *DTLinkAttribute = @"DTLink";
+NSString *DTAnchorAttribute = @"DTAnchor";
NSString *DTGUIDAttribute = @"DTGUID";
NSString *DTHeaderLevelAttribute = @"DTHeaderLevel";
NSString *DTPreserveNewlinesAttribute = @"DTPreserveNewlines";
View
4 Core/Source/DTHTMLAttributedStringBuilder.m
@@ -419,6 +419,10 @@ - (void)_registerTagStartHandlers
}
currentTag.link = link;
+
+
+ // the name attribute of A becomes an anchor
+ currentTag.anchorName = [currentTag attributeForKey:@"name"];
};
[_tagStartHandlers setObject:[aBlock copy] forKey:@"a"];
View
1  Core/Source/DTHTMLElement.h
@@ -41,6 +41,7 @@ typedef enum
@property (nonatomic, copy) DTCoreTextParagraphStyle *paragraphStyle;
@property (nonatomic, strong) DTTextAttachment *textAttachment;
@property (nonatomic, copy) NSURL *link;
+@property (nonatomic, copy) NSString *anchorName;
@property (nonatomic, strong) DTColor *textColor;
@property (nonatomic, strong) DTColor *backgroundColor;
@property (nonatomic, copy) NSString *tagName;
View
9 Core/Source/DTHTMLElement.m
@@ -29,6 +29,7 @@ @implementation DTHTMLElement
DTTextAttachment *_textAttachment;
DTTextAttachmentVerticalAlignment _textAttachmentAlignment;
NSURL *_link;
+ NSString *_anchorName;
DTColor *_textColor;
DTColor *backgroundColor;
@@ -149,6 +150,12 @@ - (NSDictionary *)attributesDictionary
[tmpDict setObject:_linkGUID forKey:DTGUIDAttribute];
}
+ // add anchor
+ if (_anchorName)
+ {
+ [tmpDict setObject:_anchorName forKey:DTAnchorAttribute];
+ }
+
// add strikout if applicable
if (strikeOut)
{
@@ -899,6 +906,7 @@ - (id)copyWithZone:(NSZone *)zone
newObject.shadows = self.shadows;
newObject.link = self.link; // copy
+ newObject.anchorName = self.anchorName; // copy
newObject.linkGUID = _linkGUID; // transfer the GUID
newObject.preserveNewlines = self.preserveNewlines;
@@ -1010,6 +1018,7 @@ - (void)setLink:(NSURL *)link
@synthesize tagName;
@synthesize text;
@synthesize link = _link;
+@synthesize anchorName = _anchorName;
@synthesize underlineStyle;
@synthesize textAttachment = _textAttachment;
@synthesize tagContentInvisible;
View
10 Core/Source/NSAttributedString+DTCoreText.h
@@ -65,9 +65,17 @@
- (NSRange)rangeOfTextBlock:(DTTextBlock *)textBlock atIndex:(NSUInteger)location;
/**
- @name Converting to Other Representations
+ Returns the range of the given href anchor.
+
+ @param list The text block.
+ @param anchorName The name of the anchor.
+ @returns The range of the given anchor.
*/
+- (NSRange)rangeOfAnchorNamed:(NSString *)anchorName;
+/**
+ @name Converting to Other Representations
+ */
/**
Encodes the receiver into a generic HTML prepresentation.
View
15 Core/Source/NSAttributedString+DTCoreText.m
@@ -197,6 +197,21 @@ - (NSRange)rangeOfTextBlock:(DTTextBlock *)textBlock atIndex:(NSUInteger)locatio
return [self _rangeOfObject:textBlock inArrayBehindAttribute:DTTextBlocksAttribute atIndex:location];
}
+- (NSRange)rangeOfAnchorNamed:(NSString *)anchorName
+{
+ __block NSRange foundRange = NSMakeRange(0, NSNotFound);
+
+ [self enumerateAttribute:DTAnchorAttribute inRange:NSMakeRange(0, [self length]) options:0 usingBlock:^(NSString *value, NSRange range, BOOL *stop) {
+ if ([value isEqualToString:anchorName])
+ {
+ *stop = YES;
+ foundRange = range;
+ }
+ }];
+
+ return foundRange;
+}
+
#pragma mark HTML Encoding
View
32 Demo/Resources/CurrentTest.html
@@ -1,3 +1,29 @@
-<p style="font-family:'Times New Roman';font-size:20px;">Hello</p>
-<p style="font-family:'Times New Roman';font-size:20px;"></p>
-<p style="font-family:'Times New Roman';font-size:20px;">World</p>
+<a href="#kapitel2">Go To Chapter2</a>
+<a name="kapitel1" href="#kapitel1">Kapitel 1</a>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<a name="kapitel2">Chapter2</a>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
+<p>text</p>
View
21 Demo/Source/DemoTextViewController.m
@@ -396,7 +396,26 @@ - (BOOL)attributedTextContentView:(DTAttributedTextContentView *)attributedTextC
- (void)linkPushed:(DTLinkButton *)button
{
- [[UIApplication sharedApplication] openURL:[button.URL absoluteURL]];
+ NSURL *URL = button.URL;
+
+ if ([[UIApplication sharedApplication] canOpenURL:[URL absoluteURL]])
+ {
+ [[UIApplication sharedApplication] openURL:[URL absoluteURL]];
+ }
+ else
+ {
+ if (![URL host] && ![URL path])
+ {
+
+ // possibly a local anchor link
+ NSString *fragment = [URL fragment];
+
+ if (fragment)
+ {
+ [_textView scrollToAnchorNamed:fragment animated:NO];
+ }
+ }
+ }
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
Please sign in to comment.
Something went wrong with that request. Please try again.