📄 dumprendertree.cpp
字号:
frame->loadRequest(request.get()); MSG msg; while (GetMessage(&msg, 0, 0, 0)) { // We get spurious WM_MOUSELEAVE events which make event handling machinery think that mouse button // is released during dragging (see e.g. fast\dynamic\layer-hit-test-crash.html). // Mouse can never leave WebView during normal DumpRenderTree operation, so we just ignore all such events. if (msg.message == WM_MOUSELEAVE) continue; TranslateMessage(&msg); DispatchMessage(&msg); } frame->stopLoading(); if (::gLayoutTestController->closeRemainingWindowsWhenComplete()) { Vector<HWND> windows = openWindows(); unsigned size = windows.size(); for (unsigned i = 0; i < size; i++) { HWND window = windows[i]; // Don't try to close the main window if (window == hostWindow) continue; DestroyWindow(window); } }exit: SysFreeString(urlBStr); ::gLayoutTestController->deref(); ::gLayoutTestController = 0; return;}static void initializePreferences(IWebPreferences* preferences){#ifdef USE_MAC_FONTS BSTR standardFamily = SysAllocString(TEXT("Times")); BSTR fixedFamily = SysAllocString(TEXT("Courier")); BSTR sansSerifFamily = SysAllocString(TEXT("Helvetica")); BSTR cursiveFamily = SysAllocString(TEXT("Apple Chancery")); BSTR fantasyFamily = SysAllocString(TEXT("Papyrus"));#else BSTR standardFamily = SysAllocString(TEXT("Times New Roman")); BSTR fixedFamily = SysAllocString(TEXT("Courier New")); BSTR sansSerifFamily = SysAllocString(TEXT("Arial")); BSTR cursiveFamily = SysAllocString(TEXT("Comic Sans MS")); // Not actually cursive, but it's what IE and Firefox use. BSTR fantasyFamily = SysAllocString(TEXT("Times New Roman"));#endif preferences->setStandardFontFamily(standardFamily); preferences->setFixedFontFamily(fixedFamily); preferences->setSerifFontFamily(standardFamily); preferences->setSansSerifFontFamily(sansSerifFamily); preferences->setCursiveFontFamily(cursiveFamily); preferences->setFantasyFontFamily(fantasyFamily); preferences->setAutosaves(FALSE); preferences->setJavaEnabled(FALSE); preferences->setPlugInsEnabled(TRUE); preferences->setDOMPasteAllowed(TRUE); preferences->setEditableLinkBehavior(WebKitEditableLinkOnlyLiveWithShiftKey); preferences->setFontSmoothing(FontSmoothingTypeStandard); preferences->setUsesPageCache(FALSE); SysFreeString(standardFamily); SysFreeString(fixedFamily); SysFreeString(sansSerifFamily); SysFreeString(cursiveFamily); SysFreeString(fantasyFamily);}static Boolean pthreadEqualCallback(const void* value1, const void* value2){ return (Boolean)pthread_equal(*(pthread_t*)value1, *(pthread_t*)value2);}static CFDictionaryKeyCallBacks pthreadKeyCallbacks = { 0, 0, 0, 0, pthreadEqualCallback, 0 };static pthread_mutex_t javaScriptThreadsMutex = PTHREAD_MUTEX_INITIALIZER;static bool javaScriptThreadsShouldTerminate;static const int javaScriptThreadsCount = 4;static CFMutableDictionaryRef javaScriptThreads(){ assert(pthread_mutex_trylock(&javaScriptThreadsMutex) == EBUSY); static CFMutableDictionaryRef staticJavaScriptThreads; if (!staticJavaScriptThreads) staticJavaScriptThreads = CFDictionaryCreateMutable(0, 0, &pthreadKeyCallbacks, 0); return staticJavaScriptThreads;}// Loops forever, running a script and randomly respawning, until // javaScriptThreadsShouldTerminate becomes true.void* runJavaScriptThread(void* arg){ const char* const script = " \ var array = []; \ for (var i = 0; i < 10; i++) { \ array.push(String(i)); \ } \ "; while (true) { JSGlobalContextRef ctx = JSGlobalContextCreate(0); JSStringRef scriptRef = JSStringCreateWithUTF8CString(script); JSValueRef exception = 0; JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception); assert(!exception); JSGlobalContextRelease(ctx); JSStringRelease(scriptRef); JSGarbageCollect(ctx); pthread_mutex_lock(&javaScriptThreadsMutex); // Check for cancellation. if (javaScriptThreadsShouldTerminate) { pthread_mutex_unlock(&javaScriptThreadsMutex); return 0; } // Respawn probabilistically. if (rand() % 5 == 0) { pthread_t pthread; pthread_create(&pthread, 0, &runJavaScriptThread, 0); pthread_detach(pthread); pthread_t self = pthread_self(); CFDictionaryRemoveValue(javaScriptThreads(), self.p); CFDictionaryAddValue(javaScriptThreads(), pthread.p, 0); pthread_mutex_unlock(&javaScriptThreadsMutex); return 0; } pthread_mutex_unlock(&javaScriptThreadsMutex); }}static void startJavaScriptThreads(void){ pthread_mutex_lock(&javaScriptThreadsMutex); for (int i = 0; i < javaScriptThreadsCount; i++) { pthread_t pthread; pthread_create(&pthread, 0, &runJavaScriptThread, 0); pthread_detach(pthread); CFDictionaryAddValue(javaScriptThreads(), pthread.p, 0); } pthread_mutex_unlock(&javaScriptThreadsMutex);}static void stopJavaScriptThreads(void){ pthread_mutex_lock(&javaScriptThreadsMutex); javaScriptThreadsShouldTerminate = true; pthread_t* pthreads[javaScriptThreadsCount] = {0}; int threadDictCount = CFDictionaryGetCount(javaScriptThreads()); assert(threadDictCount == javaScriptThreadsCount); CFDictionaryGetKeysAndValues(javaScriptThreads(), (const void**)pthreads, 0); pthread_mutex_unlock(&javaScriptThreadsMutex); for (int i = 0; i < javaScriptThreadsCount; i++) { pthread_t* pthread = pthreads[i]; pthread_join(*pthread, 0); free(pthread); }}Vector<HWND>& openWindows(){ static Vector<HWND> vector; return vector;}WindowToWebViewMap& windowToWebViewMap(){ static WindowToWebViewMap map; return map;}IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow){ HWND hostWindow = CreateWindowEx(WS_EX_TOOLWINDOW, kDumpRenderTreeClassName, TEXT("DumpRenderTree"), WS_POPUP, -maxViewWidth, -maxViewHeight, maxViewWidth, maxViewHeight, 0, 0, GetModuleHandle(0), 0); IWebView* webView; HRESULT hr = CoCreateInstance(CLSID_WebView, 0, CLSCTX_ALL, IID_IWebView, (void**)&webView); if (FAILED(hr)) { fprintf(stderr, "Failed to create CLSID_WebView instance, error 0x%x\n", hr); return 0; } if (FAILED(webView->setHostWindow((OLE_HANDLE)(ULONG64)hostWindow))) return 0; RECT clientRect; clientRect.bottom = clientRect.left = clientRect.top = clientRect.right = 0; BSTR groupName = SysAllocString(L"org.webkit.DumpRenderTree"); bool failed = FAILED(webView->initWithFrame(clientRect, 0, groupName)); SysFreeString(groupName); if (failed) return 0; COMPtr<IWebViewPrivate> viewPrivate; if (FAILED(webView->QueryInterface(&viewPrivate))) return 0; viewPrivate->setShouldApplyMacFontAscentHack(TRUE); viewPrivate->setAlwaysUsesComplexTextCodePath(forceComplexText); BSTR pluginPath = SysAllocStringLen(0, exePath().length() + _tcslen(TestPluginDir)); _tcscpy(pluginPath, exePath().c_str()); _tcscat(pluginPath, TestPluginDir); failed = FAILED(viewPrivate->addAdditionalPluginDirectory(pluginPath)); SysFreeString(pluginPath); if (failed) return 0; HWND viewWindow; if (FAILED(viewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow)))) return 0; if (webViewWindow) *webViewWindow = viewWindow; SetWindowPos(viewWindow, 0, 0, 0, maxViewWidth, maxViewHeight, 0); ShowWindow(hostWindow, SW_SHOW); if (FAILED(webView->setFrameLoadDelegate(sharedFrameLoadDelegate.get()))) return 0; if (FAILED(viewPrivate->setFrameLoadDelegatePrivate(sharedFrameLoadDelegate.get()))) return 0; if (FAILED(webView->setUIDelegate(sharedUIDelegate.get()))) return 0; COMPtr<IWebViewEditing> viewEditing; if (FAILED(webView->QueryInterface(&viewEditing))) return 0; if (FAILED(viewEditing->setEditingDelegate(sharedEditingDelegate.get()))) return 0; if (FAILED(webView->setResourceLoadDelegate(sharedResourceLoadDelegate.get()))) return 0; COMPtr<IWebPreferences> preferences; if (FAILED(webView->preferences(&preferences))) return 0; initializePreferences(preferences.get()); openWindows().append(hostWindow); windowToWebViewMap().set(hostWindow, webView); return webView;}int main(int argc, char* argv[]){ leakChecking = false; _setmode(1, _O_BINARY); _setmode(2, _O_BINARY); initialize(); Vector<const char*> tests; for (int i = 1; i < argc; ++i) { if (!stricmp(argv[i], "--threaded")) { threaded = true; continue; } if (!stricmp(argv[i], "--dump-all-pixels")) { dumpAllPixels = true; continue; } if (!stricmp(argv[i], "--pixel-tests")) { dumpPixels = true; continue; } if (!stricmp(argv[i], "--complex-text")) { forceComplexText = true; continue; } tests.append(argv[i]); } policyDelegate = new PolicyDelegate(); sharedFrameLoadDelegate.adoptRef(new FrameLoadDelegate); sharedUIDelegate.adoptRef(new UIDelegate); sharedEditingDelegate.adoptRef(new EditingDelegate); sharedResourceLoadDelegate.adoptRef(new ResourceLoadDelegate); COMPtr<IWebView> webView(AdoptCOM, createWebViewAndOffscreenWindow(&webViewWindow)); if (!webView) return -1; COMPtr<IWebIconDatabase> iconDatabase; COMPtr<IWebIconDatabase> tmpIconDatabase; if (FAILED(CoCreateInstance(CLSID_WebIconDatabase, 0, CLSCTX_ALL, IID_IWebIconDatabase, (void**)&tmpIconDatabase))) return -1; if (FAILED(tmpIconDatabase->sharedIconDatabase(&iconDatabase))) return -1; if (FAILED(webView->mainFrame(&frame))) return -1; CFURLCacheRemoveAllCachedResponses(CFURLCacheSharedURLCache());#ifdef _DEBUG _CrtMemState entryToMainMemCheckpoint; if (leakChecking) _CrtMemCheckpoint(&entryToMainMemCheckpoint);#endif if (threaded) startJavaScriptThreads(); if (tests.size() == 1 && !strcmp(tests[0], "-")) { char filenameBuffer[2048]; printSeparators = true; while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) { char* newLineCharacter = strchr(filenameBuffer, '\n'); if (newLineCharacter) *newLineCharacter = '\0'; if (strlen(filenameBuffer) == 0) continue; runTest(filenameBuffer); } } else { printSeparators = tests.size() > 1; for (int i = 0; i < tests.size(); i++) runTest(tests[i]); } if (threaded) stopJavaScriptThreads(); delete policyDelegate; frame->Release();#ifdef _DEBUG if (leakChecking) { // dump leaks to stderr _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); _CrtMemDumpAllObjectsSince(&entryToMainMemCheckpoint); }#endif shutDownWebKit(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -