📄 webnsurlextras.mm
字号:
} else { *p++ = c; outLength++; } } NSData *data = [NSData dataWithBytesNoCopy:outBytes length:outLength]; // adopts outBytes return [self _web_URLWithData:data relativeToURL:URL];}+ (NSURL *)_web_URLWithUserTypedString:(NSString *)string{ return [self _web_URLWithUserTypedString:string relativeToURL:nil];}+ (NSURL *)_web_URLWithDataAsString:(NSString *)string{ if (string == nil) { return nil; } return [self _web_URLWithDataAsString:string relativeToURL:nil];}+ (NSURL *)_web_URLWithDataAsString:(NSString *)string relativeToURL:(NSURL *)baseURL{ if (string == nil) { return nil; } string = [string _webkit_stringByTrimmingWhitespace]; NSData *data = [string dataUsingEncoding:NSISOLatin1StringEncoding]; return [self _web_URLWithData:data relativeToURL:baseURL];}+ (NSURL *)_web_URLWithData:(NSData *)data{ return [NSURL _web_URLWithData:data relativeToURL:nil];} + (NSURL *)_web_URLWithData:(NSData *)data relativeToURL:(NSURL *)baseURL{ if (data == nil) return nil; NSURL *result = nil; size_t length = [data length]; if (length > 0) { // work around <rdar://4470771>: CFURLCreateAbsoluteURLWithBytes(.., TRUE) doesn't remove non-path components. baseURL = [baseURL _webkit_URLByRemovingResourceSpecifier]; const UInt8 *bytes = static_cast<const UInt8*>([data bytes]); // NOTE: We use UTF-8 here since this encoding is used when computing strings when returning URL components // (e.g calls to NSURL -path). However, this function is not tolerant of illegal UTF-8 sequences, which // could either be a malformed string or bytes in a different encoding, like shift-jis, so we fall back // onto using ISO Latin 1 in those cases. result = WebCFAutorelease(CFURLCreateAbsoluteURLWithBytes(NULL, bytes, length, kCFStringEncodingUTF8, (CFURLRef)baseURL, YES)); if (!result) result = WebCFAutorelease(CFURLCreateAbsoluteURLWithBytes(NULL, bytes, length, kCFStringEncodingISOLatin1, (CFURLRef)baseURL, YES)); } else result = [NSURL URLWithString:@""]; return result;}- (NSData *)_web_originalData{ UInt8 *buffer = (UInt8 *)malloc(URL_BYTES_BUFFER_LENGTH); CFIndex bytesFilled = CFURLGetBytes((CFURLRef)self, buffer, URL_BYTES_BUFFER_LENGTH); if (bytesFilled == -1) { CFIndex bytesToAllocate = CFURLGetBytes((CFURLRef)self, NULL, 0); buffer = (UInt8 *)realloc(buffer, bytesToAllocate); bytesFilled = CFURLGetBytes((CFURLRef)self, buffer, bytesToAllocate); ASSERT(bytesFilled == bytesToAllocate); } // buffer is adopted by the NSData NSData *data = [NSData dataWithBytesNoCopy:buffer length:bytesFilled freeWhenDone:YES]; NSURL *baseURL = (NSURL *)CFURLGetBaseURL((CFURLRef)self); if (baseURL) return [[NSURL _web_URLWithData:data relativeToURL:baseURL] _web_originalData]; return data;}- (NSString *)_web_originalDataAsString{ return [[[NSString alloc] initWithData:[self _web_originalData] encoding:NSISOLatin1StringEncoding] autorelease];}static CFStringRef createStringWithEscapedUnsafeCharacters(CFStringRef string){ CFIndex length = CFStringGetLength(string); Vector<UChar, 2048> sourceBuffer(length); CFStringGetCharacters(string, CFRangeMake(0, length), sourceBuffer.data()); Vector<UChar, 2048> outBuffer; CFIndex i = 0; while (i < length) { UChar32 c; U16_NEXT(sourceBuffer, i, length, c) if (isLookalikeCharacter(c)) { uint8_t utf8Buffer[4]; CFIndex offset = 0; UBool failure = false; U8_APPEND(utf8Buffer, offset, 4, c, failure) ASSERT(!failure); for (CFIndex j = 0; j < offset; ++j) { outBuffer.append('%'); outBuffer.append(hexDigit(utf8Buffer[j] >> 4)); outBuffer.append(hexDigit(utf8Buffer[j] & 0xf)); } } else { UChar utf16Buffer[2]; CFIndex offset = 0; UBool failure = false; U16_APPEND(utf16Buffer, offset, 2, c, failure) ASSERT(!failure); for (CFIndex j = 0; j < offset; ++j) outBuffer.append(utf16Buffer[j]); } } return CFStringCreateWithCharacters(NULL, outBuffer.data(), outBuffer.size());}- (NSString *)_web_userVisibleString{ NSData *data = [self _web_originalData]; const unsigned char *before = static_cast<const unsigned char*>([data bytes]); int length = [data length]; bool needsHostNameDecoding = false; const unsigned char *p = before; int bufferLength = (length * 3) + 1; char *after = static_cast<char *>(malloc(bufferLength)); // large enough to %-escape every character char *q = after; int i; for (i = 0; i < length; i++) { unsigned char c = p[i]; // unescape escape sequences that indicate bytes greater than 0x7f if (c == '%' && (i + 1 < length && isHexDigit(p[i + 1])) && i + 2 < length && isHexDigit(p[i + 2])) { unsigned char u = (hexDigitValue(p[i + 1]) << 4) | hexDigitValue(p[i + 2]); if (u > 0x7f) { // unescape *q++ = u; } else { // do not unescape *q++ = p[i]; *q++ = p[i + 1]; *q++ = p[i + 2]; } i += 2; } else { *q++ = c; // Check for "xn--" in an efficient, non-case-sensitive, way. if (c == '-' && i >= 3 && !needsHostNameDecoding && (q[-4] | 0x20) == 'x' && (q[-3] | 0x20) == 'n' && q[-2] == '-') needsHostNameDecoding = true; } } *q = '\0'; // Check string to see if it can be converted to display using UTF-8 NSString *result = [NSString stringWithUTF8String:after]; if (!result) { // Could not convert to UTF-8. // Convert characters greater than 0x7f to escape sequences. // Shift current string to the end of the buffer // then we will copy back bytes to the start of the buffer // as we convert. int afterlength = q - after; char *p = after + bufferLength - afterlength - 1; memmove(p, after, afterlength + 1); // copies trailing '\0' char *q = after; while (*p) { unsigned char c = *p; if (c > 0x7f) { *q++ = '%'; *q++ = hexDigit(c >> 4); *q++ = hexDigit(c & 0xf); } else { *q++ = *p; } p++; } *q = '\0'; result = [NSString stringWithUTF8String:after]; } free(after); result = mapHostNames(result, !needsHostNameDecoding); result = [result precomposedStringWithCanonicalMapping]; return WebCFAutorelease(createStringWithEscapedUnsafeCharacters((CFStringRef)result));}- (BOOL)_web_isEmpty{ if (!CFURLGetBaseURL((CFURLRef)self)) return CFURLGetBytes((CFURLRef)self, NULL, 0) == 0; return [[self _web_originalData] length] == 0;}- (const char *)_web_URLCString{ NSMutableData *data = [NSMutableData data]; [data appendData:[self _web_originalData]]; [data appendBytes:"\0" length:1]; return (const char *)[data bytes]; }- (NSURL *)_webkit_canonicalize{ NSURLRequest *request = [[NSURLRequest alloc] initWithURL:self]; Class concreteClass = WKNSURLProtocolClassForRequest(request); if (!concreteClass) { [request release]; return self; } // This applies NSURL's concept of canonicalization, but not KURL's concept. It would // make sense to apply both, but when we tried that it caused a performance degradation // (see 5315926). It might make sense to apply only the KURL concept and not the NSURL // concept, but it's too risky to make that change for WebKit 3.0. NSURLRequest *newRequest = [concreteClass canonicalRequestForRequest:request]; NSURL *newURL = [newRequest URL]; NSURL *result = [[newURL retain] autorelease]; [request release]; return result;}typedef struct { NSString *scheme; NSString *user; NSString *password; NSString *host; CFIndex port; // kCFNotFound means ignore/omit NSString *path; NSString *query; NSString *fragment;} WebKitURLComponents;- (NSURL *)_webkit_URLByRemovingComponent:(CFURLComponentType)component{ CFRange fragRg = CFURLGetByteRangeForComponent((CFURLRef)self, component, NULL); // Check to see if a fragment exists before decomposing the URL. if (fragRg.location == kCFNotFound) return self; UInt8 *urlBytes, buffer[2048]; CFIndex numBytes = CFURLGetBytes((CFURLRef)self, buffer, 2048); if (numBytes == -1) { numBytes = CFURLGetBytes((CFURLRef)self, NULL, 0); urlBytes = static_cast<UInt8*>(malloc(numBytes)); CFURLGetBytes((CFURLRef)self, urlBytes, numBytes); } else urlBytes = buffer; NSURL *result = (NSURL *)CFMakeCollectable(CFURLCreateWithBytes(NULL, urlBytes, fragRg.location - 1, kCFStringEncodingUTF8, NULL)); if (!result) result = (NSURL *)CFMakeCollectable(CFURLCreateWithBytes(NULL, urlBytes, fragRg.location - 1, kCFStringEncodingISOLatin1, NULL)); if (urlBytes != buffer) free(urlBytes); return result ? [result autorelease] : self;}- (NSURL *)_webkit_URLByRemovingFragment{ return [self _webkit_URLByRemovingComponent:kCFURLComponentFragment];}- (NSURL *)_webkit_URLByRemovingResourceSpecifier{ return [self _webkit_URLByRemovingComponent:kCFURLComponentResourceSpecifier];}- (BOOL)_webkit_isJavaScriptURL{ return [[self _web_originalDataAsString] _webkit_isJavaScriptURL];}- (NSString *)_webkit_scriptIfJavaScriptURL{ return [[self absoluteString] _webkit_scriptIfJavaScriptURL];}- (BOOL)_webkit_isFileURL{ return [[self _web_originalDataAsString] _webkit_isFileURL];}- (BOOL)_webkit_isFTPDirectoryURL{ return [[self _web_originalDataAsString] _webkit_isFTPDirectoryURL];}- (BOOL)_webkit_shouldLoadAsEmptyDocument{ return [[self _web_originalDataAsString] _webkit_hasCaseInsensitivePrefix:@"about:"] || [self _web_isEmpty];}- (NSURL *)_web_URLWithLowercasedScheme{ CFRange range; CFURLGetByteRangeForComponent((CFURLRef)self, kCFURLComponentScheme, &range); if (range.location == kCFNotFound) { return self; } UInt8 static_buffer[URL_BYTES_BUFFER_LENGTH]; UInt8 *buffer = static_buffer; CFIndex bytesFilled = CFURLGetBytes((CFURLRef)self, buffer, URL_BYTES_BUFFER_LENGTH); if (bytesFilled == -1) { CFIndex bytesToAllocate = CFURLGetBytes((CFURLRef)self, NULL, 0); buffer = static_cast<UInt8 *>(malloc(bytesToAllocate)); bytesFilled = CFURLGetBytes((CFURLRef)self, buffer, bytesToAllocate); ASSERT(bytesFilled == bytesToAllocate); } int i; BOOL changed = NO; for (i = 0; i < range.length; ++i) { char c = buffer[range.location + i]; char lower = toASCIILower(c); if (c != lower) { buffer[range.location + i] = lower; changed = YES; } } NSURL *result = changed ? (NSURL *)WebCFAutorelease(CFURLCreateAbsoluteURLWithBytes(NULL, buffer, bytesFilled, kCFStringEncodingUTF8, nil, YES)) : (NSURL *)self; if (buffer != static_buffer) { free(buffer); } return result;}-(BOOL)_web_hasQuestionMarkOnlyQueryString{ CFRange rangeWithSeparators; CFURLGetByteRangeForComponent((CFURLRef)self, kCFURLComponentQuery, &rangeWithSeparators); if (rangeWithSeparators.location != kCFNotFound && rangeWithSeparators.length == 1) { return YES; } return NO;}-(NSData *)_web_schemeSeparatorWithoutColon{ NSData *result = nil; CFRange rangeWithSeparators; CFRange range = CFURLGetByteRangeForComponent((CFURLRef)self, kCFURLComponentScheme, &rangeWithSeparators); if (rangeWithSeparators.location != kCFNotFound) { NSString *absoluteString = [self absoluteString]; NSRange separatorsRange = NSMakeRange(range.location + range.length + 1, rangeWithSeparators.length - range.length - 1); if (separatorsRange.location + separatorsRange.length <= [absoluteString length]) { NSString *slashes = [absoluteString substringWithRange:separatorsRange]; result = [slashes dataUsingEncoding:NSISOLatin1StringEncoding]; } } return result;}#define completeURL (CFURLComponentType)-1-(NSData *)_web_dataForURLComponentType:(CFURLComponentType)componentType{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -