Reviewed by Vicki.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Jun 2005 22:09:33 +0000 (22:09 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Jun 2005 22:09:33 +0000 (22:09 +0000)
- remove dependencies on NSString and NSData extras from Foundation

        * Misc.subproj/WebKitNSStringExtras.h:
        * Misc.subproj/WebKitNSStringExtras.m:
        (-[NSString _webkit_isCaseInsensitiveEqualToString:]):
        (-[NSString _webkit_hasCaseInsensitivePrefix:]):
        (-[NSString _webkit_stringByTrimmingWhitespace]):
        (-[NSString _webkit_stringByCollapsingNonPrintingCharacters]):
        (-[NSString _webkit_fixedCarbonPOSIXPath]):
        * Misc.subproj/WebNSDataExtras.h:
        * Misc.subproj/WebNSDataExtras.m:
        (-[NSString _web_capitalizeRFC822HeaderFieldName]):
        (-[NSData _web_isCaseInsensitiveEqualToCString:]):
        (_findEOL):
        (-[NSData _web_parseRFC822HeaderFields]):
        (-[NSData _webkit_guessedMIMETypeForXML]):
        (-[NSData _webkit_guessedMIMEType]):
        * Misc.subproj/WebNSPasteboardExtras.m:
        (-[NSPasteboard _web_bestURL]):
        * Misc.subproj/WebNSURLExtras.h:
        * Misc.subproj/WebNSURLExtras.m:
        (applyHostNameFunctionToURLString):
        (+[NSURL _web_URLWithUserTypedString:relativeToURL:]):
        (+[NSURL _web_URLWithDataAsString:relativeToURL:]):
        (-[NSURL _webkit_shouldLoadAsEmptyDocument]):
        (-[NSString _webkit_isJavaScriptURL]):
        (-[NSString _webkit_isFileURL]):
        (-[NSString _webkit_isFTPDirectoryURL]):
        (-[NSString _web_encodeHostName]):
        (-[NSString _webkit_rangeOfURLScheme]):
        (-[NSString _webkit_looksLikeAbsoluteURL]):
        (-[NSString _webkit_URLFragment]):
        * Misc.subproj/WebNSViewExtras.m:
        * Plugins.subproj/WebBaseNetscapePluginView.m:
        (-[WebBaseNetscapePluginView _postURL:target:len:buf:file:notifyData:sendNotification:allowHeaders:]):
        * Plugins.subproj/WebPluginDatabase.m:
        * WebCoreSupport.subproj/WebBridge.m:
        (-[WebBridge setTitle:]):
        * WebView.subproj/WebDataSource.m:
        (-[WebDataSource _setTitle:]):
        * WebView.subproj/WebFrame.m:
        (-[WebFrame _loadItem:withLoadType:]):
        * WebView.subproj/WebPreferences.m:
        (-[WebPreferences userStyleSheetLocation]):
        * WebView.subproj/WebView.m:
        (+[WebView _MIMETypeForFile:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@9259 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
WebKit/ChangeLog
WebKit/Misc.subproj/WebKitNSStringExtras.h
WebKit/Misc.subproj/WebKitNSStringExtras.m
WebKit/Misc.subproj/WebNSDataExtras.h
WebKit/Misc.subproj/WebNSDataExtras.m
WebKit/Misc.subproj/WebNSPasteboardExtras.m
WebKit/Misc.subproj/WebNSURLExtras.h
WebKit/Misc.subproj/WebNSURLExtras.m
WebKit/Misc.subproj/WebNSViewExtras.m
WebKit/Plugins.subproj/WebBaseNetscapePluginView.m
WebKit/Plugins.subproj/WebPluginDatabase.m
WebKit/WebCoreSupport.subproj/WebBridge.m
WebKit/WebView.subproj/WebDataSource.m
WebKit/WebView.subproj/WebFrame.m
WebKit/WebView.subproj/WebPreferences.m
WebKit/WebView.subproj/WebView.m

index 3c870ec9abbd957753c701bc501167f4e356e00e..2a2dff92ba06ce748ae02b73468e30602dabbc3c 100644 (file)
@@ -1,3 +1,54 @@
+2005-06-02  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Vicki.
+
+       - remove dependencies on NSString and NSData extras from Foundation
+
+        * Misc.subproj/WebKitNSStringExtras.h:
+        * Misc.subproj/WebKitNSStringExtras.m:
+        (-[NSString _webkit_isCaseInsensitiveEqualToString:]):
+        (-[NSString _webkit_hasCaseInsensitivePrefix:]):
+        (-[NSString _webkit_stringByTrimmingWhitespace]):
+        (-[NSString _webkit_stringByCollapsingNonPrintingCharacters]):
+        (-[NSString _webkit_fixedCarbonPOSIXPath]):
+        * Misc.subproj/WebNSDataExtras.h:
+        * Misc.subproj/WebNSDataExtras.m:
+        (-[NSString _web_capitalizeRFC822HeaderFieldName]):
+        (-[NSData _web_isCaseInsensitiveEqualToCString:]):
+        (_findEOL):
+        (-[NSData _web_parseRFC822HeaderFields]):
+        (-[NSData _webkit_guessedMIMETypeForXML]):
+        (-[NSData _webkit_guessedMIMEType]):
+        * Misc.subproj/WebNSPasteboardExtras.m:
+        (-[NSPasteboard _web_bestURL]):
+        * Misc.subproj/WebNSURLExtras.h:
+        * Misc.subproj/WebNSURLExtras.m:
+        (applyHostNameFunctionToURLString):
+        (+[NSURL _web_URLWithUserTypedString:relativeToURL:]):
+        (+[NSURL _web_URLWithDataAsString:relativeToURL:]):
+        (-[NSURL _webkit_shouldLoadAsEmptyDocument]):
+        (-[NSString _webkit_isJavaScriptURL]):
+        (-[NSString _webkit_isFileURL]):
+        (-[NSString _webkit_isFTPDirectoryURL]):
+        (-[NSString _web_encodeHostName]):
+        (-[NSString _webkit_rangeOfURLScheme]):
+        (-[NSString _webkit_looksLikeAbsoluteURL]):
+        (-[NSString _webkit_URLFragment]):
+        * Misc.subproj/WebNSViewExtras.m:
+        * Plugins.subproj/WebBaseNetscapePluginView.m:
+        (-[WebBaseNetscapePluginView _postURL:target:len:buf:file:notifyData:sendNotification:allowHeaders:]):
+        * Plugins.subproj/WebPluginDatabase.m:
+        * WebCoreSupport.subproj/WebBridge.m:
+        (-[WebBridge setTitle:]):
+        * WebView.subproj/WebDataSource.m:
+        (-[WebDataSource _setTitle:]):
+        * WebView.subproj/WebFrame.m:
+        (-[WebFrame _loadItem:withLoadType:]):
+        * WebView.subproj/WebPreferences.m:
+        (-[WebPreferences userStyleSheetLocation]):
+        * WebView.subproj/WebView.m:
+        (+[WebView _MIMETypeForFile:]):
+
 2005-06-02  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by John.
index 6f396bab9d2200cd74159e44042ae52988317098..a9692d32ed352e356a25c4f3ce0801a16ceef897 100644 (file)
 + (NSStringEncoding)_web_encodingForResource:(Handle)resource;
 
 - (BOOL)_webkit_isCaseInsensitiveEqualToString:(NSString *)string;
+- (BOOL)_webkit_hasCaseInsensitivePrefix:(NSString *)suffix;
+
+- (NSString *)_webkit_stringByTrimmingWhitespace;
+- (NSString *)_webkit_stringByCollapsingNonPrintingCharacters;
+- (NSString *)_webkit_fixedCarbonPOSIXPath;
 
 @end
index 6c786c32acedccf25e2fc0cbff7bf591fe479ba0..40091af3b6d437aec6c7e95f2f5a76707e4d5264 100644 (file)
@@ -8,6 +8,7 @@
 #import <WebKit/WebNSObjectExtras.h>
 #import <WebKit/WebTextRenderer.h>
 #import <WebKit/WebTextRendererFactory.h>
+#import <Foundation/NSFileManager_NSURLExtras.h>
 
 #import <unicode/uchar.h>
 
@@ -186,4 +187,104 @@ static BOOL canUseFastRenderer(const UniChar *buffer, unsigned length)
   return [self compare:string options:(NSCaseInsensitiveSearch|NSLiteralSearch)] == NSOrderedSame;
 }
 
+-(BOOL)_webkit_hasCaseInsensitivePrefix:(NSString *)prefix
+{
+    return [self rangeOfString:prefix options:(NSCaseInsensitiveSearch | NSAnchoredSearch)].location != NSNotFound;
+}
+
+-(NSString *)_webkit_stringByTrimmingWhitespace
+{
+    NSMutableString *trimmed = [[self mutableCopy] autorelease];
+    CFStringTrimWhitespace((CFMutableStringRef)trimmed);
+    return trimmed;
+}
+
+- (NSString *)_webkit_stringByCollapsingNonPrintingCharacters
+{
+    NSMutableString *result = [NSMutableString string];
+    static NSCharacterSet *charactersToTurnIntoSpaces = nil;
+    static NSCharacterSet *charactersToNotTurnIntoSpaces = nil;
+    
+    if (charactersToTurnIntoSpaces == nil) {
+        NSMutableCharacterSet *set = [[NSMutableCharacterSet alloc] init];
+        [set addCharactersInRange:NSMakeRange(0x00, 0x21)];
+        [set addCharactersInRange:NSMakeRange(0x7F, 0x01)];
+        charactersToTurnIntoSpaces = [set copy];
+        [set release];
+        charactersToNotTurnIntoSpaces = [[charactersToTurnIntoSpaces invertedSet] retain];
+    }
+    
+    unsigned length = [self length];
+    unsigned position = 0;
+    while (position != length) {
+        NSRange nonSpace = [self rangeOfCharacterFromSet:charactersToNotTurnIntoSpaces
+            options:0 range:NSMakeRange(position, length - position)];
+        if (nonSpace.location == NSNotFound) {
+            break;
+        }
+
+        NSRange space = [self rangeOfCharacterFromSet:charactersToTurnIntoSpaces
+            options:0 range:NSMakeRange(nonSpace.location, length - nonSpace.location)];
+        if (space.location == NSNotFound) {
+            space.location = length;
+        }
+
+        if (space.location > nonSpace.location) {
+            if (position != 0) {
+                [result appendString:@" "];
+            }
+            [result appendString:[self substringWithRange:
+                NSMakeRange(nonSpace.location, space.location - nonSpace.location)]];
+        }
+
+        position = space.location;
+    }
+    
+    return result;
+}
+
+-(NSString *)_webkit_fixedCarbonPOSIXPath
+{
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    if ([fileManager fileExistsAtPath:self]) {
+        // Files exists, no need to fix.
+        return self;
+    }
+
+    NSMutableArray *pathComponents = [[[self pathComponents] mutableCopy] autorelease];
+    NSString *volumeName = [pathComponents objectAtIndex:1];
+    if ([volumeName isEqualToString:@"Volumes"]) {
+        // Path starts with "/Volumes", so the volume name is the next path component.
+        volumeName = [pathComponents objectAtIndex:2];
+        // Remove "Volumes" from the path because it may incorrectly be part of the path (3163647).
+        // We'll add it back if we have to.
+        [pathComponents removeObjectAtIndex:1];
+    }
+
+    if (!volumeName) {
+        // Should only happen if self == "/", so this shouldn't happen because that always exists.
+        return self;
+    }
+
+    if ([[fileManager _web_startupVolumeName] isEqualToString:volumeName]) {
+        // Startup volume name is included in path, remove it.
+        [pathComponents removeObjectAtIndex:1];
+    } else if ([[fileManager directoryContentsAtPath:@"/Volumes"] containsObject:volumeName]) {
+        // Path starts with other volume name, prepend "/Volumes".
+        [pathComponents insertObject:@"Volumes" atIndex:1];
+    } else {
+        // It's valid.
+        return self;
+    }
+
+    NSString *path = [NSString pathWithComponents:pathComponents];
+
+    if (![fileManager fileExistsAtPath:path]) {
+        // File at canonicalized path doesn't exist, return original.
+        return self;
+    }
+
+    return path;
+}
+
 @end
index 4a738b59cf155b48d8cedf5efc273a742f29419b..776372304a65a4bee2343528e92579b9e00aee75 100644 (file)
@@ -6,8 +6,12 @@
 
 #import <Foundation/Foundation.h>
 
+#define WEB_GUESS_MIME_TYPE_PEEK_LENGTH 1024
+
 @interface NSData (WebNSURLExtras)
 
 -(BOOL)_web_isCaseInsensitiveEqualToCString:(const char *)string;
+-(NSMutableDictionary *)_webkit_parseRFC822HeaderFields;
+-(NSString *)_webkit_guessedMIMEType;
 
 @end
index 3b5f482e4fc4dd59e51dc86ba2bba084e621c82e..f815379e4d0bffadec1005200ce1cbc01c1503cf 100644 (file)
@@ -8,6 +8,82 @@
 
 #import <WebKit/WebAssertions.h>
 
+@interface NSString (WebNSDataExtrasInternal)
+- (NSString *)_web_capitalizeRFC822HeaderFieldName;
+@end
+
+@implementation NSString (WebNSDataExtrasInternal)
+
+-(NSString *)_web_capitalizeRFC822HeaderFieldName
+{
+    CFStringRef name = (CFStringRef)self;
+    NSString *result = nil;
+
+    CFIndex i; 
+    CFIndex len = CFStringGetLength(name);
+    UInt8 *charPtr = NULL;
+    UniChar *uniCharPtr = NULL;
+    Boolean useUniCharPtr = FALSE;
+    Boolean shouldCapitalize = TRUE;
+    Boolean somethingChanged = FALSE;
+    
+    for (i = 0; i < len; i ++) {
+        UniChar ch = CFStringGetCharacterAtIndex(name, i);
+        Boolean replace = FALSE;
+        if (shouldCapitalize && ch >= 'a' && ch <= 'z') {
+            ch = ch + 'A' - 'a';
+            replace = TRUE;
+        } 
+        else if (!shouldCapitalize && ch >= 'A' && ch <= 'Z') {
+            ch = ch + 'a' - 'A';
+            replace = TRUE;
+        }
+        if (replace) {
+            if (!somethingChanged) {
+                somethingChanged = TRUE;
+                if (CFStringGetBytes(name, CFRangeMake(0, len), kCFStringEncodingISOLatin1, 0, FALSE, NULL, 0, NULL) == len) {
+                    // Can be encoded in ISOLatin1
+                    useUniCharPtr = FALSE;
+                    charPtr = CFAllocatorAllocate(NULL, len + 1, 0);
+                    CFStringGetCString(name, charPtr, len+1, kCFStringEncodingISOLatin1);
+                } 
+                else {
+                    useUniCharPtr = TRUE;
+                    uniCharPtr = CFAllocatorAllocate(NULL, len * sizeof(UniChar), 0);
+                    CFStringGetCharacters(name, CFRangeMake(0, len), uniCharPtr);
+                }
+            }
+            if (useUniCharPtr) {
+                uniCharPtr[i] = ch;
+            } 
+            else {
+                charPtr[i] = ch;
+            }
+        }
+        if (ch == '-') {
+            shouldCapitalize = TRUE;
+        } 
+        else {
+            shouldCapitalize = FALSE;
+        }
+    }
+    if (somethingChanged) {
+        if (useUniCharPtr) {
+            result = (NSString *)CFMakeCollectable(CFStringCreateWithCharacters(NULL, uniCharPtr, len));
+        } 
+        else {
+            result = (NSString *)CFMakeCollectable(CFStringCreateWithCString(NULL, charPtr, kCFStringEncodingISOLatin1));
+        }
+    } 
+    else {
+        result = [self retain];
+    }
+    
+    return [result autorelease];
+}
+
+@end
+
 @implementation NSData (WebNSDataExtras)
 
 -(BOOL)_web_isCaseInsensitiveEqualToCString:(const char *)string
     return strncasecmp(bytes, string, [self length]) == 0;
 }
 
+static const UInt8 *_findEOL(const UInt8 *bytes, CFIndex len) {
+    
+    // According to the HTTP specification EOL is defined as
+    // a CRLF pair.  Unfortunately, some servers will use LF
+    // instead.  Worse yet, some servers will use a combination
+    // of both (e.g. <header>CRLFLF<body>), so findEOL needs
+    // to be more forgiving.  It will now accept CRLF, LF, or
+    // CR.
+    //
+    // It returns NULL if EOL is not found or it will return
+    // a pointer to the first terminating character.
+    CFIndex i;
+    for (i = 0;  i < len; i++)
+    {
+        UInt8 c = bytes[i];
+        if ('\n' == c) return bytes + i;
+        if ('\r' == c)
+        {
+            // Check to see if spanning buffer bounds
+            // (CRLF is across reads).  If so, wait for
+            // next read.
+            if (i + 1 == len) break;
+                
+            return bytes + i;
+        }
+    }
+    
+    return NULL;
+}
+
+-(NSMutableDictionary *)_web_parseRFC822HeaderFields
+{
+    NSMutableDictionary *headerFields = [NSMutableDictionary dictionary];
+
+    const UInt8 *bytes = [self bytes];
+    unsigned length = [self length];
+    NSString *lastKey = nil;
+    const UInt8 *eol;
+
+    // Loop over lines until we're past the header, or we can't find any more end-of-lines
+    while ((eol = _findEOL(bytes, length))) {
+        const UInt8 *line = bytes;
+        SInt32 lineLength = eol - bytes;
+
+        // Move bytes to the character after the terminator as returned by _findEOL.
+        bytes = eol + 1;
+        if (('\r' == *eol) && ('\n' == *bytes)) {
+            bytes++; // Safe since _findEOL won't return a spanning CRLF.
+        }
+
+        length -= (bytes - line);
+        if (lineLength == 0) {
+            // Blank line; we're at the end of the header
+            break;
+        }
+        else if (*line == ' ' || *line == '\t') {
+            // Continuation of the previous header
+            if (!lastKey) {
+                // malformed header; ignore it and continue
+                continue;
+            }
+            else {
+                // Merge the continuation of the previous header
+                NSString *currentValue = [headerFields objectForKey:lastKey];
+                NSString *newValue = (NSString *)CFMakeCollectable(CFStringCreateWithBytes(NULL, line, lineLength, kCFStringEncodingISOLatin1, FALSE));
+                ASSERT(currentValue);
+                ASSERT(newValue);
+                NSString *mergedValue = [[NSString alloc] initWithFormat:@"%@%@", currentValue, newValue];
+                [headerFields setObject:(NSString *)mergedValue forKey:lastKey];
+                [newValue release];
+                [mergedValue release];
+                // Note: currentValue is autoreleased
+            }
+        }
+        else {
+            // Brand new header
+            const UInt8 *colon;
+            for (colon = line; *colon != ':' && colon != eol; colon ++) {
+                // empty loop
+            }
+            if (colon == eol) {
+                // malformed header; ignore it and continue
+                continue;
+            }
+            else {
+                lastKey = (NSString *)CFMakeCollectable(CFStringCreateWithBytes(NULL, line, colon - line, kCFStringEncodingISOLatin1, FALSE));
+                [lastKey autorelease];
+                NSString *value = [lastKey _web_capitalizeRFC822HeaderFieldName];
+                lastKey = value;
+                for (colon++; colon != eol; colon++) {
+                    if (*colon != ' ' && *colon != '\t') {
+                        break;
+                    }
+                }
+                if (colon == eol) {
+                    value = [[NSString alloc] initWithString:@""];
+                    [value autorelease];
+                }
+                else {
+                    value = (NSString *)CFMakeCollectable(CFStringCreateWithBytes(NULL, colon, eol-colon, kCFStringEncodingISOLatin1, FALSE));
+                    [value autorelease];
+                }
+                NSString *oldValue = [headerFields objectForKey:lastKey];
+                if (oldValue) {
+                    NSString *newValue = [[NSString alloc] initWithFormat:@"%@, %@", oldValue, value];
+                    value = newValue;
+                    [newValue autorelease];
+                }
+                [headerFields setObject:(NSString *)value forKey:lastKey];
+            }
+        }
+    }
+
+    return headerFields;
+}
+
+-(NSString *)_webkit_guessedMIMETypeForXML
+{
+    int length = [self length];
+    const UInt8 *bytes = [self bytes];
+
+#define CHANNEL_TAG_LENGTH 7
+
+    const char *p = (const char *)bytes;
+    int remaining = MIN(length, WEB_GUESS_MIME_TYPE_PEEK_LENGTH) - (CHANNEL_TAG_LENGTH - 1);
+
+    BOOL foundRDF = false;
+
+    while (remaining > 0) {
+        // Look for a "<".
+        const char *hit = memchr(p, '<', remaining);
+        if (!hit) {
+            break;
+        }
+
+       // We are trying to identify RSS or Atom. RSS has a top-level
+       // element of either <rss> or <rdf>. However, there are
+       // non-RSS RDF files, so in the case of <rdf> we further look
+       // for a <channel> element. In the case of an Atom file, a
+       // top-level <feed> element is all we need to see. Only tags
+       // starting with <? or <! can precede the root element. We
+       // bail if we don't find an <rss>, <feed> or <rdf> element
+       // right after those.
+
+       if (foundRDF) {
+           if (strncasecmp(hit, "<channel", strlen("<channel")) == 0) {
+               return @"application/rss+xml";
+           }
+       } else if (strncasecmp(hit, "<rdf", strlen("<rdf")) == 0) {
+           foundRDF = TRUE;
+       } else if (strncasecmp(hit, "<rss", strlen("<rss")) == 0) {
+           return @"application/rss+xml";
+       } else if (strncasecmp(hit, "<feed", strlen("<feed")) == 0) {
+           return @"application/atom+xml";
+       } else if (strncasecmp(hit, "<?", strlen("<?")) != 0 && strncasecmp(hit, "<!", strlen("<!")) != 0) {
+           return nil;
+       }
+
+        // Skip the "<" and continue.
+        remaining -= (hit + 1) - p;
+        p = hit + 1;
+    }
+
+    return nil;
+}
+
+-(NSString *)_webkit_guessedMIMEType
+{
+#define JPEG_MAGIC_NUMBER_LENGTH 4
+#define SCRIPT_TAG_LENGTH 7
+#define TEXT_HTML_LENGTH 9
+#define VCARD_HEADER_LENGTH 11
+#define VCAL_HEADER_LENGTH 15
+
+    NSString *MIMEType = [self _webkit_guessedMIMETypeForXML];
+    if ([MIMEType length] != nil) {
+        return MIMEType;
+    }
+    
+    int length = [self length];
+    const UInt8 *bytes = [self bytes];
+
+    const char *p = (const char *)bytes;
+    int remaining = MIN(length, WEB_GUESS_MIME_TYPE_PEEK_LENGTH) - (SCRIPT_TAG_LENGTH - 1);
+    while (remaining > 0) {
+        // Look for a "<".
+        const char *hit = memchr(p, '<', remaining);
+        if (!hit) {
+            break;
+        }
+
+        // If we found a "<", look for "<html>" or "<a " or "<script".
+        if (strncasecmp(hit, "<html>",         strlen("<html>")) == 0 ||
+            strncasecmp(hit, "<a ",    strlen("<a ")) == 0 ||
+            strncasecmp(hit, "<script", strlen("<script")) == 0 ||
+            strncasecmp(hit, "<title>", strlen("<title>")) == 0) {
+            return @"text/html";
+        }
+
+        // Skip the "<" and continue.
+        remaining -= (hit + 1) - p;
+        p = hit + 1;
+    }
+
+    // Test for a broken server which has sent the content type as part of the content.
+    // This code could be improved to look for other mime types.
+    p = (const char *)bytes;
+    remaining = MIN(length, WEB_GUESS_MIME_TYPE_PEEK_LENGTH) - (TEXT_HTML_LENGTH - 1);
+    while (remaining > 0) {
+        // Look for a "t" or "T".
+        const char *hit = NULL;
+        const char *lowerhit = memchr(p, 't', remaining);
+        const char *upperhit = memchr(p, 'T', remaining);
+        if (!lowerhit && !upperhit) {
+            break;
+        }
+        if (!lowerhit) {
+            hit = upperhit;
+        }
+        else if (!upperhit) {
+            hit = lowerhit;
+        }
+        else {
+            hit = MIN(lowerhit, upperhit);
+        }
+
+        // If we found a "t/T", look for "text/html".
+        if (strncasecmp(hit, "text/html", TEXT_HTML_LENGTH) == 0) {
+            return @"text/html";
+        }
+
+        // Skip the "t/T" and continue.
+        remaining -= (hit + 1) - p;
+        p = hit + 1;
+    }
+
+    if ((length >= VCARD_HEADER_LENGTH) && strncmp(bytes, "BEGIN:VCARD", VCARD_HEADER_LENGTH) == 0) {
+        return @"text/vcard";
+    }
+    if ((length >= VCAL_HEADER_LENGTH) && strncmp(bytes, "BEGIN:VCALENDAR", VCAL_HEADER_LENGTH) == 0) {
+        return @"text/calendar";
+    }
+    
+    // Test for plain text.
+    int i;
+    for(i=0; i<length; i++){
+        char c = bytes[i];
+        if ((c < 0x20 || c > 0x7E) && (c != '\t' && c != '\r' && c != '\n')) {
+            break;
+        }
+    }
+    if (i == length) {
+        // Didn't encounter any bad characters, looks like plain text.
+        return @"text/plain";
+    }
+
+    // Looks like this is a binary file.
+
+    // Sniff for the JPEG magic number.
+    if ((length >= JPEG_MAGIC_NUMBER_LENGTH) && strncmp(bytes, "\xFF\xD8\xFF\xE0", JPEG_MAGIC_NUMBER_LENGTH) == 0) {
+        return @"image/jpeg";
+    }
+
+#undef JPEG_MAGIC_NUMBER_LENGTH
+#undef SCRIPT_TAG_LENGTH
+#undef TEXT_HTML_LENGTH
+#undef VCARD_HEADER_LENGTH
+#undef VCAL_HEADER_LENGTH
+
+    return nil;
+}
+
 @end
index 7f6f7e80c6de11a84ba2eb9e4780b494f97740a4..95127fb93f296ca0da817ace51ec00ae7ff4c22b 100644 (file)
@@ -17,7 +17,6 @@
 #import <WebKit/WebURLsWithTitles.h>
 #import <WebKit/WebViewPrivate.h>
 
-#import <Foundation/NSString_NSURLExtras.h>
 #import <Foundation/NSURL_NSURLExtras.h>
 #import <Foundation/NSURLFileTypeMappings.h>
 
@@ -119,7 +118,7 @@ static NSArray *_writableTypesForImageWithArchive (void)
 
     if ([types containsObject:NSStringPboardType]) {
         NSString *URLString = [self stringForType:NSStringPboardType];
-        if ([URLString _web_looksLikeAbsoluteURL]) {
+        if ([URLString _webkit_looksLikeAbsoluteURL]) {
             NSURL *URL = [[NSURL _web_URLWithUserTypedString:URLString] _webkit_canonicalize];
             if (URL) {
                 return URL;
index 9db9e4d53fbacd847e23d2fdd1e3fc88d61ce74c..bbbf69cbfd931aa3c892fff924bc91d1cedb8b39 100644 (file)
@@ -63,5 +63,7 @@
 - (NSString *)_webkit_scriptIfJavaScriptURL;
 - (BOOL)_webkit_isFTPDirectoryURL;
 - (BOOL)_webkit_isFileURL;
+- (BOOL)_webkit_looksLikeAbsoluteURL;
+- (NSString *)_webkit_URLFragment;
 
 @end
index 3cc6f2eccee2dc8d8332d7079a36b47ac0473aa0..a9ceeffb3b6473fb705bef94709a39c93372e58e 100644 (file)
@@ -7,10 +7,10 @@
 #import <WebKit/WebNSURLExtras.h>
 
 #import <WebKit/WebAssertions.h>
+#import <WebKit/WebKitNSStringExtras.h>
 #import <WebKit/WebNSDataExtras.h>
 #import <WebKit/WebNSObjectExtras.h>
 
-#import <Foundation/NSString_NSURLExtras.h>
 #import <Foundation/NSURLProtocolPrivate.h>
 #import <Foundation/NSURLRequest.h>
 #import <Foundation/NSURL_NSURLExtras.h>
@@ -159,7 +159,7 @@ static void applyHostNameFunctionToURLString(NSString *string, StringRangeApplie
 
     // Maybe we should implement this using a character buffer instead?
 
-    if ([string _web_hasCaseInsensitivePrefix:@"mailto:"]) {
+    if ([string _webkit_hasCaseInsensitivePrefix:@"mailto:"]) {
         applyHostNameFunctionToMailToURLString(string, f, context);
         return;
     }
@@ -268,7 +268,7 @@ static NSString *mapHostNames(NSString *string, BOOL encode)
     if (string == nil) {
         return nil;
     }
-    string = mapHostNames([string _web_stringByTrimmingWhitespace], YES);
+    string = mapHostNames([string _webkit_stringByTrimmingWhitespace], YES);
 
     NSData *userTypedData = [string dataUsingEncoding:NSUTF8StringEncoding];
     ASSERT(userTypedData);
@@ -319,7 +319,7 @@ static NSString *mapHostNames(NSString *string, BOOL encode)
     if (string == nil) {
         return nil;
     }
-    string = [string _web_stringByTrimmingWhitespace];
+    string = [string _webkit_stringByTrimmingWhitespace];
     NSData *data = [string dataUsingEncoding:NSISOLatin1StringEncoding];
     return [self _web_URLWithData:data relativeToURL:baseURL];
 }
@@ -545,7 +545,7 @@ static NSString *mapHostNames(NSString *string, BOOL encode)
 
 - (BOOL)_webkit_shouldLoadAsEmptyDocument
 {
-    return [[self _web_originalDataAsString] _web_hasCaseInsensitivePrefix:@"about:"] || [self _web_isEmpty];
+    return [[self _web_originalDataAsString] _webkit_hasCaseInsensitivePrefix:@"about:"] || [self _web_isEmpty];
 }
 
 - (NSURL *)_web_URLWithLowercasedScheme
@@ -754,12 +754,12 @@ static NSString *mapHostNames(NSString *string, BOOL encode)
 
 - (BOOL)_webkit_isJavaScriptURL
 {
-    return [self _web_hasCaseInsensitivePrefix:@"javascript:"];
+    return [self _webkit_hasCaseInsensitivePrefix:@"javascript:"];
 }
 
 - (BOOL)_webkit_isFileURL
 {
-    return [self _web_hasCaseInsensitivePrefix:@"file:"];
+    return [self _webkit_hasCaseInsensitivePrefix:@"file:"];
 }
 
 - (NSString *)_webkit_stringByReplacingValidPercentEscapes
@@ -783,7 +783,7 @@ static NSString *mapHostNames(NSString *string, BOOL encode)
        return NO;
     }
     unichar lastChar = [self characterAtIndex:length - 1];
-    return lastChar == '/' && [self _web_hasCaseInsensitivePrefix:@"ftp:"];
+    return lastChar == '/' && [self _webkit_hasCaseInsensitivePrefix:@"ftp:"];
 }
 
 
@@ -947,4 +947,42 @@ static BOOL allCharactersInIDNScriptWhiteList(const UChar *buffer, int32_t lengt
     return name == nil ? self : name;
 }
 
+-(NSRange)_webkit_rangeOfURLScheme
+{
+    NSRange colon = [self rangeOfString:@":"];
+    if (colon.location != NSNotFound && colon.location > 0) {
+        NSRange scheme = {0, colon.location};
+        static NSCharacterSet *InverseSchemeCharacterSet = nil;
+        if (!InverseSchemeCharacterSet) {
+            /*
+             This stuff is very expensive.  10-15 msec on a 2x1.2GHz.  If not cached it swamps
+             everything else when adding items to the autocomplete DB.  Makes me wonder if we
+             even need to enforce the character set here.
+            */
+            NSString *acceptableCharacters = @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+.-";
+            InverseSchemeCharacterSet = [[[NSCharacterSet characterSetWithCharactersInString:acceptableCharacters] invertedSet] retain];
+        }
+        NSRange illegals = [self rangeOfCharacterFromSet:InverseSchemeCharacterSet options:0 range:scheme];
+        if (illegals.location == NSNotFound)
+            return scheme;
+    }
+    return NSMakeRange(NSNotFound, 0);
+}
+
+-(BOOL)_webkit_looksLikeAbsoluteURL
+{
+    // Trim whitespace because _web_URLWithString allows whitespace.
+    return [[self _webkit_stringByTrimmingWhitespace] _webkit_rangeOfURLScheme].location != NSNotFound;
+}
+
+- (NSString *)_webkit_URLFragment
+{
+    NSRange fragmentRange;
+    
+    fragmentRange = [self rangeOfString:@"#" options:NSLiteralSearch];
+    if (fragmentRange.location == NSNotFound)
+        return nil;
+    return [self substringFromIndex:fragmentRange.location];
+}
+
 @end
index 8db779ae94cde1c3bf829a8625d00603cc6e556d..a26b4fa7d9fde2fb24ca4dd028aabdd166ba0de8 100644 (file)
@@ -13,7 +13,6 @@
 #import <WebKit/WebNSPasteboardExtras.h>
 #import <WebKit/WebNSURLExtras.h>
 
-#import <Foundation/NSString_NSURLExtras.h>
 #import <Foundation/NSURL_NSURLExtras.h>
 #import <Foundation/NSURLFileTypeMappings.h>
 
index 0b814f7fb0cc15c290d500863f308f3c3b0c08d1..1662ba1429ee7dfd667e1db1ecc7a05a30b19c98 100644 (file)
@@ -15,6 +15,7 @@
 #import <WebKit/WebKitNSStringExtras.h>
 #import <WebKit/WebNetscapePluginStream.h>
 #import <WebKit/WebNullPluginView.h>
+#import <WebKit/WebNSDataExtras.h>
 #import <WebKit/WebNSObjectExtras.h>
 #import <WebKit/WebNSURLExtras.h>
 #import <WebKit/WebNSViewExtras.h>
@@ -23,9 +24,7 @@
 #import <WebKit/WebViewPrivate.h>
 #import <WebKit/WebUIDelegate.h>
 
-#import <Foundation/NSData_NSURLExtras.h>
 #import <Foundation/NSDictionary_NSURLExtras.h>
-#import <Foundation/NSString_NSURLExtras.h>
 #import <Foundation/NSURL_NSURLExtras.h>
 #import <Foundation/NSURLRequestPrivate.h>
 
@@ -1576,7 +1575,7 @@ static OSStatus TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEve
         } else {
             path = bufString;
         }
-        postData = [NSData dataWithContentsOfFile:[path _web_fixedCarbonPOSIXPath]];
+        postData = [NSData dataWithContentsOfFile:[path _webkit_fixedCarbonPOSIXPath]];
         CFRelease(bufString);
         if (!postData) {
             return NPERR_FILE_NOT_FOUND;
@@ -1600,7 +1599,7 @@ static OSStatus TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEve
             if (location != NSNotFound) {
                 // If the blank line is somewhere in the middle of postData, everything before is the header.
                 NSData *headerData = [postData subdataWithRange:NSMakeRange(0, location)];
-                NSMutableDictionary *header = [headerData _web_parseRFC822HeaderFields];
+                NSMutableDictionary *header = [headerData _webkit_parseRFC822HeaderFields];
                unsigned dataLength = [postData length] - location;
 
                // Sometimes plugins like to set Content-Length themselves when they post,
index c6fefa452e93452ff686e7639a2362387115f624..ad9e85b44aaabe48df0de4b76ed5231630f3b43f 100644 (file)
@@ -20,7 +20,6 @@
 
 #import <CoreGraphics/CPSProcesses.h>
 
-#import <Foundation/NSString_NSURLExtras.h>
 #import <Foundation/NSURLFileTypeMappings.h>
 
 @implementation WebPluginDatabase
index 62ad25f4d23b2eba86798cb79e487280c919e84c..655e990dc6d185cbeb0bd30c5baed569d0feec3d 100644 (file)
@@ -53,7 +53,6 @@
 #import <Foundation/NSURLRequest.h>
 #import <Foundation/NSURLRequestPrivate.h>
 #import <Foundation/NSDictionary_NSURLExtras.h>
-#import <Foundation/NSString_NSURLExtras.h>
 #import <Foundation/NSURLConnection.h>
 #import <Foundation/NSURLResponse.h>
 #import <Foundation/NSURLResponsePrivate.h>
@@ -394,7 +393,7 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
 
 - (void)setTitle:(NSString *)title
 {
-    [[self dataSource] _setTitle:[title _web_stringByCollapsingNonPrintingCharacters]];
+    [[self dataSource] _setTitle:[title _webkit_stringByCollapsingNonPrintingCharacters]];
 }
 
 - (void)setStatusText:(NSString *)status
index 83ab8b07d28bddba4e143edc5cbba062df36f24f..ce80d972ba3a96b0ef1c981aba7204cb8efb86d2 100644 (file)
@@ -28,6 +28,7 @@
 #import <WebKit/WebImageView.h>
 #import <WebKit/WebKitErrorsPrivate.h>
 #import <WebKit/WebKitLogging.h>
+#import <WebKit/WebKitNSStringExtras.h>
 #import <WebKit/WebKitStatisticsPrivate.h>
 #import <WebKit/WebMainResourceClient.h>
 #import <WebKit/WebNSObjectExtras.h>
@@ -41,7 +42,6 @@
 #import <WebKit/WebViewPrivate.h>
 
 #import <Foundation/NSDictionary_NSURLExtras.h>
-#import <Foundation/NSString_NSURLExtras.h>
 #import <Foundation/NSURLConnection.h>
 #import <Foundation/NSURLRequest.h>
 #import <Foundation/NSURLResponsePrivate.h>
     if (title == nil) {
         trimmed = nil;
     } else {
-        trimmed = [title _web_stringByTrimmingWhitespace];
+        trimmed = [title _webkit_stringByTrimmingWhitespace];
         if ([trimmed length] == 0)
             trimmed = nil;
     }
index dd0f8f9b9d92f845a3df2b979032643b7a424b59..64d99a1d8366d322a50ff28aba71b57b3688cfdc 100644 (file)
@@ -40,7 +40,6 @@
 #import <WebKit/WebUIDelegate.h>
 
 #import <Foundation/NSDictionary_NSURLExtras.h>
-#import <Foundation/NSString_NSURLExtras.h>
 #import <Foundation/NSURLRequestPrivate.h>
 
 #import <objc/objc-runtime.h>
@@ -1331,7 +1330,7 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
         // FIXME: form state might want to be saved here too
 
         // FIXME: Perhaps we can use scrollToAnchorWithURL here instead and remove the older scrollToAnchor:?
-        NSString *anchor = [[item URLString] _web_URLFragment];
+        NSString *anchor = [[item URLString] _webkit_URLFragment];
         if (anchor)
             [[_private->dataSource _bridge] scrollToAnchor: anchor];
     
index 96de669672640e5567850c0449050fd1fdb2ee70..eac4aea1ac8cbc8076e80b376f09b0c6e7a83405 100644 (file)
@@ -11,7 +11,6 @@
 #import <WebKit/WebNSURLExtras.h>
 
 #import <Foundation/NSDictionary_NSURLExtras.h>
-#import <Foundation/NSString_NSURLExtras.h>
 
 #import <WebCore/WebCoreSettings.h>
 
@@ -402,7 +401,7 @@ NS_ENDHANDLER
 {
     NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
     
-    if ([locationString _web_looksLikeAbsoluteURL]) {
+    if ([locationString _webkit_looksLikeAbsoluteURL]) {
         return [NSURL _web_URLWithDataAsString:locationString];
     } else {
         locationString = [locationString stringByExpandingTildeInPath];
index 24460650e163d3790d3b43f12c23eb51fc60aa93..a85a2ef94e1497995587cd1c69986f6a1f57f386 100644 (file)
@@ -38,6 +38,7 @@
 #import <WebKit/WebKitLogging.h>
 #import <WebKit/WebKitNSStringExtras.h>
 #import <WebKit/WebKitStatisticsPrivate.h>
+#import <WebKit/WebNSDataExtras.h>
 #import <WebKit/WebNSObjectExtras.h>
 #import <WebKit/WebNSPasteboardExtras.h>
 #import <WebKit/WebNSPrintOperationExtras.h>
@@ -58,7 +59,6 @@
 #import <WebCore/WebCoreSettings.h>
 #import <WebCore/WebCoreView.h>
 
-#import <Foundation/NSData_NSURLExtras.h>
 #import <Foundation/NSDictionary_NSURLExtras.h>
 #import <Foundation/NSURLConnection.h>
 #import <Foundation/NSURLDownloadPrivate.h>
@@ -518,10 +518,10 @@ static bool debugWidget = true;
     // If we can't get a known MIME type from the extension, sniff.
     if ([MIMEType length] == 0 || [MIMEType isEqualToString:@"application/octet-stream"]) {
         NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
-        NSData *data = [handle readDataOfLength:GUESS_MIME_TYPE_PEEK_LENGTH];
+        NSData *data = [handle readDataOfLength:WEB_GUESS_MIME_TYPE_PEEK_LENGTH];
         [handle closeFile];
         if ([data length] != 0) {
-            MIMEType = [data _web_guessedMIMEType];
+            MIMEType = [data _webkit_guessedMIMEType];
         }
         if ([MIMEType length] == 0) {
             MIMEType = @"application/octet-stream";