| 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]; |
|---|
| 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]; |
|---|