📄 dumprendertree.mm
字号:
[responseDictionary setObject:allHeaderFields forKey:@"allHeaderFields"]; [allHeaderFields release]; [responseDictionary setObject:[NSNumber numberWithInt:[httpResponse statusCode]] forKey:@"statusCode"]; } [propertyList setObject:responseDictionary forKey:@"WebResourceResponse"]; [responseDictionary release];}static NSInteger compareResourceURLs(id resource1, id resource2, void *context){ NSString *url1 = [resource1 objectForKey:@"WebResourceURL"]; NSString *url2 = [resource2 objectForKey:@"WebResourceURL"]; return [url1 compare:url2];}static NSString *serializeWebArchiveToXML(WebArchive *webArchive){ NSString *errorString; NSMutableDictionary *propertyList = [NSPropertyListSerialization propertyListFromData:[webArchive data] mutabilityOption:NSPropertyListMutableContainersAndLeaves format:NULL errorDescription:&errorString]; if (!propertyList) return errorString; NSMutableArray *resources = [NSMutableArray arrayWithCapacity:1]; [resources addObject:propertyList]; while ([resources count]) { NSMutableDictionary *resourcePropertyList = [resources objectAtIndex:0]; [resources removeObjectAtIndex:0]; NSMutableDictionary *mainResource = [resourcePropertyList objectForKey:@"WebMainResource"]; normalizeWebResourceURL([mainResource objectForKey:@"WebResourceURL"]); convertWebResourceDataToString(mainResource); // Add subframeArchives to list for processing NSMutableArray *subframeArchives = [resourcePropertyList objectForKey:@"WebSubframeArchives"]; // WebSubframeArchivesKey in WebArchive.m if (subframeArchives) [resources addObjectsFromArray:subframeArchives]; NSMutableArray *subresources = [resourcePropertyList objectForKey:@"WebSubresources"]; // WebSubresourcesKey in WebArchive.m NSEnumerator *enumerator = [subresources objectEnumerator]; NSMutableDictionary *subresourcePropertyList; while ((subresourcePropertyList = [enumerator nextObject])) { normalizeWebResourceURL([subresourcePropertyList objectForKey:@"WebResourceURL"]); convertWebResourceResponseToDictionary(subresourcePropertyList); convertWebResourceDataToString(subresourcePropertyList); } // Sort the subresources so they're always in a predictable order for the dump if (NSArray *sortedSubresources = [subresources sortedArrayUsingFunction:compareResourceURLs context:nil]) [resourcePropertyList setObject:sortedSubresources forKey:@"WebSubresources"]; } NSData *xmlData = [NSPropertyListSerialization dataFromPropertyList:propertyList format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorString]; if (!xmlData) return errorString; NSMutableString *string = [[[NSMutableString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding] autorelease]; // Replace "Apple Computer" with "Apple" in the DTD declaration. NSRange range = [string rangeOfString:@"-//Apple Computer//"]; if (range.location != NSNotFound) [string replaceCharactersInRange:range withString:@"-//Apple//"]; return string;}static void dumpBackForwardListForWebView(WebView *view){ printf("\n============== Back Forward List ==============\n"); WebBackForwardList *bfList = [view backForwardList]; // Print out all items in the list after prevTestBFItem, which was from the previous test // Gather items from the end of the list, the print them out from oldest to newest NSMutableArray *itemsToPrint = [[NSMutableArray alloc] init]; for (int i = [bfList forwardListCount]; i > 0; i--) { WebHistoryItem *item = [bfList itemAtIndex:i]; // something is wrong if the item from the last test is in the forward part of the b/f list assert(item != prevTestBFItem); [itemsToPrint addObject:item]; } assert([bfList currentItem] != prevTestBFItem); [itemsToPrint addObject:[bfList currentItem]]; int currentItemIndex = [itemsToPrint count] - 1; for (int i = -1; i >= -[bfList backListCount]; i--) { WebHistoryItem *item = [bfList itemAtIndex:i]; if (item == prevTestBFItem) break; [itemsToPrint addObject:item]; } for (int i = [itemsToPrint count]-1; i >= 0; i--) dumpHistoryItem([itemsToPrint objectAtIndex:i], 8, i == currentItemIndex); [itemsToPrint release]; printf("===============================================\n");}static void sizeWebViewForCurrentTest(){ // W3C SVG tests expect to be 480x360 bool isSVGW3CTest = (gLayoutTestController->testPathOrURL().find("svg/W3C-SVG-1.1") != string::npos); if (isSVGW3CTest) [[mainFrame webView] setFrameSize:NSMakeSize(480, 360)]; else [[mainFrame webView] setFrameSize:NSMakeSize(maxViewWidth, maxViewHeight)];}static const char *methodNameStringForFailedTest(){ const char *errorMessage; if (gLayoutTestController->dumpAsText()) errorMessage = "[documentElement innerText]"; else if (gLayoutTestController->dumpDOMAsWebArchive()) errorMessage = "[[mainFrame DOMDocument] webArchive]"; else if (gLayoutTestController->dumpSourceAsWebArchive()) errorMessage = "[[mainFrame dataSource] webArchive]"; else errorMessage = "[mainFrame renderTreeAsExternalRepresentation]"; return errorMessage;}static void dumpBackForwardListForAllWindows(){ CFArrayRef openWindows = (CFArrayRef)[DumpRenderTreeWindow openWindows]; unsigned count = CFArrayGetCount(openWindows); for (unsigned i = 0; i < count; i++) { NSWindow *window = (NSWindow *)CFArrayGetValueAtIndex(openWindows, i); WebView *webView = [[[window contentView] subviews] objectAtIndex:0]; dumpBackForwardListForWebView(webView); }}static void invalidateAnyPreviousWaitToDumpWatchdog(){ if (waitToDumpWatchdog) { CFRunLoopTimerInvalidate(waitToDumpWatchdog); CFRelease(waitToDumpWatchdog); waitToDumpWatchdog = 0; }}void dump(){ invalidateAnyPreviousWaitToDumpWatchdog(); bool dumpAsText = gLayoutTestController->dumpAsText(); if (dumpTree) { NSString *resultString = nil; NSData *resultData = nil; NSString *resultMimeType = @"text/plain"; dumpAsText |= [[[mainFrame dataSource] _responseMIMEType] isEqualToString:@"text/plain"]; gLayoutTestController->setDumpAsText(dumpAsText); if (gLayoutTestController->dumpAsText()) { resultString = dumpFramesAsText(mainFrame); } else if (gLayoutTestController->dumpAsPDF()) { resultData = dumpFrameAsPDF(mainFrame); resultMimeType = @"application/pdf"; } else if (gLayoutTestController->dumpDOMAsWebArchive()) { WebArchive *webArchive = [[mainFrame DOMDocument] webArchive]; resultString = serializeWebArchiveToXML(webArchive); resultMimeType = @"application/x-webarchive"; } else if (gLayoutTestController->dumpSourceAsWebArchive()) { WebArchive *webArchive = [[mainFrame dataSource] webArchive]; resultString = serializeWebArchiveToXML(webArchive); resultMimeType = @"application/x-webarchive"; } else { sizeWebViewForCurrentTest(); resultString = [mainFrame renderTreeAsExternalRepresentation]; } if (resultString && !resultData) resultData = [resultString dataUsingEncoding:NSUTF8StringEncoding]; printf("Content-Type: %s\n", [resultMimeType UTF8String]); if (resultData) { fwrite([resultData bytes], 1, [resultData length], stdout); if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive()) dumpFrameScrollPosition(mainFrame); if (gLayoutTestController->dumpBackForwardList()) dumpBackForwardListForAllWindows(); } else printf("ERROR: nil result from %s", methodNameStringForFailedTest()); if (printSeparators) { puts("#EOF"); // terminate the content block fputs("#EOF\n", stderr); } } if (dumpPixels && !dumpAsText) dumpWebViewAsPixelsAndCompareWithExpected(gLayoutTestController->expectedPixelHash()); puts("#EOF"); // terminate the (possibly empty) pixels block fflush(stdout); fflush(stderr); done = YES;}static bool shouldLogFrameLoadDelegates(const char *pathOrURL){ return strstr(pathOrURL, "loading/");}static void resetWebViewToConsistentStateBeforeTesting(){ WebView *webView = [mainFrame webView]; [(EditingDelegate *)[webView editingDelegate] setAcceptsEditing:YES]; [webView makeTextStandardSize:nil]; [webView resetPageZoom:nil]; [webView setTabKeyCyclesThroughElements:YES]; [webView setPolicyDelegate:nil]; [webView _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:NO]; [webView _clearMainFrameName]; WebPreferences *preferences = [webView preferences]; [preferences setPrivateBrowsingEnabled:NO]; [preferences setAuthorAndUserStylesEnabled:YES]; [preferences setJavaScriptCanOpenWindowsAutomatically:YES]; [preferences setOfflineWebApplicationCacheEnabled:YES]; [preferences setFullDocumentTeardownEnabled:YES]; [preferences setDeveloperExtrasEnabled:NO]; if (persistentUserStyleSheetLocation) { [preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]]; [preferences setUserStyleSheetEnabled:YES]; } else [preferences setUserStyleSheetEnabled:NO]; [[mainFrame webView] setSmartInsertDeleteEnabled:YES]; [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:NO]; [WebView _setUsesTestModeFocusRingColor:YES];}static void runTest(const string& testPathOrURL){ ASSERT(!testPathOrURL.empty()); // Look for "'" as a separator between the path or URL, and the pixel dump hash that follows. string pathOrURL(testPathOrURL); string expectedPixelHash; size_t separatorPos = pathOrURL.find("'"); if (separatorPos != string::npos) { pathOrURL = string(testPathOrURL, 0, separatorPos); expectedPixelHash = string(testPathOrURL, separatorPos + 1); } NSString *pathOrURLString = [NSString stringWithUTF8String:pathOrURL.c_str()]; if (!pathOrURLString) { fprintf(stderr, "Failed to parse \"%s\" as UTF-8\n", pathOrURL.c_str()); return; } NSURL *url; if ([pathOrURLString hasPrefix:@"http://"] || [pathOrURLString hasPrefix:@"https://"]) url = [NSURL URLWithString:pathOrURLString]; else url = [NSURL fileURLWithPath:pathOrURLString]; if (!url) { fprintf(stderr, "Failed to parse \"%s\" as a URL\n", pathOrURL.c_str()); return; } const string testURL([[url absoluteString] UTF8String]); resetWebViewToConsistentStateBeforeTesting(); gLayoutTestController = new LayoutTestController(testURL, expectedPixelHash); topLoadingFrame = nil; done = NO; gLayoutTestController->setIconDatabaseEnabled(false); if (disallowedURLs) CFSetRemoveAllValues(disallowedURLs); if (shouldLogFrameLoadDelegates(pathOrURL.c_str())) gLayoutTestController->setDumpFrameLoadCallbacks(true); if ([WebHistory optionalSharedHistory]) [WebHistory setOptionalSharedHistory:nil]; lastMousePosition = NSZeroPoint; lastClickPosition = NSZeroPoint; [prevTestBFItem release]; prevTestBFItem = [[[[mainFrame webView] backForwardList] currentItem] retain]; WorkQueue::shared()->clear(); WorkQueue::shared()->setFrozen(false); bool ignoreWebCoreNodeLeaks = shouldIgnoreWebCoreNodeLeaks(testURL); if (ignoreWebCoreNodeLeaks) [WebCoreStatistics startIgnoringWebCoreNodeLeaks]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [mainFrame loadRequest:[NSURLRequest requestWithURL:url]]; [pool release]; while (!done) { pool = [[NSAutoreleasePool alloc] init]; [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]; [pool release]; } pool = [[NSAutoreleasePool alloc] init]; [EventSendingController clearSavedEvents]; [[mainFrame webView] setSelectedDOMRange:nil affinity:NSSelectionAffinityDownstream]; WorkQueue::shared()->clear(); if (gLayoutTestController->closeRemainingWindowsWhenComplete()) { NSArray* array = [DumpRenderTreeWindow openWindows]; unsigned count = [array count]; for (unsigned i = 0; i < count; i++) { NSWindow *window = [array objectAtIndex:i]; // Don't try to close the main window if (window == [[mainFrame webView] window]) continue; WebView *webView = [[[window contentView] subviews] objectAtIndex:0]; [webView close]; [window close]; } } [mainFrame loadHTMLString:@"<html></html>" baseURL:[NSURL URLWithString:@"about:blank"]]; [mainFrame stopLoading]; [pool release]; // We should only have our main window left open when we're done ASSERT(CFArrayGetCount(openWindowsRef) == 1); ASSERT(CFArrayGetValueAtIndex(openWindowsRef, 0) == [[mainFrame webView] window]); gLayoutTestController->deref(); gLayoutTestController = 0; if (ignoreWebCoreNodeLeaks) [WebCoreStatistics stopIgnoringWebCoreNodeLeaks];}void displayWebView(){ NSView *webView = [mainFrame webView]; [webView display]; [webView lockFocus]; [[[NSColor blackColor] colorWithAlphaComponent:0.66] set]; NSRectFillUsingOperation([webView frame], NSCompositeSourceOver); [webView unlockFocus];}@implementation DumpRenderTreeEvent+ (NSPoint)mouseLocation{ return [[[mainFrame webView] window] convertBaseToScreen:lastMousePosition];}@end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -