adium 5204:92c9c36c10a3: Integrate changes from mainline AutoHyp...
commits at adium.im
commits at adium.im
Sun Oct 28 01:27:11 UTC 2012
details: http://hg.adium.im/adium/rev/92c9c36c10a3
revision: 5204:92c9c36c10a3
branch: adium-1.6
author: Stephen Holt <sholt at adium.im>
date: Sat Oct 27 18:08:05 2012 -0700
Integrate changes from mainline AutoHyperlinks which fixes some issues with enclosure tracking.
Specifically, this change: http://hg.cloggedtubes.com/autohyperlinks2/changeset/5802517b0b9a38ce6c5c8f39ccad9a0f0b3ccd40
diffs (304 lines):
diff -r cc1b1e1e9bf3 -r 92c9c36c10a3 Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.h
--- a/Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.h Thu Oct 25 14:50:07 2012 +0100
+++ b/Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.h Sat Oct 27 18:08:05 2012 -0700
@@ -47,7 +47,8 @@
{
NSDictionary *m_urlSchemes;
NSString *m_scanString;
-#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ NSMutableArray *m_openEnclosureStack;
+#if TARGET_OS_IPHONE
NSString *m_linkifiedString;
#else
NSAttributedString *m_scanAttrString;
@@ -59,7 +60,11 @@
}
@property (assign) unsigned long scanLocation;
+#if TARGET_OS_IPHONE
+ at property (readonly) NSString *linkifiedString;
+#else
@property (readonly) NSAttributedString *linkifiedString;
+#endif
/*!
* @brief Allocs and inits a new lax AHHyperlinkScanner with the given NSString
diff -r cc1b1e1e9bf3 -r 92c9c36c10a3 Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.m
--- a/Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.m Thu Oct 25 14:50:07 2012 +0100
+++ b/Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.m Sat Oct 27 18:08:05 2012 -0700
@@ -34,6 +34,8 @@
#define ENC_INDEX_KEY @"encIndex"
#define ENC_CHAR_KEY @"encChar"
+#define MIN_LINK_LENGTH 4
+
@interface AHHyperlinkScanner (PRIVATE)
- (AHMarkedHyperlink *)nextURIFromLocation:(unsigned long *)_scanLocation;
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
@@ -122,13 +124,14 @@
#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
m_scanAttrString = nil;
#endif
+ m_openEnclosureStack = [[NSMutableArray alloc] init];
}
return self;
}
- (id)initWithString:(NSString *)inString usingStrictChecking:(BOOL)flag
{
- if((self = [super init])){
+ if((self = [self init])){
m_scanString = [inString retain];
m_urlSchemes = [[NSDictionary alloc] initWithObjectsAndKeys:
@"ftp://", @"ftp",
@@ -142,7 +145,7 @@
#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
- (id)initWithAttributedString:(NSAttributedString *)inString usingStrictChecking:(BOOL)flag
{
- if((self = [super init])){
+ if((self = [self init])){
m_scanString = [[inString string] retain];
m_scanAttrString = [inString retain];
m_urlSchemes = [[NSDictionary alloc] initWithObjectsAndKeys:
@@ -161,6 +164,7 @@
[m_linkifiedString release];
[m_scanString release];
[m_urlSchemes release];
+ [m_openEnclosureStack release];
#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
if(m_scanAttrString) [m_scanAttrString release];
#endif
@@ -253,96 +257,106 @@
// main scanning loop
while([self _scanString:m_scanString upToCharactersFromSet:skipSet intoRange:&scannedRange fromIndex:&scannedLocation]) {
-
- // Check for and filter enclosures. We can't add (, [, etc. to the skipSet as they may be in a URI
- if([enclosureSet characterIsMember:[m_scanString characterAtIndex:scannedRange.location]]){
- unsigned long encIdx = [enclosureStartArray indexOfObject:[m_scanString substringWithRange:NSMakeRange(scannedRange.location, 1)]];
- NSRange encRange;
- if(NSNotFound != encIdx) {
- encRange = [m_scanString rangeOfString:[enclosureStopArray objectAtIndex:encIdx] options:NSBackwardsSearch range:scannedRange];
- if(NSNotFound != encRange.location){
- scannedRange.location++; scannedRange.length -= 2;
- }
- }
- }
- if(!scannedRange.length) break;
-
- // Find balanced enclosure chars
- NSRange longestEnclosure = [self _longestBalancedEnclosureInRange:scannedRange];
- while (scannedRange.length > 2 && [endSet characterIsMember:[m_scanString characterAtIndex:(scannedRange.location + scannedRange.length - 1)]]) {
- if((longestEnclosure.location + longestEnclosure.length) < scannedRange.length){
- scannedRange.length--;
- }else break;
- }
-
- // if we have a valid URL then save the scanned string, and make a SHMarkedHyperlink out of it.
- // this way, we can preserve things like the matched string (to be converted to a NSURL),
- // parent string, its validation status (valid, file, degenerate, etc), and its range in the parent string
- AH_URI_VERIFICATION_STATUS validStatus;
- NSString *_scanString = nil;
- unsigned long schemeLength = 0;
- if(4 < scannedRange.length) _scanString = [m_scanString substringWithRange:scannedRange];
- if((4 < scannedRange.length) && [[self class] isStringValidURI:_scanString usingStrict:m_strictChecking fromIndex:&m_scanLocation withStatus:&validStatus schemeLength:&schemeLength]){
- AHMarkedHyperlink *markedLink;
- BOOL makeLink = TRUE;
- //insert typical specifiers if the URL is degenerate
- switch(validStatus){
- case AH_URL_DEGENERATE:
- {
- NSString *scheme = DEFAULT_URL_SCHEME;
- unsigned long i = 0;
-
- NSRange firstComponent;
- [self _scanString:_scanString
- upToCharactersFromSet:hostnameComponentSeparatorSet
- intoRange:&firstComponent
- fromIndex:&i];
-
- if(NSNotFound != firstComponent.location) {
- NSString *hostnameScheme = [m_urlSchemes objectForKey:[_scanString substringWithRange:firstComponent]];
- if(hostnameScheme) scheme = hostnameScheme;
+ if (MIN_LINK_LENGTH < scannedRange.length) {
+ // Check for and filter enclosures. We can't add (, [, etc. to the skipSet as they may be in a URI
+ NSString *topEncChar = [m_openEnclosureStack lastObject];
+ if(topEncChar || [enclosureSet characterIsMember:[m_scanString characterAtIndex:scannedRange.location]]){
+ unsigned long encIdx = [enclosureStartArray indexOfObject:topEncChar? topEncChar : [m_scanString substringWithRange:NSMakeRange(scannedRange.location, 1)]];
+ NSRange encRange;
+ if(NSNotFound != encIdx) {
+ encRange = [m_scanString rangeOfString:[enclosureStopArray objectAtIndex:encIdx] options:NSBackwardsSearch range:scannedRange];
+ if(NSNotFound != encRange.location){
+ scannedRange.length--;
+ if (topEncChar) {
+ [m_openEnclosureStack removeLastObject];
+ } else {
+ scannedRange.location++;
+ scannedRange.length--;
+ }
+ } else {
+ [m_openEnclosureStack addObject:[enclosureStartArray objectAtIndex:encIdx]];
}
-
- _scanString = [scheme stringByAppendingString:_scanString];
-
- break;
}
-
- case AH_MAILTO_DEGENERATE:
- _scanString = [@"mailto:" stringByAppendingString:_scanString];
- break;
- case AH_URL_TENTATIVE:
- {
- NSString *scheme = [_scanString substringToIndex:schemeLength];
- NSArray *apps = (NSArray *)LSCopyAllHandlersForURLScheme((CFStringRef)scheme);
-
- if(!apps.count)
- makeLink = FALSE;
- [apps release];
- break;
- }
- default:
- break;
+ }
+ if(!scannedRange.length) break;
+
+ // Find balanced enclosure chars
+ NSRange longestEnclosure = [self _longestBalancedEnclosureInRange:scannedRange];
+ while (scannedRange.length > 2 && [endSet characterIsMember:[m_scanString characterAtIndex:(scannedRange.location + scannedRange.length - 1)]]) {
+ if((longestEnclosure.location + longestEnclosure.length) < scannedRange.length){
+ scannedRange.length--;
+ }else break;
}
- if(makeLink){
- //make a marked link
- markedLink = [[AHMarkedHyperlink alloc] initWithString:_scanString
- withValidationStatus:validStatus
- parentString:m_scanString
- andRange:scannedRange];
- return [markedLink autorelease];
- }
+ // if we have a valid URL then save the scanned string, and make a SHMarkedHyperlink out of it.
+ // this way, we can preserve things like the matched string (to be converted to a NSURL),
+ // parent string, its validation status (valid, file, degenerate, etc), and its range in the parent string
+ AH_URI_VERIFICATION_STATUS validStatus;
+ NSString *_scanString = nil;
+ unsigned long schemeLength = 0;
+ if(MIN_LINK_LENGTH < scannedRange.length) _scanString = [m_scanString substringWithRange:scannedRange];
+ if((MIN_LINK_LENGTH < scannedRange.length) && [[self class] isStringValidURI:_scanString usingStrict:m_strictChecking fromIndex:&m_scanLocation withStatus:&validStatus schemeLength:&schemeLength]){
+ AHMarkedHyperlink *markedLink;
+ BOOL makeLink = TRUE;
+ //insert typical specifiers if the URL is degenerate
+ switch(validStatus){
+ case AH_URL_DEGENERATE:
+ {
+ NSString *scheme = DEFAULT_URL_SCHEME;
+ unsigned long i = 0;
+
+ NSRange firstComponent;
+ [self _scanString:_scanString
+ upToCharactersFromSet:hostnameComponentSeparatorSet
+ intoRange:&firstComponent
+ fromIndex:&i];
+
+ if(NSNotFound != firstComponent.location) {
+ NSString *hostnameScheme = [m_urlSchemes objectForKey:[_scanString substringWithRange:firstComponent]];
+ if(hostnameScheme) scheme = hostnameScheme;
+ }
+
+ _scanString = [scheme stringByAppendingString:_scanString];
+
+ break;
+ }
+
+ case AH_MAILTO_DEGENERATE:
+ _scanString = [@"mailto:" stringByAppendingString:_scanString];
+ break;
+ case AH_URL_TENTATIVE:
+ {
+ NSString *scheme = [_scanString substringToIndex:schemeLength];
+ NSArray *apps = (NSArray *)LSCopyAllHandlersForURLScheme((CFStringRef)scheme);
+
+ if(!apps.count)
+ makeLink = FALSE;
+ [apps release];
+ break;
+ }
+ default:
+ break;
+ }
+
+ if(makeLink){
+ //make a marked link
+ markedLink = [[AHMarkedHyperlink alloc] initWithString:_scanString
+ withValidationStatus:validStatus
+ parentString:m_scanString
+ andRange:scannedRange];
+ return [markedLink autorelease];
+ }
+ }
+
+ //step location after scanning a string
+ NSRange startRange = [m_scanString rangeOfCharacterFromSet:puncSet options:NSLiteralSearch range:scannedRange];
+ if (startRange.location != NSNotFound)
+ m_scanLocation = startRange.location + startRange.length;
+ else
+ m_scanLocation += scannedRange.length;
+
+ scannedLocation = m_scanLocation;
}
-
- //step location after scanning a string
- NSRange startRange = [m_scanString rangeOfCharacterFromSet:puncSet options:NSLiteralSearch range:scannedRange];
- if (startRange.location != NSNotFound)
- m_scanLocation = startRange.location + startRange.length;
- else
- m_scanLocation += scannedRange.length;
-
- scannedLocation = m_scanLocation;
}
// if we're here, then NSScanner hit the end of the string
diff -r cc1b1e1e9bf3 -r 92c9c36c10a3 Frameworks/AutoHyperlinks Framework/Source/AHLinkLexer.l
--- a/Frameworks/AutoHyperlinks Framework/Source/AHLinkLexer.l Thu Oct 25 14:50:07 2012 +0100
+++ b/Frameworks/AutoHyperlinks Framework/Source/AHLinkLexer.l Sat Oct 27 18:08:05 2012 -0700
@@ -54,7 +54,7 @@
%{
/*The Unicode standard, version 4.1, table 3-6, says that the highest byte that will occur in a valid UTF-8 sequence is 0xF4.*/
%}
-userAndPass [^:@]+(:[^:@]+)?
+userAndPass [^:@[:space:]]+(:[^:@[:space:]]+)?
singleDomain [_[:alnum:]\x80-\xf4-]+
urlPath \/[^[:space:]]*
@@ -74,7 +74,7 @@
userAtDomain [^:@\/[:space:]]+\@{singleDomain}(\.{singleDomain})*
mailSpec {userAtDomain}\.{TLDs}
-%option noyywrap nounput noinput 8bit caseless never-interactive reentrant warn prefix="AH"
+%option noyywrap nounput noinput 8bit caseless align nodefault never-interactive reentrant warn prefix="AH"
%x CANONICAL TENTATIVE
%%
diff -r cc1b1e1e9bf3 -r 92c9c36c10a3 Frameworks/AutoHyperlinks Framework/UnitTests/HyperlinkContextTest.m
--- a/Frameworks/AutoHyperlinks Framework/UnitTests/HyperlinkContextTest.m Thu Oct 25 14:50:07 2012 +0100
+++ b/Frameworks/AutoHyperlinks Framework/UnitTests/HyperlinkContextTest.m Sat Oct 27 18:08:05 2012 -0700
@@ -13,7 +13,7 @@
AHHyperlinkScanner *scanner = [AHHyperlinkScanner hyperlinkScannerWithString:testString];
AHMarkedHyperlink *ahLink = [scanner nextURI];
- STAssertNotNil(ahLink.URL, @"-[SHHyperlinkScanner nextURL] found no URI in \"%@\"", testString);
+ STAssertNotNil(ahLink, @"-[SHHyperlinkScanner nextURL] found no URI in \"%@\"", testString);
STAssertEqualObjects([[ahLink parentString] substringWithRange:[ahLink range]], URIString, @"in context: '%@'", testString);
}
@@ -218,6 +218,8 @@
[self testLaxContext:@"foo (bar) %@" withURI:@"http://example.com/path/to/url.html"];
[self testLaxContext:@"%@ doesn't link." withURI:@"http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW3"];
+ [self testLaxContext:@"foo (bar: %@)" withURI:@"http://example.com/path/to/url_(other)"];
+ [self testLaxContext:@"foo [bar: %@]" withURI:@"http://example.com/path/to/url_(other)"];
}
- (void)testCompositeContext {
More information about the commits
mailing list