Changeset 2124

Show
Ignore:
Timestamp:
11/19/04 22:04:18 (4 years ago)
Author:
timothy
Message:

Much cleaner attributedStringWithHTMLFragment. Removed the "green hack", so Safari 1.3 wont output the green color when it should have be caught by us later. This removes a level of processing on the NSAttributedString.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/NSAttributedStringAdditions.m

    r2093 r2124  
    1 #import <WebKit/WebKit.h> 
    21#import "NSAttributedStringAdditions.h" 
    32#import "NSColorAdditions.h" 
     
    8685#pragma mark - 
    8786 
    88 static NSConditionLock *renderingFragmentLock = nil; 
    89 static WebView *fragmentWebView = nil; 
    90  
    9187@implementation NSAttributedString (NSAttributedStringHTMLAdditions) 
    9288+ (id) attributedStringWithHTMLFragment:(NSString *) fragment baseURL:(NSURL *) url { 
    93         extern NSConditionLock *renderingFragmentLock
    94         extern WebView *fragmentWebView; 
     89        NSParameterAssert( fragment != nil )
     90 
    9591        NSMutableAttributedString *result = nil; 
    96  
    97         NSParameterAssert( fragment != nil ); 
    98  
    9992        if( NSAppKitVersionNumber >= 700. ) { 
    100                 NSString *render = [NSString stringWithFormat:@"<font color=\"#01fe02\">%@</font>", fragment]; 
    101                 result = [[[NSMutableAttributedString alloc] initWithHTML:[render dataUsingEncoding:NSUTF8StringEncoding] options:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1], @"UseWebKit", @"utf-8", @"TextEncodingName", url, @"BaseURL", nil] documentAttributes:NULL] autorelease]; 
     93                // the rgba CSS makes WebKit give colorless text where no color was specified (instead of black) 
     94                NSString *render = [NSString stringWithFormat:@"<span style=\"color: rgba( 0, 0, 0, 0.0 )\">%@</span>", fragment]; 
     95                result = [[NSMutableAttributedString alloc] initWithHTML:[render dataUsingEncoding:NSUTF8StringEncoding] options:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1], @"UseWebKit", @"utf-8", @"TextEncodingName", url, @"BaseURL", nil] documentAttributes:NULL]; 
    10296        } else { 
    103                 if( ! renderingFragmentLock ) 
    104                         renderingFragmentLock = [[NSConditionLock alloc] initWithCondition:2]; 
    105  
    106                 if( [renderingFragmentLock lockWhenCondition:2 beforeDate:[NSDate dateWithTimeIntervalSinceNow:2.]] ) { // wait until any other call to this method finishes; timesout after 2 seconds waiting 
    107                         [renderingFragmentLock unlockWithCondition:0]; 
    108  
    109                         [NSThread detachNewThreadSelector:@selector( renderHTMLFragment: ) toTarget:self withObject:[NSDictionary dictionaryWithObjectsAndKeys:fragment, @"fragment", url, @"url", nil]]; 
    110  
    111                         if( [renderingFragmentLock lockWhenCondition:1 beforeDate:[NSDate dateWithTimeIntervalSinceNow:3.]] ) { // wait until the rendering is done; timeouts in 3 seconds 
    112                                 result = [[[(id <WebDocumentText>)[[[fragmentWebView mainFrame] frameView] documentView] attributedString] mutableCopy] autorelease]; 
    113                                 [renderingFragmentLock unlockWithCondition:2]; // we are done, safe for relase WebView 
    114                         } 
    115                 } 
    116  
    117                 if( ! result ) { 
    118                         NSString *render = [NSString stringWithFormat:@"<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /></head><body><font color=\"#01fe02\">%@</font></body></html>", fragment]; 
    119                         result = [[[NSMutableAttributedString alloc] initWithHTML:[render dataUsingEncoding:NSUTF8StringEncoding] baseURL:url documentAttributes:NULL] autorelease]; 
    120                 } 
    121         } 
    122  
    123         NSRange limitRange, effectiveRange; 
    124         limitRange = NSMakeRange( 0, [result length] ); 
    125         while( limitRange.length > 0 ) { 
    126                 NSColor *color = [result attribute:NSForegroundColorAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange]; 
    127                 if( [[color colorSpaceName] isEqualToString:NSCalibratedRGBColorSpace] && [[color HTMLAttributeValue] isEqualToString:@"#01fe02"] ) 
    128                         [result removeAttribute:NSForegroundColorAttributeName range:effectiveRange]; 
    129                 limitRange = NSMakeRange( NSMaxRange( effectiveRange ), NSMaxRange( limitRange ) - NSMaxRange( effectiveRange ) ); 
    130         } 
    131  
    132         return [[[self alloc] initWithAttributedString:result] autorelease]; 
    133 
    134  
    135 + (void) renderHTMLFragment:(NSDictionary *) info { 
    136         extern WebView *fragmentWebView; 
    137         extern NSConditionLock *renderingFragmentLock; 
    138         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    139  
    140         [renderingFragmentLock lockWhenCondition:0]; // start the rendering, makes parent thread block 
    141  
    142         [NSThread setThreadPriority:1.0]; 
    143  
    144         NSString *fragment = [info objectForKey:@"fragment"]; 
    145         NSURL *url = [info objectForKey:@"url"]; 
    146  
    147         if( ! fragmentWebView ) fragmentWebView = [[WebView alloc] initWithFrame:NSMakeRect( 0., 0., 2000., 100. ) frameName:nil groupName:nil]; 
    148         [fragmentWebView setFrameLoadDelegate:self]; 
    149         [[fragmentWebView mainFrame] loadHTMLString:[NSString stringWithFormat:@"<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /></head><body><font color=\"#01fe02\">%@</font></body></html>", fragment] baseURL:url]; 
    150  
    151         [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; 
    152  
    153         [renderingFragmentLock lockWhenCondition:2]; // wait until it is safe to release 
    154         [renderingFragmentLock unlockWithCondition:2]; 
    155  
    156         [pool release]; 
    157 
    158  
    159 + (void) webView:(WebView *) sender didFinishLoadForFrame:(WebFrame *) frame { 
    160         extern NSConditionLock *renderingFragmentLock; 
    161         [renderingFragmentLock unlockWithCondition:1]; // rendering is complete 
    162         [sender setFrameLoadDelegate:nil]; 
     97                NSString *render = [NSString stringWithFormat:@"<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /></head><body>%@</body></html>", fragment]; 
     98                result = [[NSAttributedString alloc] initWithHTML:[render dataUsingEncoding:NSUTF8StringEncoding] baseURL:url documentAttributes:NULL]; 
     99        } 
     100 
     101        NSAttributedString *ret = [[self alloc] initWithAttributedString:result]; 
     102        [result release]; 
     103 
     104        return [ret autorelease]; 
    163105} 
    164106