summaryrefslogtreecommitdiffstats
path: root/WebKitTools/DumpRenderTree
diff options
context:
space:
mode:
authorLeon Clarke <leonclarke@google.com>2010-06-03 14:33:32 +0100
committerLeon Clarke <leonclarke@google.com>2010-06-08 12:24:51 +0100
commit5af96e2c7b73ebc627c6894727826a7576d31758 (patch)
treef9d5e6f6175ccd7e3d14de9b290f08937a0d17ba /WebKitTools/DumpRenderTree
parent8cc4fcf4f6adcbc0e0aebfc24fbad9a4cddf2cfb (diff)
downloadexternal_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')
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.gypi2
-rw-r--r--WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp50
-rw-r--r--WebKitTools/DumpRenderTree/chromium/LayoutTestHelperWin.cpp84
-rw-r--r--WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp14
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestEventPrinter.cpp167
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestEventPrinter.h43
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShell.cpp58
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShell.h15
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp123
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp12
-rw-r--r--WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp5
-rw-r--r--WebKitTools/DumpRenderTree/chromium/fonts.conf155
-rw-r--r--WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp1
-rw-r--r--WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm263
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp27
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h3
-rw-r--r--WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp24
-rw-r--r--WebKitTools/DumpRenderTree/qt/EventSenderQt.h4
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp12
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h1
-rw-r--r--WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp2
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
}