diff options
author | Leon Clarke <leonclarke@google.com> | 2010-06-03 14:33:32 +0100 |
---|---|---|
committer | Leon Clarke <leonclarke@google.com> | 2010-06-08 12:24:51 +0100 |
commit | 5af96e2c7b73ebc627c6894727826a7576d31758 (patch) | |
tree | f9d5e6f6175ccd7e3d14de9b290f08937a0d17ba /WebKitTools/DumpRenderTree | |
parent | 8cc4fcf4f6adcbc0e0aebfc24fbad9a4cddf2cfb (diff) | |
download | external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.zip external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.tar.gz external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.tar.bz2 |
Merge webkit.org at r60469 : Initial merge by git.
Change-Id: I66a0047aa2af802f66bb0c7f2a8b02247a596234
Diffstat (limited to 'WebKitTools/DumpRenderTree')
21 files changed, 988 insertions, 77 deletions
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.gypi b/WebKitTools/DumpRenderTree/DumpRenderTree.gypi index 693f02e..280c8dd 100644 --- a/WebKitTools/DumpRenderTree/DumpRenderTree.gypi +++ b/WebKitTools/DumpRenderTree/DumpRenderTree.gypi @@ -20,6 +20,8 @@ 'chromium/NotificationPresenter.cpp', 'chromium/PlainTextController.cpp', 'chromium/PlainTextController.h', + 'chromium/TestEventPrinter.h', + 'chromium/TestEventPrinter.cpp', 'chromium/TestNavigationController.cpp', 'chromium/TestNavigationController.h', 'chromium/TestShell.cpp', diff --git a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp index 8f292ed..b0cff82 100644 --- a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp @@ -45,17 +45,38 @@ static const char optionPixelTests[] = "--pixel-tests"; static const char optionThreaded[] = "--threaded"; static const char optionTree[] = "--tree"; -static void runTest(TestShell& shell, TestParams& params, const string& testName) +static const char optionPixelTestsWithName[] = "--pixel-tests="; +static const char optionTestShell[] = "--test-shell"; + +static void runTest(TestShell& shell, TestParams& params, const string& testName, bool testShellMode) { + int oldTimeoutMsec = shell.layoutTestTimeout(); + params.pixelHash = ""; string pathOrURL = testName; - string::size_type separatorPosition = pathOrURL.find("'"); - if (separatorPosition != string::npos) { - params.pixelHash = pathOrURL.substr(separatorPosition + 1); - pathOrURL.erase(separatorPosition); + if (testShellMode) { + string timeOut; + string::size_type separatorPosition = pathOrURL.find(' '); + if (separatorPosition != string::npos) { + timeOut = pathOrURL.substr(separatorPosition + 1); + pathOrURL.erase(separatorPosition); + separatorPosition = timeOut.find_first_of(' '); + if (separatorPosition != string::npos) { + params.pixelHash = timeOut.substr(separatorPosition + 1); + timeOut.erase(separatorPosition); + } + shell.setLayoutTestTimeout(atoi(timeOut.c_str())); + } + } else { + string::size_type separatorPosition = pathOrURL.find("'"); + if (separatorPosition != string::npos) { + params.pixelHash = pathOrURL.substr(separatorPosition + 1); + pathOrURL.erase(separatorPosition); + } } params.testUrl = webkit_support::CreateURLForPathOrURL(pathOrURL); shell.resetTestController(); shell.runFileTest(params); + shell.setLayoutTestTimeout(oldTimeoutMsec); } int main(int argc, char* argv[]) @@ -66,6 +87,7 @@ int main(int argc, char* argv[]) TestParams params; Vector<string> tests; bool serverMode = false; + bool testShellMode = false; for (int i = 1; i < argc; ++i) { string argument(argv[i]); if (argument == "-") @@ -74,14 +96,24 @@ int main(int argc, char* argv[]) params.dumpTree = false; else if (argument == optionPixelTests) params.dumpPixels = true; - else if (argument.size() && argument[0] == '-') + else if (!argument.find(optionPixelTestsWithName)) { + params.dumpPixels = true; + params.pixelFileName = argument.substr(strlen(optionPixelTestsWithName)); + } else if (argument == optionTestShell) { + testShellMode = true; + serverMode = true; + } else if (argument.size() && argument[0] == '-') fprintf(stderr, "Unknown option: %s\n", argv[i]); else tests.append(argument); } + if (testShellMode && params.dumpPixels && params.pixelFileName.empty()) { + fprintf(stderr, "--pixel-tests with --test-shell requires a file name.\n"); + return EXIT_FAILURE; + } { // Explicit scope for the TestShell instance. - TestShell shell; + TestShell shell(testShellMode); if (serverMode && !tests.size()) { params.printSeparators = true; char testString[2048]; // 2048 is the same as the sizes of other platforms. @@ -91,14 +123,14 @@ int main(int argc, char* argv[]) *newLinePosition = '\0'; if (testString[0] == '\0') continue; - runTest(shell, params, testString); + runTest(shell, params, testString, testShellMode); } } else if (!tests.size()) printf("#EOF\n"); else { params.printSeparators = tests.size() > 1; for (unsigned i = 0; i < tests.size(); i++) - runTest(shell, params, tests[i]); + runTest(shell, params, tests[i], testShellMode); } shell.callJSGC(); diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestHelperWin.cpp b/WebKitTools/DumpRenderTree/chromium/LayoutTestHelperWin.cpp new file mode 100644 index 0000000..25efdcd --- /dev/null +++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestHelperWin.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <windows.h> + +static BOOL fontSmoothingEnabled = FALSE; + +static void saveInitialSettings(void) +{ + ::SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0); +} + +// Technically, all we need to do is disable ClearType. However, +// for some reason, the call to SPI_SETFONTSMOOTHINGTYPE doesn't +// seem to work, so we just disable font smoothing all together +// (which works reliably) +static void installLayoutTestSettings(void) +{ + ::SystemParametersInfo(SPI_SETFONTSMOOTHING, FALSE, 0, 0); +} + +static void restoreInitialSettings(void) +{ + ::SystemParametersInfo(SPI_SETFONTSMOOTHING, static_cast<UINT>(fontSmoothingEnabled), 0, 0); +} + +static void simpleSignalHandler(int signalNumber) +{ + // Try to restore the settings and then go down cleanly + restoreInitialSettings(); + exit(128 + signalNumber); +} + +int main(int, char*[]) +{ + // Hooks the ways we might get told to clean up... + signal(SIGINT, simpleSignalHandler); + signal(SIGTERM, simpleSignalHandler); + + saveInitialSettings(); + + installLayoutTestSettings(); + + // Let the script know we're ready + printf("ready\n"); + fflush(stdout); + + // Wait for any key (or signal) + getchar(); + + restoreInitialSettings(); + + return EXIT_SUCCESS; +} diff --git a/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp b/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp index 501b513..86903be 100644 --- a/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp +++ b/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp @@ -52,11 +52,23 @@ void NotificationPresenter::grantPermission(const WebString& origin) // The output from all these methods matches what DumpRenderTree produces. bool NotificationPresenter::show(const WebNotification& notification) { + if (!notification.replaceId().isEmpty()) { + String replaceId(notification.replaceId().data(), notification.replaceId().length()); + if (m_replacements.find(replaceId) != m_replacements.end()) + printf("REPLACING NOTIFICATION %s\n", + m_replacements.find(replaceId)->second.utf8().data()); + + WebString identifier = notification.isHTML() ? + notification.url().spec().utf16() : notification.title(); + m_replacements.set(replaceId, String(identifier.data(), identifier.length())); + } + if (notification.isHTML()) { printf("DESKTOP NOTIFICATION: contents at %s\n", notification.url().spec().data()); } else { - printf("DESKTOP NOTIFICATION: icon %s, title %s, text %s\n", + printf("DESKTOP NOTIFICATION:%s icon %s, title %s, text %s\n", + notification.dir() == "rtl" ? "(RTL)" : "", notification.iconURL().isEmpty() ? "" : notification.iconURL().spec().data(), notification.title().isEmpty() ? "" : diff --git a/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.cpp b/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.cpp new file mode 100644 index 0000000..929656d --- /dev/null +++ b/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "TestEventPrinter.h" + +#include <stdio.h> +#include <stdlib.h> +#include <wtf/Assertions.h> + +class DRTPrinter : public TestEventPrinter { +public: + DRTPrinter() {} + void handleTestHeader(const char* url) const; + void handleTimedOut() const; + void handleTextHeader() const; + void handleTextFooter() const; + void handleImage(const char* actualHash, const char* expectedHash, const unsigned char* imageData, size_t imageSize, const char* fileName) const; + void handleImageFooter() const; + void handleTestFooter(bool dumpedAnything) const; +}; + +class TestShellPrinter : public TestEventPrinter { +public: + TestShellPrinter() {} + void handleTestHeader(const char* url) const; + void handleTimedOut() const; + void handleTextHeader() const; + void handleTextFooter() const; + void handleImage(const char* actualHash, const char* expectedHash, const unsigned char* imageData, size_t imageSize, const char* fileName) const; + void handleImageFooter() const; + void handleTestFooter(bool dumpedAnything) const; +}; + +TestEventPrinter* TestEventPrinter::createDRTPrinter() +{ + return new DRTPrinter; +} + +TestEventPrinter* TestEventPrinter::createTestShellPrinter() +{ + return new TestShellPrinter; +} + +// ---------------------------------------------------------------- + +void DRTPrinter::handleTestHeader(const char*) const +{ +} + +void DRTPrinter::handleTimedOut() const +{ + fprintf(stderr, "FAIL: Timed out waiting for notifyDone to be called\n"); + fprintf(stdout, "FAIL: Timed out waiting for notifyDone to be called\n"); +} + +void DRTPrinter::handleTextHeader() const +{ + printf("Content-Type: text/plain\n"); +} + +void DRTPrinter::handleTextFooter() const +{ + printf("#EOF\n"); +} + +void DRTPrinter::handleImage(const char* actualHash, const char* expectedHash, const unsigned char* imageData, size_t imageSize, const char*) const +{ + ASSERT(actualHash); + printf("\nActualHash: %s\n", actualHash); + if (expectedHash && expectedHash[0]) + printf("\nExpectedHash: %s\n", expectedHash); + if (imageData && imageSize) { + printf("Content-Type: image/png\n"); + printf("Content-Length: %lu\n", imageSize); + if (fwrite(imageData, 1, imageSize, stdout) != imageSize) { + fprintf(stderr, "Short write to stdout.\n"); + exit(1); + } + } +} + +void DRTPrinter::handleImageFooter() const +{ + printf("#EOF\n"); +} + +void DRTPrinter::handleTestFooter(bool) const +{ +} + +// ---------------------------------------------------------------- + +void TestShellPrinter::handleTestHeader(const char* url) const +{ + printf("#URL:%s\n", url); +} + +void TestShellPrinter::handleTimedOut() const +{ + puts("#TEST_TIMED_OUT\n"); +} + +void TestShellPrinter::handleTextHeader() const +{ +} + +void TestShellPrinter::handleTextFooter() const +{ +} + +void TestShellPrinter::handleImage(const char* actualHash, const char*, const unsigned char* imageData, size_t imageSize, const char* fileName) const +{ + ASSERT(actualHash); + if (imageData && imageSize) { + ASSERT(fileName); + FILE* fp = fopen(fileName, "wb"); + if (fp) { + perror(fileName); + exit(EXIT_FAILURE); + } + if (fwrite(imageData, 1, imageSize, fp) != imageSize) { + perror(fileName); + fclose(fp); + exit(EXIT_FAILURE); + } + fclose(fp); + } + printf("#MD5:%s\n", actualHash); +} + +void TestShellPrinter::handleImageFooter() const +{ +} + +void TestShellPrinter::handleTestFooter(bool dumpedAnything) const +{ + if (dumpedAnything) + printf("#EOF\n"); +} diff --git a/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.h b/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.h new file mode 100644 index 0000000..fdbfd02 --- /dev/null +++ b/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +class TestEventPrinter { +public: + static TestEventPrinter* createDRTPrinter(); + static TestEventPrinter* createTestShellPrinter(); + + virtual void handleTestHeader(const char* url) const = 0; + virtual void handleTimedOut() const = 0; + virtual void handleTextHeader() const = 0; + virtual void handleTextFooter() const = 0; + virtual void handleImage(const char* actualHash, const char* expectedHash, const unsigned char* imageData, size_t imageSize, const char* fileName) const = 0; + virtual void handleImageFooter() const = 0; + virtual void handleTestFooter(bool dumpedAnything) const = 0; +}; diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp index 29bd596..761f8d1 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp +++ b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp @@ -75,10 +75,11 @@ static const char fileTestPrefix[] = "(file test):"; static const char dataUrlPattern[] = "data:"; static const string::size_type dataUrlPatternSize = sizeof(dataUrlPattern) - 1; -TestShell::TestShell() +TestShell::TestShell(bool testShellMode) : m_testIsPending(false) , m_testIsPreparing(false) , m_focusedWidget(0) + , m_testShellMode(testShellMode) { WebRuntimeFeatures::enableGeolocation(true); m_accessibilityController.set(new AccessibilityController(this)); @@ -87,6 +88,13 @@ TestShell::TestShell() m_plainTextController.set(new PlainTextController()); m_textInputController.set(new TextInputController(this)); m_notificationPresenter.set(new NotificationPresenter(this)); + m_printer.set(m_testShellMode ? TestEventPrinter::createTestShellPrinter() : TestEventPrinter::createDRTPrinter()); + + // 30 second is the same as the value in Mac DRT. + // If we use a value smaller than the timeout value of + // (new-)run-webkit-tests, (new-)run-webkit-tests misunderstands that a + // timed-out DRT process was crashed. + m_timeout = 30 * 1000; m_webViewHost = createWebView(); m_webView = m_webViewHost->webView(); @@ -174,6 +182,12 @@ void TestShell::resetWebSettings(WebView& webView) settings->setLoadsImagesAutomatically(true); settings->setImagesEnabled(true); + +#if OS(DARWIN) + settings->setEditingBehavior(WebSettings::EditingBehaviorMac); +#else + settings->setEditingBehavior(WebSettings::EditingBehaviorWin); +#endif } void TestShell::runFileTest(const TestParams& params) @@ -186,6 +200,7 @@ void TestShell::runFileTest(const TestParams& params) bool inspectorTestMode = testUrl.find("/inspector/") != string::npos || testUrl.find("\\inspector\\") != string::npos; m_webView->settings()->setDeveloperExtrasEnabled(inspectorTestMode); + m_printer->handleTestHeader(testUrl.c_str()); loadURL(m_params.testUrl); m_testIsPreparing = false; @@ -277,8 +292,7 @@ void TestShell::testFinished() void TestShell::testTimedOut() { - fprintf(stderr, "FAIL: Timed out waiting for notifyDone to be called\n"); - fprintf(stdout, "FAIL: Timed out waiting for notifyDone to be called\n"); + m_printer->handleTimedOut(); testFinished(); } @@ -428,7 +442,7 @@ void TestShell::dump() bool dumpedAnything = false; if (m_params.dumpTree) { dumpedAnything = true; - printf("Content-Type: text/plain\n"); + m_printer->handleTextHeader(); // Text output: the test page can request different types of output // which we handle here. if (!shouldDumpAsText) { @@ -450,7 +464,7 @@ void TestShell::dump() printf("%s", dumpAllBackForwardLists().c_str()); } if (dumpedAnything && m_params.printSeparators) - printf("#EOF\n"); + m_printer->handleTextFooter(); if (m_params.dumpPixels && !shouldDumpAsText) { // Image output: we write the image data to the file given on the @@ -491,14 +505,15 @@ void TestShell::dump() } } - string md5sum = dumpImage(m_webViewHost->canvas(), m_params.pixelHash); + dumpImage(m_webViewHost->canvas()); } - printf("#EOF\n"); // For the image. + m_printer->handleImageFooter(); + m_printer->handleTestFooter(dumpedAnything); fflush(stdout); fflush(stderr); } -string TestShell::dumpImage(skia::PlatformCanvas* canvas, const string& expectedHash) +void TestShell::dumpImage(skia::PlatformCanvas* canvas) const { skia::BitmapPlatformDevice& device = static_cast<skia::BitmapPlatformDevice&>(canvas->getTopPlatformDevice()); @@ -532,13 +547,10 @@ string TestShell::dumpImage(skia::PlatformCanvas* canvas, const string& expected MD5Digest digest; MD5Final(&digest, &ctx); string md5hash = MD5DigestToBase16(digest); - printf("\nActualHash: %s\n", md5hash.c_str()); - if (!expectedHash.empty()) - printf("\nExpectedHash: %s\n", expectedHash.c_str()); // Only encode and dump the png if the hashes don't match. Encoding the image // is really expensive. - if (md5hash.compare(expectedHash)) { + if (md5hash.compare(m_params.pixelHash)) { std::vector<unsigned char> png; gfx::PNGCodec::ColorFormat colorFormat = gfx::PNGCodec::FORMAT_BGRA; gfx::PNGCodec::Encode( @@ -546,14 +558,9 @@ string TestShell::dumpImage(skia::PlatformCanvas* canvas, const string& expected colorFormat, sourceBitmap.width(), sourceBitmap.height(), static_cast<int>(sourceBitmap.rowBytes()), discardTransparency, &png); - printf("Content-Type: image/png\n"); - printf("Content-Length: %lu\n", png.size()); - // Write to disk. - if (fwrite(&png[0], 1, png.size(), stdout) != png.size()) - FATAL("Short write to stdout.\n"); - } - - return md5hash; + m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), &png[0], png.size(), m_params.pixelFileName.c_str()); + } else + m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), 0, 0, m_params.pixelFileName.c_str()); } void TestShell::bindJSObjectsToWindow(WebFrame* frame) @@ -565,15 +572,6 @@ void TestShell::bindJSObjectsToWindow(WebFrame* frame) m_textInputController->bindToJavascript(frame, WebString::fromUTF8("textInputController")); } -int TestShell::layoutTestTimeout() -{ - // 30 second is the same as the value in Mac DRT. - // If we use a value smaller than the timeout value of - // (new-)run-webkit-tests, (new-)run-webkit-tests misunderstands that a - // timed-out DRT process was crashed. - return 30 * 1000; -} - WebViewHost* TestShell::createWebView() { return createNewWindow(WebURL()); @@ -599,6 +597,8 @@ void TestShell::closeWindow(WebViewHost* window) return; } m_windowList.remove(i); + if (window->webWidget() == m_focusedWidget) + m_focusedWidget = 0; window->webWidget()->close(); delete window; } diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.h b/WebKitTools/DumpRenderTree/chromium/TestShell.h index 6dd0198..2b99b3d 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShell.h +++ b/WebKitTools/DumpRenderTree/chromium/TestShell.h @@ -33,6 +33,7 @@ #include "LayoutTestController.h" #include "NotificationPresenter.h" #include "PlainTextController.h" +#include "TestEventPrinter.h" #include "TextInputController.h" #include "WebViewHost.h" #include <string> @@ -58,6 +59,7 @@ struct TestParams { bool dumpPixels; bool printSeparators; WebKit::WebURL testUrl; + // Resultant image file name. Reqruired only if the test_shell mode. std::string pixelFileName; std::string pixelHash; @@ -69,7 +71,7 @@ struct TestParams { class TestShell { public: - TestShell(); + TestShell(bool testShellMode); ~TestShell(); // The main WebView. WebKit::WebView* webView() const { return m_webView; } @@ -79,6 +81,7 @@ public: EventSender* eventSender() const { return m_eventSender.get(); } AccessibilityController* accessibilityController() const { return m_accessibilityController.get(); } NotificationPresenter* notificationPresenter() const { return m_notificationPresenter.get(); } + TestEventPrinter* printer() const { return m_printer.get(); } void bindJSObjectsToWindow(WebKit::WebFrame*); void runFileTest(const TestParams&); @@ -110,8 +113,9 @@ public: #endif // Get the timeout for running a test in milliseconds. - static int layoutTestTimeout(); - static int layoutTestTimeoutForWatchDog() { return layoutTestTimeout() + 1000; } + int layoutTestTimeout() { return m_timeout; } + int layoutTestTimeoutForWatchDog() { return layoutTestTimeout() + 1000; } + void setLayoutTestTimeout(int timeout) { m_timeout = timeout; } WebViewHost* createWebView(); WebViewHost* createNewWindow(const WebKit::WebURL&); @@ -127,13 +131,14 @@ private: static void resetWebSettings(WebKit::WebView&); void dump(); std::string dumpAllBackForwardLists(); - static std::string dumpImage(skia::PlatformCanvas*, const std::string& expectedHash); + void dumpImage(skia::PlatformCanvas*) const; bool m_testIsPending; bool m_testIsPreparing; bool m_isLoading; WebKit::WebView* m_webView; WebKit::WebWidget* m_focusedWidget; + bool m_testShellMode; WebViewHost* m_webViewHost; OwnPtr<AccessibilityController*> m_accessibilityController; OwnPtr<EventSender*> m_eventSender; @@ -141,7 +146,9 @@ private: OwnPtr<PlainTextController*> m_plainTextController; OwnPtr<TextInputController*> m_textInputController; OwnPtr<NotificationPresenter*> m_notificationPresenter; + OwnPtr<TestEventPrinter*> m_printer; TestParams m_params; + int m_timeout; // timeout value in millisecond // List of all windows in this process. // The main window should be put into windowList[0]. diff --git a/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp b/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp index e31ca0a..4f3eefd 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp +++ b/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp @@ -32,6 +32,7 @@ #include "TestShell.h" #include "webkit/support/webkit_support.h" +#include <fontconfig/fontconfig.h> #include <signal.h> static void AlarmHandler(int signatl) @@ -43,6 +44,127 @@ static void AlarmHandler(int signatl) exit(0); } +static void setupFontconfig() +{ + // We wish to make the layout tests reproducable with respect to fonts. Skia + // uses fontconfig to resolve font family names from WebKit into actual font + // files found on the current system. This means that fonts vary based on the + // system and also on the fontconfig configuration. + // + // To avoid this we initialise fontconfig here and install a configuration + // which only knows about a few, select, fonts. + + // We have fontconfig parse a config file from our resources file. This + // sets a number of aliases ("sans"->"Arial" etc), but doesn't include any + // font directories. + FcInit(); + + char drtPath[PATH_MAX + 1]; + int drtPathSize = readlink("/proc/self/exe", drtPath, PATH_MAX); + if (drtPathSize < 0 || drtPathSize > PATH_MAX) { + fputs("Unable to resolve /proc/self/exe.", stderr); + exit(1); + } + drtPath[drtPathSize] = 0; + std::string drtDirPath(drtPath); + size_t lastPathPos = drtDirPath.rfind("/"); + ASSERT(lastPathPos != std::string::npos); + drtDirPath.erase(lastPathPos + 1); + + FcConfig* fontcfg = FcConfigCreate(); + std::string fontconfigPath = drtDirPath + "fonts.conf"; + if (!FcConfigParseAndLoad(fontcfg, reinterpret_cast<const FcChar8*>(fontconfigPath.c_str()), true)) { + fputs("Failed to parse fontconfig config file\n", stderr); + exit(1); + } + + // This is the list of fonts that fontconfig will know about. It + // will try its best to match based only on the fonts here in. The + // paths are where these fonts are found on our Ubuntu boxes. + static const char *const fonts[] = { + "/usr/share/fonts/truetype/kochi/kochi-gothic.ttf", + "/usr/share/fonts/truetype/kochi/kochi-mincho.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Arial_Bold_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Arial_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS_Bold.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Courier_New.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Courier_New_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Georgia.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Georgia_Bold.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Georgia_Bold_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Georgia_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Impact.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Bold.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Bold_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Verdana.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Verdana_Bold.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Verdana_Bold_Italic.ttf", + "/usr/share/fonts/truetype/msttcorefonts/Verdana_Italic.ttf", + // The DejaVuSans font is used by the css2.1 tests. + "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf", + "/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_ta.ttf", + "/usr/share/fonts/truetype/ttf-indic-fonts-core/MuktiNarrow.ttf", + }; + for (size_t i = 0; i < arraysize(fonts); ++i) { + if (access(fonts[i], R_OK)) { + fprintf(stderr, "You are missing %s. Try installing msttcorefonts. Also see " + "http://code.google.com/p/chromium/wiki/LinuxBuildInstructions", + fonts[i]); + exit(1); + } + if (!FcConfigAppFontAddFile(fontcfg, (FcChar8 *) fonts[i])) { + fprintf(stderr, "Failed to load font %s\n", fonts[i]); + exit(1); + } + } + + // We special case these fonts because they're only needed in a + // few layout tests. + static const char* const optionalFonts[] = { + "/usr/share/fonts/truetype/ttf-lucida/LucidaSansRegular.ttf", + + // This font changed paths across Ubuntu releases. + "/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_pa.ttf", + "/usr/share/fonts/truetype/ttf-punjabi-fonts/lohit_pa.ttf", + }; + for (size_t i = 0; i < arraysize(optionalFonts); ++i) { + const char* font = optionalFonts[i]; + if (access(font, R_OK) < 0) { + fprintf(stderr, "You are missing %s. Without this, some layout tests may fail. " + "See http://code.google.com/p/chromium/wiki/LinuxBuildInstructionsPrerequisites " + "for more.\n", font); + } else { + if (!FcConfigAppFontAddFile(fontcfg, (FcChar8 *) font)) { + fprintf(stderr, "Failed to load font %s\n", font); + exit(1); + } + } + } + + // Also load the layout-test-specific "Ahem" font. + std::string ahemPath = drtDirPath + "AHEM____.TTF"; + if (!FcConfigAppFontAddFile(fontcfg, reinterpret_cast<const FcChar8*>(ahemPath.c_str()))) { + fprintf(stderr, "Failed to load font %s\n", ahemPath.c_str()); + exit(1); + } + + if (!FcConfigSetCurrent(fontcfg)) { + fputs("Failed to set the default font configuration\n", stderr); + exit(1); + } +} + void TestShell::waitTestFinished() { ASSERT(!m_testIsPending); @@ -65,4 +187,5 @@ void TestShell::waitTestFinished() void platformInit() { + setupFontconfig(); } diff --git a/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp b/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp index e0e0af1..3884e94 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp +++ b/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp @@ -38,27 +38,23 @@ #include <shlwapi.h> #include <sys/stat.h> -// Default timeout in ms for file page loads when in layout test mode. -const int kDefaultFileTestTimeoutMillisecs = 10 * 1000; -const int kDefaultWatchDogTimeoutMillisecs = kDefaultFileTestTimeoutMillisecs + 1 * 1000; - // Thread main to run for the thread which just tests for timeout. -unsigned int __stdcall watchDogThread(void *arg) +unsigned int __stdcall watchDogThread(void* arg) { // If we're debugging a layout test, don't timeout. if (::IsDebuggerPresent()) - return 0; + return 0; TestShell* shell = static_cast<TestShell*>(arg); // FIXME: Do we need user-specified time settings as with the original // Chromium implementation? - DWORD timeout = static_cast<DWORD>(kDefaultWatchDogTimeoutMillisecs); + DWORD timeout = static_cast<DWORD>(shell->layoutTestTimeoutForWatchDog()); DWORD rv = WaitForSingleObject(shell->finishedEvent(), timeout); if (rv == WAIT_TIMEOUT) { // Print a warning to be caught by the layout-test script. // Note: the layout test driver may or may not recognize // this as a timeout. - puts("#TEST_TIMED_OUT\n"); + puts("\n#TEST_TIMED_OUT\n"); puts("#EOF\n"); fflush(stdout); TerminateProcess(GetCurrentProcess(), 0); diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp index eb44c2a..d3aadc8 100644 --- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp +++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp @@ -531,7 +531,7 @@ WebNotificationPresenter* WebViewHost::notificationPresenter() WebKit::WebGeolocationService* WebViewHost::geolocationService() { if (!m_geolocationServiceMock.get()) - m_geolocationServiceMock.set(new WebGeolocationServiceMock); + m_geolocationServiceMock.set(WebGeolocationServiceMock::createWebGeolocationServiceMock()); return m_geolocationServiceMock.get(); } @@ -1036,6 +1036,7 @@ void WebViewHost::reset() this->~WebViewHost(); new (this) WebViewHost(shell); setWebWidget(widget); + webView()->mainFrame()->clearName(); } void WebViewHost::setSelectTrailingWhitespaceEnabled(bool enabled) @@ -1285,7 +1286,7 @@ void WebViewHost::paintRect(const WebRect& rect) #if PLATFORM(CG) webWidget()->paint(m_canvas->getTopPlatformDevice().GetBitmapContext(), rect); #else - webWidget()->paint(m_canvas.get(), rect); + webWidget()->paint(canvas(), rect); #endif m_isPainting = false; } diff --git a/WebKitTools/DumpRenderTree/chromium/fonts.conf b/WebKitTools/DumpRenderTree/chromium/fonts.conf new file mode 100644 index 0000000..be214c6 --- /dev/null +++ b/WebKitTools/DumpRenderTree/chromium/fonts.conf @@ -0,0 +1,155 @@ +<?xml version="1.0"?> +<!DOCTYPE fontconfig SYSTEM "fonts.dtd"> +<!-- /etc/fonts/fonts.conf file to configure system font access --> +<fontconfig> + <match target="pattern"> + <test qual="any" name="family"> + <string>Times</string> + </test> + <edit name="family" mode="assign"> + <string>Times New Roman</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>sans</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>sans serif</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + </match> + + <!-- Some layout tests specify Helvetica as a family and we need to make sure + that we don't fallback to Times New Roman for them --> + <match target="pattern"> + <test qual="any" name="family"> + <string>Helvetica</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>sans-serif</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>serif</string> + </test> + <edit name="family" mode="assign"> + <string>Times New Roman</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>mono</string> + </test> + <edit name="family" mode="assign"> + <string>Courier New</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>monospace</string> + </test> + <edit name="family" mode="assign"> + <string>Courier New</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>Courier</string> + </test> + <edit name="family" mode="assign"> + <string>Courier New</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>cursive</string> + </test> + <edit name="family" mode="assign"> + <string>Comic Sans MS</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>fantasy</string> + </test> + <edit name="family" mode="assign"> + <string>Impact</string> + </edit> + </match> + + <match target="pattern"> + <test qual="any" name="family"> + <string>Monaco</string> + </test> + <edit name="family" mode="assign"> + <string>Times New Roman</string> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>NonAntiAliasedSans</string> + </test> + <edit name="family" mode="assign"> + <string>Arial</string> + </edit> + <edit name="antialias" mode="assign"> + <bool>false</bool> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>SlightHintedGeorgia</string> + </test> + <edit name="family" mode="assign"> + <string>Georgia</string> + </edit> + <edit name="hintstyle" mode="assign"> + <const>hintslight</const> + </edit> + </match> + + <match target="pattern"> + <test name="family" compare="eq"> + <string>NonHintedSans</string> + </test> + <edit name="family" mode="assign"> + <string>Verdana</string> + </edit> + <!-- These deliberately contradict each other. The 'hinting' preference + should take priority --> + <edit name="hintstyle" mode="assign"> + <const>hintfull</const> + </edit> + <edit name="hinting" mode="assign"> + <bool>false</bool> + </edit> + </match> +</fontconfig> diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp index 273bcdf..02c0abb 100644 --- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -343,6 +343,7 @@ static void resetDefaultsToConsistentValues() "auto-resize-window", TRUE, "enable-java-applet", FALSE, "enable-plugins", TRUE, + "editing-behavior", WEBKIT_EDITING_BEHAVIOR_MAC, NULL); webkit_web_frame_clear_main_frame_name(mainFrame); diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm index a39dabb..3fa9c40 100644 --- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm +++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm @@ -53,6 +53,12 @@ #define NSAccessibilityDropEffectsAttribute @"AXDropEffects" #endif +// If an unsupported attribute is passed in, it will raise an accessibility exception. These are usually caught by the Accessibility Runtime to inform +// the AX client app of the error. However, DRT is the AX client app, so it must catch these exceptions. +#define BEGIN_AX_OBJC_EXCEPTIONS @try { +#define END_AX_OBJC_EXCEPTIONS } @catch(NSException *e) { if (![[e name] isEqualToString:NSAccessibilityException]) @throw; } + + typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context); @interface NSObject (WebKitAccessibilityAdditions) @@ -224,11 +230,11 @@ static NSString* attributesOfElement(id accessibilityObject) // accessibilityAttributeValue: can throw an if an attribute is not returned. // For DumpRenderTree's purpose, we should ignore those exceptions - @try { - id valueObject = [accessibilityObject accessibilityAttributeValue:attribute]; - NSString* value = descriptionOfValue(valueObject, accessibilityObject); - [attributesString appendFormat:@"%@: %@\n", attribute, value]; - } @catch (NSException* e) { } + BEGIN_AX_OBJC_EXCEPTIONS + id valueObject = [accessibilityObject accessibilityAttributeValue:attribute]; + NSString* value = descriptionOfValue(valueObject, accessibilityObject); + [attributesString appendFormat:@"%@: %@\n", attribute, value]; + END_AX_OBJC_EXCEPTIONS } return attributesString; @@ -269,26 +275,34 @@ static JSStringRef descriptionOfElements(Vector<AccessibilityUIElement>& element void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector) { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; convertNSArrayToVector(linkedElements, elementVector); + END_AX_OBJC_EXCEPTIONS } void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>& elementVector) { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"]; convertNSArrayToVector(linkElements, elementVector); + END_AX_OBJC_EXCEPTIONS } void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& elementVector) { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute]; convertNSArrayToVector(children, elementVector); + END_AX_OBJC_EXCEPTIONS } void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned location, unsigned length) { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length]; convertNSArrayToVector(children, elementVector); + END_AX_OBJC_EXCEPTIONS } int AccessibilityUIElement::childrenCount() @@ -325,63 +339,77 @@ AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index) AccessibilityUIElement AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index) { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityOwnsAttribute]; if (index < [objects count]) return [objects objectAtIndex:index]; + END_AX_OBJC_EXCEPTIONS return 0; } AccessibilityUIElement AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index) { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; if (index < [objects count]) return [objects objectAtIndex:index]; + END_AX_OBJC_EXCEPTIONS return 0; } AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index) { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedRowsAttribute]; if (index < [rows count]) return [rows objectAtIndex:index]; + END_AX_OBJC_EXCEPTIONS return 0; } AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index) { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilitySelectedRowsAttribute]; if (index < [rows count]) return [rows objectAtIndex:index]; + END_AX_OBJC_EXCEPTIONS return 0; } AccessibilityUIElement AccessibilityUIElement::titleUIElement() { + BEGIN_AX_OBJC_EXCEPTIONS id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityTitleUIElementAttribute]; if (accessibilityObject) return AccessibilityUIElement(accessibilityObject); + END_AX_OBJC_EXCEPTIONS return 0; } AccessibilityUIElement AccessibilityUIElement::parentElement() { + BEGIN_AX_OBJC_EXCEPTIONS id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityParentAttribute]; if (accessibilityObject) return AccessibilityUIElement(accessibilityObject); + END_AX_OBJC_EXCEPTIONS return 0; } AccessibilityUIElement AccessibilityUIElement::disclosedByRow() { + BEGIN_AX_OBJC_EXCEPTIONS id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedByRowAttribute]; if (accessibilityObject) return AccessibilityUIElement(accessibilityObject); + END_AX_OBJC_EXCEPTIONS return 0; } @@ -415,29 +443,42 @@ JSStringRef AccessibilityUIElement::allAttributes() JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute) { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; - if (![value isKindOfClass:[NSString class]]) - return NULL; - return [value createJSStringRef]; + if ([value isKindOfClass:[NSString class]]) + return [value createJSStringRef]; + END_AX_OBJC_EXCEPTIONS + + return 0; } bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute) { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; - if (![value isKindOfClass:[NSNumber class]]) - return NULL; + if ([value isKindOfClass:[NSNumber class]]) + return [value boolValue]; + END_AX_OBJC_EXCEPTIONS - return [value boolValue]; + return false; } bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute) { + BEGIN_AX_OBJC_EXCEPTIONS return [m_element accessibilityIsAttributeSettable:[NSString stringWithJSStringRef:attribute]]; + END_AX_OBJC_EXCEPTIONS + + return false; } bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute) { + BEGIN_AX_OBJC_EXCEPTIONS return [[m_element accessibilityAttributeNames] containsObject:[NSString stringWithJSStringRef:attribute]]; + END_AX_OBJC_EXCEPTIONS + + return false; } JSStringRef AccessibilityUIElement::parameterizedAttributeNames() @@ -454,169 +495,260 @@ JSStringRef AccessibilityUIElement::parameterizedAttributeNames() JSStringRef AccessibilityUIElement::role() { - NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleAttribute], m_element); + BEGIN_AX_OBJC_EXCEPTIONS + NSString *role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleAttribute], m_element); return concatenateAttributeAndValue(@"AXRole", role); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::subrole() { + BEGIN_AX_OBJC_EXCEPTIONS NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilitySubroleAttribute], m_element); return concatenateAttributeAndValue(@"AXSubrole", role); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::roleDescription() { + BEGIN_AX_OBJC_EXCEPTIONS NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute], m_element); return concatenateAttributeAndValue(@"AXRoleDescription", role); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::title() { + BEGIN_AX_OBJC_EXCEPTIONS NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityTitleAttribute], m_element); return concatenateAttributeAndValue(@"AXTitle", title); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::description() { + BEGIN_AX_OBJC_EXCEPTIONS id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityDescriptionAttribute], m_element); return concatenateAttributeAndValue(@"AXDescription", description); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::orientation() const { + BEGIN_AX_OBJC_EXCEPTIONS id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityOrientationAttribute], m_element); return concatenateAttributeAndValue(@"AXOrientation", description); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::stringValue() { + BEGIN_AX_OBJC_EXCEPTIONS id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityValueAttribute], m_element); return concatenateAttributeAndValue(@"AXValue", description); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::language() { + BEGIN_AX_OBJC_EXCEPTIONS id description = descriptionOfValue([m_element accessibilityAttributeValue:@"AXLanguage"], m_element); return concatenateAttributeAndValue(@"AXLanguage", description); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::helpText() const { + BEGIN_AX_OBJC_EXCEPTIONS id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityHelpAttribute], m_element); return concatenateAttributeAndValue(@"AXHelp", description); + END_AX_OBJC_EXCEPTIONS + + return 0; } double AccessibilityUIElement::x() { + BEGIN_AX_OBJC_EXCEPTIONS NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute]; return static_cast<double>([positionValue pointValue].x); + END_AX_OBJC_EXCEPTIONS + + return 0.0f; } double AccessibilityUIElement::y() { + BEGIN_AX_OBJC_EXCEPTIONS NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute]; return static_cast<double>([positionValue pointValue].y); + END_AX_OBJC_EXCEPTIONS + + return 0.0f; } double AccessibilityUIElement::width() { + BEGIN_AX_OBJC_EXCEPTIONS NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute]; return static_cast<double>([sizeValue sizeValue].width); + END_AX_OBJC_EXCEPTIONS + + return 0.0f; } double AccessibilityUIElement::height() { + BEGIN_AX_OBJC_EXCEPTIONS NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute]; return static_cast<double>([sizeValue sizeValue].height); + END_AX_OBJC_EXCEPTIONS + + return 0.0f; } double AccessibilityUIElement::clickPointX() { + BEGIN_AX_OBJC_EXCEPTIONS NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"]; return static_cast<double>([positionValue pointValue].x); + END_AX_OBJC_EXCEPTIONS + + return 0.0f; } double AccessibilityUIElement::clickPointY() { + BEGIN_AX_OBJC_EXCEPTIONS NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"]; return static_cast<double>([positionValue pointValue].y); + END_AX_OBJC_EXCEPTIONS + + return 0.0f; } double AccessibilityUIElement::intValue() const { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityValueAttribute]; if ([value isKindOfClass:[NSNumber class]]) return [(NSNumber*)value doubleValue]; + END_AX_OBJC_EXCEPTIONS + return 0.0f; } double AccessibilityUIElement::minValue() { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityMinValueAttribute]; if ([value isKindOfClass:[NSNumber class]]) return [(NSNumber*)value doubleValue]; + END_AX_OBJC_EXCEPTIONS + return 0.0f; } double AccessibilityUIElement::maxValue() { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityMaxValueAttribute]; if ([value isKindOfClass:[NSNumber class]]) return [(NSNumber*)value doubleValue]; + END_AX_OBJC_EXCEPTIONS + return 0.0; } JSStringRef AccessibilityUIElement::valueDescription() { + BEGIN_AX_OBJC_EXCEPTIONS NSString* valueDescription = [m_element accessibilityAttributeValue:NSAccessibilityValueDescriptionAttribute]; if ([valueDescription isKindOfClass:[NSString class]]) return [valueDescription createJSStringRef]; + + END_AX_OBJC_EXCEPTIONS return 0; } int AccessibilityUIElement::insertionPointLineNumber() { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityInsertionPointLineNumberAttribute]; if ([value isKindOfClass:[NSNumber class]]) return [(NSNumber *)value intValue]; + END_AX_OBJC_EXCEPTIONS + return -1; } bool AccessibilityUIElement::isActionSupported(JSStringRef action) { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* actions = [m_element accessibilityActionNames]; return [actions containsObject:[NSString stringWithJSStringRef:action]]; + END_AX_OBJC_EXCEPTIONS + + return false; } bool AccessibilityUIElement::isEnabled() { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityEnabledAttribute]; if ([value isKindOfClass:[NSNumber class]]) return [value boolValue]; + END_AX_OBJC_EXCEPTIONS + return false; } bool AccessibilityUIElement::isRequired() const { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:@"AXRequired"]; if ([value isKindOfClass:[NSNumber class]]) return [value boolValue]; + END_AX_OBJC_EXCEPTIONS + return false; } bool AccessibilityUIElement::isSelected() const { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilitySelectedAttribute]; if ([value isKindOfClass:[NSNumber class]]) return [value boolValue]; + END_AX_OBJC_EXCEPTIONS + return false; } bool AccessibilityUIElement::isExpanded() const { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityExpandedAttribute]; if ([value isKindOfClass:[NSNumber class]]) return [value boolValue]; + END_AX_OBJC_EXCEPTIONS + return false; } @@ -628,22 +760,29 @@ bool AccessibilityUIElement::isChecked() const int AccessibilityUIElement::hierarchicalLevel() const { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityDisclosureLevelAttribute]; if ([value isKindOfClass:[NSNumber class]]) return [value intValue]; + END_AX_OBJC_EXCEPTIONS + return 0; } bool AccessibilityUIElement::ariaIsGrabbed() const { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityGrabbedAttribute]; if ([value isKindOfClass:[NSNumber class]]) return [value boolValue]; + END_AX_OBJC_EXCEPTIONS + return false; } JSStringRef AccessibilityUIElement::ariaDropEffects() const { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityDropEffectsAttribute]; if (![value isKindOfClass:[NSArray class]]) return 0; @@ -657,20 +796,27 @@ JSStringRef AccessibilityUIElement::ariaDropEffects() const } return [dropEffects createJSStringRef]; + END_AX_OBJC_EXCEPTIONS + + return 0; } // parameterized attributes int AccessibilityUIElement::lineForIndex(int index) { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:[NSNumber numberWithInt:index]]; if ([value isKindOfClass:[NSNumber class]]) return [(NSNumber *)value intValue]; + END_AX_OBJC_EXCEPTIONS + return -1; } JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length) { NSRange range = NSMakeRange(location, length); + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:NSAccessibilityBoundsForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; NSRect rect = NSMakeRect(0,0,0,0); if ([value isKindOfClass:[NSValue class]]) @@ -679,61 +825,89 @@ JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned l // don't return position information because it is platform dependent NSMutableString* boundsDescription = [NSMutableString stringWithFormat:@"{{%f, %f}, {%f, %f}}",-1.0f,-1.0f,rect.size.width,rect.size.height]; return [boundsDescription createJSStringRef]; + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned length) { NSRange range = NSMakeRange(location, length); + BEGIN_AX_OBJC_EXCEPTIONS id string = [m_element accessibilityAttributeValue:NSAccessibilityStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; if (![string isKindOfClass:[NSString class]]) return 0; return [string createJSStringRef]; + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::attributesOfColumnHeaders() { // not yet defined in AppKit... odd + BEGIN_AX_OBJC_EXCEPTIONS NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"]; Vector<AccessibilityUIElement> columnHeadersVector; convertNSArrayToVector(columnHeadersArray, columnHeadersVector); return descriptionOfElements(columnHeadersVector); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::attributesOfRowHeaders() { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"]; Vector<AccessibilityUIElement> rowHeadersVector; convertNSArrayToVector(rowHeadersArray, rowHeadersVector); return descriptionOfElements(rowHeadersVector); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::attributesOfColumns() { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute]; Vector<AccessibilityUIElement> columnsVector; convertNSArrayToVector(columnsArray, columnsVector); return descriptionOfElements(columnsVector); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::attributesOfRows() { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute]; Vector<AccessibilityUIElement> rowsVector; convertNSArrayToVector(rowsArray, rowsVector); return descriptionOfElements(rowsVector); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::attributesOfVisibleCells() { + BEGIN_AX_OBJC_EXCEPTIONS NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"]; Vector<AccessibilityUIElement> cellsVector; convertNSArrayToVector(cellsArray, cellsVector); return descriptionOfElements(cellsVector); + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::attributesOfHeader() { + BEGIN_AX_OBJC_EXCEPTIONS id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute]; if (!headerObject) return [@"" createJSStringRef]; @@ -741,81 +915,127 @@ JSStringRef AccessibilityUIElement::attributesOfHeader() Vector<AccessibilityUIElement> headerVector; headerVector.append(headerObject); return descriptionOfElements(headerVector); + END_AX_OBJC_EXCEPTIONS + + return 0; } int AccessibilityUIElement::rowCount() { + BEGIN_AX_OBJC_EXCEPTIONS return [m_element accessibilityArrayAttributeCount:NSAccessibilityRowsAttribute]; + END_AX_OBJC_EXCEPTIONS + + return 0; } int AccessibilityUIElement::columnCount() { + BEGIN_AX_OBJC_EXCEPTIONS return [m_element accessibilityArrayAttributeCount:NSAccessibilityColumnsAttribute]; + END_AX_OBJC_EXCEPTIONS + + return 0; } int AccessibilityUIElement::indexInTable() { + BEGIN_AX_OBJC_EXCEPTIONS NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute]; - if (!indexNumber) - return -1; - return [indexNumber intValue]; + if (indexNumber) + return [indexNumber intValue]; + END_AX_OBJC_EXCEPTIONS + + return -1; } JSStringRef AccessibilityUIElement::rowIndexRange() { + NSRange range = NSMakeRange(0,0); + BEGIN_AX_OBJC_EXCEPTIONS NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"]; - NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0); + if (indexRange) + range = [indexRange rangeValue]; NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; return [rangeDescription createJSStringRef]; + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::columnIndexRange() { + NSRange range = NSMakeRange(0,0); + BEGIN_AX_OBJC_EXCEPTIONS NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"]; - NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0); + if (indexRange) + range = [indexRange rangeValue]; NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; return [rangeDescription createJSStringRef]; + END_AX_OBJC_EXCEPTIONS + + return 0; } AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row) { NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil]; + BEGIN_AX_OBJC_EXCEPTIONS return [m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray]; + END_AX_OBJC_EXCEPTIONS + + return 0; } JSStringRef AccessibilityUIElement::selectedTextRange() { + NSRange range = NSMakeRange(0,0); + BEGIN_AX_OBJC_EXCEPTIONS NSNumber *indexRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextRangeAttribute]; - NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0); + if (indexRange) + range = [indexRange rangeValue]; NSMutableString *rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; return [rangeDescription createJSStringRef]; + END_AX_OBJC_EXCEPTIONS + + return 0; } void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length) { NSRange textRange = NSMakeRange(location, length); NSValue *textRangeValue = [NSValue valueWithRange:textRange]; + BEGIN_AX_OBJC_EXCEPTIONS [m_element accessibilitySetValue:textRangeValue forAttribute:NSAccessibilitySelectedTextRangeAttribute]; + END_AX_OBJC_EXCEPTIONS } void AccessibilityUIElement::increment() { + BEGIN_AX_OBJC_EXCEPTIONS [m_element accessibilityPerformAction:NSAccessibilityIncrementAction]; + END_AX_OBJC_EXCEPTIONS } void AccessibilityUIElement::decrement() { + BEGIN_AX_OBJC_EXCEPTIONS [m_element accessibilityPerformAction:NSAccessibilityDecrementAction]; + END_AX_OBJC_EXCEPTIONS } void AccessibilityUIElement::showMenu() { + BEGIN_AX_OBJC_EXCEPTIONS [m_element accessibilityPerformAction:NSAccessibilityShowMenuAction]; + END_AX_OBJC_EXCEPTIONS } void AccessibilityUIElement::press() { + BEGIN_AX_OBJC_EXCEPTIONS [m_element accessibilityPerformAction:NSAccessibilityPressAction]; + END_AX_OBJC_EXCEPTIONS } JSStringRef AccessibilityUIElement::accessibilityValue() const @@ -836,8 +1056,12 @@ JSStringRef AccessibilityUIElement::documentURI() JSStringRef AccessibilityUIElement::url() { + BEGIN_AX_OBJC_EXCEPTIONS NSURL *url = [m_element accessibilityAttributeValue:NSAccessibilityURLAttribute]; return [[url absoluteString] createJSStringRef]; + END_AX_OBJC_EXCEPTIONS + + return nil; } bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback) @@ -896,9 +1120,12 @@ bool AccessibilityUIElement::isCollapsed() const bool AccessibilityUIElement::hasPopup() const { + BEGIN_AX_OBJC_EXCEPTIONS id value = [m_element accessibilityAttributeValue:@"AXHasPopup"]; if ([value isKindOfClass:[NSNumber class]]) return [value boolValue]; + END_AX_OBJC_EXCEPTIONS + return false; } diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp index f119dd0..ba9780b 100644 --- a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp +++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp @@ -130,6 +130,15 @@ public: }; #endif +void checkPermissionCallback(QObject* receiver, const QUrl& url, NotificationPermission& permission) +{ + qobject_cast<DumpRenderTree*>(receiver)->checkPermission(url, permission); +} + +void requestPermissionCallback(QObject* receiver, QWebPage* page, const QString& origin) +{ + qobject_cast<DumpRenderTree*>(receiver)->requestPermission(page, origin); +} WebPage::WebPage(QObject* parent, DumpRenderTree* drt) : QWebPage(parent) @@ -158,6 +167,11 @@ WebPage::WebPage(QObject* parent, DumpRenderTree* drt) setNetworkAccessManager(m_drt->networkAccessManager()); setPluginFactory(new TestPlugin(this)); + + DumpRenderTreeSupportQt::setNotificationsReceiver(this, m_drt); + DumpRenderTreeSupportQt::setCheckPermissionFunction(checkPermissionCallback); + DumpRenderTreeSupportQt::setRequestPermissionFunction(requestPermissionCallback); + } WebPage::~WebPage() @@ -457,6 +471,9 @@ void DumpRenderTree::resetToConsistentStateBeforeTesting() DumpRenderTreeSupportQt::resetOriginAccessWhiteLists(); + // Qt defaults to Windows editing behavior. + DumpRenderTreeSupportQt::setEditingBehavior(m_page, "win"); + QLocale::setDefault(QLocale::c()); setlocale(LC_ALL, ""); } @@ -898,6 +915,16 @@ void DumpRenderTree::switchFocus(bool focused) QApplication::sendEvent(m_mainView, &event); } +void DumpRenderTree::checkPermission(const QUrl& url, NotificationPermission& permission) +{ + permission = m_controller->checkDesktopNotificationPermission(url.scheme() + "://" + url.host()) ? NotificationAllowed : NotificationDenied; +} + +void DumpRenderTree::requestPermission(QWebPage* page, const QString& origin) +{ + DumpRenderTreeSupportQt::allowNotificationForOrigin(page, origin); +} + #if defined(Q_WS_X11) void DumpRenderTree::initializeFonts() { diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h index ad41e3a..3fa4485 100644 --- a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h +++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h @@ -40,6 +40,7 @@ #include <QSslError> #endif +#include "../../../WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h" #include <qwebframe.h> #include <qwebinspector.h> #include <qwebpage.h> @@ -113,6 +114,8 @@ public Q_SLOTS: void dumpDatabaseQuota(QWebFrame* frame, const QString& dbName); void statusBarMessage(const QString& message); void windowCloseRequested(); + void checkPermission(const QUrl&, NotificationPermission&); + void requestPermission(QWebPage* page, const QString&); Q_SIGNALS: void quit(); diff --git a/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp b/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp index 7432052..a548a63 100644 --- a/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp +++ b/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp @@ -70,6 +70,9 @@ EventSender::EventSender(QWebPage* parent) m_currentButton = 0; resetClickCount(); m_page->view()->installEventFilter(this); + // So that we can match Scrollbar::pixelsPerLineStep() in WheelEventQt.cpp and + // pass fast/events/platform-wheelevent-in-scrolling-div.html + QApplication::setWheelScrollLines(2); } void EventSender::mouseDown(int button) @@ -155,6 +158,27 @@ void EventSender::mouseMoveTo(int x, int y) sendOrQueueEvent(event); } +#ifndef QT_NO_WHEELEVENT +void EventSender::mouseScrollBy(int x, int y) +{ + continuousMouseScrollBy((x*120), (y*120)); +} + +void EventSender::continuousMouseScrollBy(int x, int y) +{ + // continuousMouseScrollBy() mimics devices that send fine-grained scroll events where the 'delta' specified is not the usual + // multiple of 120. See http://doc.qt.nokia.com/4.6/qwheelevent.html#delta for a good explanation of this. + if (x) { + QWheelEvent* event = new QWheelEvent(m_mousePos, m_mousePos, x, m_mouseButtons, Qt::NoModifier, Qt::Horizontal); + sendOrQueueEvent(event); + } + if (y) { + QWheelEvent* event = new QWheelEvent(m_mousePos, m_mousePos, y, m_mouseButtons, Qt::NoModifier, Qt::Vertical); + sendOrQueueEvent(event); + } +} +#endif + void EventSender::leapForward(int ms) { eventQueue[endOfQueue].m_delay = ms; diff --git a/WebKitTools/DumpRenderTree/qt/EventSenderQt.h b/WebKitTools/DumpRenderTree/qt/EventSenderQt.h index e824e0f..d5b45ac 100644 --- a/WebKitTools/DumpRenderTree/qt/EventSenderQt.h +++ b/WebKitTools/DumpRenderTree/qt/EventSenderQt.h @@ -57,6 +57,10 @@ public slots: void mouseDown(int button = 0); void mouseUp(int button = 0); void mouseMoveTo(int x, int y); +#ifndef QT_NO_WHEELEVENT + void mouseScrollBy(int x, int y); + void continuousMouseScrollBy(int x, int y); +#endif void leapForward(int ms); void keyDown(const QString& string, const QStringList& modifiers = QStringList(), unsigned int location = 0); void clearKillRing() {} diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp index 9616835..9079be2 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp @@ -64,6 +64,8 @@ void LayoutTestController::reset() m_handleErrorPages = false; m_webHistory = 0; m_globalFlag = false; + m_desktopNotificationAllowedOrigins.clear(); + DumpRenderTreeSupportQt::dumpEditingCallbacks(false); DumpRenderTreeSupportQt::dumpFrameLoader(false); DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(false); @@ -71,6 +73,7 @@ void LayoutTestController::reset() DumpRenderTreeSupportQt::setWillSendRequestReturnsNull(false); DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(QStringList()); setIconDatabaseEnabled(false); + emit hidePage(); } @@ -181,13 +184,12 @@ int LayoutTestController::windowCount() void LayoutTestController::grantDesktopNotificationPermission(const QString& origin) { - // FIXME: Implement for notification security + m_desktopNotificationAllowedOrigins.append(origin); } bool LayoutTestController::checkDesktopNotificationPermission(const QString& origin) { - // FIXME: Implement for notification security - return true; + return m_desktopNotificationAllowedOrigins.contains(origin); } void LayoutTestController::display() @@ -484,7 +486,7 @@ void LayoutTestController::addOriginAccessWhitelistEntry(const QString& sourceOr void LayoutTestController::removeOriginAccessWhitelistEntry(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains) { - // FIXME: Implement. + DumpRenderTreeSupportQt::removeWhiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains); } void LayoutTestController::waitForPolicyDelegate() @@ -640,7 +642,7 @@ void LayoutTestController::setIconDatabaseEnabled(bool enable) void LayoutTestController::setEditingBehavior(const QString& editingBehavior) { - // FIXME: Implement. + DumpRenderTreeSupportQt::setEditingBehavior(m_drt->webPage(), editingBehavior); } const unsigned LayoutTestController::maxViewWidth = 800; diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h index 5fb40b6..d7bb839 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h @@ -218,6 +218,7 @@ private: QWebFrame* m_topLoadingFrame; WebCore::DumpRenderTree* m_drt; QWebHistory* m_webHistory; + QStringList m_desktopNotificationAllowedOrigins; }; #endif // LayoutTestControllerQt_h diff --git a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp index d34e40a..265802d 100644 --- a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp +++ b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp @@ -447,7 +447,7 @@ void LayoutTestController::authenticateSession(JSStringRef, JSStringRef, JSStrin { } -void LayoutTestController::setEditingBehavior(JSStringRef editingBehavior) +void LayoutTestController::setEditingBehavior(const char* editingBehavior) { // FIXME: Implement } |