diff options
Diffstat (limited to 'WebKitTools/DumpRenderTree')
13 files changed, 184 insertions, 32 deletions
diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp index c4d5e6f..e09eb35 100644 --- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp +++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp @@ -152,6 +152,29 @@ static JSValueRef stringForRangeCallback(JSContextRef context, JSObjectRef funct return JSValueMakeString(context, stringDescription.get()); } +static JSValueRef attributedStringForRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + unsigned location = UINT_MAX, length = 0; + if (argumentCount == 2) { + location = JSValueToNumber(context, arguments[0], exception); + length = JSValueToNumber(context, arguments[1], exception); + } + + JSRetainPtr<JSStringRef> stringDescription(Adopt, toAXElement(thisObject)->attributedStringForRange(location, length)); + return JSValueMakeString(context, stringDescription.get()); +} + +static JSValueRef attributedStringRangeIsMisspelledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + unsigned location = UINT_MAX, length = 0; + if (argumentCount == 2) { + location = JSValueToNumber(context, arguments[0], exception); + length = JSValueToNumber(context, arguments[1], exception); + } + + return JSValueMakeBoolean(context, toAXElement(thisObject)->attributedStringRangeIsMisspelled(location, length)); +} + static JSValueRef indexOfChildCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (argumentCount != 1) @@ -711,6 +734,8 @@ JSClassRef AccessibilityUIElement::getJSClass() { "lineForIndex", lineForIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "boundsForRange", boundsForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "stringForRange", stringForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "attributedStringForRange", attributedStringForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "attributedStringRangeIsMisspelled", attributedStringRangeIsMisspelledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "linkedUIElementAtIndex", linkedUIElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "indexOfChild", indexOfChildCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h index 2a06962..13415cd 100644 --- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h +++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h @@ -177,6 +177,8 @@ public: JSStringRef boundsForRange(unsigned location, unsigned length); void setSelectedTextRange(unsigned location, unsigned length); JSStringRef stringForRange(unsigned location, unsigned length); + JSStringRef attributedStringForRange(unsigned location, unsigned length); + bool attributedStringRangeIsMisspelled(unsigned location, unsigned length); // Table-specific AccessibilityUIElement cellForColumnAndRow(unsigned column, unsigned row); diff --git a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp index fbdbd23..a09ad2a 100644 --- a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp @@ -499,6 +499,18 @@ JSStringRef AccessibilityUIElement::stringForRange(unsigned, unsigned) return JSStringCreateWithCharacters(0, 0); } +JSStringRef AccessibilityUIElement::attributedStringForRange(unsigned, unsigned) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length) +{ + // FIXME: implement + return false; +} + AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row) { // FIXME: implement diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp index 2812224..bd9c0c9 100644 --- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -886,6 +886,10 @@ static WebKitWebView* createWebView() "signal::document-load-finished", webViewDocumentLoadFinished, 0, "signal::geolocation-policy-decision-requested", geolocationPolicyDecisionRequested, 0, "signal::onload-event", webViewOnloadEvent, 0, + "signal::drag-begin", dragBeginCallback, 0, + "signal::drag-end", dragEndCallback, 0, + "signal::drag-failed", dragFailedCallback, 0, + NULL); g_signal_connect(view, diff --git a/WebKitTools/DumpRenderTree/gtk/EventSender.cpp b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp index 4936fe5..b95fec2 100644 --- a/WebKitTools/DumpRenderTree/gtk/EventSender.cpp +++ b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp @@ -45,8 +45,6 @@ #include <gdk/gdkkeysyms.h> #include <string.h> -// FIXME: Implement support for synthesizing drop events. - extern "C" { extern void webkit_web_frame_layout(WebKitWebFrame* frame); } @@ -62,6 +60,7 @@ static int lastClickTimeOffset; static int lastClickButton; static int buttonCurrentlyDown; static int clickCount; +GdkDragContext* currentDragSourceContext; struct DelayedMessage { GdkEvent event; @@ -359,13 +358,36 @@ static void dispatchEvent(GdkEvent event) return; gtk_main_do_event(&event); + + if (!currentDragSourceContext) + return; + + if (event.type == GDK_MOTION_NOTIFY) { + // WebKit has called gtk_drag_start(), but because the main loop isn't + // running GDK internals don't know that the drag has started yet. Pump + // the main loop a little bit so that GDK is in the correct state. + while (gtk_events_pending()) + gtk_main_iteration(); + + // Simulate a drag motion on the top-level GDK window. + GtkWidget* parentWidget = gtk_widget_get_parent(GTK_WIDGET(view)); + GdkWindow* parentWidgetWindow = parentWidget->window; + gdk_drag_motion(currentDragSourceContext, parentWidgetWindow, GDK_DRAG_PROTO_XDND, + event.motion.x_root, event.motion.y_root, + currentDragSourceContext->action, currentDragSourceContext->actions, GDK_CURRENT_TIME); + + } else if (currentDragSourceContext && event.type == GDK_BUTTON_RELEASE) { + // We've released the mouse button, we should just be able to spin the + // event loop here and have GTK+ send the appropriate notifications for + // the end of the drag. + while (gtk_events_pending()) + gtk_main_iteration(); + } + } void replaySavedEvents() { - // FIXME: Eventually we may need to have more sophisticated logic to - // track drag-and-drop operations. - // First send all the events that are ready to be sent while (startOfQueue < endOfQueue) { if (msgQueue[startOfQueue].delay) { @@ -631,7 +653,26 @@ JSObjectRef makeEventSender(JSContextRef context, bool isTopFrame) endOfQueue = 0; startOfQueue = 0; + + currentDragSourceContext = 0; } return JSObjectMake(context, getClass(context), 0); } + +void dragBeginCallback(GtkWidget*, GdkDragContext* context, gpointer) +{ + currentDragSourceContext = context; +} + +void dragEndCallback(GtkWidget*, GdkDragContext* context, gpointer) +{ + currentDragSourceContext = 0; +} + +gboolean dragFailedCallback(GtkWidget*, GdkDragContext* context, gpointer) +{ + // Return TRUE here to disable the stupid GTK+ drag failed animation, + // which introduces asynchronous behavior into our drags. + return TRUE; +} diff --git a/WebKitTools/DumpRenderTree/gtk/EventSender.h b/WebKitTools/DumpRenderTree/gtk/EventSender.h index ce33ccc..e9b758d 100644 --- a/WebKitTools/DumpRenderTree/gtk/EventSender.h +++ b/WebKitTools/DumpRenderTree/gtk/EventSender.h @@ -32,8 +32,15 @@ typedef const struct OpaqueJSContext* JSContextRef; typedef struct OpaqueJSValue* JSObjectRef; +typedef struct _GtkWidget GtkWidget; +typedef struct _GdkDragContext GdkDragContext; +typedef void* gpointer; +typedef int gboolean; JSObjectRef makeEventSender(JSContextRef context, bool isTopFrame); void replaySavedEvents(); +void dragBeginCallback(GtkWidget*, GdkDragContext*, gpointer); +void dragEndCallback(GtkWidget*, GdkDragContext*, gpointer); +gboolean dragFailedCallback(GtkWidget*, GdkDragContext*, gpointer); #endif diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm index ba0631d..d1592b2 100644 --- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm +++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm @@ -855,6 +855,37 @@ JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned l return 0; } +JSStringRef AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length) +{ + NSRange range = NSMakeRange(location, length); + BEGIN_AX_OBJC_EXCEPTIONS + NSAttributedString* string = [m_element accessibilityAttributeValue:NSAccessibilityAttributedStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; + if (![string isKindOfClass:[NSAttributedString class]]) + return 0; + + NSString* stringWithAttrs = [string description]; + return [stringWithAttrs createJSStringRef]; + END_AX_OBJC_EXCEPTIONS + + return 0; +} + +bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length) +{ + NSRange range = NSMakeRange(location, length); + BEGIN_AX_OBJC_EXCEPTIONS + NSAttributedString* string = [m_element accessibilityAttributeValue:NSAccessibilityAttributedStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; + if (![string isKindOfClass:[NSAttributedString class]]) + return false; + + NSDictionary* attrs = [string attributesAtIndex:0 effectiveRange:nil]; + if([[attrs objectForKey:NSAccessibilityMisspelledTextAttribute] boolValue]) + return true; + END_AX_OBJC_EXCEPTIONS + + return false; +} + JSStringRef AccessibilityUIElement::attributesOfColumnHeaders() { // not yet defined in AppKit... odd diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp index 022a867..c6c39b5 100644 --- a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp +++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp @@ -130,16 +130,6 @@ public: }; #endif -void checkPermissionCallback(QObject* receiver, const QUrl& url, NotificationPermission& permission) -{ - qobject_cast<DumpRenderTree*>(receiver)->checkPermission(url, permission); -} - -void requestPermissionCallback(QObject* receiver, const QString& origin) -{ - qobject_cast<DumpRenderTree*>(receiver)->requestPermission(origin); -} - WebPage::WebPage(QObject* parent, DumpRenderTree* drt) : QWebPage(parent) , m_webInspector(0) @@ -167,10 +157,9 @@ WebPage::WebPage(QObject* parent, DumpRenderTree* drt) setNetworkAccessManager(m_drt->networkAccessManager()); setPluginFactory(new TestPlugin(this)); - DumpRenderTreeSupportQt::setNotificationsReceiver(m_drt); - DumpRenderTreeSupportQt::setCheckPermissionFunction(checkPermissionCallback); - DumpRenderTreeSupportQt::setRequestPermissionFunction(requestPermissionCallback); - + connect(this, SIGNAL(requestPermissionFromUser(QWebFrame*, QWebPage::PermissionDomain)), this, SLOT(requestPermission(QWebFrame*, QWebPage::PermissionDomain))); + connect(this, SIGNAL(checkPermissionFromUser(QWebFrame*, QWebPage::PermissionDomain, QWebPage::PermissionPolicy&)), this, SLOT(checkPermission(QWebFrame*, QWebPage::PermissionDomain, QWebPage::PermissionPolicy&))); + connect(this, SIGNAL(cancelRequestsForPermissionFromUser(QWebFrame*, QWebPage::PermissionDomain)), this, SLOT(cancelRequestsForPermissionFromUser(QWebFrame*, QWebPage::PermissionDomain))); } WebPage::~WebPage() @@ -228,6 +217,36 @@ void WebPage::javaScriptAlert(QWebFrame*, const QString& message) fprintf(stdout, "ALERT: %s\n", message.toUtf8().constData()); } +void WebPage::requestPermission(QWebFrame* frame, QWebPage::PermissionDomain domain) +{ + switch (domain) { + case NotificationsPermissionDomain: + if (!m_drt->layoutTestController()->ignoreReqestForPermission()) + setUserPermission(frame, domain, PermissionGranted); + break; + default: + break; + } +} + +void WebPage::checkPermission(QWebFrame* frame, QWebPage::PermissionDomain domain, QWebPage::PermissionPolicy& policy) +{ + switch (domain) { + case NotificationsPermissionDomain: + { + QUrl url = frame->url(); + policy = m_drt->layoutTestController()->checkDesktopNotificationPermission(url.scheme() + "://" + url.host()) ? PermissionGranted : PermissionDenied; + break; + } + default: + break; + } +} + +void WebPage::cancelRequestsForPermission(QWebFrame*, QWebPage::PermissionDomain) +{ +} + static QString urlSuitableForTestResult(const QString& url) { if (url.isEmpty() || !url.startsWith(QLatin1String("file://"))) @@ -992,16 +1011,6 @@ void DumpRenderTree::switchFocus(bool focused) } -void DumpRenderTree::checkPermission(const QUrl& url, NotificationPermission& permission) -{ - permission = m_controller->checkDesktopNotificationPermission(url.scheme() + "://" + url.host()) ? NotificationAllowed : NotificationDenied; -} - -void DumpRenderTree::requestPermission(const QString& origin) -{ - DumpRenderTreeSupportQt::allowNotificationForOrigin(origin); -} - #if defined(Q_WS_X11) void DumpRenderTree::initializeFonts() { diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h index f258189..de0c6c5 100644 --- a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h +++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h @@ -119,8 +119,6 @@ public Q_SLOTS: void dumpDatabaseQuota(QWebFrame* frame, const QString& dbName); void statusBarMessage(const QString& message); void windowCloseRequested(); - void checkPermission(const QUrl&, NotificationPermission&); - void requestPermission(const QString&); Q_SIGNALS: void quit(); @@ -193,6 +191,9 @@ public: public slots: bool shouldInterruptJavaScript() { return false; } bool allowGeolocationRequest(QWebFrame *frame); + void requestPermission(QWebFrame* frame, QWebPage::PermissionDomain domain); + void checkPermission(QWebFrame* frame, QWebPage::PermissionDomain domain, QWebPage::PermissionPolicy& policy); + void cancelRequestsForPermission(QWebFrame* frame, QWebPage::PermissionDomain domain); protected: bool acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, NavigationType type); diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp index 3a6229f..8ebdbae 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp @@ -67,6 +67,7 @@ void LayoutTestController::reset() m_globalFlag = false; m_userStyleSheetEnabled = false; m_desktopNotificationAllowedOrigins.clear(); + m_ignoreDesktopNotification = false; DumpRenderTreeSupportQt::dumpEditingCallbacks(false); DumpRenderTreeSupportQt::dumpFrameLoader(false); @@ -193,9 +194,14 @@ void LayoutTestController::grantDesktopNotificationPermission(const QString& ori m_desktopNotificationAllowedOrigins.append(origin); } +void LayoutTestController::ignoreDesktopNotificationPermissionRequests() +{ + m_ignoreDesktopNotification = true; +} + bool LayoutTestController::checkDesktopNotificationPermission(const QString& origin) { - return m_desktopNotificationAllowedOrigins.contains(origin); + return !m_ignoreDesktopNotification && m_desktopNotificationAllowedOrigins.contains(origin); } void LayoutTestController::display() diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h index 4e95381..4ebf99d 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h @@ -70,6 +70,7 @@ public: bool canOpenWindows() const { return m_canOpenWindows; } bool shouldDumpTitleChanges() const { return m_dumpTitleChanges; } bool waitForPolicy() const { return m_waitForPolicy; } + bool ignoreReqestForPermission() const { return m_ignoreDesktopNotification; } void reset(); @@ -120,6 +121,7 @@ public slots: void setCloseRemainingWindowsWhenComplete(bool = false) {} int windowCount(); void grantDesktopNotificationPermission(const QString& origin); + void ignoreDesktopNotificationPermissionRequests(); bool checkDesktopNotificationPermission(const QString& origin); void display(); void clearBackForwardList(); @@ -252,6 +254,7 @@ private: WebCore::DumpRenderTree* m_drt; QWebHistory* m_webHistory; QStringList m_desktopNotificationAllowedOrigins; + bool m_ignoreDesktopNotification; }; #endif // LayoutTestControllerQt_h diff --git a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp index 6aef32e..8c2fea2 100644 --- a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp +++ b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp @@ -450,6 +450,16 @@ JSStringRef AccessibilityUIElement::stringForRange(unsigned, unsigned) return JSStringCreateWithCharacters(0, 0); } +JSStringRef AccessibilityUIElement::attributedStringForRange(unsigned, unsigned) +{ + return JSStringCreateWithCharacters(0, 0); +} + +bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned, unsigned) +{ + return false; +} + AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row) { return 0; diff --git a/WebKitTools/DumpRenderTree/wscript b/WebKitTools/DumpRenderTree/wscript index 5e6c597..75d208f 100644 --- a/WebKitTools/DumpRenderTree/wscript +++ b/WebKitTools/DumpRenderTree/wscript @@ -33,6 +33,7 @@ include_paths = [ os.path.join(output_dir), os.path.join(wk_root, 'JavaScriptCore'), os.path.join(wk_root, 'WebCore'), + os.path.join(wk_root, 'WebCore', 'bindings', 'wx'), os.path.join(wk_root, 'WebKit', 'wx'), '.', 'wx' |