diff options
author | Steve Block <steveblock@google.com> | 2011-05-25 08:15:24 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-05-25 08:15:24 -0700 |
commit | fa91a01aee5d4a80ca6c80f722116b850f09996c (patch) | |
tree | f72740e60d3c3d4f0ab144e88c03d1f134944ce3 /Tools/DumpRenderTree | |
parent | 96f37d6d1b390f6690858789706ee6ec25bc1677 (diff) | |
parent | feebf8e7a79ad68b04a1a948e2b8078d6e5f0048 (diff) | |
download | external_webkit-fa91a01aee5d4a80ca6c80f722116b850f09996c.zip external_webkit-fa91a01aee5d4a80ca6c80f722116b850f09996c.tar.gz external_webkit-fa91a01aee5d4a80ca6c80f722116b850f09996c.tar.bz2 |
Merge changes I78ff6a85,Ic85c6405,Ibf903baa,I3a0459db,I35140385,I54790419,I6bfe5d24,Ia9f39b83,I5bcecd5a,I1de96683,I543c6810,I8a5b0878,I0ae670bf,Ide4d58dc,I28ebaf3d,I499d6631,Ie5090e0d,I6d3e5f1f
* changes:
Merge WebKit at r78450: Update ThirdPartyProject.prop
Merge WebKit at r78450: Add new Font::canExpandAroundIdeographsInComplexText()
Merge WebKit at r78450: Add new ChromeClient::selectItemAlignmentFollowsMenuWritingDirection()
Merge WebKit at r78450: FrameLoaderClient::didRunInsecureContent() signature changed
Merge WebKit at r78450: HTMLAreaElement::getRect() renamed
Merge WebKit at r78450: FrameLoader::url() removed
Merge WebKit at r78450: HTMLParserQuirks removed
Merge WebKit at r78450: TextRun::padding() renamed
Merge WebKit at r78450: Use new FontMetrics
Merge WebKit at r78450: GraphicsContext current path removed
Merge WebKit at r78450: TransformationMatrix multiply methods renamed and meaning changed
Merge WebKit at r78450: FontCustomPlatformData::fontPlatformData() signature changed
Merge WebKit at r78450: IntRect::bottom()/right() renamed
Merge WebKit at r78450: Fix remaining conflicts
Merge WebKit at r78450: Fix conflicts due to new ENABLE_WEB_ARCHIVE guard
Merge WebKit at r78450: Fix conflicts in media controls
Merge WebKit at r78450: Fix Makefiles
Merge WebKit at r78450: Initial merge by git.
Diffstat (limited to 'Tools/DumpRenderTree')
41 files changed, 817 insertions, 110 deletions
diff --git a/Tools/DumpRenderTree/AccessibilityController.cpp b/Tools/DumpRenderTree/AccessibilityController.cpp index 798389f..4fcd4f5 100644 --- a/Tools/DumpRenderTree/AccessibilityController.cpp +++ b/Tools/DumpRenderTree/AccessibilityController.cpp @@ -77,6 +77,13 @@ static JSValueRef logScrollingStartEventsCallback(JSContextRef ctx, JSObjectRef, return JSValueMakeUndefined(ctx); } +static JSValueRef logAccessibilityEventsCallback(JSContextRef ctx, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*) +{ + AccessibilityController* controller = static_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject)); + controller->setLogAccessibilityEvents(true); + return JSValueMakeUndefined(ctx); +} + static JSValueRef getElementAtPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { int x = 0; @@ -96,6 +103,7 @@ JSClassRef AccessibilityController::getJSClass() { "logFocusEvents", logFocusEventsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "logValueChangeEvents", logValueChangeEventsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "logScrollingStartEvents", logScrollingStartEventsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "logAccessibilityEvents", logAccessibilityEventsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "elementAtPoint", getElementAtPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { 0, 0, 0 } }; @@ -119,4 +127,5 @@ void AccessibilityController::resetToConsistentState() setLogFocusEvents(false); setLogValueChangeEvents(false); setLogScrollingStartEvents(false); + setLogAccessibilityEvents(false); } diff --git a/Tools/DumpRenderTree/AccessibilityController.h b/Tools/DumpRenderTree/AccessibilityController.h index 5a6ca13..462c484 100644 --- a/Tools/DumpRenderTree/AccessibilityController.h +++ b/Tools/DumpRenderTree/AccessibilityController.h @@ -50,6 +50,7 @@ public: void setLogFocusEvents(bool); void setLogValueChangeEvents(bool); void setLogScrollingStartEvents(bool); + void setLogAccessibilityEvents(bool); void resetToConsistentState(); diff --git a/Tools/DumpRenderTree/DumpRenderTree.gypi b/Tools/DumpRenderTree/DumpRenderTree.gypi index b7de580..3c3384d 100644 --- a/Tools/DumpRenderTree/DumpRenderTree.gypi +++ b/Tools/DumpRenderTree/DumpRenderTree.gypi @@ -53,8 +53,12 @@ 'TestNetscapePlugIn/TestObject.cpp', 'TestNetscapePlugIn/TestObject.h', 'TestNetscapePlugIn/Tests/DocumentOpenInDestroyStream.cpp', + 'TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp', + 'TestNetscapePlugIn/Tests/GetUserAgentWithNullNPPFromNPPNew.cpp', 'TestNetscapePlugIn/Tests/NPRuntimeObjectFromDestroyedPlugin.cpp', 'TestNetscapePlugIn/Tests/NPRuntimeRemoveProperty.cpp', + 'TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp', + 'TestNetscapePlugIn/Tests/PassDifferentNPPStruct.cpp', 'TestNetscapePlugIn/Tests/PluginScriptableNPObjectInvokeDefault.cpp', 'TestNetscapePlugIn/main.cpp', ], diff --git a/Tools/DumpRenderTree/LayoutTestController.cpp b/Tools/DumpRenderTree/LayoutTestController.cpp index 1133a88..29eeeb0 100644 --- a/Tools/DumpRenderTree/LayoutTestController.cpp +++ b/Tools/DumpRenderTree/LayoutTestController.cpp @@ -445,6 +445,17 @@ static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JS return JSValueMakeUndefined(context); } +static JSValueRef displayInvalidatedRegionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // Has mac & windows implementation + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + // LayoutTestController::display() only renders the invalidated region so + // we can just use that. + controller->display(); + + return JSValueMakeUndefined(context); +} + static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac implementation @@ -1980,6 +1991,7 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "displayInvalidatedRegion", displayInvalidatedRegionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpApplicationCacheDelegateCallbacks", dumpApplicationCacheDelegateCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, diff --git a/Tools/DumpRenderTree/LayoutTestController.h b/Tools/DumpRenderTree/LayoutTestController.h index b80d805..11558dd 100644 --- a/Tools/DumpRenderTree/LayoutTestController.h +++ b/Tools/DumpRenderTree/LayoutTestController.h @@ -59,6 +59,7 @@ public: void disableImageLoading(); void dispatchPendingLoadRequests(); void display(); + void displayInvalidatedRegion(); void execCommand(JSStringRef name, JSStringRef value); bool findString(JSContextRef, JSStringRef, JSObjectRef optionsArray); bool isCommandEnabled(JSStringRef name); diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp index 45e5ddb..24ee12c 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp @@ -199,6 +199,7 @@ enum { ID_SET_STATUS, ID_RESIZE_TO, ID_NORMALIZE, + ID_INVALIDATE_RECT, NUM_METHOD_IDENTIFIERS }; @@ -239,7 +240,8 @@ static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = { "refCount", "setStatus", "resizeTo", - "normalize" + "normalize", + "invalidateRect" }; static NPUTF8* createCStringFromNPVariant(const NPVariant* variant) @@ -986,6 +988,20 @@ static bool normalizeOverride(PluginObject* obj, const NPVariant* args, uint32_t return true; } +static bool invalidateRect(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) +{ + if (argCount != 4) + return false; + + NPRect rect; + rect.left = static_cast<int>(NPVARIANT_TO_DOUBLE(args[0])); + rect.top = static_cast<int>(NPVARIANT_TO_DOUBLE(args[1])); + rect.right = static_cast<int>(NPVARIANT_TO_DOUBLE(args[2])); + rect.bottom = static_cast<int>(NPVARIANT_TO_DOUBLE(args[3])); + + browser->invalidaterect(obj->npp, &rect); + return true; +} static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result) { @@ -1101,6 +1117,8 @@ static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* a return testResizeTo(plugin, args, argCount, result); if (name == pluginMethodIdentifiers[ID_NORMALIZE]) return normalizeOverride(plugin, args, argCount, result); + if (name == pluginMethodIdentifiers[ID_INVALIDATE_RECT]) + return invalidateRect(plugin, args, argCount, result); return false; } diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp index 703d9d5..0dd9da6 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp @@ -33,11 +33,14 @@ extern NPNetscapeFuncs *browser; PluginTest* PluginTest::create(NPP npp, const string& identifier) { + if (identifier.empty()) + return new PluginTest(npp, identifier); + CreateTestFunction createTestFunction = createTestFunctions()[identifier]; if (createTestFunction) return createTestFunction(npp, identifier); - return new PluginTest(npp, identifier); + return 0; } PluginTest::PluginTest(NPP npp, const string& identifier) diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp index b4b7fa3..7635a09 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp @@ -200,6 +200,9 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc else if (strcasecmp(argn[i], "src") == 0 && strcasecmp(argv[i], "data:application/x-webkit-test-netscape,returnerrorfromnewstream") == 0) obj->returnErrorFromNewStream = TRUE; + else if (strcasecmp(argn[i], "src") == 0 && + strcasecmp(argv[i], "data:application/x-webkit-test-netscape,alertwhenloaded") == 0) + executeScript(obj, "alert('Plugin Loaded!')"); else if (strcasecmp(argn[i], "onSetWindow") == 0 && !obj->onSetWindow) obj->onSetWindow = strdup(argv[i]); else if (strcasecmp(argn[i], "onNew") == 0 && !onNewScript) @@ -256,6 +259,15 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc // When testing evaluate script on mouse-down or key-down, allow event logging to handle events. if (obj->evaluateScriptOnMouseDownOrKeyDown) obj->eventLogging = true; + } else if (!strcasecmp(argn[i], "windowedPlugin")) { + void* windowed = 0; + if (!strcasecmp(argv[i], "false") || !strcasecmp(argv[i], "0")) + windowed = 0; + else if (!strcasecmp(argv[i], "true") || !strcasecmp(argv[i], "1")) + windowed = reinterpret_cast<void*>(1); + else + assert(false); + browser->setvalue(instance, NPPVpluginWindowBool, windowed); } } @@ -271,6 +283,11 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc obj->pluginTest = PluginTest::create(instance, testIdentifier); + if (!obj->pluginTest) { + pluginLog(instance, "NPP_New: Could not find a test named \"%s\", maybe its .cpp file wasn't added to the build system?", testIdentifier.c_str()); + return NPERR_GENERIC_ERROR; + } + #ifdef XP_UNIX // On Unix, plugins only get events if they are windowless. browser->setvalue(instance, NPPVpluginWindowBool, 0); @@ -663,6 +680,19 @@ static int16_t handleEventX11(NPP instance, PluginObject* obj, XEvent* event) } #endif // XP_UNIX +#ifdef XP_WIN +static int16_t handleEventWin(NPP instance, PluginObject* obj, NPEvent* event) +{ + switch (event->event) { + case WM_PAINT: + if (obj->onPaintEvent) + executeScript(obj, obj->onPaintEvent); + return 1; + } + return 0; +} +#endif // XP_WIN + int16_t NPP_HandleEvent(NPP instance, void *event) { PluginObject* obj = static_cast<PluginObject*>(instance->pdata); @@ -677,6 +707,8 @@ int16_t NPP_HandleEvent(NPP instance, void *event) return handleEventCocoa(instance, obj, static_cast<NPCocoaEvent*>(event)); #elif defined(XP_UNIX) return handleEventX11(instance, obj, static_cast<XEvent*>(event)); +#elif defined(XP_WIN) + return handleEventWin(instance, obj, static_cast<NPEvent*>(event)); #else // FIXME: Implement for other platforms. return 0; diff --git a/Tools/DumpRenderTree/chromium/DumpRenderTree.cpp b/Tools/DumpRenderTree/chromium/DumpRenderTree.cpp index bd5075c..7e9010f 100644 --- a/Tools/DumpRenderTree/chromium/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/chromium/DumpRenderTree.cpp @@ -58,6 +58,7 @@ static const char optionEnableAccelerated2DCanvas[] = "--enable-accelerated-2d-c static const char optionStressOpt[] = "--stress-opt"; static const char optionStressDeopt[] = "--stress-deopt"; static const char optionJavaScriptFlags[] = "--js-flags="; +static const char optionNoTimeout[] = "--no-timeout="; static void runTest(TestShell& shell, TestParams& params, const string& testName, bool testShellMode) { @@ -123,6 +124,7 @@ int main(int argc, char* argv[]) bool stressDeopt = false; bool hardwareAcceleratedGL = false; string javaScriptFlags; + bool noTimeout = false; for (int i = 1; i < argc; ++i) { string argument(argv[i]); if (argument == "-") @@ -155,6 +157,8 @@ int main(int argc, char* argv[]) stressDeopt = true; else if (!argument.find(optionJavaScriptFlags)) javaScriptFlags = argument.substr(strlen(optionJavaScriptFlags)); + else if (!argument.find(optionNoTimeout)) + noTimeout = true; else if (argument.size() && argument[0] == '-') fprintf(stderr, "Unknown option: %s\n", argv[i]); else @@ -182,6 +186,10 @@ int main(int argc, char* argv[]) shell.setJavaScriptFlags(javaScriptFlags); shell.setStressOpt(stressOpt); shell.setStressDeopt(stressDeopt); + if (noTimeout) { + // 0x20000000ms is big enough for the purpose to avoid timeout in debugging. + shell.setLayoutTestTimeout(0x20000000); + } if (serverMode && !tests.size()) { params.printSeparators = true; char testString[2048]; // 2048 is the same as the sizes of other platforms. diff --git a/Tools/DumpRenderTree/chromium/ImageDiff.cpp b/Tools/DumpRenderTree/chromium/ImageDiff.cpp index f2875dd..d676430 100644 --- a/Tools/DumpRenderTree/chromium/ImageDiff.cpp +++ b/Tools/DumpRenderTree/chromium/ImageDiff.cpp @@ -88,7 +88,7 @@ public: if (!byteLength) return false; - OwnArrayPtr<unsigned char> source(new unsigned char[byteLength]); + OwnArrayPtr<unsigned char> source = adoptArrayPtr(new unsigned char[byteLength]); if (fread(source.get(), 1, byteLength, stdin) != byteLength) return false; diff --git a/Tools/DumpRenderTree/chromium/LayoutTestController.cpp b/Tools/DumpRenderTree/chromium/LayoutTestController.cpp index 529019b..59537c6 100644 --- a/Tools/DumpRenderTree/chromium/LayoutTestController.cpp +++ b/Tools/DumpRenderTree/chromium/LayoutTestController.cpp @@ -89,6 +89,7 @@ LayoutTestController::LayoutTestController(TestShell* shell) bindMethod("counterValueForElementById", &LayoutTestController::counterValueForElementById); bindMethod("disableImageLoading", &LayoutTestController::disableImageLoading); bindMethod("display", &LayoutTestController::display); + bindMethod("displayInvalidatedRegion", &LayoutTestController::displayInvalidatedRegion); bindMethod("dumpAsText", &LayoutTestController::dumpAsText); bindMethod("dumpBackForwardList", &LayoutTestController::dumpBackForwardList); bindMethod("dumpChildFramesAsText", &LayoutTestController::dumpChildFramesAsText); @@ -106,7 +107,6 @@ LayoutTestController::LayoutTestController(TestShell* shell) bindMethod("evaluateInWebInspector", &LayoutTestController::evaluateInWebInspector); bindMethod("evaluateScriptInIsolatedWorld", &LayoutTestController::evaluateScriptInIsolatedWorld); bindMethod("execCommand", &LayoutTestController::execCommand); - bindMethod("forceRedSelectionColors", &LayoutTestController::forceRedSelectionColors); bindMethod("grantDesktopNotificationPermission", &LayoutTestController::grantDesktopNotificationPermission); bindMethod("isCommandEnabled", &LayoutTestController::isCommandEnabled); bindMethod("layerTreeAsText", &LayoutTestController::layerTreeAsText); @@ -628,9 +628,11 @@ void LayoutTestController::setAlwaysAcceptCookies(const CppArgumentList& argumen result->setNull(); } -void LayoutTestController::setAsynchronousSpellCheckingEnabled(const CppArgumentList&, CppVariant*) +void LayoutTestController::setAsynchronousSpellCheckingEnabled(const CppArgumentList& arguments, CppVariant* result) { - // FIXME: Implement this. + if (arguments.size() > 0 && arguments[0].isBool()) + m_shell->webView()->settings()->setAsynchronousSpellCheckingEnabled(cppVariantToBool(arguments[0])); + result->setNull(); } void LayoutTestController::showWebInspector(const CppArgumentList&, CppVariant* result) @@ -800,11 +802,11 @@ void LayoutTestController::pathToLocalResource(const CppArgumentList& arguments, // We want a temp file. const unsigned tempPrefixLength = 5; size_t bufferSize = MAX_PATH; - OwnArrayPtr<WCHAR> tempPath(new WCHAR[bufferSize]); + OwnArrayPtr<WCHAR> tempPath = adoptArrayPtr(new WCHAR[bufferSize]); DWORD tempLength = ::GetTempPathW(bufferSize, tempPath.get()); if (tempLength + url.length() - tempPrefixLength + 1 > bufferSize) { bufferSize = tempLength + url.length() - tempPrefixLength + 1; - tempPath.set(new WCHAR[bufferSize]); + tempPath = adoptArrayPtr(new WCHAR[bufferSize]); tempLength = GetTempPathW(bufferSize, tempPath.get()); ASSERT(tempLength < bufferSize); } @@ -1083,6 +1085,14 @@ void LayoutTestController::display(const CppArgumentList& arguments, CppVariant* result->setNull(); } +void LayoutTestController::displayInvalidatedRegion(const CppArgumentList& arguments, CppVariant* result) +{ + WebViewHost* host = m_shell->webViewHost(); + host->paintInvalidatedRegion(); + host->displayRepaintMask(); + result->setNull(); +} + void LayoutTestController::testRepaint(const CppArgumentList&, CppVariant* result) { m_testRepaint = true; @@ -1464,12 +1474,6 @@ void LayoutTestController::evaluateInWebInspector(const CppArgumentList& argumen m_shell->drtDevToolsAgent()->evaluateInWebInspector(arguments[0].toInt32(), arguments[1].toString()); } -void LayoutTestController::forceRedSelectionColors(const CppArgumentList& arguments, CppVariant* result) -{ - result->setNull(); - m_shell->webView()->setSelectionColors(0xffee0000, 0xff00ee00, 0xff000000, 0xffc0c0c0); -} - void LayoutTestController::addUserScript(const CppArgumentList& arguments, CppVariant* result) { result->setNull(); diff --git a/Tools/DumpRenderTree/chromium/LayoutTestController.h b/Tools/DumpRenderTree/chromium/LayoutTestController.h index 13d1447..0ef8607 100644 --- a/Tools/DumpRenderTree/chromium/LayoutTestController.h +++ b/Tools/DumpRenderTree/chromium/LayoutTestController.h @@ -250,6 +250,7 @@ public: void dumpTitleChanges(const CppArgumentList&, CppVariant*); void setMainFrameIsFirstResponder(const CppArgumentList&, CppVariant*); void display(const CppArgumentList&, CppVariant*); + void displayInvalidatedRegion(const CppArgumentList&, CppVariant*); void testRepaint(const CppArgumentList&, CppVariant*); void repaintSweepHorizontally(const CppArgumentList&, CppVariant*); void clearBackForwardList(const CppArgumentList&, CppVariant*); @@ -311,9 +312,6 @@ public: // Allows layout tests to exec scripts at WebInspector side. void evaluateInWebInspector(const CppArgumentList&, CppVariant*); - // Forces the selection colors for testing under Linux. - void forceRedSelectionColors(const CppArgumentList&, CppVariant*); - // Adds a user script or user style sheet to be injected into new documents. void addUserScript(const CppArgumentList&, CppVariant*); void addUserStyleSheet(const CppArgumentList&, CppVariant*); diff --git a/Tools/DumpRenderTree/chromium/NotificationPresenter.cpp b/Tools/DumpRenderTree/chromium/NotificationPresenter.cpp index 7e7053b..63a70e4 100644 --- a/Tools/DumpRenderTree/chromium/NotificationPresenter.cpp +++ b/Tools/DumpRenderTree/chromium/NotificationPresenter.cpp @@ -95,7 +95,7 @@ bool NotificationPresenter::show(const WebNotification& notification) notification.url().spec().data()); } else { printf("DESKTOP NOTIFICATION:%s icon %s, title %s, text %s\n", - notification.dir() == "rtl" ? "(RTL)" : "", + notification.direction() == WebTextDirectionRightToLeft ? "(RTL)" : "", notification.iconURL().isEmpty() ? "" : notification.iconURL().spec().data(), notification.title().isEmpty() ? "" : diff --git a/Tools/DumpRenderTree/chromium/TestShell.cpp b/Tools/DumpRenderTree/chromium/TestShell.cpp index ec6a502..11a598f 100644 --- a/Tools/DumpRenderTree/chromium/TestShell.cpp +++ b/Tools/DumpRenderTree/chromium/TestShell.cpp @@ -93,6 +93,7 @@ TestShell::TestShell(bool testShellMode) WebRuntimeFeatures::enableGeolocation(true); WebRuntimeFeatures::enableIndexedDatabase(true); WebRuntimeFeatures::enableFileSystem(true); + WebRuntimeFeatures::enableJavaScriptI18NAPI(true); m_accessibilityController.set(new AccessibilityController(this)); m_layoutTestController.set(new LayoutTestController(this)); m_eventSender.set(new EventSender(this)); diff --git a/Tools/DumpRenderTree/chromium/WebViewHost.cpp b/Tools/DumpRenderTree/chromium/WebViewHost.cpp index 18b107f..e1a2fcb 100644 --- a/Tools/DumpRenderTree/chromium/WebViewHost.cpp +++ b/Tools/DumpRenderTree/chromium/WebViewHost.cpp @@ -52,6 +52,8 @@ #include "WebSize.h" #include "WebSpeechInputControllerMock.h" #include "WebStorageNamespace.h" +#include "WebTextCheckingCompletion.h" +#include "WebTextCheckingResult.h" #include "WebURLRequest.h" #include "WebURLResponse.h" #include "WebView.h" @@ -60,6 +62,7 @@ #include "webkit/support/webkit_support.h" #include <wtf/Assertions.h> #include <wtf/PassOwnPtr.h> +#include <wtf/Vector.h> using namespace WebCore; using namespace WebKit; @@ -225,6 +228,12 @@ static string textAffinityDescription(WebTextAffinity affinity) return "(UNKNOWN AFFINITY)"; } +static void invokeFinishLastTextCheck(void* context) +{ + WebViewHost* wvh = static_cast<WebViewHost*>(context); + wvh->finishLastTextCheck(); +} + // WebViewClient ------------------------------------------------------------- WebView* WebViewHost::createView(WebFrame*, const WebURLRequest&, const WebWindowFeatures&, const WebString&) @@ -409,6 +418,35 @@ void WebViewHost::spellCheck(const WebString& text, int& misspelledOffset, int& m_spellcheck.spellCheckWord(text, &misspelledOffset, &misspelledLength); } +void WebViewHost::requestCheckingOfText(const WebString& text, WebTextCheckingCompletion* completion) +{ + m_lastRequestedTextCheckingCompletion = completion; + m_lastRequestedTextCheckString = text; + webkit_support::PostDelayedTask(invokeFinishLastTextCheck, static_cast<void*>(this), 0); +} + +void WebViewHost::finishLastTextCheck() +{ + Vector<WebTextCheckingResult> results; + // FIXME: Do the grammar check. + int offset = 0; + String text(m_lastRequestedTextCheckString.data(), m_lastRequestedTextCheckString.length()); + while (text.length()) { + int misspelledPosition = 0; + int misspelledLength = 0; + m_spellcheck.spellCheckWord(WebString(text.characters(), text.length()), &misspelledPosition, &misspelledLength); + if (!misspelledLength) + break; + results.append(WebTextCheckingResult(WebTextCheckingResult::ErrorSpelling, offset + misspelledPosition, misspelledLength)); + text = text.substring(misspelledPosition + misspelledLength); + offset += misspelledPosition; + } + + m_lastRequestedTextCheckingCompletion->didFinishCheckingText(results); + m_lastRequestedTextCheckingCompletion = 0; +} + + WebString WebViewHost::autoCorrectWord(const WebString&) { // Returns an empty string as Mac WebKit ('WebKitSupport/WebEditorClient.mm') @@ -1094,7 +1132,7 @@ void WebViewHost::didDisplayInsecureContent(WebFrame*) fputs("didDisplayInsecureContent\n", stdout); } -void WebViewHost::didRunInsecureContent(WebFrame*, const WebSecurityOrigin& origin) +void WebViewHost::didRunInsecureContent(WebFrame*, const WebSecurityOrigin& origin, const WebURL& insecureURL) { if (m_shell->shouldDumpFrameLoadCallbacks()) fputs("didRunInsecureContent\n", stdout); @@ -1115,6 +1153,7 @@ void WebViewHost::openFileSystem(WebFrame* frame, WebFileSystem::Type type, long WebViewHost::WebViewHost(TestShell* shell) : m_shell(shell) , m_webWidget(0) + , m_lastRequestedTextCheckingCompletion(0) { reset(); } diff --git a/Tools/DumpRenderTree/chromium/WebViewHost.h b/Tools/DumpRenderTree/chromium/WebViewHost.h index 83d21dc..e6d82ae 100644 --- a/Tools/DumpRenderTree/chromium/WebViewHost.h +++ b/Tools/DumpRenderTree/chromium/WebViewHost.h @@ -126,6 +126,7 @@ class WebViewHost : public WebKit::WebViewClient, public WebKit::WebFrameClient, virtual void didEndEditing(); virtual bool handleCurrentKeyboardEvent(); virtual void spellCheck(const WebKit::WebString&, int& offset, int& length); + virtual void requestCheckingOfText(const WebKit::WebString&, WebKit::WebTextCheckingCompletion*); virtual WebKit::WebString autoCorrectWord(const WebKit::WebString&); virtual void runModalAlertDialog(WebKit::WebFrame*, const WebKit::WebString&); virtual bool runModalConfirmDialog(WebKit::WebFrame*, const WebKit::WebString&); @@ -202,12 +203,15 @@ class WebViewHost : public WebKit::WebViewClient, public WebKit::WebFrameClient, virtual void didFinishResourceLoad(WebKit::WebFrame*, unsigned identifier); virtual void didFailResourceLoad(WebKit::WebFrame*, unsigned identifier, const WebKit::WebURLError&); virtual void didDisplayInsecureContent(WebKit::WebFrame*); - virtual void didRunInsecureContent(WebKit::WebFrame*, const WebKit::WebSecurityOrigin&); + virtual void didRunInsecureContent(WebKit::WebFrame*, const WebKit::WebSecurityOrigin&, const WebKit::WebURL&); virtual bool allowScript(WebKit::WebFrame*, bool enabledPerSettings); virtual void openFileSystem(WebKit::WebFrame*, WebKit::WebFileSystem::Type, long long size, bool create, WebKit::WebFileSystemCallbacks*); WebKit::WebDeviceOrientationClientMock* deviceOrientationClientMock(); + + // Spellcheck related helper APIs MockSpellCheck* mockSpellCheck(); + void finishLastTextCheck(); // Geolocation client mocks for LayoutTestController WebKit::WebGeolocationClientMock* geolocationClientMock(); @@ -320,6 +324,9 @@ private: OwnPtr<WebKit::WebSpeechInputControllerMock> m_speechInputControllerMock; OwnPtr<TestNavigationController*> m_navigationController; + + WebKit::WebString m_lastRequestedTextCheckString; + WebKit::WebTextCheckingCompletion* m_lastRequestedTextCheckingCompletion; }; #endif // WebViewHost_h diff --git a/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.cpp b/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.cpp new file mode 100644 index 0000000..be66513 --- /dev/null +++ b/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AccessibilityCallbacks.h" + +#include "AccessibilityController.h" +#include "DumpRenderTree.h" +#include "GOwnPtr.h" +#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +static guint stateChangeListenerId = 0; +static guint focusEventListenerId = 0; +static guint activeDescendantChangedListenerId = 0; +static guint childrenChangedListenerId = 0; +static guint propertyChangedListenerId = 0; +static guint visibleDataChangedListenerId = 0; + +static guint loadCompleteListenerId = 0; +static guint loadStoppedListenerId = 0; +static guint reloadListenerId = 0; + +static void printAccessibilityEvent(AtkObject* accessible, const gchar* signalName) +{ + // Sanity check. + if (!accessible || !ATK_IS_OBJECT(accessible) || !signalName) + return; + + const gchar* objectName = atk_object_get_name(accessible); + guint objectRole = atk_object_get_role(accessible); + + // Try to always provide a name to be logged for the object. + if (!objectName || *objectName == '\0') + objectName = "(No name)"; + + printf("Accessibility object emitted \"%s\" / Name: \"%s\" / Role: %d\n", + signalName, objectName, objectRole); +} + +static gboolean axObjectEventListener(GSignalInvocationHint *signalHint, + guint numParamValues, + const GValue *paramValues, + gpointer data) +{ + // At least we should receive the instance emitting the signal. + if (numParamValues < 1) + return TRUE; + + AtkObject* accessible = ATK_OBJECT(g_value_get_object(¶mValues[0])); + if (!accessible || !ATK_IS_OBJECT(accessible)) + return TRUE; + + GSignalQuery signal_query; + GOwnPtr<gchar> signalName; + + g_signal_query(signalHint->signal_id, &signal_query); + + if (!g_strcmp0(signal_query.signal_name, "state-change")) { + signalName.set(g_strdup_printf("state-change:%s = %d", + g_value_get_string(¶mValues[1]), + g_value_get_boolean(¶mValues[2]))); + } else if (!g_strcmp0(signal_query.signal_name, "focus-event")) { + signalName.set(g_strdup_printf("focus-event = %d", + g_value_get_boolean(¶mValues[1]))); + } else if (!g_strcmp0(signal_query.signal_name, "children-changed")) { + signalName.set(g_strdup_printf("children-changed = %d", + g_value_get_uint(¶mValues[1]))); + } else + signalName.set(g_strdup(signal_query.signal_name)); + + printAccessibilityEvent(accessible, signalName.get()); + + return TRUE; +} + +static gboolean axDocumentEventListener(GSignalInvocationHint *signalHint, + guint numParamValues, + const GValue *paramValues, + gpointer data) +{ + // At least we should receive the instance emitting the signal. + if (numParamValues < 1) + return TRUE; + + AtkObject* accessible = ATK_OBJECT(g_value_get_object(¶mValues[0])); + if (!accessible || !ATK_IS_DOCUMENT(accessible)) + return TRUE; + + GSignalQuery signal_query; + g_signal_query(signalHint->signal_id, &signal_query); + + printAccessibilityEvent(accessible, signal_query.signal_name); + + return TRUE; +} + +void connectAccessibilityCallbacks() +{ + // Ensure no callbacks are connected before. + disconnectAccessibilityCallbacks(); + + // Ensure that accessibility is initialized for the WebView by querying for + // the root accessible object, which will create the full hierarchy. + DumpRenderTreeSupportGtk::getRootAccessibleElement(mainFrame); + + // Add global listeners for AtkObject's signals. + stateChangeListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:state-change"); + focusEventListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:focus-event"); + activeDescendantChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:active-descendant-changed"); + childrenChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:children-changed"); + propertyChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:property-change"); + visibleDataChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:visible-data-changed"); + + // Ensure the Atk interface types are registered, otherwise + // the AtkDocument signal handlers below won't get registered. + GObject* dummyAxObject = G_OBJECT(g_object_new(ATK_TYPE_OBJECT, 0)); + AtkObject* dummyNoOpAxObject = atk_no_op_object_new(dummyAxObject); + g_object_unref(G_OBJECT(dummyNoOpAxObject)); + g_object_unref(dummyAxObject); + + // Add global listeners for AtkDocument's signals. + loadCompleteListenerId = atk_add_global_event_listener(axDocumentEventListener, "Gtk:AtkDocument:load-complete"); + loadStoppedListenerId = atk_add_global_event_listener(axDocumentEventListener, "Gtk:AtkDocument:load-stopped"); + reloadListenerId = atk_add_global_event_listener(axDocumentEventListener, "Gtk:AtkDocument:reload"); +} + +void disconnectAccessibilityCallbacks() +{ + // AtkObject signals. + if (stateChangeListenerId) { + atk_remove_global_event_listener(stateChangeListenerId); + stateChangeListenerId = 0; + } + if (focusEventListenerId) { + atk_remove_global_event_listener(focusEventListenerId); + focusEventListenerId = 0; + } + if (activeDescendantChangedListenerId) { + atk_remove_global_event_listener(activeDescendantChangedListenerId); + activeDescendantChangedListenerId = 0; + } + if (childrenChangedListenerId) { + atk_remove_global_event_listener(childrenChangedListenerId); + childrenChangedListenerId = 0; + } + if (propertyChangedListenerId) { + atk_remove_global_event_listener(propertyChangedListenerId); + propertyChangedListenerId = 0; + } + if (visibleDataChangedListenerId) { + atk_remove_global_event_listener(visibleDataChangedListenerId); + visibleDataChangedListenerId = 0; + } + + // AtkDocument signals. + if (loadCompleteListenerId) { + atk_remove_global_event_listener(loadCompleteListenerId); + loadCompleteListenerId = 0; + } + if (loadStoppedListenerId) { + atk_remove_global_event_listener(loadStoppedListenerId); + loadStoppedListenerId = 0; + } + if (reloadListenerId) { + atk_remove_global_event_listener(reloadListenerId); + reloadListenerId = 0; + } +} + diff --git a/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.h b/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.h new file mode 100644 index 0000000..7225757 --- /dev/null +++ b/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef AccessibilityCallbacks_h +#define AccessibilityCallbacks_h + +void connectAccessibilityCallbacks(); +void disconnectAccessibilityCallbacks(); + +#endif diff --git a/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp b/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp index c572633..da70efc 100644 --- a/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp +++ b/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp @@ -27,6 +27,7 @@ #include "config.h" #include "AccessibilityController.h" +#include "AccessibilityCallbacks.h" #include "AccessibilityUIElement.h" #include "DumpRenderTree.h" #include "WebCoreSupport/DumpRenderTreeSupportGtk.h" @@ -35,6 +36,8 @@ #include <gtk/gtk.h> #include <webkit/webkit.h> +static bool loggingAccessibilityEvents = false; + AccessibilityController::AccessibilityController() { } @@ -79,6 +82,21 @@ void AccessibilityController::setLogValueChangeEvents(bool) { } +void AccessibilityController::setLogAccessibilityEvents(bool logAccessibilityEvents) +{ + if (logAccessibilityEvents == loggingAccessibilityEvents) + return; + + if (!logAccessibilityEvents) { + disconnectAccessibilityCallbacks(); + loggingAccessibilityEvents = false; + return; + } + + connectAccessibilityCallbacks(); + loggingAccessibilityEvents = true; +} + void AccessibilityController::addNotificationListener(PlatformUIElement, JSObjectRef) { } diff --git a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp index ff90d81..ff3327f 100644 --- a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -39,6 +39,7 @@ #include "GOwnPtr.h" #include "LayoutTestController.h" #include "PixelDumpSupport.h" +#include "TextInputController.h" #include "WebCoreSupport/DumpRenderTreeSupportGtk.h" #include "WorkQueue.h" #include "WorkQueueItem.h" @@ -419,6 +420,7 @@ static void resetDefaultsToConsistentValues() "enable-fullscreen", TRUE, NULL); webkit_web_view_set_settings(webView, settings); + webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER); DumpRenderTreeSupportGtk::clearMainFrameName(mainFrame); @@ -432,7 +434,6 @@ static void resetDefaultsToConsistentValues() WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView); webkit_web_back_forward_list_clear(list); -#ifdef HAVE_LIBSOUP_2_29_90 SoupSession* session = webkit_get_default_session(); SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR)); @@ -440,11 +441,14 @@ static void resetDefaultsToConsistentValues() // HTTP. Should we initialize it earlier, perhaps? if (jar) g_object_set(G_OBJECT(jar), SOUP_COOKIE_JAR_ACCEPT_POLICY, SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY, NULL); -#endif setlocale(LC_ALL, ""); DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(true); + DumpRenderTreeSupportGtk::setIconDatabaseEnabled(false); + + if (axController) + axController->resetToConsistentState(); } static bool useLongRunningServerMode(int argc, char *argv[]) @@ -738,6 +742,11 @@ static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void dump(); } +static gboolean webViewLoadError(WebKitWebView*, WebKitWebFrame*, gchar*, gpointer, gpointer) +{ + return TRUE; // Return true here to disable the default error page. +} + static void webViewDocumentLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*) { if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) { @@ -781,6 +790,11 @@ static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* fram JSValueRef eventSender = makeEventSender(context, !webkit_web_frame_get_parent(frame)); JSObjectSetProperty(context, windowObject, eventSenderStr, eventSender, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); JSStringRelease(eventSenderStr); + + JSStringRef textInputControllerStr = JSStringCreateWithUTF8CString("textInputController"); + JSValueRef textInputController = makeTextInputController(context); + JSObjectSetProperty(context, windowObject, textInputControllerStr, textInputController, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); + JSStringRelease(textInputControllerStr); } static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data) @@ -999,6 +1013,7 @@ static WebKitWebView* createWebView() g_object_connect(G_OBJECT(view), "signal::load-started", webViewLoadStarted, 0, "signal::load-finished", webViewLoadFinished, 0, + "signal::load-error", webViewLoadError, 0, "signal::window-object-cleared", webViewWindowObjectCleared, 0, "signal::console-message", webViewConsoleMessage, 0, "signal::script-alert", webViewScriptAlert, 0, diff --git a/Tools/DumpRenderTree/gtk/EventSender.cpp b/Tools/DumpRenderTree/gtk/EventSender.cpp index 923a4ba..10e129c 100644 --- a/Tools/DumpRenderTree/gtk/EventSender.cpp +++ b/Tools/DumpRenderTree/gtk/EventSender.cpp @@ -240,33 +240,42 @@ static void updateClickCount(int button) clickCount++; } +static guint gdkModifierFromJSValue(JSContextRef context, const JSValueRef value) +{ + JSStringRef string = JSValueToStringCopy(context, value, 0); + guint gdkModifier = 0; + if (JSStringIsEqualToUTF8CString(string, "ctrlKey") + || JSStringIsEqualToUTF8CString(string, "addSelectionKey")) + gdkModifier = GDK_CONTROL_MASK; + else if (JSStringIsEqualToUTF8CString(string, "shiftKey") + || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey")) + gdkModifier = GDK_SHIFT_MASK; + else if (JSStringIsEqualToUTF8CString(string, "altKey")) + gdkModifier = GDK_MOD1_MASK; + + // Currently the metaKey as defined in WebCore/platform/gtk/MouseEventGtk.cpp + // is GDK_MOD2_MASK. This code must be kept in sync with that file. + else if (JSStringIsEqualToUTF8CString(string, "metaKey")) + gdkModifier = GDK_MOD2_MASK; + + JSStringRelease(string); + return gdkModifier; +} + static guint gdkModifersFromJSValue(JSContextRef context, const JSValueRef modifiers) { + // The value may either be a string with a single modifier or an array of modifiers. + if (JSValueIsString(context, modifiers)) + return gdkModifierFromJSValue(context, modifiers); + JSObjectRef modifiersArray = JSValueToObject(context, modifiers, 0); if (!modifiersArray) return 0; guint gdkModifiers = 0; int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, JSStringCreateWithUTF8CString("length"), 0), 0); - for (int i = 0; i < modifiersCount; ++i) { - JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0); - JSStringRef string = JSValueToStringCopy(context, value, 0); - if (JSStringIsEqualToUTF8CString(string, "ctrlKey") - || JSStringIsEqualToUTF8CString(string, "addSelectionKey")) - gdkModifiers |= GDK_CONTROL_MASK; - else if (JSStringIsEqualToUTF8CString(string, "shiftKey") - || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey")) - gdkModifiers |= GDK_SHIFT_MASK; - else if (JSStringIsEqualToUTF8CString(string, "altKey")) - gdkModifiers |= GDK_MOD1_MASK; - - // Currently the metaKey as defined in WebCore/platform/gtk/MouseEventGtk.cpp - // is GDK_MOD2_MASK. This code must be kept in sync with that file. - else if (JSStringIsEqualToUTF8CString(string, "metaKey")) - gdkModifiers |= GDK_MOD2_MASK; - - JSStringRelease(string); - } + for (int i = 0; i < modifiersCount; ++i) + gdkModifiers |= gdkModifierFromJSValue(context, JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0)); return gdkModifiers; } diff --git a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index 1527811..56d75f7 100644 --- a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -3,7 +3,7 @@ * Copyright (C) 2007 Eric Seidel <eric@webkit.org> * Copyright (C) 2008 Nuanti Ltd. * Copyright (C) 2009 Jan Michael Alonzo <jmalonzo@gmail.com> - * Copyright (C) 2009 Collabora Ltd. + * Copyright (C) 2009,2011 Collabora Ltd. * Copyright (C) 2010 Joone Hur <joone@kldp.org> * * Redistribution and use in source and binary forms, with or without @@ -230,7 +230,6 @@ void LayoutTestController::setAcceptsEditing(bool acceptsEditing) void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) { -#ifdef HAVE_LIBSOUP_2_29_90 SoupSession* session = webkit_get_default_session(); SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR)); @@ -251,7 +250,6 @@ void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; g_object_set(G_OBJECT(jar), SOUP_COOKIE_JAR_ACCEPT_POLICY, policy, NULL); -#endif } void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permissive) @@ -492,9 +490,9 @@ void LayoutTestController::addMockSpeechInputResult(JSStringRef result, double c // See https://bugs.webkit.org/show_bug.cgi?id=39485. } -void LayoutTestController::setIconDatabaseEnabled(bool flag) +void LayoutTestController::setIconDatabaseEnabled(bool enabled) { - // FIXME: implement + DumpRenderTreeSupportGtk::setIconDatabaseEnabled(enabled); } void LayoutTestController::setJavaScriptProfilingEnabled(bool flag) @@ -546,10 +544,42 @@ void LayoutTestController::execCommand(JSStringRef name, JSStringRef value) g_free(cValue); } -bool LayoutTestController::findString(JSContextRef /* context */, JSStringRef /* target */, JSObjectRef /* optionsArray */) +bool LayoutTestController::findString(JSContextRef context, JSStringRef target, JSObjectRef optionsArray) { - // FIXME: Implement - return false; + WebKitFindOptions findOptions = 0; + WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); + ASSERT(webView); + + JSRetainPtr<JSStringRef> lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length")); + JSValueRef lengthValue = JSObjectGetProperty(context, optionsArray, lengthPropertyName.get(), 0); + if (!JSValueIsNumber(context, lengthValue)) + return false; + + GOwnPtr<gchar> targetString(JSStringCopyUTF8CString(target)); + + size_t length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0)); + for (size_t i = 0; i < length; ++i) { + JSValueRef value = JSObjectGetPropertyAtIndex(context, optionsArray, i, 0); + if (!JSValueIsString(context, value)) + continue; + + JSRetainPtr<JSStringRef> optionName(Adopt, JSValueToStringCopy(context, value, 0)); + + if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive")) + findOptions |= WebKit::WebFindOptionsCaseInsensitive; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts")) + findOptions |= WebKit::WebFindOptionsAtWordStarts; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart")) + findOptions |= WebKit::WebFindOptionsTreatMedialCapitalAsWordStart; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards")) + findOptions |= WebKit::WebFindOptionsBackwards; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround")) + findOptions |= WebKit::WebFindOptionsWrapAround; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection")) + findOptions |= WebKit::WebFindOptionsStartInSelection; + } + + return DumpRenderTreeSupportGtk::findString(webView, targetString.get(), findOptions); } bool LayoutTestController::isCommandEnabled(JSStringRef name) @@ -565,10 +595,20 @@ bool LayoutTestController::isCommandEnabled(JSStringRef name) void LayoutTestController::setCacheModel(int cacheModel) { - if (!cacheModel) // WebCacheModelDocumentViewer - webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER); - else - webkit_set_cache_model(WEBKIT_CACHE_MODEL_WEB_BROWSER); + // These constants are derived from the Mac cache model enum in Source/WebKit/mac/WebView/WebPreferences.h. + switch (cacheModel) { + case 0: + webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER); + break; + case 1: + webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER); + break; + case 3: + webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER); + break; + default: + ASSERT_NOT_REACHED(); + } } void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL) diff --git a/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp b/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp index 32bc600..1e591bb 100644 --- a/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp +++ b/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp @@ -37,13 +37,14 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool, bool, bool, bool) { WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + GtkWidget* viewContainer = gtk_widget_get_parent(GTK_WIDGET(view)); gint width, height; #ifdef GTK_API_VERSION_2 - GdkPixmap* pixmap = gtk_widget_get_snapshot(GTK_WIDGET(view), 0); + GdkPixmap* pixmap = gtk_widget_get_snapshot(viewContainer, 0); gdk_pixmap_get_size(pixmap, &width, &height); #else - width = gtk_widget_get_allocated_width(GTK_WIDGET(view)); - height = gtk_widget_get_allocated_height(GTK_WIDGET(view)); + width = gtk_widget_get_allocated_width(viewContainer); + height = gtk_widget_get_allocated_height(viewContainer); #endif cairo_surface_t* imageSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); @@ -53,7 +54,7 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool, bool, bool, bool) cairo_paint(context); g_object_unref(pixmap); #else - gtk_widget_draw(GTK_WIDGET(view), context); + gtk_widget_draw(viewContainer, context); #endif return BitmapContext::createByAdoptingBitmapAndContext(0, context); diff --git a/Tools/DumpRenderTree/gtk/TextInputController.cpp b/Tools/DumpRenderTree/gtk/TextInputController.cpp new file mode 100644 index 0000000..7243fdc --- /dev/null +++ b/Tools/DumpRenderTree/gtk/TextInputController.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TextInputController.h" + +#include "DumpRenderTree.h" +#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" +#include <GOwnPtrGtk.h> +#include <JavaScriptCore/JSObjectRef.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <JavaScriptCore/JSStringRef.h> +#include <cstring> + +static JSValueRef setMarkedTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + if (argumentCount < 3) + return JSValueMakeUndefined(context); + + JSStringRef string = JSValueToStringCopy(context, arguments[0], exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + size_t bufferSize = JSStringGetMaximumUTF8CStringSize(string); + GOwnPtr<gchar> stringBuffer(static_cast<gchar*>(g_malloc(bufferSize))); + JSStringGetUTF8CString(string, stringBuffer.get(), bufferSize); + JSStringRelease(string); + + int start = static_cast<int>(JSValueToNumber(context, arguments[1], exception)); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + int end = static_cast<int>(JSValueToNumber(context, arguments[2], exception)); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + DumpRenderTreeSupportGtk::setComposition(view, stringBuffer.get(), start, end); + + return JSValueMakeUndefined(context); +} + +static JSValueRef insertTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + JSStringRef string = JSValueToStringCopy(context, arguments[0], exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + size_t bufferSize = JSStringGetMaximumUTF8CStringSize(string); + GOwnPtr<gchar> stringBuffer(static_cast<gchar*>(g_malloc(bufferSize))); + JSStringGetUTF8CString(string, stringBuffer.get(), bufferSize); + JSStringRelease(string); + + DumpRenderTreeSupportGtk::confirmComposition(view, stringBuffer.get()); + + return JSValueMakeUndefined(context); +} + +static JSValueRef unmarkTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + DumpRenderTreeSupportGtk::confirmComposition(view, 0); + return JSValueMakeUndefined(context); +} + +static JSValueRef firstRectForCharacterRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + if (argumentCount < 2) + return JSValueMakeUndefined(context); + + int location = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + int length = static_cast<int>(JSValueToNumber(context, arguments[1], exception)); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + GdkRectangle rect; + if (!DumpRenderTreeSupportGtk::firstRectForCharacterRange(view, location, length, &rect)) + return JSValueMakeUndefined(context); + + JSValueRef arrayValues[4]; + arrayValues[0] = JSValueMakeNumber(context, rect.x); + arrayValues[1] = JSValueMakeNumber(context, rect.y); + arrayValues[2] = JSValueMakeNumber(context, rect.width); + arrayValues[3] = JSValueMakeNumber(context, rect.height); + JSObjectRef arrayObject = JSObjectMakeArray(context, 4, arrayValues, exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + return arrayObject; +} + +static JSValueRef selectedRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + int start, end; + if (!DumpRenderTreeSupportGtk::selectedRange(view, &start, &end)) + return JSValueMakeUndefined(context); + + JSValueRef arrayValues[2]; + arrayValues[0] = JSValueMakeNumber(context, start); + arrayValues[1] = JSValueMakeNumber(context, end); + JSObjectRef arrayObject = JSObjectMakeArray(context, 2, arrayValues, exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + return arrayObject; +} + +static JSStaticFunction staticFunctions[] = { + { "setMarkedText", setMarkedTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "insertText", insertTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "unmarkText", unmarkTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "firstRectForCharacterRange", firstRectForCharacterRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "selectedRange", selectedRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { 0, 0, 0 } +}; + +static JSClassRef getClass(JSContextRef context) +{ + static JSClassRef textInputControllerClass = 0; + + if (!textInputControllerClass) { + JSClassDefinition classDefinition = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + classDefinition.staticFunctions = staticFunctions; + + textInputControllerClass = JSClassCreate(&classDefinition); + } + + return textInputControllerClass; +} + +JSObjectRef makeTextInputController(JSContextRef context) +{ + return JSObjectMake(context, getClass(context), 0); +} diff --git a/Tools/DumpRenderTree/gtk/TextInputController.h b/Tools/DumpRenderTree/gtk/TextInputController.h new file mode 100644 index 0000000..53793f6 --- /dev/null +++ b/Tools/DumpRenderTree/gtk/TextInputController.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TextInputController_h +#define TextInputController_h + +typedef const struct OpaqueJSContext* JSContextRef; +typedef struct OpaqueJSValue* JSObjectRef; + +JSObjectRef makeTextInputController(JSContextRef); + +#endif diff --git a/Tools/DumpRenderTree/mac/AccessibilityControllerMac.mm b/Tools/DumpRenderTree/mac/AccessibilityControllerMac.mm index 1a9f9c9..d41f01d 100644 --- a/Tools/DumpRenderTree/mac/AccessibilityControllerMac.mm +++ b/Tools/DumpRenderTree/mac/AccessibilityControllerMac.mm @@ -74,6 +74,10 @@ void AccessibilityController::setLogValueChangeEvents(bool) { } +void AccessibilityController::setLogAccessibilityEvents(bool) +{ +} + void AccessibilityController::addNotificationListener(PlatformUIElement, JSObjectRef) { } diff --git a/Tools/DumpRenderTree/mac/DumpRenderTree.mm b/Tools/DumpRenderTree/mac/DumpRenderTree.mm index ed09cf6..eab3742 100644 --- a/Tools/DumpRenderTree/mac/DumpRenderTree.mm +++ b/Tools/DumpRenderTree/mac/DumpRenderTree.mm @@ -448,6 +448,7 @@ static void resetDefaultsToConsistentValues() [preferences setDeveloperExtrasEnabled:NO]; [preferences setLoadsImagesAutomatically:YES]; [preferences setFrameFlatteningEnabled:NO]; + [preferences setSpatialNavigationEnabled:NO]; [preferences setEditingBehavior:WebKitEditingMacBehavior]; if (persistentUserStyleSheetLocation) { [preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]]; @@ -753,7 +754,10 @@ static void dumpHistoryItem(WebHistoryItem *item, int indent, BOOL current) static void dumpFrameScrollPosition(WebFrame *f) { - NSPoint scrollPosition = [[[[f frameView] documentView] superview] bounds].origin; + WebScriptObject* scriptObject = [f windowObject]; + NSPoint scrollPosition = NSMakePoint( + [[scriptObject valueForKey:@"pageXOffset"] floatValue], + [[scriptObject valueForKey:@"pageYOffset"] floatValue]); if (ABS(scrollPosition.x) > 0.00000001 || ABS(scrollPosition.y) > 0.00000001) { if ([f parentFrame] != nil) printf("frame '%s' ", [[f name] UTF8String]); diff --git a/Tools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp b/Tools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp index 5a48b27..1266c02 100644 --- a/Tools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp +++ b/Tools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp @@ -37,6 +37,8 @@ #include <wtf/Assertions.h> #include <wtf/HashSet.h> +static JSContextGroupRef javaScriptThreadsGroup; + static pthread_mutex_t javaScriptThreadsMutex = PTHREAD_MUTEX_INITIALIZER; static bool javaScriptThreadsShouldTerminate; @@ -51,58 +53,68 @@ static ThreadSet* javaScriptThreads() return &staticJavaScriptThreads; } -// Loops forever, running a script and randomly respawning, until -// javaScriptThreadsShouldTerminate becomes true. +// This function exercises JSC in a loop until javaScriptThreadsShouldTerminate +// becomes true or it probabilistically decides to spawn a replacement thread and exit. void* runJavaScriptThread(void* arg) { - const char* const script = + static const char* const script = "var array = [];" - "for (var i = 0; i < 10; i++) {" + "for (var i = 0; i < 1024; i++) {" " array.push(String(i));" "}"; - while (1) { - JSGlobalContextRef ctx = JSGlobalContextCreate(0); - JSStringRef scriptRef = JSStringCreateWithUTF8CString(script); + pthread_mutex_lock(&javaScriptThreadsMutex); + JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(javaScriptThreadsGroup, 0); + pthread_mutex_unlock(&javaScriptThreadsMutex); + + pthread_mutex_lock(&javaScriptThreadsMutex); + JSStringRef scriptRef = JSStringCreateWithUTF8CString(script); + pthread_mutex_unlock(&javaScriptThreadsMutex); + while (1) { + pthread_mutex_lock(&javaScriptThreadsMutex); JSValueRef exception = 0; JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception); ASSERT(!exception); - - JSGarbageCollect(ctx); - JSGlobalContextRelease(ctx); - JSStringRelease(scriptRef); - - JSGarbageCollect(0); + pthread_mutex_unlock(&javaScriptThreadsMutex); pthread_mutex_lock(&javaScriptThreadsMutex); + size_t valuesCount = 1024; + JSValueRef values[valuesCount]; + for (size_t i = 0; i < valuesCount; ++i) + values[i] = JSObjectMake(ctx, 0, 0); + pthread_mutex_unlock(&javaScriptThreadsMutex); // Check for cancellation. - if (javaScriptThreadsShouldTerminate) { - javaScriptThreads()->remove(pthread_self()); - pthread_mutex_unlock(&javaScriptThreadsMutex); - return 0; - } + if (javaScriptThreadsShouldTerminate) + goto done; // Respawn probabilistically. if (random() % 5 == 0) { + pthread_mutex_lock(&javaScriptThreadsMutex); pthread_t pthread; pthread_create(&pthread, 0, &runJavaScriptThread, 0); pthread_detach(pthread); - - javaScriptThreads()->remove(pthread_self()); javaScriptThreads()->add(pthread); - pthread_mutex_unlock(&javaScriptThreadsMutex); - return 0; + goto done; } - - pthread_mutex_unlock(&javaScriptThreadsMutex); } + +done: + pthread_mutex_lock(&javaScriptThreadsMutex); + JSStringRelease(scriptRef); + JSGarbageCollect(ctx); + JSGlobalContextRelease(ctx); + javaScriptThreads()->remove(pthread_self()); + pthread_mutex_unlock(&javaScriptThreadsMutex); + return 0; } void startJavaScriptThreads() { + javaScriptThreadsGroup = JSContextGroupCreate(); + pthread_mutex_lock(&javaScriptThreadsMutex); for (int i = 0; i < javaScriptThreadsCount; i++) { @@ -121,8 +133,6 @@ void stopJavaScriptThreads() javaScriptThreadsShouldTerminate = true; - ASSERT(javaScriptThreads()->size() == javaScriptThreadsCount); - pthread_mutex_unlock(&javaScriptThreadsMutex); while (true) { diff --git a/Tools/DumpRenderTree/qt/DumpRenderTree.pro b/Tools/DumpRenderTree/qt/DumpRenderTree.pro index a7c6c26..d84af96 100644 --- a/Tools/DumpRenderTree/qt/DumpRenderTree.pro +++ b/Tools/DumpRenderTree/qt/DumpRenderTree.pro @@ -5,12 +5,12 @@ CONFIG += uitools BASEDIR = $$PWD/../ isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../.. -include(../../../WebKit.pri) +include(../../../Source/WebKit.pri) INCLUDEPATH += ../../../Source INCLUDEPATH += ../../../Source/JavaScriptCore INCLUDEPATH += ../../../Source/JavaScriptCore/ForwardingHeaders INCLUDEPATH += $$BASEDIR -DESTDIR = ../../../bin +DESTDIR = ../../bin unix:!mac:!symbian { CONFIG += link_pkgconfig diff --git a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp index ce608cc..7d20f47 100644 --- a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp +++ b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp @@ -83,6 +83,8 @@ namespace WebCore { +const int databaseDefaultQuota = 5 * 1024 * 1024; + NetworkAccessManager::NetworkAccessManager(QObject* parent) : QNetworkAccessManager(parent) { @@ -520,7 +522,7 @@ void DumpRenderTree::dryRunPrint(QWebFrame* frame) #endif } -void DumpRenderTree::resetToConsistentStateBeforeTesting() +void DumpRenderTree::resetToConsistentStateBeforeTesting(const QUrl& url) { // reset so that any current loads are stopped // NOTE: that this has to be done before the layoutTestController is @@ -529,6 +531,10 @@ void DumpRenderTree::resetToConsistentStateBeforeTesting() m_page->triggerAction(QWebPage::Stop); m_page->blockSignals(false); + QList<QWebSecurityOrigin> knownOrigins = QWebSecurityOrigin::allOrigins(); + for (int i = 0; i < knownOrigins.size(); ++i) + knownOrigins[i].setDatabaseQuota(databaseDefaultQuota); + // reset the layoutTestController at this point, so that we under no // circumstance dump (stop the waitUntilDone timer) during the reset // of the DRT. @@ -550,6 +556,14 @@ void DumpRenderTree::resetToConsistentStateBeforeTesting() m_page->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded); m_page->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded); + if (url.scheme() == "http" || url.scheme() == "https") { + // credentials may exist from previous tests. + m_page->setNetworkAccessManager(0); + delete m_networkAccessManager; + m_networkAccessManager = new NetworkAccessManager(this); + m_page->setNetworkAccessManager(m_networkAccessManager); + } + WorkQueue::shared()->clear(); WorkQueue::shared()->setFrozen(false); @@ -560,6 +574,7 @@ void DumpRenderTree::resetToConsistentStateBeforeTesting() QLocale::setDefault(QLocale::c()); + layoutTestController()->setDeveloperExtrasEnabled(true); #ifndef Q_OS_WINCE setlocale(LC_ALL, ""); #endif @@ -579,26 +594,16 @@ static bool isWebInspectorTest(const QUrl& url) return false; } -static bool shouldEnableDeveloperExtras(const QUrl& url) -{ - return true; -} - void DumpRenderTree::open(const QUrl& url) { DumpRenderTreeSupportQt::dumpResourceLoadCallbacksPath(QFileInfo(url.toString()).path()); - resetToConsistentStateBeforeTesting(); + resetToConsistentStateBeforeTesting(url); - if (shouldEnableDeveloperExtras(m_page->mainFrame()->url())) { + if (isWebInspectorTest(m_page->mainFrame()->url())) layoutTestController()->closeWebInspector(); - layoutTestController()->setDeveloperExtrasEnabled(false); - } - if (shouldEnableDeveloperExtras(url)) { - layoutTestController()->setDeveloperExtrasEnabled(true); - if (isWebInspectorTest(url)) - layoutTestController()->showWebInspector(); - } + if (isWebInspectorTest(url)) + layoutTestController()->showWebInspector(); if (isGlobalHistoryTest(url)) layoutTestController()->dumpHistoryCallbacks(); @@ -1028,7 +1033,7 @@ void DumpRenderTree::dumpDatabaseQuota(QWebFrame* frame, const QString& dbName) origin.host().toUtf8().data(), origin.port(), dbName.toUtf8().data()); - origin.setDatabaseQuota(5 * 1024 * 1024); + origin.setDatabaseQuota(databaseDefaultQuota); } void DumpRenderTree::dumpApplicationCacheQuota(QWebSecurityOrigin* origin, quint64 defaultOriginQuota) @@ -1085,9 +1090,6 @@ void DumpRenderTree::windowCloseRequested() QWebPage* page = qobject_cast<QWebPage*>(sender()); QObject* container = page->parent(); windows.removeAll(container); - // Our use of container->deleteLater() means we need to remove closed pages - // from the org.webkit.qt.DumpRenderTree group explicitly. - DumpRenderTreeSupportQt::webPageSetGroupName(page, ""); container->deleteLater(); } diff --git a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.h b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.h index 8cb5efb..5b53cd9 100644 --- a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.h +++ b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.h @@ -86,7 +86,7 @@ public: void setDumpPixels(bool); void closeRemainingWindows(); - void resetToConsistentStateBeforeTesting(); + void resetToConsistentStateBeforeTesting(const QUrl&); LayoutTestController *layoutTestController() const { return m_controller; } EventSender *eventSender() const { return m_eventSender; } diff --git a/Tools/DumpRenderTree/qt/EventSenderQt.cpp b/Tools/DumpRenderTree/qt/EventSenderQt.cpp index 6fb75a5..6449484 100644 --- a/Tools/DumpRenderTree/qt/EventSenderQt.cpp +++ b/Tools/DumpRenderTree/qt/EventSenderQt.cpp @@ -360,7 +360,7 @@ void EventSender::keyDown(const QString& string, const QStringList& modifiers, u sendEvent(m_page, &event2); } -void EventSender::contextClick() +QStringList EventSender::contextClick() { QMouseEvent event(QEvent::MouseButtonPress, m_mousePos, Qt::RightButton, Qt::RightButton, Qt::NoModifier); sendEvent(m_page, &event); @@ -378,6 +378,7 @@ void EventSender::contextClick() QContextMenuEvent ctxEvent(QContextMenuEvent::Mouse, m_mousePos); sendEvent(m_page->view(), &ctxEvent); } + return DumpRenderTreeSupportQt::contextMenu(m_page); } void EventSender::scheduleAsynchronousClick() diff --git a/Tools/DumpRenderTree/qt/EventSenderQt.h b/Tools/DumpRenderTree/qt/EventSenderQt.h index 4ba8382..ecb06e2 100644 --- a/Tools/DumpRenderTree/qt/EventSenderQt.h +++ b/Tools/DumpRenderTree/qt/EventSenderQt.h @@ -65,7 +65,7 @@ public slots: void leapForward(int ms); void keyDown(const QString& string, const QStringList& modifiers = QStringList(), unsigned int location = 0); void clearKillRing() {} - void contextClick(); + QStringList contextClick(); void scheduleAsynchronousClick(); void addTouchPoint(int x, int y); void updateTouchPoint(int index, int x, int y); diff --git a/Tools/DumpRenderTree/qt/ImageDiff.pro b/Tools/DumpRenderTree/qt/ImageDiff.pro index a218449..cdb067e 100644 --- a/Tools/DumpRenderTree/qt/ImageDiff.pro +++ b/Tools/DumpRenderTree/qt/ImageDiff.pro @@ -2,7 +2,7 @@ TARGET = ImageDiff CONFIG -= app_bundle isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../.. -include(../../../WebKit.pri) +include(../../../Source/WebKit.pri) INCLUDEPATH += ../../../Source/JavaScriptCore DESTDIR = $$OUTPUT_DIR/bin diff --git a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp index 56406c2..a11bc60 100644 --- a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp +++ b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp @@ -87,6 +87,7 @@ void LayoutTestController::reset() DumpRenderTreeSupportQt::dumpHistoryCallbacks(false); DumpRenderTreeSupportQt::dumpVisitedLinksCallbacks(false); setIconDatabaseEnabled(false); + clearAllDatabases(); emit hidePage(); } @@ -830,5 +831,10 @@ QVariantList LayoutTestController::nodesFromRect(const QWebElement& document, in return DumpRenderTreeSupportQt::nodesFromRect(document, x, y, top, right, bottom, left, ignoreClipping); } +void LayoutTestController::addURLToRedirect(const QString& origin, const QString& destination) +{ + DumpRenderTreeSupportQt::addURLToRedirect(origin, destination); +} + const unsigned LayoutTestController::maxViewWidth = 800; const unsigned LayoutTestController::maxViewHeight = 600; diff --git a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h index 0048a7e..bc62c51 100644 --- a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h +++ b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h @@ -230,6 +230,8 @@ public slots: QVariantList nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping); + void addURLToRedirect(const QString& origin, const QString& destination); + /* Policy values: 'on', 'auto' or 'off'. Orientation values: 'vertical' or 'horizontal'. diff --git a/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro b/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro index 6f96d0a..176c4c4 100644 --- a/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro +++ b/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro @@ -3,7 +3,7 @@ TARGET = TestNetscapePlugIn VPATH = ../../unix/TestNetscapePlugin ../../TestNetscapePlugIn isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../.. -include(../../../../WebKit.pri) +include(../../../../Source/WebKit.pri) DESTDIR = $$OUTPUT_DIR/lib/plugins diff --git a/Tools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp b/Tools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp index 2f7288a..4936efd 100644 --- a/Tools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp +++ b/Tools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp @@ -79,6 +79,9 @@ webkit_test_plugin_new_instance(NPMIMEType mimetype, else if (strcasecmp(argn[i], "src") == 0 && strcasecmp(argv[i], "data:application/x-webkit-test-netscape,returnerrorfromnewstream") == 0) obj->returnErrorFromNewStream = TRUE; + else if (!strcasecmp(argn[i], "src") + && !strcasecmp(argv[i], "data:application/x-webkit-test-netscape,alertwhenloaded")) + executeScript(obj, "alert('Plugin Loaded!')"); else if (strcasecmp(argn[i], "logfirstsetwindow") == 0) obj->logSetWindow = TRUE; else if (strcasecmp(argn[i], "testnpruntime") == 0) diff --git a/Tools/DumpRenderTree/win/AccessibilityControllerWin.cpp b/Tools/DumpRenderTree/win/AccessibilityControllerWin.cpp index f03c102..6e4ee46 100644 --- a/Tools/DumpRenderTree/win/AccessibilityControllerWin.cpp +++ b/Tools/DumpRenderTree/win/AccessibilityControllerWin.cpp @@ -213,6 +213,10 @@ void AccessibilityController::setLogScrollingStartEvents(bool logScrollingStartE ASSERT(m_scrollingStartEventHook); } +void AccessibilityController::setLogAccessibilityEvents(bool) +{ +} + static string stringEvent(DWORD event) { switch(event) { diff --git a/Tools/DumpRenderTree/win/ImageDiffCommon.vsprops b/Tools/DumpRenderTree/win/ImageDiffCommon.vsprops index 1156a72..5d41bf4 100644 --- a/Tools/DumpRenderTree/win/ImageDiffCommon.vsprops +++ b/Tools/DumpRenderTree/win/ImageDiffCommon.vsprops @@ -7,6 +7,7 @@ <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories=""$(ConfigurationBuildDir)\include";"$(ConfigurationBuildDir)\include\private";"$(ConfigurationBuildDir)\include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private"" + PreprocessorDefinitions="NOMINMAX" /> <Tool Name="VCLinkerTool" diff --git a/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp index 32b5f7e..1befb77 100644 --- a/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp +++ b/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp @@ -544,3 +544,8 @@ bool LayoutTestController::findString(JSContextRef context, JSStringRef target, // FIXME: Implement return false; } + +void LayoutTestController::setSerializeHTTPLoads(bool) +{ + // FIXME: Implement. +} |