📄 dumprendertree.cpp
字号:
/* * Copyright (C) 2007 Eric Seidel <eric@webkit.org> * Copyright (C) 2008 Alp Toker <alp@nuanti.com> * Copyright (C) 2009 Jan Alonzo <jmalonzo@gmail.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "DumpRenderTree.h"#include "LayoutTestController.h"#include "WorkQueue.h"#include "WorkQueueItem.h"#include <gtk/gtk.h>#include <webkit/webkit.h>#include <JavaScriptCore/JavaScript.h>#include <wtf/Assertions.h>#include <cassert>#include <getopt.h>#include <stdlib.h>#include <string.h>using namespace std;extern "C" {// This API is not yet public.extern G_CONST_RETURN gchar* webkit_web_history_item_get_target(WebKitWebHistoryItem*);extern gboolean webkit_web_history_item_is_target_item(WebKitWebHistoryItem*);extern GList* webkit_web_history_item_get_children(WebKitWebHistoryItem*);extern GSList* webkit_web_frame_get_children(WebKitWebFrame* frame);extern gchar* webkit_web_frame_get_inner_text(WebKitWebFrame* frame);extern gchar* webkit_web_frame_dump_render_tree(WebKitWebFrame* frame);extern void webkit_web_settings_add_extra_plugin_directory(WebKitWebView* view, const gchar* directory);extern gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame);}volatile bool done;static bool printSeparators;static int dumpPixels;static int dumpTree = 1;LayoutTestController* gLayoutTestController = 0;static WebKitWebView* webView;WebKitWebFrame* mainFrame = 0;WebKitWebFrame* topLoadingFrame = 0;guint waitToDumpWatchdog = 0;// current b/f item at the end of the previous teststatic WebKitWebHistoryItem* prevTestBFItem = NULL;const unsigned maxViewHeight = 600;const unsigned maxViewWidth = 800;const unsigned historyItemIndent = 8;static gchar* autocorrectURL(const gchar* url){ if (strncmp("http://", url, 7) != 0 && strncmp("https://", url, 8) != 0) { GString* string = g_string_new("file://"); g_string_append(string, url); return g_string_free(string, FALSE); } return g_strdup(url);}static bool shouldLogFrameLoadDelegates(const char* pathOrURL){ return strstr(pathOrURL, "loading/");}void dumpFrameScrollPosition(WebKitWebFrame* frame){}void displayWebView(){}static void appendString(gchar*& target, gchar* string){ gchar* oldString = target; target = g_strconcat(target, string, NULL); g_free(oldString);}static gchar* dumpFramesAsText(WebKitWebFrame* frame){ gchar* result = 0; // Add header for all but the main frame. bool isMainFrame = (webkit_web_view_get_main_frame(webView) == frame); gchar* innerText = webkit_web_frame_get_inner_text(frame); if (isMainFrame) result = g_strdup_printf("%s\n", innerText); else { const gchar* frameName = webkit_web_frame_get_name(frame); result = g_strdup_printf("\n--------\nFrame: '%s'\n--------\n%s\n", frameName, innerText); } g_free(innerText); if (gLayoutTestController->dumpChildFramesAsText()) { GSList* children = webkit_web_frame_get_children(frame); for (GSList* child = children; child; child = g_slist_next(child)) appendString(result, dumpFramesAsText((WebKitWebFrame*)children->data)); g_slist_free(children); } return result;}static gint compareHistoryItems(gpointer* item1, gpointer* item2){ return g_ascii_strcasecmp(webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item1)), webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item2)));}static void dumpHistoryItem(WebKitWebHistoryItem* item, int indent, bool current){ ASSERT(item != NULL); int start = 0; g_object_ref(item); if (current) { printf("curr->"); start = 6; } for (int i = start; i < indent; i++) putchar(' '); printf("%s", webkit_web_history_item_get_uri(item)); const gchar* target = webkit_web_history_item_get_target(item); if (target && g_utf8_strlen(target, 0) > 0) printf(" (in frame \"%s\")", target); if (webkit_web_history_item_is_target_item(item)) printf(" **nav target**"); putchar('\n'); GList* kids = webkit_web_history_item_get_children(item); if (kids) { // must sort to eliminate arbitrary result ordering which defeats reproducible testing kids = g_list_sort(kids, (GCompareFunc) compareHistoryItems); for (unsigned i = 0; i < g_list_length(kids); i++) dumpHistoryItem(WEBKIT_WEB_HISTORY_ITEM(g_list_nth_data(kids, i)), indent+4, FALSE); } g_object_unref(item);}static void dumpBackForwardListForWebView(WebKitWebView* view){ printf("\n============== Back Forward List ==============\n"); WebKitWebBackForwardList* bfList = webkit_web_view_get_back_forward_list(view); // 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 GList* itemsToPrint = NULL; gint forwardListCount = webkit_web_back_forward_list_get_forward_length(bfList); for (int i = forwardListCount; i > 0; i--) { WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i); // something is wrong if the item from the last test is in the forward part of the b/f list ASSERT(item != prevTestBFItem); g_object_ref(item); itemsToPrint = g_list_append(itemsToPrint, item); } WebKitWebHistoryItem* currentItem = webkit_web_back_forward_list_get_current_item(bfList); g_object_ref(currentItem); itemsToPrint = g_list_append(itemsToPrint, currentItem); gint currentItemIndex = g_list_length(itemsToPrint) - 1; gint backListCount = webkit_web_back_forward_list_get_back_length(bfList); for (int i = -1; i >= -(backListCount); i--) { WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i); if (item == prevTestBFItem) break; g_object_ref(item); itemsToPrint = g_list_append(itemsToPrint, item); } for (int i = g_list_length(itemsToPrint) - 1; i >= 0; i--) { WebKitWebHistoryItem* item = WEBKIT_WEB_HISTORY_ITEM(g_list_nth_data(itemsToPrint, i)); dumpHistoryItem(item, historyItemIndent, i == currentItemIndex); g_object_unref(item); } g_list_free(itemsToPrint); printf("===============================================\n");}static void invalidateAnyPreviousWaitToDumpWatchdog(){ if (waitToDumpWatchdog) { g_source_remove(waitToDumpWatchdog); waitToDumpWatchdog = 0; }}void dump(){ invalidateAnyPreviousWaitToDumpWatchdog(); bool dumpAsText = gLayoutTestController->dumpAsText(); if (dumpTree) { char* result = 0; gchar* responseMimeType = webkit_web_frame_get_response_mime_type(mainFrame); dumpAsText = g_ascii_strcasecmp(responseMimeType, "text/plain"); g_free(responseMimeType); gLayoutTestController->setDumpAsText(dumpAsText); if (gLayoutTestController->dumpAsText()) result = dumpFramesAsText(mainFrame); else result = webkit_web_frame_dump_render_tree(mainFrame); if (!result) { 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]"; printf("ERROR: nil result from %s", errorMessage); } else { printf("%s", result); g_free(result); if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive()) dumpFrameScrollPosition(mainFrame);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -