summaryrefslogtreecommitdiff
path: root/Tools/DumpRenderTree
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Tools/DumpRenderTree
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Tools/DumpRenderTree')
-rw-r--r--Tools/DumpRenderTree/AccessibilityController.cpp16
-rw-r--r--Tools/DumpRenderTree/AccessibilityController.h6
-rw-r--r--Tools/DumpRenderTree/AccessibilityTextMarker.h8
-rw-r--r--Tools/DumpRenderTree/AccessibilityUIElement.cpp462
-rw-r--r--Tools/DumpRenderTree/AccessibilityUIElement.h57
-rw-r--r--Tools/DumpRenderTree/CMakeLists.txt127
-rw-r--r--Tools/DumpRenderTree/DefaultPolicyDelegate.h13
-rw-r--r--Tools/DumpRenderTree/DumpRenderTree.h4
-rw-r--r--Tools/DumpRenderTree/DumpRenderTree.sln100
-rw-r--r--Tools/DumpRenderTree/DumpRenderTreeFileDraggingSource.h43
-rw-r--r--Tools/DumpRenderTree/DumpRenderTreePrefix.h13
-rw-r--r--Tools/DumpRenderTree/ForwardingHeaders/runtime/ArrayBufferView.h1
-rw-r--r--Tools/DumpRenderTree/ForwardingHeaders/runtime/JSArrayBufferView.h1
-rw-r--r--Tools/DumpRenderTree/ForwardingHeaders/runtime/JSExportMacros.h1
-rw-r--r--Tools/DumpRenderTree/ForwardingHeaders/runtime/TypedArrayInlines.h1
-rw-r--r--Tools/DumpRenderTree/GCController.cpp2
-rw-r--r--Tools/DumpRenderTree/GCController.h4
-rw-r--r--Tools/DumpRenderTree/JavaScriptThreading.cpp157
-rw-r--r--Tools/DumpRenderTree/JavaScriptThreading.h2
-rw-r--r--Tools/DumpRenderTree/PixelDumpSupport.cpp4
-rw-r--r--Tools/DumpRenderTree/PixelDumpSupport.h2
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt61
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp44
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp19
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h7
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSWithinNPP_New.cpp56
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/Tests/InvokeDestroysPluginWithinNPP_New.cpp67
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/Tests/PluginScriptableObjectOverridesAllProperties.cpp82
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/Tests/SlowNPPNew.cpp87
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp167
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp53
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/unix/ForwardingHeaders/WebKit/npapi.h (renamed from Tools/DumpRenderTree/TestNetscapePlugIn/ForwardingHeaders/WebKit/npapi.h)0
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/unix/ForwardingHeaders/WebKit/npfunctions.h (renamed from Tools/DumpRenderTree/TestNetscapePlugIn/ForwardingHeaders/WebKit/npfunctions.h)0
-rw-r--r--Tools/DumpRenderTree/TestNetscapePlugIn/unix/ForwardingHeaders/WebKit/npruntime.h (renamed from Tools/DumpRenderTree/TestNetscapePlugIn/ForwardingHeaders/WebKit/npruntime.h)0
-rw-r--r--Tools/DumpRenderTree/TestRunner.cpp162
-rw-r--r--Tools/DumpRenderTree/TestRunner.h34
-rw-r--r--Tools/DumpRenderTree/WorkQueue.cpp7
-rw-r--r--Tools/DumpRenderTree/WorkQueue.h8
-rw-r--r--Tools/DumpRenderTree/WorkQueueItem.h2
-rw-r--r--Tools/DumpRenderTree/atk/AccessibilityCallbacks.h44
-rw-r--r--Tools/DumpRenderTree/atk/AccessibilityCallbacksAtk.cpp297
-rw-r--r--Tools/DumpRenderTree/atk/AccessibilityControllerAtk.cpp145
-rw-r--r--Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.cpp55
-rw-r--r--Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.h51
-rw-r--r--Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp1604
-rw-r--r--Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp2
-rw-r--r--Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.h2
-rw-r--r--Tools/DumpRenderTree/config.h43
-rw-r--r--Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp79
-rw-r--r--Tools/DumpRenderTree/gtk/DumpRenderTree.cpp1557
-rw-r--r--Tools/DumpRenderTree/gtk/DumpRenderTreeGtk.h50
-rw-r--r--Tools/DumpRenderTree/gtk/EditingCallbacks.cpp202
-rw-r--r--Tools/DumpRenderTree/gtk/EditingCallbacks.h35
-rw-r--r--Tools/DumpRenderTree/gtk/EventSender.cpp1004
-rw-r--r--Tools/DumpRenderTree/gtk/EventSender.h42
-rw-r--r--Tools/DumpRenderTree/gtk/GCControllerGtk.cpp50
-rw-r--r--Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp115
-rw-r--r--Tools/DumpRenderTree/gtk/SelfScrollingWebKitWebView.cpp78
-rw-r--r--Tools/DumpRenderTree/gtk/SelfScrollingWebKitWebView.h51
-rw-r--r--Tools/DumpRenderTree/gtk/TestRunnerGtk.cpp914
-rw-r--r--Tools/DumpRenderTree/gtk/TextInputController.cpp215
-rw-r--r--Tools/DumpRenderTree/gtk/TextInputController.h37
-rw-r--r--Tools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp102
63 files changed, 7029 insertions, 1625 deletions
diff --git a/Tools/DumpRenderTree/AccessibilityController.cpp b/Tools/DumpRenderTree/AccessibilityController.cpp
index d035dea99..dd9996be8 100644
--- a/Tools/DumpRenderTree/AccessibilityController.cpp
+++ b/Tools/DumpRenderTree/AccessibilityController.cpp
@@ -130,20 +130,6 @@ static JSValueRef removeNotificationListenerCallback(JSContextRef context, JSObj
return JSValueMakeUndefined(context);
}
-static JSValueRef enableEnhancedAccessibilityCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityController* controller = static_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount == 1)
- controller->enableEnhancedAccessibility(JSValueToBoolean(context, arguments[0]));
- return JSValueMakeUndefined(context);
-}
-
-static JSValueRef getEnhancedAccessibilityEnabledCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
-{
- AccessibilityController* controller = static_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeBoolean(context, controller->enhancedAccessibilityEnabled());
-}
-
static JSValueRef getPlatformNameCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
AccessibilityController* controller = static_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
@@ -164,14 +150,12 @@ JSClassRef AccessibilityController::getJSClass()
{ "accessibleElementById", getAccessibleElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "addNotificationListener", addNotificationListenerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "removeNotificationListener", removeNotificationListenerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "enableEnhancedAccessibility", enableEnhancedAccessibilityCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ 0, 0, 0 }
};
static JSStaticValue staticValues[] = {
{ "focusedElement", getFocusedElementCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "rootElement", getRootElementCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "enhancedAccessibilityEnabled", getEnhancedAccessibilityEnabledCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "platformName", getPlatformNameCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ 0, 0, 0, 0 }
};
diff --git a/Tools/DumpRenderTree/AccessibilityController.h b/Tools/DumpRenderTree/AccessibilityController.h
index 9f66dd6ee..2f4f6ae9e 100644
--- a/Tools/DumpRenderTree/AccessibilityController.h
+++ b/Tools/DumpRenderTree/AccessibilityController.h
@@ -64,10 +64,6 @@ public:
bool addNotificationListener(JSObjectRef functionCallback);
void removeNotificationListener();
- // Enhanced accessibility.
- void enableEnhancedAccessibility(bool);
- bool enhancedAccessibilityEnabled();
-
JSRetainPtr<JSStringRef> platformName() const;
#if PLATFORM(WIN)
@@ -93,7 +89,7 @@ private:
HashMap<PlatformUIElement, JSObjectRef> m_notificationListeners;
#endif
-#if PLATFORM(COCOA) || PLATFORM(IOS)
+#if PLATFORM(MAC)
RetainPtr<NotificationHandler> m_globalNotificationHandler;
#endif
diff --git a/Tools/DumpRenderTree/AccessibilityTextMarker.h b/Tools/DumpRenderTree/AccessibilityTextMarker.h
index 7809ea459..b890e28a9 100644
--- a/Tools/DumpRenderTree/AccessibilityTextMarker.h
+++ b/Tools/DumpRenderTree/AccessibilityTextMarker.h
@@ -28,13 +28,13 @@
#include <JavaScriptCore/JSObjectRef.h>
-#if PLATFORM(MAC) || PLATFORM(IOS)
+#if PLATFORM(MAC) && !PLATFORM(IOS)
#define SUPPORTS_AX_TEXTMARKERS 1
#else
#define SUPPORTS_AX_TEXTMARKERS 0
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
#include <wtf/RetainPtr.h>
typedef CFTypeRef PlatformTextMarker;
typedef CFTypeRef PlatformTextMarkerRange;
@@ -58,7 +58,7 @@ public:
private:
static JSClassRef getJSClass();
-#if SUPPORTS_AX_TEXTMARKERS && PLATFORM(MAC)
+#if SUPPORTS_AX_TEXTMARKERS
RetainPtr<PlatformTextMarker> m_textMarker;
#else
PlatformTextMarker m_textMarker;
@@ -78,7 +78,7 @@ public:
private:
static JSClassRef getJSClass();
-#if SUPPORTS_AX_TEXTMARKERS && PLATFORM(MAC)
+#if SUPPORTS_AX_TEXTMARKERS
RetainPtr<PlatformTextMarkerRange> m_textMarkerRange;
#else
PlatformTextMarkerRange m_textMarkerRange;
diff --git a/Tools/DumpRenderTree/AccessibilityUIElement.cpp b/Tools/DumpRenderTree/AccessibilityUIElement.cpp
index 1d77d7717..793b3103d 100644
--- a/Tools/DumpRenderTree/AccessibilityUIElement.cpp
+++ b/Tools/DumpRenderTree/AccessibilityUIElement.cpp
@@ -209,8 +209,7 @@ static JSValueRef uiElementCountForSearchPredicateCallback(JSContextRef context,
JSValueRef searchKey = nullptr;
JSRetainPtr<JSStringRef> searchText = nullptr;
bool visibleOnly = false;
- bool immediateDescendantsOnly = false;
- if (argumentCount >= 5 && argumentCount <= 6) {
+ if (argumentCount == 5) {
if (JSValueIsObject(context, arguments[0]))
startElement = toAXElement(JSValueToObject(context, arguments[0], exception));
@@ -222,12 +221,9 @@ static JSValueRef uiElementCountForSearchPredicateCallback(JSContextRef context,
searchText.adopt(JSValueToStringCopy(context, arguments[3], exception));
visibleOnly = JSValueToBoolean(context, arguments[4]);
-
- if (argumentCount == 6)
- immediateDescendantsOnly = JSValueToBoolean(context, arguments[5]);
}
- return JSValueMakeNumber(context, toAXElement(thisObject)->uiElementCountForSearchPredicate(context, startElement, isDirectionNext, searchKey, searchText.get(), visibleOnly, immediateDescendantsOnly));
+ return JSValueMakeNumber(context, toAXElement(thisObject)->uiElementCountForSearchPredicate(context, startElement, isDirectionNext, searchKey, searchText.get(), visibleOnly));
}
static JSValueRef uiElementForSearchPredicateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -237,8 +233,7 @@ static JSValueRef uiElementForSearchPredicateCallback(JSContextRef context, JSOb
JSValueRef searchKey = nullptr;
JSRetainPtr<JSStringRef> searchText = nullptr;
bool visibleOnly = false;
- bool immediateDescendantsOnly = false;
- if (argumentCount >= 5 && argumentCount <= 6) {
+ if (argumentCount == 5) {
if (JSValueIsObject(context, arguments[0]))
startElement = toAXElement(JSValueToObject(context, arguments[0], exception));
@@ -250,34 +245,9 @@ static JSValueRef uiElementForSearchPredicateCallback(JSContextRef context, JSOb
searchText.adopt(JSValueToStringCopy(context, arguments[3], exception));
visibleOnly = JSValueToBoolean(context, arguments[4]);
-
- if (argumentCount == 6)
- immediateDescendantsOnly = JSValueToBoolean(context, arguments[5]);
}
- return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->uiElementForSearchPredicate(context, startElement, isDirectionNext, searchKey, searchText.get(), visibleOnly, immediateDescendantsOnly));
-}
-
-static JSValueRef selectTextWithCriteriaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- if (argumentCount < 2 || argumentCount > 4)
- return JSValueMakeUndefined(context);
-
- JSRetainPtr<JSStringRef> ambiguityResolution(Adopt, JSValueToStringCopy(context, arguments[0], exception));
- JSValueRef searchStrings = arguments[1];
- JSStringRef replacementString = nullptr;
- if (argumentCount == 3)
- replacementString = JSValueToStringCopy(context, arguments[2], exception);
- JSStringRef activityString = nullptr;
- if (argumentCount == 4)
- activityString = JSValueToStringCopy(context, arguments[3], exception);
-
- JSRetainPtr<JSStringRef> result(Adopt, toAXElement(thisObject)->selectTextWithCriteria(context, ambiguityResolution.get(), searchStrings, replacementString, activityString));
- if (replacementString)
- JSStringRelease(replacementString);
- if (activityString)
- JSStringRelease(activityString);
- return JSValueMakeString(context, result.get());
+ return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->uiElementForSearchPredicate(context, startElement, isDirectionNext, searchKey, searchText.get(), visibleOnly));
}
static JSValueRef indexOfChildCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -317,13 +287,12 @@ static JSValueRef elementsForRangeCallback(JSContextRef context, JSObjectRef fun
Vector<AccessibilityUIElement> elements;
toAXElement(thisObject)->elementsForRange(location, length, elements);
- JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0);
- JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0);
unsigned elementsSize = elements.size();
+ JSValueRef valueElements[elementsSize];
for (unsigned k = 0; k < elementsSize; ++k)
- JSObjectSetPropertyAtIndex(context, arrayObj, k, AccessibilityUIElement::makeJSAccessibilityUIElement(context, elements[k]), 0);
+ valueElements[k] = AccessibilityUIElement::makeJSAccessibilityUIElement(context, elements[k]);
- return arrayResult;
+ return JSObjectMakeArray(context, elementsSize, valueElements, 0);
}
static JSValueRef increaseTextSelectionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -332,26 +301,6 @@ static JSValueRef increaseTextSelectionCallback(JSContextRef context, JSObjectRe
return JSValueMakeUndefined(context);
}
-static JSValueRef scrollPageUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- return JSValueMakeBoolean(context, toAXElement(thisObject)->scrollPageUp());
-}
-
-static JSValueRef scrollPageDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- return JSValueMakeBoolean(context, toAXElement(thisObject)->scrollPageDown());
-}
-
-static JSValueRef scrollPageLeftCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- return JSValueMakeBoolean(context, toAXElement(thisObject)->scrollPageLeft());
-}
-
-static JSValueRef scrollPageRightCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- return JSValueMakeBoolean(context, toAXElement(thisObject)->scrollPageRight());
-}
-
static JSValueRef decreaseTextSelectionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
toAXElement(thisObject)->decreaseTextSelection();
@@ -364,11 +313,6 @@ static JSValueRef assistiveTechnologySimulatedFocusCallback(JSContextRef context
return JSValueMakeUndefined(context);
}
-static JSValueRef fieldsetAncestorElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->fieldsetAncestorElement());
-}
-
#endif
static JSValueRef childAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -425,15 +369,6 @@ static JSValueRef ariaFlowToElementAtIndexCallback(JSContextRef context, JSObjec
return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->ariaFlowToElementAtIndex(indexNumber));
}
-static JSValueRef ariaControlsElementAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- int indexNumber = 0;
- if (argumentCount == 1)
- indexNumber = JSValueToNumber(context, arguments[0], exception);
-
- return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->ariaControlsElementAtIndex(indexNumber));
-}
-
static JSValueRef selectedRowAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
int indexNumber = 0;
@@ -463,19 +398,6 @@ static JSValueRef isEqualCallback(JSContextRef context, JSObjectRef function, JS
return JSValueMakeBoolean(context, toAXElement(thisObject)->isEqual(toAXElement(otherElement)));
}
-static JSValueRef setValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- JSRetainPtr<JSStringRef> valueText = 0;
- if (argumentCount == 1) {
- if (JSValueIsString(context, arguments[0]))
- valueText.adopt(JSValueToStringCopy(context, arguments[0], exception));
- }
-
- toAXElement(thisObject)->setValue(valueText.get());
-
- return JSValueMakeUndefined(context);
-}
-
static JSValueRef setSelectedChildCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
JSObjectRef element = 0;
@@ -487,24 +409,6 @@ static JSValueRef setSelectedChildCallback(JSContextRef context, JSObjectRef fun
return JSValueMakeUndefined(context);
}
-static JSValueRef setSelectedChildAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- if (argumentCount == 1) {
- unsigned indexNumber = JSValueToNumber(context, arguments[0], exception);
- toAXElement(thisObject)->setSelectedChildAtIndex(indexNumber);
- }
- return JSValueMakeUndefined(context);
-}
-
-static JSValueRef removeSelectionAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- if (argumentCount == 1) {
- unsigned indexNumber = JSValueToNumber(context, arguments[0], exception);
- toAXElement(thisObject)->removeSelectionAtIndex(indexNumber);
- }
- return JSValueMakeUndefined(context);
-}
-
static JSValueRef elementAtPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
int x = 0;
@@ -566,20 +470,6 @@ static JSValueRef boolAttributeValueCallback(JSContextRef context, JSObjectRef f
return result;
}
-static JSValueRef setBoolAttributeValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- JSStringRef attribute = nullptr;
- bool value = false;
- if (argumentCount == 2) {
- attribute = JSValueToStringCopy(context, arguments[0], exception);
- value = JSValueToBoolean(context, arguments[1]);
- }
- toAXElement(thisObject)->setBoolAttributeValue(attribute, value);
- if (attribute)
- JSStringRelease(attribute);
- return JSValueMakeUndefined(context);
-}
-
static JSValueRef stringAttributeValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
JSStringRef attribute = 0;
@@ -594,14 +484,12 @@ static JSValueRef stringAttributeValueCallback(JSContextRef context, JSObjectRef
static JSValueRef convertElementsToObjectArray(JSContextRef context, Vector<AccessibilityUIElement>& elements, JSValueRef* exception)
{
- JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0);
- JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0);
-
size_t elementCount = elements.size();
+ auto valueElements = std::make_unique<JSValueRef[]>(elementCount);
for (size_t i = 0; i < elementCount; ++i)
- JSObjectSetPropertyAtIndex(context, arrayObj, i, AccessibilityUIElement::makeJSAccessibilityUIElement(context, elements[i]), 0);
-
- return arrayResult;
+ valueElements[i] = AccessibilityUIElement::makeJSAccessibilityUIElement(context, elements[i]);
+
+ return JSObjectMakeArray(context, elementCount, valueElements.get(), exception);
}
static JSValueRef columnHeadersCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -713,36 +601,6 @@ static JSValueRef pressCallback(JSContextRef context, JSObjectRef function, JSOb
return JSValueMakeUndefined(context);
}
-static JSValueRef scrollToMakeVisibleWithSubFocusCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- unsigned x = 0;
- unsigned y = 0;
- unsigned width = 0;
- unsigned height = 0;
- if (argumentCount == 4) {
- x = JSValueToNumber(context, arguments[0], exception);
- y = JSValueToNumber(context, arguments[1], exception);
- width = JSValueToNumber(context, arguments[2], exception);
- height = JSValueToNumber(context, arguments[3], exception);
- }
-
- toAXElement(thisObject)->scrollToMakeVisibleWithSubFocus(x, y, width, height);
- return JSValueMakeUndefined(context);
-}
-
-static JSValueRef scrollToGlobalPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- unsigned x = 0;
- unsigned y = 0;
- if (argumentCount == 2) {
- x = JSValueToNumber(context, arguments[0], exception);
- y = JSValueToNumber(context, arguments[1], exception);
- }
-
- toAXElement(thisObject)->scrollToGlobalPoint(x, y);
- return JSValueMakeUndefined(context);
-}
-
static JSValueRef scrollToMakeVisibleCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
toAXElement(thisObject)->scrollToMakeVisible();
@@ -773,14 +631,6 @@ static JSValueRef removeSelectionCallback(JSContextRef context, JSObjectRef func
return JSValueMakeUndefined(context);
}
-static JSValueRef lineTextMarkerRangeForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* textMarker = nullptr;
- if (argumentCount == 1)
- textMarker = toTextMarker(JSValueToObject(context, arguments[0], exception));
- return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->lineTextMarkerRangeForTextMarker(textMarker));
-}
-
static JSValueRef textMarkerRangeForElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
AccessibilityUIElement* uiElement = 0;
@@ -790,17 +640,6 @@ static JSValueRef textMarkerRangeForElementCallback(JSContextRef context, JSObje
return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->textMarkerRangeForElement(uiElement));
}
-static JSValueRef selectedTextMarkerRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->selectedTextMarkerRange());
-}
-
-static JSValueRef resetSelectedTextMarkerRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- toAXElement(thisObject)->resetSelectedTextMarkerRange();
- return JSValueMakeUndefined(context);
-}
-
static JSValueRef attributedStringForTextMarkerRangeContainsAttributeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
AccessibilityTextMarkerRange* markerRange = 0;
@@ -974,109 +813,6 @@ static JSValueRef endTextMarkerCallback(JSContextRef context, JSObjectRef thisOb
return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->endTextMarker());
}
-static JSValueRef leftWordTextMarkerRangeForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->leftWordTextMarkerRangeForTextMarker(marker));
-}
-
-static JSValueRef rightWordTextMarkerRangeForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->rightWordTextMarkerRangeForTextMarker(marker));
-}
-
-static JSValueRef previousWordStartTextMarkerForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->previousWordStartTextMarkerForTextMarker(marker));
-}
-
-static JSValueRef nextWordEndTextMarkerForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->nextWordEndTextMarkerForTextMarker(marker));
-}
-
-static JSValueRef paragraphTextMarkerRangeForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->paragraphTextMarkerRangeForTextMarker(marker));
-}
-
-static JSValueRef previousParagraphStartTextMarkerForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->previousParagraphStartTextMarkerForTextMarker(marker));
-}
-
-static JSValueRef nextParagraphEndTextMarkerForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->nextParagraphEndTextMarkerForTextMarker(marker));
-}
-
-static JSValueRef sentenceTextMarkerRangeForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->sentenceTextMarkerRangeForTextMarker(marker));
-}
-
-static JSValueRef previousSentenceStartTextMarkerForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->previousSentenceStartTextMarkerForTextMarker(marker));
-}
-
-static JSValueRef nextSentenceEndTextMarkerForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityTextMarker* marker = nullptr;
- if (argumentCount == 1)
- marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
-
- return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->nextSentenceEndTextMarkerForTextMarker(marker));
-}
-
-static JSValueRef setSelectedVisibleTextRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- AccessibilityUIElement* uiElement = toAXElement(thisObject);
- AccessibilityTextMarkerRange* textMarkerRange = nullptr;
- if (argumentCount == 1)
- textMarkerRange = toTextMarkerRange(JSValueToObject(context, arguments[0], exception));
-
- if (uiElement)
- return JSValueMakeBoolean(context, uiElement->setSelectedVisibleTextRange(textMarkerRange));
-
- return JSValueMakeBoolean(context, false);
-}
-
// Static Value Getters
static JSValueRef getARIADropEffectsCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
@@ -1125,12 +861,6 @@ static JSValueRef getRoleDescriptionCallback(JSContextRef context, JSObjectRef t
return JSValueMakeString(context, roleDesc.get());
}
-static JSValueRef getComputedRoleStringCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
-{
- JSRetainPtr<JSStringRef> compRole(Adopt, toAXElement(thisObject)->computedRoleString());
- return JSValueMakeString(context, compRole.get());
-}
-
static JSValueRef getTitleCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
JSRetainPtr<JSStringRef> title(Adopt, toAXElement(thisObject)->title());
@@ -1439,48 +1169,56 @@ static JSValueRef sentenceAtOffsetCallback(JSContextRef context, JSObjectRef fun
#elif PLATFORM(IOS)
-static JSValueRef getIsSearchFieldCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+static JSValueRef stringForSelectionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
- return JSValueMakeBoolean(context, toAXElement(thisObject)->isSearchField());
+ JSRetainPtr<JSStringRef> labelString(Adopt, toAXElement(thisObject)->stringForSelection());
+ return JSValueMakeString(context, labelString.get());
}
-static JSValueRef getIsTextAreaCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+static JSValueRef getIPhoneLabelCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
- return JSValueMakeBoolean(context, toAXElement(thisObject)->isTextArea());
+ JSRetainPtr<JSStringRef> labelString(Adopt, toAXElement(thisObject)->iphoneLabel());
+ return JSValueMakeString(context, labelString.get());
}
-static JSValueRef stringForSelectionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+static JSValueRef getIPhoneHintCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
- JSRetainPtr<JSStringRef> labelString(Adopt, toAXElement(thisObject)->stringForSelection());
- return JSValueMakeString(context, labelString.get());
+ JSRetainPtr<JSStringRef> hintString(Adopt, toAXElement(thisObject)->iphoneHint());
+ return JSValueMakeString(context, hintString.get());
}
-static JSValueRef getIdentifierCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+static JSValueRef getIPhoneValueCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
- JSRetainPtr<JSStringRef> valueString(Adopt, toAXElement(thisObject)->identifier());
+ JSRetainPtr<JSStringRef> valueString(Adopt, toAXElement(thisObject)->iphoneValue());
+ return JSValueMakeString(context, valueString.get());
+}
+
+static JSValueRef getIPhoneIdentifierCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> valueString(Adopt, toAXElement(thisObject)->iphoneIdentifier());
return JSValueMakeString(context, valueString.get());
}
-static JSValueRef getTraitsCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+static JSValueRef getIPhoneTraitsCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
- JSRetainPtr<JSStringRef> valueString(Adopt, toAXElement(thisObject)->traits());
+ JSRetainPtr<JSStringRef> valueString(Adopt, toAXElement(thisObject)->iphoneTraits());
return JSValueMakeString(context, valueString.get());
}
-static JSValueRef getElementTextPositionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+static JSValueRef getIPhoneIsElementCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
- return JSValueMakeNumber(context, toAXElement(thisObject)->elementTextPosition());
+ return JSValueMakeBoolean(context, toAXElement(thisObject)->iphoneIsElement());
}
-static JSValueRef getElementTextLengthCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+static JSValueRef getIPhoneElementTextPositionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
- return JSValueMakeNumber(context, toAXElement(thisObject)->elementTextLength());
+ return JSValueMakeNumber(context, toAXElement(thisObject)->iphoneElementTextPosition());
}
-static JSValueRef hasContainedByFieldsetTraitCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
+static JSValueRef getIPhoneElementTextLengthCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
- return JSValueMakeBoolean(context, toAXElement(thisObject)->hasContainedByFieldsetTrait());
+ return JSValueMakeNumber(context, toAXElement(thisObject)->iphoneElementTextLength());
}
#endif // PLATFORM(IOS)
@@ -1514,8 +1252,8 @@ JSStringRef AccessibilityUIElement::speak() { return 0; }
JSStringRef AccessibilityUIElement::rangeForLine(int line) { return 0; }
JSStringRef AccessibilityUIElement::rangeForPosition(int, int) { return 0; }
void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement*) const { }
-void AccessibilityUIElement::setSelectedChildAtIndex(unsigned) const { }
-void AccessibilityUIElement::removeSelectionAtIndex(unsigned) const { }
+unsigned AccessibilityUIElement::selectedChildrenCount() const { return 0; }
+AccessibilityUIElement AccessibilityUIElement::selectedChildAtIndex(unsigned) const { return 0; }
AccessibilityUIElement AccessibilityUIElement::horizontalScrollbar() const { return 0; }
AccessibilityUIElement AccessibilityUIElement::verticalScrollbar() const { return 0; }
AccessibilityUIElement AccessibilityUIElement::uiElementAttributeValue(JSStringRef) const { return 0; }
@@ -1523,11 +1261,12 @@ AccessibilityUIElement AccessibilityUIElement::uiElementAttributeValue(JSStringR
#if !PLATFORM(MAC) && !PLATFORM(IOS)
JSStringRef AccessibilityUIElement::pathDescription() const { return 0; }
-void AccessibilityUIElement::setValue(JSStringRef) { }
#endif
-#if !PLATFORM(COCOA)
+#if !PLATFORM(MAC)
void AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef, Vector<AccessibilityUIElement>&) const { }
+void AccessibilityUIElement::columnHeaders(Vector<AccessibilityUIElement>&) const { }
+void AccessibilityUIElement::rowHeaders(Vector<AccessibilityUIElement>&) const { }
#endif
#if !PLATFORM(WIN)
@@ -1539,31 +1278,13 @@ bool AccessibilityUIElement::isEqual(AccessibilityUIElement* otherElement)
}
#endif
-#if !PLATFORM(MAC)
-void AccessibilityUIElement::setBoolAttributeValue(JSStringRef, bool) { }
-#endif
-
#if !SUPPORTS_AX_TEXTMARKERS
-AccessibilityTextMarkerRange AccessibilityUIElement::lineTextMarkerRangeForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement*)
{
return 0;
}
-AccessibilityTextMarkerRange AccessibilityUIElement::selectedTextMarkerRange()
-{
- return nullptr;
-}
-
-void AccessibilityUIElement::resetSelectedTextMarkerRange()
-{
-}
-
int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange*)
{
return 0;
@@ -1649,61 +1370,6 @@ AccessibilityTextMarker AccessibilityUIElement::endTextMarker()
return nullptr;
}
-bool AccessibilityUIElement::setSelectedVisibleTextRange(AccessibilityTextMarkerRange*)
-{
- return false;
-}
-
-AccessibilityTextMarkerRange AccessibilityUIElement::leftWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
-AccessibilityTextMarkerRange AccessibilityUIElement::rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
-AccessibilityTextMarker AccessibilityUIElement::previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
-AccessibilityTextMarker AccessibilityUIElement::nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
-AccessibilityTextMarkerRange AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
-AccessibilityTextMarker AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
-AccessibilityTextMarker AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
-AccessibilityTextMarkerRange AccessibilityUIElement::sentenceTextMarkerRangeForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
-AccessibilityTextMarker AccessibilityUIElement::previousSentenceStartTextMarkerForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
-AccessibilityTextMarker AccessibilityUIElement::nextSentenceEndTextMarkerForTextMarker(AccessibilityTextMarker*)
-{
- return nullptr;
-}
-
#endif
// Destruction
@@ -1730,7 +1396,6 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "role", getRoleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "subrole", getSubroleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "roleDescription", getRoleDescriptionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "computedRoleString", getComputedRoleStringCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "title", getTitleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "description", getDescriptionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "language", getLanguageCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1784,14 +1449,15 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "startTextMarker", startTextMarkerCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "endTextMarker", endTextMarkerCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
#if PLATFORM(IOS)
- { "identifier", getIdentifierCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "traits", getTraitsCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "elementTextPosition", getElementTextPositionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "elementTextLength", getElementTextLengthCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "iphoneLabel", getIPhoneLabelCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "iphoneHint", getIPhoneHintCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "iphoneValue", getIPhoneValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "iphoneIdentifier", getIPhoneIdentifierCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "iphoneTraits", getIPhoneTraitsCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "iphoneIsElement", getIPhoneIsElementCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "iphoneElementTextPosition", getIPhoneElementTextPositionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "iphoneElementTextLength", getIPhoneElementTextLengthCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "stringForSelection", stringForSelectionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "hasContainedByFieldsetTrait", hasContainedByFieldsetTraitCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "isSearchField", getIsSearchFieldCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "isTextArea", getIsTextAreaCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
#endif // PLATFORM(IOS)
#if PLATFORM(MAC) && !PLATFORM(IOS)
{ "supportedActions", supportedActionsCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1814,9 +1480,8 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "stringForRange", stringForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "attributedStringForRange", attributedStringForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "attributedStringRangeIsMisspelled", attributedStringRangeIsMisspelledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "uiElementCountForSearchPredicate", uiElementCountForSearchPredicateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "uiElementCountForSearchPredicate", uiElementCountForSearchPredicateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeReadOnly },
{ "uiElementForSearchPredicate", uiElementForSearchPredicateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "selectTextWithCriteria", selectTextWithCriteriaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "linkedUIElementAtIndex", linkedUIElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "indexOfChild", indexOfChildCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1840,7 +1505,6 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "uiElementAttributeValue", uiElementAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "numberAttributeValue", numberAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "boolAttributeValue", boolAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "setBoolAttributeValue", setBoolAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "isAttributeSupported", isAttributeSupportedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "isAttributeSettable", isAttributeSettableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "isPressActionSupported", isPressActionSupportedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1855,7 +1519,6 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "disclosedRowAtIndex", disclosedRowAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "ariaOwnsElementAtIndex", ariaOwnsElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "ariaFlowToElementAtIndex", ariaFlowToElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "ariaControlsElementAtIndex", ariaControlsElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "selectedRowAtIndex", selectedRowAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "rowAtIndex", rowAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "isEqual", isEqualCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1865,10 +1528,7 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "takeSelection", takeSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "addSelection", addSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "removeSelection", removeSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "lineTextMarkerRangeForTextMarker", lineTextMarkerRangeForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "textMarkerRangeForElement", textMarkerRangeForElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "selectedTextMarkerRange", selectedTextMarkerRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "resetSelectedTextMarkerRange", resetSelectedTextMarkerRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "attributedStringForTextMarkerRangeContainsAttribute", attributedStringForTextMarkerRangeContainsAttributeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "indexForTextMarker", indexForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "isTextMarkerValid", isTextMarkerValidCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1884,25 +1544,9 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "nextTextMarker", nextTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "previousTextMarker", previousTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "stringForTextMarkerRange", stringForTextMarkerRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "leftWordTextMarkerRangeForTextMarker", leftWordTextMarkerRangeForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "rightWordTextMarkerRangeForTextMarker", rightWordTextMarkerRangeForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "previousWordStartTextMarkerForTextMarker", previousWordStartTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "nextWordEndTextMarkerForTextMarker", nextWordEndTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "paragraphTextMarkerRangeForTextMarker", paragraphTextMarkerRangeForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "previousParagraphStartTextMarkerForTextMarker", previousParagraphStartTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "nextParagraphEndTextMarkerForTextMarker", nextParagraphEndTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "sentenceTextMarkerRangeForTextMarker", sentenceTextMarkerRangeForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "previousSentenceStartTextMarkerForTextMarker", previousSentenceStartTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "nextSentenceEndTextMarkerForTextMarker", nextSentenceEndTextMarkerForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setSelectedChild", setSelectedChildCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "setSelectedChildAtIndex", setSelectedChildAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "removeSelectionAtIndex", removeSelectionAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "setValue", setValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "setSelectedVisibleTextRange", setSelectedVisibleTextRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "selectedChildAtIndex", selectedChildAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "scrollToMakeVisible", scrollToMakeVisibleCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "scrollToGlobalPoint", scrollToGlobalPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "scrollToMakeVisibleWithSubFocus", scrollToMakeVisibleWithSubFocusCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
#if PLATFORM(GTK) || PLATFORM(EFL)
{ "characterAtOffset", characterAtOffsetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "wordAtOffset", wordAtOffsetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1914,12 +1558,8 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "elementsForRange", elementsForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "increaseTextSelection", increaseTextSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "decreaseTextSelection", decreaseTextSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "scrollPageUp", scrollPageUpCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "scrollPageDown", scrollPageDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "scrollPageLeft", scrollPageLeftCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "scrollPageRight", scrollPageRightCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "assistiveTechnologySimulatedFocus", assistiveTechnologySimulatedFocusCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "fieldsetAncestorElement", fieldsetAncestorElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+
#endif
{ 0, 0, 0 }
};
diff --git a/Tools/DumpRenderTree/AccessibilityUIElement.h b/Tools/DumpRenderTree/AccessibilityUIElement.h
index 4abf9e9aa..f1f21b69b 100644
--- a/Tools/DumpRenderTree/AccessibilityUIElement.h
+++ b/Tools/DumpRenderTree/AccessibilityUIElement.h
@@ -31,7 +31,7 @@
#include <wtf/Platform.h>
#include <wtf/Vector.h>
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
#ifdef __OBJC__
typedef id PlatformUIElement;
#else
@@ -53,7 +53,7 @@ typedef AtkObject* PlatformUIElement;
typedef void* PlatformUIElement;
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
#ifdef __OBJC__
typedef id NotificationHandler;
#else
@@ -109,7 +109,6 @@ public:
void uiElementArrayAttributeValue(JSStringRef attribute, Vector<AccessibilityUIElement>& elements) const;
AccessibilityUIElement uiElementAttributeValue(JSStringRef attribute) const;
bool boolAttributeValue(JSStringRef attribute);
- void setBoolAttributeValue(JSStringRef attribute, bool value);
bool isAttributeSupported(JSStringRef attribute);
bool isAttributeSettable(JSStringRef attribute);
bool isPressActionSupported();
@@ -118,13 +117,11 @@ public:
JSStringRef role();
JSStringRef subrole();
JSStringRef roleDescription();
- JSStringRef computedRoleString();
JSStringRef title();
JSStringRef description();
JSStringRef language();
JSStringRef stringValue();
JSStringRef accessibilityValue() const;
- void setValue(JSStringRef);
JSStringRef helpText() const;
JSStringRef orientation() const;
double x();
@@ -150,8 +147,6 @@ public:
void setSelectedChild(AccessibilityUIElement*) const;
unsigned selectedChildrenCount() const;
AccessibilityUIElement selectedChildAtIndex(unsigned) const;
- void setSelectedChildAtIndex(unsigned) const;
- void removeSelectionAtIndex(unsigned) const;
bool isExpanded() const;
bool isChecked() const;
@@ -196,7 +191,6 @@ public:
// ARIA specific
AccessibilityUIElement ariaOwnsElementAtIndex(unsigned);
AccessibilityUIElement ariaFlowToElementAtIndex(unsigned);
- AccessibilityUIElement ariaControlsElementAtIndex(unsigned);
// ARIA Drag and Drop
bool ariaIsGrabbed() const;
@@ -212,23 +206,14 @@ public:
JSStringRef stringForRange(unsigned location, unsigned length);
JSStringRef attributedStringForRange(unsigned location, unsigned length);
bool attributedStringRangeIsMisspelled(unsigned location, unsigned length);
- unsigned uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
- AccessibilityUIElement uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
- JSStringRef selectTextWithCriteria(JSContextRef, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity);
+ unsigned uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly);
+ AccessibilityUIElement uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly);
#if PLATFORM(IOS)
void elementsForRange(unsigned location, unsigned length, Vector<AccessibilityUIElement>& elements);
JSStringRef stringForSelection();
void increaseTextSelection();
void decreaseTextSelection();
AccessibilityUIElement linkedElement();
-
- bool scrollPageUp();
- bool scrollPageDown();
- bool scrollPageLeft();
- bool scrollPageRight();
-
- bool hasContainedByFieldsetTrait();
- AccessibilityUIElement fieldsetAncestorElement();
#endif
#if PLATFORM(GTK) || PLATFORM(EFL)
@@ -247,7 +232,6 @@ public:
AccessibilityUIElement verticalScrollbar() const;
// Text markers.
- AccessibilityTextMarkerRange lineTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
AccessibilityTextMarkerRange textMarkerRangeForElement(AccessibilityUIElement*);
AccessibilityTextMarkerRange textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker);
AccessibilityTextMarker startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
@@ -260,19 +244,6 @@ public:
AccessibilityUIElement accessibilityElementForTextMarker(AccessibilityTextMarker*);
AccessibilityTextMarker startTextMarker();
AccessibilityTextMarker endTextMarker();
- AccessibilityTextMarkerRange leftWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarkerRange rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarker previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarker nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarkerRange paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarker previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarker nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarkerRange sentenceTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarker previousSentenceStartTextMarkerForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarker nextSentenceEndTextMarkerForTextMarker(AccessibilityTextMarker*);
- AccessibilityTextMarkerRange selectedTextMarkerRange();
- void resetSelectedTextMarkerRange();
- bool setSelectedVisibleTextRange(AccessibilityTextMarkerRange*);
JSStringRef stringForTextMarkerRange(AccessibilityTextMarkerRange*);
int textMarkerRangeLength(AccessibilityTextMarkerRange*);
@@ -292,17 +263,17 @@ public:
void removeNotificationListener();
#if PLATFORM(IOS)
- JSStringRef traits();
- JSStringRef identifier();
- int elementTextPosition();
- int elementTextLength();
+ JSStringRef iphoneLabel();
+ JSStringRef iphoneValue();
+ JSStringRef iphoneTraits();
+ JSStringRef iphoneHint();
+ JSStringRef iphoneIdentifier();
+ bool iphoneIsElement();
+ int iphoneElementTextPosition();
+ int iphoneElementTextLength();
AccessibilityUIElement headerElementAtIndex(unsigned);
// This will simulate the accessibilityDidBecomeFocused API in UIKit.
void assistiveTechnologySimulatedFocus();
-
- bool isTextArea() const;
- bool isSearchField() const;
-
#endif // PLATFORM(IOS)
#if PLATFORM(MAC) && !PLATFORM(IOS)
@@ -318,7 +289,9 @@ private:
static JSClassRef getJSClass();
PlatformUIElement m_element;
-#if PLATFORM(COCOA)
+#if PLATFORM(IOS)
+ JSObjectRef m_notificationFunctionCallback;
+#elif PLATFORM(MAC)
// A retained, platform specific object used to help manage notifications for this object.
NotificationHandler m_notificationHandler;
#endif
diff --git a/Tools/DumpRenderTree/CMakeLists.txt b/Tools/DumpRenderTree/CMakeLists.txt
deleted file mode 100644
index 1baa510fb..000000000
--- a/Tools/DumpRenderTree/CMakeLists.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-set(DumpRenderTree_SOURCES
- AccessibilityController.cpp
- AccessibilityTextMarker.cpp
- AccessibilityUIElement.cpp
- CyclicRedundancyCheck.cpp
- DumpRenderTreeCommon.cpp
- GCController.cpp
- JavaScriptThreading.cpp
- PixelDumpSupport.cpp
- TestRunner.cpp
- WorkQueue.cpp
-)
-
-set(DumpRenderTree_LIBRARIES
- JavaScriptCore
- WTF
- WebCoreTestSupport
- WebKit
-)
-
-set(DumpRenderTree_INCLUDE_DIRECTORIES
- ${WEBCORE_DIR}
- ${WEBCORE_DIR}/bindings
- ${WEBCORE_DIR}/bridge
- ${WEBCORE_DIR}/bridge/jsc
- ${WEBCORE_DIR}/css
- ${WEBCORE_DIR}/dom
- ${WEBCORE_DIR}/editing
- ${WEBCORE_DIR}/history
- ${WEBCORE_DIR}/html
- ${WEBCORE_DIR}/inspector
- ${WEBCORE_DIR}/loader
- ${WEBCORE_DIR}/loader/cache
- ${WEBCORE_DIR}/loader/icon
- ${WEBCORE_DIR}/page
- ${WEBCORE_DIR}/page/animation
- ${WEBCORE_DIR}/platform
- ${WEBCORE_DIR}/platform/animation
- ${WEBCORE_DIR}/platform/graphics
- ${WEBCORE_DIR}/platform/graphics/transforms
- ${WEBCORE_DIR}/platform/network
- ${WEBCORE_DIR}/platform/text
- ${WEBCORE_DIR}/plugins
- ${WEBCORE_DIR}/rendering
- ${WEBCORE_DIR}/rendering/shapes
- ${WEBCORE_DIR}/rendering/style
- ${JAVASCRIPTCORE_DIR}
- ${JAVASCRIPTCORE_DIR}/API
- ${JAVASCRIPTCORE_DIR}/assembler
- ${JAVASCRIPTCORE_DIR}/bytecode
- ${JAVASCRIPTCORE_DIR}/dfg
- ${JAVASCRIPTCORE_DIR}/disassembler
- ${JAVASCRIPTCORE_DIR}/heap
- ${JAVASCRIPTCORE_DIR}/interpreter
- ${JAVASCRIPTCORE_DIR}/jit
- ${JAVASCRIPTCORE_DIR}/llint
- ${JAVASCRIPTCORE_DIR}/parser
- ${JAVASCRIPTCORE_DIR}/profiler
- ${JAVASCRIPTCORE_DIR}/runtime
- ${JAVASCRIPTCORE_DIR}/ForwardingHeaders
- ${DERIVED_SOURCES_DIR}/ForwardingHeaders
- ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}
- ${TOOLS_DIR}/DumpRenderTree
- ${WTF_DIR}
- ${CMAKE_SOURCE_DIR}/Source
- ${CMAKE_BINARY_DIR}
- ${DERIVED_SOURCES_DIR}
- ${DERIVED_SOURCES_WEBCORE_DIR}
- ${WEBCORE_DIR}/bindings/js
- ${WEBCORE_DIR}/testing/js
-)
-
-set(TestNetscapePlugin_SOURCES
- TestNetscapePlugin/PluginObject.cpp
- TestNetscapePlugin/PluginTest.cpp
- TestNetscapePlugin/TestObject.cpp
- TestNetscapePlugin/main.cpp
-
- TestNetscapePlugin/Tests/DocumentOpenInDestroyStream.cpp
- TestNetscapePlugin/Tests/EvaluateJSAfterRemovingPluginElement.cpp
- TestNetscapePlugin/Tests/FormValue.cpp
- TestNetscapePlugin/Tests/GetURLNotifyWithURLThatFailsToLoad.cpp
- TestNetscapePlugin/Tests/GetURLWithJavaScriptURL.cpp
- TestNetscapePlugin/Tests/GetURLWithJavaScriptURLDestroyingPlugin.cpp
- TestNetscapePlugin/Tests/GetUserAgentWithNullNPPFromNPPNew.cpp
- TestNetscapePlugin/Tests/LogNPPSetWindow.cpp
- TestNetscapePlugin/Tests/NPDeallocateCalledBeforeNPShutdown.cpp
- TestNetscapePlugin/Tests/NPPNewFails.cpp
- TestNetscapePlugin/Tests/NPPSetWindowCalledDuringDestruction.cpp
- TestNetscapePlugin/Tests/NPRuntimeCallsWithNullNPP.cpp
- TestNetscapePlugin/Tests/NPRuntimeObjectFromDestroyedPlugin.cpp
- TestNetscapePlugin/Tests/NPRuntimeRemoveProperty.cpp
- TestNetscapePlugin/Tests/NullNPPGetValuePointer.cpp
- TestNetscapePlugin/Tests/PassDifferentNPPStruct.cpp
- TestNetscapePlugin/Tests/PluginScriptableNPObjectInvokeDefault.cpp
- TestNetscapePlugin/Tests/PluginScriptableObjectOverridesAllProperties.cpp
- TestNetscapePlugin/Tests/PrivateBrowsing.cpp
- TestNetscapePlugin/Tests/ToStringAndValueOfObject.cpp
- TestNetscapePlugin/Tests/URLRedirect.cpp
-)
-
-set(TestNetscapePlugin_LIBRARIES
- JavaScriptCore
- WTF
- WebCoreTestSupport
- WebKit
-)
-
-list(APPEND TestNetscapePlugin_LIBRARIES
- WebKit
-)
-
-WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS()
-
-include_directories(${DumpRenderTree_INCLUDE_DIRECTORIES})
-
-add_executable(DumpRenderTree ${DumpRenderTree_SOURCES})
-target_link_libraries(DumpRenderTree ${DumpRenderTree_LIBRARIES})
-set_target_properties(DumpRenderTree PROPERTIES FOLDER "Tools")
-
-add_library(TestNetscapePlugin SHARED ${TestNetscapePlugin_SOURCES})
-target_link_libraries(TestNetscapePlugin ${TestNetscapePlugin_LIBRARIES})
-set_target_properties(TestNetscapePlugin PROPERTIES FOLDER "Tools")
-
-if (WIN32)
- add_dependencies(DumpRenderTree DumpRenderTreeLib)
-endif ()
diff --git a/Tools/DumpRenderTree/DefaultPolicyDelegate.h b/Tools/DumpRenderTree/DefaultPolicyDelegate.h
deleted file mode 100644
index 6ff5becca..000000000
--- a/Tools/DumpRenderTree/DefaultPolicyDelegate.h
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// DefaultPolicyDelegate.h
-// DumpRenderTree
-//
-// Created by Anders Carlsson on 7/9/13.
-//
-//
-
-#import <WebKit/WebDefaultPolicyDelegate.h>
-
-@interface DefaultPolicyDelegate : WebDefaultPolicyDelegate
-
-@end
diff --git a/Tools/DumpRenderTree/DumpRenderTree.h b/Tools/DumpRenderTree/DumpRenderTree.h
index 2a2ea1467..3e6323525 100644
--- a/Tools/DumpRenderTree/DumpRenderTree.h
+++ b/Tools/DumpRenderTree/DumpRenderTree.h
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
@@ -34,7 +34,7 @@
#include <wtf/Platform.h>
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
#include "DumpRenderTreeMac.h"
#elif PLATFORM(WIN)
#include "DumpRenderTreeWin.h"
diff --git a/Tools/DumpRenderTree/DumpRenderTree.sln b/Tools/DumpRenderTree/DumpRenderTree.sln
deleted file mode 100644
index 7cce30330..000000000
--- a/Tools/DumpRenderTree/DumpRenderTree.sln
+++ /dev/null
@@ -1,100 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DumpRenderTree", "win\DumpRenderTree.vcproj", "{6567DFD4-D6DE-4CD5-825D-17E353D160E1}"
- ProjectSection(ProjectDependencies) = postProject
- {C0737398-3565-439E-A2B8-AB2BE4D5430C} = {C0737398-3565-439E-A2B8-AB2BE4D5430C}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestNetscapePlugin", "TestNetscapePlugin\win\TestNetscapePlugin.vcproj", "{C0737398-3565-439E-A2B8-AB2BE4D5430C}"
- ProjectSection(ProjectDependencies) = postProject
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017} = {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageDiff", "win\ImageDiff.vcproj", "{59CC0547-70AC-499C-9B19-EC01C6F61137}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DumpRenderTreeLauncher", "win\DumpRenderTreeLauncher.vcproj", "{2974EA02-840B-4995-8719-8920A61006F1}"
- ProjectSection(ProjectDependencies) = postProject
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1} = {6567DFD4-D6DE-4CD5-825D-17E353D160E1}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageDiffLauncher", "win\ImageDiffLauncher.vcproj", "{DD7949B6-F2B4-47C2-9C42-E21E84CB1017}"
- ProjectSection(ProjectDependencies) = postProject
- {59CC0547-70AC-499C-9B19-EC01C6F61137} = {59CC0547-70AC-499C-9B19-EC01C6F61137}
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug_All|Win32 = Debug_All|Win32
- Debug_Cairo_CFLite|Win32 = Debug_Cairo_CFLite|Win32
- Debug|Win32 = Debug|Win32
- Production|Win32 = Production|Win32
- Release_Cairo_CFLite|Win32 = Release_Cairo_CFLite|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug_All|Win32.Build.0 = Debug_All|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug|Win32.ActiveCfg = Debug|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug|Win32.Build.0 = Debug|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Production|Win32.ActiveCfg = Production|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Production|Win32.Build.0 = Production|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Release|Win32.ActiveCfg = Release|Win32
- {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Release|Win32.Build.0 = Release|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug_All|Win32.Build.0 = Debug_All|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug|Win32.ActiveCfg = Debug|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug|Win32.Build.0 = Debug|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Production|Win32.ActiveCfg = Production|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Production|Win32.Build.0 = Production|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Release|Win32.ActiveCfg = Release|Win32
- {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Release|Win32.Build.0 = Release|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug_All|Win32.Build.0 = Debug_All|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug|Win32.ActiveCfg = Debug|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug|Win32.Build.0 = Debug|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Production|Win32.ActiveCfg = Production|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Production|Win32.Build.0 = Production|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Release|Win32.ActiveCfg = Release|Win32
- {59CC0547-70AC-499C-9B19-EC01C6F61137}.Release|Win32.Build.0 = Release|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Debug_All|Win32.Build.0 = Debug_All|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Debug|Win32.ActiveCfg = Debug|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Debug|Win32.Build.0 = Debug|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Production|Win32.ActiveCfg = Production|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Production|Win32.Build.0 = Production|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Release|Win32.ActiveCfg = Release|Win32
- {2974EA02-840B-4995-8719-8920A61006F1}.Release|Win32.Build.0 = Release|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Debug_All|Win32.Build.0 = Debug_All|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Debug|Win32.ActiveCfg = Debug|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Debug|Win32.Build.0 = Debug|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Production|Win32.ActiveCfg = Production|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Production|Win32.Build.0 = Production|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Release|Win32.ActiveCfg = Release|Win32
- {DD7949B6-F2B4-47C2-9C42-E21E84CB1017}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Tools/DumpRenderTree/DumpRenderTreeFileDraggingSource.h b/Tools/DumpRenderTree/DumpRenderTreeFileDraggingSource.h
deleted file mode 100644
index 1d42a474c..000000000
--- a/Tools/DumpRenderTree/DumpRenderTreeFileDraggingSource.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2009, Google Inc. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#if !PLATFORM(IOS)
-
-#import <Cocoa/Cocoa.h>
-
-// An implementation of NSDraggingSource for use with DumpRenderTreeDraggingInfo when dragging files
-// Used by -[EventSendingController beginDragWithFiles:]
-
-@interface DumpRenderTreeFileDraggingSource : NSObject {
-}
-
-- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)flag;
-
-@end
-
-#endif
diff --git a/Tools/DumpRenderTree/DumpRenderTreePrefix.h b/Tools/DumpRenderTree/DumpRenderTreePrefix.h
index 105b54356..64eae0704 100644
--- a/Tools/DumpRenderTree/DumpRenderTreePrefix.h
+++ b/Tools/DumpRenderTree/DumpRenderTreePrefix.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005 Apple Inc. All rights reserved.
+ * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
@@ -26,17 +26,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H && defined(BUILDING_WITH_CMAKE)
-#include "cmakeconfig.h"
-#endif
-
#include <wtf/Platform.h>
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif
-
-#if OS(WINDOWS)
-#undef WEBCORE_EXPORT
-#define WEBCORE_EXPORT WTF_IMPORT_DECLARATION
-#endif
diff --git a/Tools/DumpRenderTree/ForwardingHeaders/runtime/ArrayBufferView.h b/Tools/DumpRenderTree/ForwardingHeaders/runtime/ArrayBufferView.h
deleted file mode 100644
index 7731671c8..000000000
--- a/Tools/DumpRenderTree/ForwardingHeaders/runtime/ArrayBufferView.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <JavaScriptCore/ArrayBufferView.h>
diff --git a/Tools/DumpRenderTree/ForwardingHeaders/runtime/JSArrayBufferView.h b/Tools/DumpRenderTree/ForwardingHeaders/runtime/JSArrayBufferView.h
deleted file mode 100644
index e38a8040f..000000000
--- a/Tools/DumpRenderTree/ForwardingHeaders/runtime/JSArrayBufferView.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <JavaScriptCore/JSArrayBufferView.h>
diff --git a/Tools/DumpRenderTree/ForwardingHeaders/runtime/JSExportMacros.h b/Tools/DumpRenderTree/ForwardingHeaders/runtime/JSExportMacros.h
deleted file mode 100644
index 4c5dcb983..000000000
--- a/Tools/DumpRenderTree/ForwardingHeaders/runtime/JSExportMacros.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <JavaScriptCore/JSExportMacros.h> \ No newline at end of file
diff --git a/Tools/DumpRenderTree/ForwardingHeaders/runtime/TypedArrayInlines.h b/Tools/DumpRenderTree/ForwardingHeaders/runtime/TypedArrayInlines.h
deleted file mode 100644
index 6a61945ea..000000000
--- a/Tools/DumpRenderTree/ForwardingHeaders/runtime/TypedArrayInlines.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <JavaScriptCore/TypedArrayInlines.h>
diff --git a/Tools/DumpRenderTree/GCController.cpp b/Tools/DumpRenderTree/GCController.cpp
index 781a828eb..06a04fbca 100644
--- a/Tools/DumpRenderTree/GCController.cpp
+++ b/Tools/DumpRenderTree/GCController.cpp
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
diff --git a/Tools/DumpRenderTree/GCController.h b/Tools/DumpRenderTree/GCController.h
index 79ceafc9f..afc1de087 100644
--- a/Tools/DumpRenderTree/GCController.h
+++ b/Tools/DumpRenderTree/GCController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
diff --git a/Tools/DumpRenderTree/JavaScriptThreading.cpp b/Tools/DumpRenderTree/JavaScriptThreading.cpp
deleted file mode 100644
index e2f9bade6..000000000
--- a/Tools/DumpRenderTree/JavaScriptThreading.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
- * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
- * (C) 2007 Eric Seidel <eric@webkit.org>
- * (C) 2012 Patrick Ganstere <paroga@paroga.com>
- *
- * 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 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 "JavaScriptThreading.h"
-
-#include <JavaScriptCore/JavaScriptCore.h>
-#include <stdlib.h>
-#include <wtf/Assertions.h>
-#include <wtf/HashSet.h>
-#include <wtf/Lock.h>
-#include <wtf/Threading.h>
-#include <wtf/ThreadingPrimitives.h>
-#include <wtf/Vector.h>
-
-static const size_t javaScriptThreadsCount = 4;
-static bool javaScriptThreadsShouldTerminate;
-static JSContextGroupRef javaScriptThreadsGroup;
-
-static Lock& javaScriptThreadsMutex()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(Lock, staticMutex, ());
- return staticMutex;
-}
-
-typedef HashSet<ThreadIdentifier> ThreadSet;
-static ThreadSet& javaScriptThreads()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(ThreadSet, staticJavaScriptThreads, ());
- ASSERT(!javaScriptThreadsMutex().tryLock());
- return staticJavaScriptThreads;
-}
-
-// 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*)
-{
- static const char* const script =
- "var array = [];"
- "for (var i = 0; i < 1024; i++) {"
- " array.push(String(i));"
- "}";
-
- JSGlobalContextRef ctx;
- {
- LockHolder locker(javaScriptThreadsMutex());
- ctx = JSGlobalContextCreateInGroup(javaScriptThreadsGroup, 0);
- }
-
- JSStringRef scriptRef;
- {
- LockHolder locker(javaScriptThreadsMutex());
- scriptRef = JSStringCreateWithUTF8CString(script);
- }
-
- while (true) {
- {
- LockHolder locker(javaScriptThreadsMutex());
- JSValueRef exception = 0;
- JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception);
- ASSERT(!exception);
- }
-
- {
- LockHolder locker(javaScriptThreadsMutex());
- const size_t valuesCount = 1024;
- JSValueRef values[valuesCount];
- for (size_t i = 0; i < valuesCount; ++i)
- values[i] = JSObjectMake(ctx, 0, 0);
- }
-
- {
- LockHolder locker(javaScriptThreadsMutex());
- if (javaScriptThreadsShouldTerminate)
- break;
- }
-
- // Respawn probabilistically.
- if (rand() % 5)
- continue;
-
- LockHolder locker(javaScriptThreadsMutex());
- ThreadIdentifier thread = currentThread();
- detachThread(thread);
- javaScriptThreads().remove(thread);
- javaScriptThreads().add(createThread(&runJavaScriptThread, 0, 0));
- break;
- }
-
- LockHolder locker(javaScriptThreadsMutex());
- JSStringRelease(scriptRef);
- JSGarbageCollect(ctx);
- JSGlobalContextRelease(ctx);
-}
-
-void startJavaScriptThreads()
-{
- javaScriptThreadsGroup = JSContextGroupCreate();
-
- LockHolder locker(javaScriptThreadsMutex());
-
- for (size_t i = 0; i < javaScriptThreadsCount; ++i)
- javaScriptThreads().add(createThread(&runJavaScriptThread, 0, 0));
-}
-
-void stopJavaScriptThreads()
-{
- {
- LockHolder locker(javaScriptThreadsMutex());
- javaScriptThreadsShouldTerminate = true;
- }
-
- Vector<ThreadIdentifier, javaScriptThreadsCount> threads;
- {
- LockHolder locker(javaScriptThreadsMutex());
- copyToVector(javaScriptThreads(), threads);
- ASSERT(threads.size() == javaScriptThreadsCount);
- }
-
- for (size_t i = 0; i < javaScriptThreadsCount; ++i)
- waitForThreadCompletion(threads[i]);
-
- {
- LockHolder locker(javaScriptThreadsMutex());
- javaScriptThreads().clear();
- }
-
- JSContextGroupRelease(javaScriptThreadsGroup);
-}
diff --git a/Tools/DumpRenderTree/JavaScriptThreading.h b/Tools/DumpRenderTree/JavaScriptThreading.h
index 5bbe9cafe..43795a1a2 100644
--- a/Tools/DumpRenderTree/JavaScriptThreading.h
+++ b/Tools/DumpRenderTree/JavaScriptThreading.h
@@ -12,7 +12,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
diff --git a/Tools/DumpRenderTree/PixelDumpSupport.cpp b/Tools/DumpRenderTree/PixelDumpSupport.cpp
index aeb902ceb..ba619bbea 100644
--- a/Tools/DumpRenderTree/PixelDumpSupport.cpp
+++ b/Tools/DumpRenderTree/PixelDumpSupport.cpp
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
@@ -43,6 +43,7 @@
#include "PixelDumpSupportCairo.h"
#endif
+#if !PLATFORM(IOS)
void dumpWebViewAsPixelsAndCompareWithExpected(const std::string& expectedHash)
{
RefPtr<BitmapContext> context;
@@ -73,6 +74,7 @@ void dumpWebViewAsPixelsAndCompareWithExpected(const std::string& expectedHash)
if (dumpImage)
dumpBitmap(context.get(), actualHash);
}
+#endif
static void appendIntToVector(unsigned number, Vector<unsigned char>& vector)
{
diff --git a/Tools/DumpRenderTree/PixelDumpSupport.h b/Tools/DumpRenderTree/PixelDumpSupport.h
index a0ec1e1c7..3bd8820c7 100644
--- a/Tools/DumpRenderTree/PixelDumpSupport.h
+++ b/Tools/DumpRenderTree/PixelDumpSupport.h
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt b/Tools/DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt
deleted file mode 100644
index c431667b2..000000000
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-set(WEBKIT_TESTNETSCAPEPLUGIN_DIR "${TOOLS_DIR}/DumpRenderTree/TestNetscapePlugIn")
-
-set(WebKitTestNetscapePlugin_SOURCES
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/PluginObject.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/PluginTest.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/TestObject.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/main.cpp
-
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/DocumentOpenInDestroyStream.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/EvaluateJSAfterRemovingPluginElement.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/FormValue.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/GetURLNotifyWithURLThatFailsToLoad.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/GetURLWithJavaScriptURL.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/GetURLWithJavaScriptURLDestroyingPlugin.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/GetUserAgentWithNullNPPFromNPPNew.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/LogNPPSetWindow.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/NPDeallocateCalledBeforeNPShutdown.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/NPPNewFails.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/NPPSetWindowCalledDuringDestruction.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/NPRuntimeCallsWithNullNPP.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/NPRuntimeObjectFromDestroyedPlugin.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/NPRuntimeRemoveProperty.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/NullNPPGetValuePointer.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/PassDifferentNPPStruct.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/PluginScriptableNPObjectInvokeDefault.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/PluginScriptableObjectOverridesAllProperties.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/PrivateBrowsing.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/ToStringAndValueOfObject.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/URLRedirect.cpp
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/x11/CallInvalidateRectWithNullNPPArgument.cpp
-)
-
-set(WebKitTestNetscapePlugin_INCLUDE_DIRECTORIES
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}
- ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/ForwardingHeaders
- ${WEBCORE_DIR}
- ${WTF_DIR}
-)
-
-set(WebKitTestNetscapePlugin_SYSTEM_INCLUDE_DIRECTORIES
- ${X11_INCLUDE_DIR}
-)
-
-include_directories(${WebKitTestNetscapePlugin_INCLUDE_DIRECTORIES})
-include_directories(SYSTEM ${WebKitTestNetscapePlugin_SYSTEM_INCLUDE_DIRECTORIES})
-
-set(WebKitTestNetscapePlugin_LIBRARIES
- ${X11_LIBRARIES}
-)
-
-if (WTF_OS_UNIX)
- add_definitions(-DXP_UNIX)
-endif ()
-
-add_library(TestNetscapePlugin SHARED ${WebKitTestNetscapePlugin_SOURCES})
-target_link_libraries(TestNetscapePlugin ${WebKitTestNetscapePlugin_LIBRARIES})
-set_target_properties(TestNetscapePlugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugins)
-WEBKIT_SET_EXTRA_COMPILER_FLAGS(TestNetscapePlugin)
-
-# Suppress unused parameter warnings for sources in WebKit2.
-ADD_TARGET_PROPERTIES(TestNetscapePlugin COMPILE_FLAGS "-Wno-unused-parameter")
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
index 982452b68..75631842f 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
@@ -30,14 +30,10 @@
#include "PluginTest.h"
#include "TestObject.h"
#include <assert.h>
-#include <memory>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <wtf/Platform.h>
-#include <wtf/ExportMacros.h>
-#include <wtf/Assertions.h>
// Helper function which takes in the plugin window object for logging to the console object.
static void pluginLogWithWindowObject(NPObject* windowObject, NPP instance, const char* message)
@@ -64,7 +60,6 @@ static void pluginLogWithWindowObject(NPObject* windowObject, NPP instance, cons
browser->releaseobject(consoleObject);
}
-WTF_ATTRIBUTE_PRINTF(2, 0)
void pluginLogWithArguments(NPP instance, const char* format, va_list args)
{
const size_t messageBufferSize = 2048;
@@ -85,7 +80,6 @@ void pluginLogWithArguments(NPP instance, const char* format, va_list args)
}
// Helper function to log to the console object.
-WTF_ATTRIBUTE_PRINTF(2, 3)
void pluginLog(NPP instance, const char* format, ...)
{
va_list args;
@@ -776,15 +770,11 @@ static bool testGetPropertyReturnValue(PluginObject* obj, const NPVariant* args,
return true;
}
-static std::unique_ptr<char[]> toCString(const NPString& string)
+static char* toCString(const NPString& string)
{
- size_t length = string.UTF8Length;
- std::unique_ptr<char[]> result(new char[length + 1]);
- if (!result)
- return result;
-
- memcpy(result.get(), string.UTF8Characters, length);
- result[length] = '\0';
+ char* result = static_cast<char*>(malloc(string.UTF8Length + 1));
+ memcpy(result, string.UTF8Characters, string.UTF8Length);
+ result[string.UTF8Length] = '\0';
return result;
}
@@ -795,27 +785,30 @@ static bool testPostURLFile(PluginObject* obj, const NPVariant* args, uint32_t a
return false;
NPString urlString = NPVARIANT_TO_STRING(args[0]);
- auto url = toCString(urlString);
+ char* url = toCString(urlString);
NPString targetString = NPVARIANT_TO_STRING(args[1]);
- auto target = toCString(targetString);
+ char* target = toCString(targetString);
NPString pathString = NPVARIANT_TO_STRING(args[2]);
- auto path = toCString(pathString);
+ char* path = toCString(pathString);
NPString contentsString = NPVARIANT_TO_STRING(args[3]);
- FILE* tempFile = fopen(path.get(), "w");
+ FILE* tempFile = fopen(path, "w");
if (!tempFile)
return false;
- size_t count = fwrite(contentsString.UTF8Characters, contentsString.UTF8Length, 1, tempFile);
+ if (!fwrite(contentsString.UTF8Characters, contentsString.UTF8Length, 1, tempFile))
+ return false;
+
fclose(tempFile);
- if (!count)
- return false;
+ NPError error = browser->posturl(obj->npp, url, target, pathString.UTF8Length, path, TRUE);
- NPError error = browser->posturl(obj->npp, url.get(), target.get(), pathString.UTF8Length, path.get(), TRUE);
+ free(path);
+ free(target);
+ free(url);
BOOLEAN_TO_NPVARIANT(error == NPERR_NO_ERROR, *result);
return true;
@@ -974,14 +967,15 @@ bool testWindowOpen(NPP npp)
static bool testSetStatus(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
- std::unique_ptr<char[]> message;
+ char* message = 0;
if (argCount && NPVARIANT_IS_STRING(args[0])) {
NPString statusString = NPVARIANT_TO_STRING(args[0]);
message = toCString(statusString);
}
+
+ browser->status(obj->npp, message);
- browser->status(obj->npp, message.get());
-
+ free(message);
return true;
}
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
index da78148d4..c2195c5b1 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
@@ -28,9 +28,6 @@
#include "PluginObject.h"
#include <assert.h>
#include <string.h>
-#include <wtf/Platform.h>
-#include <wtf/ExportMacros.h>
-#include <wtf/Assertions.h>
#if defined(XP_UNIX) || defined(ANDROID)
#include <unistd.h>
@@ -136,11 +133,6 @@ bool PluginTest::NPP_URLNotify(const char* url, NPReason, void* notifyData)
return false;
}
-void PluginTest::NPP_URLRedirectNotify(const char*, int32_t, void* notifyData)
-{
- NPN_URLRedirectResponse(notifyData, true);
-}
-
NPError PluginTest::NPP_GetValue(NPPVariable variable, void *value)
{
// We don't know anything about plug-in values so just return NPERR_GENERIC_ERROR.
@@ -164,11 +156,6 @@ NPError PluginTest::NPN_GetURLNotify(const char *url, const char *target, void *
return browser->geturlnotify(m_npp, url, target, notifyData);
}
-NPError PluginTest::NPN_PostURLNotify(const char *url, const char *target, uint32_t len, const char* buf, NPBool file, void *notifyData)
-{
- return browser->posturlnotify(m_npp, url, target, len, buf, file, notifyData);
-}
-
NPError PluginTest::NPN_GetValue(NPNVariable variable, void* value)
{
return browser->getvalue(m_npp, variable, value);
@@ -241,11 +228,6 @@ void PluginTest::NPN_ReleaseVariantValue(NPVariant* variant)
browser->releasevariantvalue(variant);
}
-void PluginTest::NPN_URLRedirectResponse(void* notifyData, NPBool allow)
-{
- browser->urlredirectresponse(m_npp, notifyData, allow);
-}
-
#ifdef XP_MACOSX
bool PluginTest::NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace)
{
@@ -272,7 +254,6 @@ void PluginTest::executeScript(const char* script)
browser->releasevariantvalue(&browserResult);
}
-WTF_ATTRIBUTE_PRINTF(2, 3)
void PluginTest::log(const char* format, ...)
{
va_list args;
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
index d7a5163ff..f8a9aaee3 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
@@ -31,10 +31,6 @@
#include <map>
#include <string>
-#if defined(_MSC_VER) && _MSC_VER < 1900
-#define snprintf _snprintf
-#endif
-
// Helper classes for implementing has_member
typedef char (&no_tag)[1];
typedef char (&yes_tag)[2];
@@ -72,14 +68,12 @@ public:
virtual int16_t NPP_HandleEvent(void* event);
virtual bool NPP_URLNotify(const char* url, NPReason, void* notifyData);
- virtual void NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData);
virtual NPError NPP_GetValue(NPPVariable, void* value);
virtual NPError NPP_SetValue(NPNVariable, void *value);
// NPN functions.
NPError NPN_GetURL(const char* url, const char* target);
NPError NPN_GetURLNotify(const char* url, const char* target, void* notifyData);
- NPError NPN_PostURLNotify(const char *url, const char *target, uint32_t len, const char* buf, NPBool file, void *notifyData);
NPError NPN_GetValue(NPNVariable, void* value);
void NPN_InvalidateRect(NPRect* invalidRect);
bool NPN_Invoke(NPObject *, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result);
@@ -97,7 +91,6 @@ public:
void NPN_ReleaseObject(NPObject*);
bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName);
void NPN_ReleaseVariantValue(NPVariant*);
- void NPN_URLRedirectResponse(void* notifyData, NPBool allow);
#ifdef XP_MACOSX
bool NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSWithinNPP_New.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSWithinNPP_New.cpp
deleted file mode 100644
index c066db59f..000000000
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSWithinNPP_New.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "PluginTest.h"
-
-#include "PluginObject.h"
-
-using namespace std;
-
-// Executing JS within NPP_New when initializing asynchronously should not be able to deadlock with the WebProcess
-
-class EvaluteJSWithinNPP_New : public PluginTest {
-public:
- EvaluteJSWithinNPP_New(NPP, const string& identifier);
-
-private:
- virtual NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData *);
-
-};
-
-EvaluteJSWithinNPP_New::EvaluteJSWithinNPP_New(NPP npp, const string& identifier)
- : PluginTest(npp, identifier)
-{
-}
-
-NPError EvaluteJSWithinNPP_New::NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData *saved)
-{
- // Give the WebProcess enough time to be deadlocked waiting for the PluginProcess.
- usleep(15000);
- executeScript("var theLocation = window.location;");
- return NPERR_NO_ERROR;
-}
-
-static PluginTest::Register<EvaluteJSWithinNPP_New> registrar("evalute-js-within-npp-new");
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/InvokeDestroysPluginWithinNPP_New.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/InvokeDestroysPluginWithinNPP_New.cpp
deleted file mode 100644
index 0e2dbdce7..000000000
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/InvokeDestroysPluginWithinNPP_New.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "PluginTest.h"
-
-#include "PluginObject.h"
-
-using namespace std;
-
-// Executing JS within NPP_New when initializing asynchronously should not be able to deadlock with the WebProcess
-
-class InvokeDestroysPluginWithinNPP_New : public PluginTest {
-public:
- InvokeDestroysPluginWithinNPP_New(NPP, const string& identifier);
-
-private:
- virtual NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData *);
-
-};
-
-InvokeDestroysPluginWithinNPP_New::InvokeDestroysPluginWithinNPP_New(NPP npp, const string& identifier)
- : PluginTest(npp, identifier)
-{
-}
-
-NPError InvokeDestroysPluginWithinNPP_New::NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData *saved)
-{
- // Give the WebProcess enough time to be deadlocked waiting for the PluginProcess if things aren't working correctly.
- usleep(15000);
-
- NPObject* windowObject = 0;
- if (NPN_GetValue(NPNVWindowNPObject, &windowObject) != NPERR_NO_ERROR)
- return NPERR_GENERIC_ERROR;
-
- if (!windowObject)
- return NPERR_GENERIC_ERROR;
-
- NPVariant result;
- if (!NPN_Invoke(windowObject, NPN_GetStringIdentifier("removePluginElement"), 0, 0, &result))
- return NPERR_GENERIC_ERROR;
-
- return NPERR_NO_ERROR;
-}
-
-static PluginTest::Register<InvokeDestroysPluginWithinNPP_New> registrar("invoke-destroys-plugin-within-npp-new");
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/PluginScriptableObjectOverridesAllProperties.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/PluginScriptableObjectOverridesAllProperties.cpp
deleted file mode 100644
index ca399a816..000000000
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/PluginScriptableObjectOverridesAllProperties.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "PluginTest.h"
-
-#include <string.h>
-
-using namespace std;
-
-class PluginScriptableObjectOverridesAllProperties : public PluginTest {
-public:
- PluginScriptableObjectOverridesAllProperties(NPP npp, const string& identifier)
- : PluginTest(npp, identifier)
- {
- }
-
-private:
- class PluginObject : public Object<PluginObject> {
- public:
- PluginObject()
- {
- }
-
- ~PluginObject()
- {
- }
-
- bool hasProperty(NPIdentifier propertyName)
- {
- return true;
- }
-
- bool getProperty(NPIdentifier propertyName, NPVariant* result)
- {
- static const char* message = "My name is ";
- char* propertyString = pluginTest()->NPN_UTF8FromIdentifier(propertyName);
-
- int bufferLength = strlen(propertyString) + strlen(message) + 1;
- char* resultBuffer = static_cast<char*>(pluginTest()->NPN_MemAlloc(bufferLength));
- snprintf(resultBuffer, bufferLength, "%s%s", message, propertyString);
-
- STRINGZ_TO_NPVARIANT(resultBuffer, *result);
-
- return true;
- }
- };
-
- virtual NPError NPP_GetValue(NPPVariable variable, void *value)
- {
- if (variable != NPPVpluginScriptableNPObject)
- return NPERR_GENERIC_ERROR;
-
- *(NPObject**)value = PluginObject::create(this);
-
- return NPERR_NO_ERROR;
- }
-
-};
-
-static PluginTest::Register<PluginScriptableObjectOverridesAllProperties> pluginScriptableObjectOverridesAllProperties("plugin-scriptable-object-overrides-all-properties");
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/SlowNPPNew.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/SlowNPPNew.cpp
deleted file mode 100644
index 8c80d55a5..000000000
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/SlowNPPNew.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "PluginTest.h"
-
-#include <string.h>
-
-using namespace std;
-
-class SlowNPPNew : public PluginTest {
-public:
- SlowNPPNew(NPP npp, const string& identifier)
- : PluginTest(npp, identifier)
- {
- }
-
-private:
- class PluginObject : public Object<PluginObject> {
- public:
- PluginObject()
- {
- }
-
- ~PluginObject()
- {
- }
-
- bool hasProperty(NPIdentifier propertyName)
- {
- return true;
- }
-
- bool getProperty(NPIdentifier propertyName, NPVariant* result)
- {
- static const char* message = "My name is ";
- char* propertyString = pluginTest()->NPN_UTF8FromIdentifier(propertyName);
-
- int bufferLength = strlen(propertyString) + strlen(message) + 1;
- char* resultBuffer = static_cast<char*>(pluginTest()->NPN_MemAlloc(bufferLength));
- snprintf(resultBuffer, bufferLength, "%s%s", message, propertyString);
-
- STRINGZ_TO_NPVARIANT(resultBuffer, *result);
-
- return true;
- }
- };
-
- virtual NPError NPP_GetValue(NPPVariable variable, void *value)
- {
- if (variable != NPPVpluginScriptableNPObject)
- return NPERR_GENERIC_ERROR;
-
- *(NPObject**)value = PluginObject::create(this);
-
- return NPERR_NO_ERROR;
- }
-
- virtual NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData *saved)
- {
- usleep(550000);
- return NPERR_NO_ERROR;
- }
-};
-
-static PluginTest::Register<SlowNPPNew> slowNPPNew("slow-npp-new");
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp
deleted file mode 100644
index b834703da..000000000
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "PluginTest.h"
-
-#include <string.h>
-
-using namespace std;
-
-class URLRedirect : public PluginTest {
-public:
- URLRedirect(NPP npp, const string& identifier)
- : PluginTest(npp, identifier)
- {
- }
-
- struct Redirect {
- int redirectsRemaining;
- bool async;
- bool hasFired;
- };
-
- std::map<void*, Redirect> redirects;
-
-private:
- // This is the test object.
- class TestObject : public Object<TestObject> { };
-
- // This is the scriptable object. It has a single "testObject" property and an "evaluate" function.
- class ScriptableObject : public Object<ScriptableObject> {
- public:
- bool hasMethod(NPIdentifier methodName)
- {
- return identifierIs(methodName, "get") || identifierIs(methodName, "getAsync") || identifierIs(methodName, "serviceAsync");
- }
-
- bool get(const NPVariant* args, uint32_t argCount, NPVariant* result, bool async)
- {
- if (argCount != 3 || !NPVARIANT_IS_STRING(args[0]) || !(NPVARIANT_IS_BOOLEAN(args[1]) || NPVARIANT_IS_DOUBLE(args[1]) || NPVARIANT_IS_INT32(args[1])) || !NPVARIANT_IS_STRING(args[2]))
- return false;
-
- const NPString* notifyString = &NPVARIANT_TO_STRING(args[2]);
- basic_string<NPUTF8> notify(notifyString->UTF8Characters, notifyString->UTF8Length);
- NPIdentifier notifyMethod = pluginTest()->NPN_GetStringIdentifier(notify.c_str());
-
- Redirect& redirect = static_cast<URLRedirect*>(pluginTest())->redirects[reinterpret_cast<void*>(notifyMethod)];
- if (NPVARIANT_IS_DOUBLE(args[1]))
- redirect.redirectsRemaining = NPVARIANT_TO_DOUBLE(args[1]);
- else if (NPVARIANT_IS_INT32(args[1]))
- redirect.redirectsRemaining = NPVARIANT_TO_INT32(args[1]);
- else if (NPVARIANT_IS_BOOLEAN(args[1]))
- redirect.redirectsRemaining = NPVARIANT_TO_BOOLEAN(args[1]);
- redirect.async = async;
- redirect.hasFired = true;
-
- const NPString* urlString = &NPVARIANT_TO_STRING(args[0]);
- basic_string<NPUTF8> url(urlString->UTF8Characters, urlString->UTF8Length);
-
- pluginTest()->NPN_GetURLNotify(url.c_str(), 0, reinterpret_cast<void*>(notifyMethod));
-
- VOID_TO_NPVARIANT(*result);
- return true;
- }
-
- bool serviceAsync(const NPVariant* args, uint32_t argCount, NPVariant* result)
- {
- if (argCount)
- return false;
-
- NPBool seen = 0;
- URLRedirect* plugin = static_cast<URLRedirect*>(pluginTest());
- for (auto& redirect : plugin->redirects) {
- if (redirect.second.hasFired)
- continue;
- redirect.second.hasFired = true;
- plugin->NPN_URLRedirectResponse(redirect.first, redirect.second.redirectsRemaining);
- if (redirect.second.redirectsRemaining)
- --redirect.second.redirectsRemaining;
- seen = 1;
- }
-
- BOOLEAN_TO_NPVARIANT(seen, *result);
- return true;
- }
-
- bool invoke(NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result)
- {
- if (identifierIs(methodName, "get"))
- return get(args, argCount, result, false);
-
- if (identifierIs(methodName, "getAsync"))
- return get(args, argCount, result, true);
-
- if (identifierIs(methodName, "serviceAsync"))
- return serviceAsync(args, argCount, result);
-
- return false;
- }
- };
-
- virtual NPError NPP_GetValue(NPPVariable variable, void *value)
- {
- if (variable != NPPVpluginScriptableNPObject)
- return NPERR_GENERIC_ERROR;
-
- *(NPObject**)value = ScriptableObject::create(this);
-
- return NPERR_NO_ERROR;
- }
-
- virtual bool NPP_URLNotify(const char* url, NPReason reason, void* notifyData)
- {
- NPVariant args[2];
-
- NPObject* windowScriptObject;
- NPN_GetValue(NPNVWindowNPObject, &windowScriptObject);
-
- NPIdentifier callbackIdentifier = notifyData;
-
- INT32_TO_NPVARIANT(reason, args[0]);
- STRINGZ_TO_NPVARIANT(url, args[1]);
-
- NPVariant browserResult;
- if (NPN_Invoke(windowScriptObject, callbackIdentifier, args, 2, &browserResult))
- NPN_ReleaseVariantValue(&browserResult);
-
- return true;
- }
-
- virtual void NPP_URLRedirectNotify(const char*, int32_t, void* notifyData)
- {
- Redirect& redirect = redirects[notifyData];
- if (redirect.async) {
- redirect.hasFired = false;
- return;
- }
-
- NPN_URLRedirectResponse(notifyData, redirect.redirectsRemaining);
- if (redirect.redirectsRemaining)
- --redirect.redirectsRemaining;
- }
-};
-
-static PluginTest::Register<URLRedirect> urlRedirect("url-redirect");
-
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp
index 6a7303f13..85cd41d2c 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp
@@ -41,17 +41,10 @@ extern "C" void GlobalToLocal(Point*);
using namespace std;
-#if defined(__GNUC__)
-#define CRASH() do { \
- *(int *)(uintptr_t)0xbbadbeef = 0; \
- __builtin_trap(); /* More reliable, but doesn't say BBADBEEF. */ \
-} while (false)
-#else
#define CRASH() do { \
*(int *)(uintptr_t)0xbbadbeef = 0; \
((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
-} while (false)
-#endif
+} while(false)
static bool getEntryPointsWasCalled;
static bool initializeWasCalled;
@@ -123,7 +116,6 @@ NPError STDCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs)
pluginFuncs->print = NPP_Print;
pluginFuncs->event = NPP_HandleEvent;
pluginFuncs->urlnotify = NPP_URLNotify;
- pluginFuncs->urlredirectnotify = NPP_URLRedirectNotify;
pluginFuncs->getvalue = NPP_GetValue;
pluginFuncs->setvalue = NPP_SetValue;
@@ -356,30 +348,29 @@ NPError NPP_SetWindow(NPP instance, NPWindow *window)
{
PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
- if (!obj)
- return NPERR_GENERIC_ERROR;
-
- obj->lastWindow = *window;
+ if (obj) {
+ obj->lastWindow = *window;
- if (obj->logSetWindow) {
- pluginLog(instance, "NPP_SetWindow: %d %d", (int)window->width, (int)window->height);
- obj->logSetWindow = FALSE;
- executeScript(obj, "testRunner.notifyDone();");
- }
+ if (obj->logSetWindow) {
+ pluginLog(instance, "NPP_SetWindow: %d %d", (int)window->width, (int)window->height);
+ obj->logSetWindow = FALSE;
+ executeScript(obj, "testRunner.notifyDone();");
+ }
- if (obj->onSetWindow)
- executeScript(obj, obj->onSetWindow);
+ if (obj->onSetWindow)
+ executeScript(obj, obj->onSetWindow);
- if (obj->testWindowOpen) {
- testWindowOpen(instance);
- obj->testWindowOpen = FALSE;
- }
+ if (obj->testWindowOpen) {
+ testWindowOpen(instance);
+ obj->testWindowOpen = FALSE;
+ }
- if (obj->testKeyboardFocusForPlugins) {
- obj->eventLogging = true;
- executeScript(obj, "eventSender.keyDown('A');");
+ if (obj->testKeyboardFocusForPlugins) {
+ obj->eventLogging = true;
+ executeScript(obj, "eventSender.keyDown('A');");
+ }
}
-
+
return obj->pluginTest->NPP_SetWindow(window);
}
@@ -808,12 +799,6 @@ void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyD
handleCallback(obj, url, reason, notifyData);
}
-void NPP_URLRedirectNotify(NPP instance, const char *url, int32_t status, void *notifyData)
-{
- PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
- obj->pluginTest->NPP_URLRedirectNotify(url, status, notifyData);
-}
-
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
#ifdef XP_UNIX
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/ForwardingHeaders/WebKit/npapi.h b/Tools/DumpRenderTree/TestNetscapePlugIn/unix/ForwardingHeaders/WebKit/npapi.h
index 627bc97a9..627bc97a9 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/ForwardingHeaders/WebKit/npapi.h
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/unix/ForwardingHeaders/WebKit/npapi.h
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/ForwardingHeaders/WebKit/npfunctions.h b/Tools/DumpRenderTree/TestNetscapePlugIn/unix/ForwardingHeaders/WebKit/npfunctions.h
index 54a603dbb..54a603dbb 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/ForwardingHeaders/WebKit/npfunctions.h
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/unix/ForwardingHeaders/WebKit/npfunctions.h
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/ForwardingHeaders/WebKit/npruntime.h b/Tools/DumpRenderTree/TestNetscapePlugIn/unix/ForwardingHeaders/WebKit/npruntime.h
index e435ae2ab..e435ae2ab 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/ForwardingHeaders/WebKit/npruntime.h
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/unix/ForwardingHeaders/WebKit/npruntime.h
diff --git a/Tools/DumpRenderTree/TestRunner.cpp b/Tools/DumpRenderTree/TestRunner.cpp
index b5270dc46..7b249770e 100644
--- a/Tools/DumpRenderTree/TestRunner.cpp
+++ b/Tools/DumpRenderTree/TestRunner.cpp
@@ -11,7 +11,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
@@ -59,7 +59,7 @@ const unsigned TestRunner::viewHeight = 600;
const unsigned TestRunner::w3cSVGViewWidth = 480;
const unsigned TestRunner::w3cSVGViewHeight = 360;
-TestRunner::TestRunner(const std::string& testURL, const std::string& expectedPixelHash)
+TestRunner::TestRunner(const std::string& testPathOrURL, const std::string& expectedPixelHash)
: m_disallowIncreaseForApplicationCacheQuota(false)
, m_dumpApplicationCacheDelegateCallbacks(false)
, m_dumpAsAudio(false)
@@ -112,16 +112,15 @@ TestRunner::TestRunner(const std::string& testURL, const std::string& expectedPi
, m_hasPendingWebNotificationClick(false)
, m_databaseDefaultQuota(-1)
, m_databaseMaxQuota(-1)
- , m_testURL(testURL)
+ , m_testPathOrURL(testPathOrURL)
, m_expectedPixelHash(expectedPixelHash)
, m_titleTextDirection("ltr")
- , m_timeout(0)
{
}
-PassRefPtr<TestRunner> TestRunner::create(const std::string& testURL, const std::string& expectedPixelHash)
+PassRefPtr<TestRunner> TestRunner::create(const std::string& testPathOrURL, const std::string& expectedPixelHash)
{
- return adoptRef(new TestRunner(testURL, expectedPixelHash));
+ return adoptRef(new TestRunner(testPathOrURL, expectedPixelHash));
}
// Static Functions
@@ -467,6 +466,73 @@ static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef fu
return JSValueMakeUndefined(context);
}
+static JSValueRef syncLocalStorageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
+
+ controller->syncLocalStorage();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef observeStorageTrackerNotificationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
+
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ unsigned numNotifications = JSValueToNumber(context, arguments[0], exception);
+
+ ASSERT(!*exception);
+
+ controller->observeStorageTrackerNotifications(numNotifications);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef deleteAllLocalStorageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
+ controller->deleteAllLocalStorage();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef deleteLocalStorageForOriginCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
+
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ controller->deleteLocalStorageForOrigin(url.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef localStorageDiskUsageForOriginCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
+
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> originURL(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ return JSValueMakeNumber(context, controller->localStorageDiskUsageForOrigin(originURL.get()));
+}
+
+static JSValueRef originsWithLocalStorageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
+ return controller->originsWithLocalStorage(context);
+}
+
static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
// Has mac & windows implementation
@@ -646,12 +712,6 @@ static JSValueRef numberOfPendingGeolocationPermissionRequestsCallback(JSContext
return JSValueMakeNumber(context, controller->numberOfPendingGeolocationPermissionRequests());
}
-static JSValueRef isGeolocationProviderActiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeBoolean(context, controller->isGeolocationProviderActive());
-}
-
static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
// Has mac & windows implementation
@@ -1044,6 +1104,38 @@ static JSValueRef setMockGeolocationPositionUnavailableErrorCallback(JSContextRe
return JSValueMakeUndefined(context);
}
+static JSValueRef addMockSpeechInputResultCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 3)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> result(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ double confidence = JSValueToNumber(context, arguments[1], exception);
+
+ JSRetainPtr<JSStringRef> language(Adopt, JSValueToStringCopy(context, arguments[2], exception));
+ ASSERT(!*exception);
+
+ TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
+ controller->addMockSpeechInputResult(result.get(), confidence, language.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setMockSpeechInputDumpRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ bool dumpRect = JSValueToBoolean(context, arguments[0]);
+
+ TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
+ controller->setMockSpeechInputDumpRect(dumpRect);
+
+ return JSValueMakeUndefined(context);
+}
+
static JSValueRef setNewWindowsCopyBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
// Has mac implementation
@@ -1487,10 +1579,12 @@ static JSValueRef closeWebInspectorCallback(JSContextRef context, JSObjectRef fu
static JSValueRef evaluateInWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
- JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ double callId = JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!*exception);
+ JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception));
ASSERT(!*exception);
- controller->evaluateInWebInspector(script.get());
+ controller->evaluateInWebInspector(static_cast<long>(callId), script.get());
return JSValueMakeUndefined(context);
}
@@ -1790,13 +1884,6 @@ static JSValueRef getTitleTextDirectionCallback(JSContextRef context, JSObjectRe
return JSValueMakeString(context, titleDirection.get());
}
-static JSValueRef getInspectorTestStubURLCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
-{
- TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
- JSRetainPtr<JSStringRef> url(Adopt, controller->inspectorTestStubURL());
- return JSValueMakeString(context, url.get());
-}
-
static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
{
TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
@@ -1933,16 +2020,11 @@ static JSValueRef simulateWebNotificationClickCallback(JSContextRef context, JSO
return JSValueMakeUndefined(context);
}
-static JSValueRef failNextNewCodeBlock(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+static JSValueRef numberOfDFGCompiles(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
if (argumentCount < 1)
return JSValueMakeUndefined(context);
- return JSC::failNextNewCodeBlock(context);
-}
-
-static JSValueRef numberOfDFGCompiles(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
return JSC::numberOfDFGCompiles(context, arguments[0]);
}
@@ -1995,7 +2077,6 @@ JSStaticValue* TestRunner::staticValues()
{ "titleTextDirection", getTitleTextDirectionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "databaseDefaultQuota", getDatabaseDefaultQuotaCallback, setDatabaseDefaultQuotaCallback, kJSPropertyAttributeNone },
{ "databaseMaxQuota", getDatabaseMaxQuotaCallback, setDatabaseMaxQuotaCallback, kJSPropertyAttributeNone },
- { "inspectorTestStubURL", getInspectorTestStubURLCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ 0, 0, 0, 0 }
};
return staticValues;
@@ -2052,7 +2133,6 @@ JSStaticFunction* TestRunner::staticFunctions()
{ "originsWithApplicationCache", originsWithApplicationCacheCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "goBack", goBackCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "ignoreLegacyWebNotificationPermissionRequests", ignoreLegacyWebNotificationPermissionRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "isGeolocationProviderActive", isGeolocationProviderActiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "numberOfPendingGeolocationPermissionRequests", numberOfPendingGeolocationPermissionRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -2098,6 +2178,8 @@ JSStaticFunction* TestRunner::staticFunctions()
{ "setMockDeviceOrientation", setMockDeviceOrientationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setMockGeolocationPositionUnavailableError", setMockGeolocationPositionUnavailableErrorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setMockGeolocationPosition", setMockGeolocationPositionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "addMockSpeechInputResult", addMockSpeechInputResultCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setMockSpeechInputDumpRect", setMockSpeechInputDumpRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setNewWindowsCopyBackForwardList", setNewWindowsCopyBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setPageVisibility", setPageVisibilityCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setPOSIXLocale", setPOSIXLocaleCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -2139,6 +2221,12 @@ JSStaticFunction* TestRunner::staticFunctions()
{ "addOriginAccessWhitelistEntry", addOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setScrollbarPolicy", setScrollbarPolicyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "authenticateSession", authenticateSessionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "deleteAllLocalStorage", deleteAllLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "syncLocalStorage", syncLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "observeStorageTrackerNotifications", observeStorageTrackerNotificationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "deleteLocalStorageForOrigin", deleteLocalStorageForOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "localStorageDiskUsageForOrigin", localStorageDiskUsageForOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "originsWithLocalStorage", originsWithLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setShouldPaintBrokenImage", setShouldPaintBrokenImageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setTextDirection", setTextDirectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setShouldStayOnPageAfterHandlingBeforeUnload", setShouldStayOnPageAfterHandlingBeforeUnloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -2154,7 +2242,6 @@ JSStaticFunction* TestRunner::staticFunctions()
{ "denyWebNotificationPermission", denyWebNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "removeAllWebNotificationPermissions", removeAllWebNotificationPermissionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "simulateWebNotificationClick", simulateWebNotificationClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
- { "failNextNewCodeBlock", failNextNewCodeBlock, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "numberOfDFGCompiles", numberOfDFGCompiles, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "neverInlineFunction", neverInlineFunction, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ 0, 0, 0 }
@@ -2165,37 +2252,37 @@ JSStaticFunction* TestRunner::staticFunctions()
void TestRunner::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL)
{
- WorkQueue::singleton().queue(new LoadHTMLStringItem(content, baseURL));
+ WorkQueue::shared()->queue(new LoadHTMLStringItem(content, baseURL));
}
void TestRunner::queueLoadAlternateHTMLString(JSStringRef content, JSStringRef baseURL, JSStringRef unreachableURL)
{
- WorkQueue::singleton().queue(new LoadHTMLStringItem(content, baseURL, unreachableURL));
+ WorkQueue::shared()->queue(new LoadHTMLStringItem(content, baseURL, unreachableURL));
}
void TestRunner::queueBackNavigation(int howFarBack)
{
- WorkQueue::singleton().queue(new BackItem(howFarBack));
+ WorkQueue::shared()->queue(new BackItem(howFarBack));
}
void TestRunner::queueForwardNavigation(int howFarForward)
{
- WorkQueue::singleton().queue(new ForwardItem(howFarForward));
+ WorkQueue::shared()->queue(new ForwardItem(howFarForward));
}
void TestRunner::queueLoadingScript(JSStringRef script)
{
- WorkQueue::singleton().queue(new LoadingScriptItem(script));
+ WorkQueue::shared()->queue(new LoadingScriptItem(script));
}
void TestRunner::queueNonLoadingScript(JSStringRef script)
{
- WorkQueue::singleton().queue(new NonLoadingScriptItem(script));
+ WorkQueue::shared()->queue(new NonLoadingScriptItem(script));
}
void TestRunner::queueReload()
{
- WorkQueue::singleton().queue(new ReloadItem);
+ WorkQueue::shared()->queue(new ReloadItem);
}
void TestRunner::ignoreLegacyWebNotificationPermissionRequests()
@@ -2206,6 +2293,7 @@ void TestRunner::ignoreLegacyWebNotificationPermissionRequests()
void TestRunner::waitToDumpWatchdogTimerFired()
{
const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
+ fprintf(stderr, "%s", message);
fprintf(stdout, "%s", message);
notifyDone();
}
diff --git a/Tools/DumpRenderTree/TestRunner.h b/Tools/DumpRenderTree/TestRunner.h
index d51ac6feb..882c0e96c 100644
--- a/Tools/DumpRenderTree/TestRunner.h
+++ b/Tools/DumpRenderTree/TestRunner.h
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
@@ -39,7 +39,7 @@
class TestRunner : public RefCounted<TestRunner> {
public:
- static PassRefPtr<TestRunner> create(const std::string& testURL, const std::string& expectedPixelHash);
+ static PassRefPtr<TestRunner> create(const std::string& testPathOrURL, const std::string& expectedPixelHash);
static const unsigned viewWidth;
static const unsigned viewHeight;
@@ -52,8 +52,6 @@ public:
void makeWindowObject(JSContextRef, JSObjectRef windowObject, JSValueRef* exception);
void addDisallowedURL(JSStringRef url);
- const std::set<std::string>& allowedHosts() const { return m_allowedHosts; }
- void setAllowedHosts(std::set<std::string> hosts) { m_allowedHosts = WTFMove(hosts); }
void addURLToRedirect(std::string origin, std::string destination);
const std::string& redirectionDestinationForURL(std::string);
void clearAllApplicationCaches();
@@ -76,7 +74,6 @@ public:
void keepWebHistory();
void notifyDone();
int numberOfPendingGeolocationPermissionRequests();
- bool isGeolocationProviderActive();
void overridePreference(JSStringRef key, JSStringRef value);
JSStringRef pathToLocalResource(JSContextRef, JSStringRef url);
void queueBackNavigation(int howFarBackward);
@@ -105,6 +102,8 @@ public:
void setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma);
void setMockGeolocationPosition(double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed);
void setMockGeolocationPositionUnavailableError(JSStringRef message);
+ void addMockSpeechInputResult(JSStringRef result, double confidence, JSStringRef language);
+ void setMockSpeechInputDumpRect(bool flag);
void setPersistentUserStyleSheetLocation(JSStringRef path);
void setPluginsEnabled(bool);
void setPopupBlockingEnabled(bool);
@@ -118,6 +117,7 @@ public:
void setXSSAuditorEnabled(bool flag);
void setSpatialNavigationEnabled(bool);
void setScrollbarPolicy(JSStringRef orientation, JSStringRef policy);
+ void startSpeechInput(JSContextRef inputElement);
#if PLATFORM(IOS)
void setTelephoneNumberParsingEnabled(bool enable);
void setPagePaused(bool paused);
@@ -288,7 +288,7 @@ public:
bool useDeferredFrameLoading() const { return m_useDeferredFrameLoading; }
void setUseDeferredFrameLoading(bool flag) { m_useDeferredFrameLoading = flag; }
- const std::string& testURL() const { return m_testURL; }
+ const std::string& testPathOrURL() const { return m_testPathOrURL; }
const std::string& expectedPixelHash() const { return m_expectedPixelHash; }
const std::vector<char>& audioResult() const { return m_audioResult; }
@@ -307,9 +307,7 @@ public:
void setDeveloperExtrasEnabled(bool);
void showWebInspector();
void closeWebInspector();
- void evaluateInWebInspector(JSStringRef script);
- JSStringRef inspectorTestStubURL();
-
+ void evaluateInWebInspector(long callId, JSStringRef script);
void evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script);
void evaluateScriptInIsolatedWorldAndReturnValue(unsigned worldID, JSObjectRef globalObject, JSStringRef script);
@@ -338,6 +336,13 @@ public:
// Simulate a request an embedding application could make, populating per-session credential storage.
void authenticateSession(JSStringRef url, JSStringRef username, JSStringRef password);
+ JSValueRef originsWithLocalStorage(JSContextRef);
+ void deleteAllLocalStorage();
+ void deleteLocalStorageForOrigin(JSStringRef originIdentifier);
+ long long localStorageDiskUsageForOrigin(JSStringRef originIdentifier);
+ void observeStorageTrackerNotifications(unsigned number);
+ void syncLocalStorage();
+
void setShouldPaintBrokenImage(bool);
bool shouldPaintBrokenImage() const { return m_shouldPaintBrokenImage; }
@@ -354,10 +359,8 @@ public:
bool hasPendingWebNotificationClick() const { return m_hasPendingWebNotificationClick; }
- void setCustomTimeout(int duration) { m_timeout = duration; }
-
private:
- TestRunner(const std::string& testURL, const std::string& expectedPixelHash);
+ TestRunner(const std::string& testPathOrURL, const std::string& expectedPixelHash);
void setGeolocationPermissionCommon(bool allow);
@@ -418,22 +421,19 @@ private:
std::string m_authenticationUsername;
std::string m_authenticationPassword;
- std::string m_testURL;
+ std::string m_testPathOrURL;
std::string m_expectedPixelHash; // empty string if no hash
std::string m_titleTextDirection;
std::set<std::string> m_willSendRequestClearHeaders;
- std::set<std::string> m_allowedHosts;
std::vector<char> m_audioResult;
std::map<std::string, std::string> m_URLsToRedirect;
-
+
static JSClassRef getJSClass();
static JSStaticValue* staticValues();
static JSStaticFunction* staticFunctions();
-
- int m_timeout;
};
#endif // TestRunner_h
diff --git a/Tools/DumpRenderTree/WorkQueue.cpp b/Tools/DumpRenderTree/WorkQueue.cpp
index 097f4cdd2..0106fbac1 100644
--- a/Tools/DumpRenderTree/WorkQueue.cpp
+++ b/Tools/DumpRenderTree/WorkQueue.cpp
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
@@ -31,7 +31,6 @@
#include "WorkQueueItem.h"
#include <wtf/Assertions.h>
-#include <wtf/NeverDestroyed.h>
static const unsigned queueLength = 1024;
@@ -39,9 +38,9 @@ static WorkQueueItem* theQueue[queueLength];
static unsigned startOfQueue;
static unsigned endOfQueue;
-WorkQueue& WorkQueue::singleton()
+WorkQueue* WorkQueue::shared()
{
- static NeverDestroyed<WorkQueue> sharedInstance;
+ static WorkQueue* sharedInstance = new WorkQueue;
return sharedInstance;
}
diff --git a/Tools/DumpRenderTree/WorkQueue.h b/Tools/DumpRenderTree/WorkQueue.h
index 0697e7c3e..649c6c1f5 100644
--- a/Tools/DumpRenderTree/WorkQueue.h
+++ b/Tools/DumpRenderTree/WorkQueue.h
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
@@ -29,15 +29,11 @@
#ifndef WorkQueue_h
#define WorkQueue_h
-#include <wtf/Forward.h>
-
class WorkQueueItem;
class WorkQueue {
-friend class WTF::NeverDestroyed<WorkQueue>;
-
public:
- static WorkQueue& singleton();
+ static WorkQueue* shared();
void queue(WorkQueueItem*);
WorkQueueItem* dequeue();
diff --git a/Tools/DumpRenderTree/WorkQueueItem.h b/Tools/DumpRenderTree/WorkQueueItem.h
index 6a49f593f..08fc2208b 100644
--- a/Tools/DumpRenderTree/WorkQueueItem.h
+++ b/Tools/DumpRenderTree/WorkQueueItem.h
@@ -10,7 +10,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
diff --git a/Tools/DumpRenderTree/atk/AccessibilityCallbacks.h b/Tools/DumpRenderTree/atk/AccessibilityCallbacks.h
new file mode 100644
index 000000000..0feef55c8
--- /dev/null
+++ b/Tools/DumpRenderTree/atk/AccessibilityCallbacks.h
@@ -0,0 +1,44 @@
+/*
+ * 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
+
+#if HAVE(ACCESSIBILITY)
+
+#include "AccessibilityNotificationHandlerAtk.h"
+#include "AccessibilityUIElement.h"
+
+void connectAccessibilityCallbacks();
+bool disconnectAccessibilityCallbacks();
+void addAccessibilityNotificationHandler(AccessibilityNotificationHandler*);
+void removeAccessibilityNotificationHandler(AccessibilityNotificationHandler*);
+
+#endif // HAVE(ACCESSIBILITY)
+
+#endif // AccessibilityCallbacks_h
diff --git a/Tools/DumpRenderTree/atk/AccessibilityCallbacksAtk.cpp b/Tools/DumpRenderTree/atk/AccessibilityCallbacksAtk.cpp
new file mode 100644
index 000000000..01f6651b4
--- /dev/null
+++ b/Tools/DumpRenderTree/atk/AccessibilityCallbacksAtk.cpp
@@ -0,0 +1,297 @@
+/*
+ * 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"
+
+#if HAVE(ACCESSIBILITY)
+
+#include "AccessibilityController.h"
+#include "AccessibilityNotificationHandlerAtk.h"
+#include "DumpRenderTree.h"
+#include "JSRetainPtr.h"
+#include <atk/atk.h>
+#include <wtf/gobject/GUniquePtr.h>
+
+#if PLATFORM(GTK)
+#include "WebCoreSupport/DumpRenderTreeSupportGtk.h"
+#include <webkit/webkit.h>
+#endif
+
+#if PLATFORM(EFL)
+#include "DumpRenderTreeChrome.h"
+#include "WebCoreSupport/DumpRenderTreeSupportEfl.h"
+#endif
+
+typedef HashMap<PlatformUIElement, AccessibilityNotificationHandler*> NotificationHandlersMap;
+
+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;
+// Up to 2014 it was obligatory to mirror the changes from
+// WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.cpp,
+// but the habit has been dropped: https://bugs.webkit.org/show_bug.cgi?id=132527#c6
+static NotificationHandlersMap notificationHandlers;
+static AccessibilityNotificationHandler* globalNotificationHandler = 0;
+
+extern bool loggingAccessibilityEvents;
+
+static void printAccessibilityEvent(AtkObject* accessible, const gchar* signalName, const gchar* signalValue)
+{
+ // Do not handle state-change:defunct signals, as the AtkObject
+ // associated to them will not be valid at this point already.
+ if (!signalName || !g_strcmp0(signalName, "state-change:defunct"))
+ return;
+
+ if (!accessible || !ATK_IS_OBJECT(accessible))
+ return;
+
+ const gchar* objectName = atk_object_get_name(accessible);
+ AtkRole 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)";
+
+ GUniquePtr<gchar> signalNameAndValue(signalValue ? g_strdup_printf("%s = %s", signalName, signalValue) : g_strdup(signalName));
+ printf("Accessibility object emitted \"%s\" / Name: \"%s\" / Role: %d\n", signalNameAndValue.get(), 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(&paramValues[0]));
+ if (!accessible || !ATK_IS_OBJECT(accessible))
+ return true;
+
+ GSignalQuery signalQuery;
+ GUniquePtr<gchar> signalName;
+ GUniquePtr<gchar> signalValue;
+ String notificationName;
+
+ g_signal_query(signalHint->signal_id, &signalQuery);
+
+ if (!g_strcmp0(signalQuery.signal_name, "state-change")) {
+ signalName.reset(g_strdup_printf("state-change:%s", g_value_get_string(&paramValues[1])));
+ signalValue.reset(g_strdup_printf("%d", g_value_get_boolean(&paramValues[2])));
+ if (!g_strcmp0(g_value_get_string(&paramValues[1]), "checked"))
+ notificationName = "CheckedStateChanged";
+ else if (!g_strcmp0(g_value_get_string(&paramValues[1]), "invalid-entry"))
+ notificationName = "AXInvalidStatusChanged";
+ } else if (!g_strcmp0(signalQuery.signal_name, "focus-event")) {
+ signalName.reset(g_strdup("focus-event"));
+ signalValue.reset(g_strdup_printf("%d", g_value_get_boolean(&paramValues[1])));
+ if (g_value_get_boolean(&paramValues[1]))
+ notificationName = "AXFocusedUIElementChanged";
+ } else if (!g_strcmp0(signalQuery.signal_name, "children-changed")) {
+ const gchar* childrenChangedDetail = g_quark_to_string(signalHint->detail);
+ signalName.reset(g_strdup_printf("children-changed:%s", childrenChangedDetail));
+ signalValue.reset(g_strdup_printf("%d", g_value_get_uint(&paramValues[1])));
+ notificationName = !g_strcmp0(childrenChangedDetail, "add") ? "AXChildrenAdded" : "AXChildrenRemoved";
+ } else if (!g_strcmp0(signalQuery.signal_name, "property-change")) {
+ signalName.reset(g_strdup_printf("property-change:%s", g_quark_to_string(signalHint->detail)));
+ if (!g_strcmp0(g_quark_to_string(signalHint->detail), "accessible-value"))
+ notificationName = "AXValueChanged";
+ } else if (!g_strcmp0(signalQuery.signal_name, "load-complete"))
+ notificationName = "AXLoadComplete";
+ else
+ signalName.reset(g_strdup(signalQuery.signal_name));
+
+ if (loggingAccessibilityEvents)
+ printAccessibilityEvent(accessible, signalName.get(), signalValue.get());
+
+#if PLATFORM(GTK)
+ JSGlobalContextRef jsContext = webkit_web_frame_get_global_context(mainFrame);
+#elif PLATFORM(EFL)
+ JSGlobalContextRef jsContext = DumpRenderTreeSupportEfl::globalContextRefForFrame(browser->mainFrame());
+#else
+ JSContextRef jsContext = 0;
+#endif
+ if (!jsContext)
+ return true;
+
+ if (notificationName.length()) {
+ JSRetainPtr<JSStringRef> jsNotificationEventName(Adopt, JSStringCreateWithUTF8CString(notificationName.utf8().data()));
+ JSValueRef notificationNameArgument = JSValueMakeString(jsContext, jsNotificationEventName.get());
+ NotificationHandlersMap::iterator elementNotificationHandler = notificationHandlers.find(accessible);
+ if (elementNotificationHandler != notificationHandlers.end()) {
+ // Listener for one element just gets one argument, the notification name.
+ JSObjectCallAsFunction(jsContext, elementNotificationHandler->value->notificationFunctionCallback(), 0, 1, &notificationNameArgument, 0);
+ }
+
+ if (globalNotificationHandler) {
+ // A global listener gets the element and the notification name as arguments.
+ JSValueRef arguments[2];
+ arguments[0] = AccessibilityUIElement::makeJSAccessibilityUIElement(jsContext, AccessibilityUIElement(accessible));
+ arguments[1] = notificationNameArgument;
+ JSObjectCallAsFunction(jsContext, globalNotificationHandler->notificationFunctionCallback(), 0, 2, arguments, 0);
+ }
+ }
+
+ return true;
+}
+
+void connectAccessibilityCallbacks()
+{
+ // Ensure no callbacks are connected before.
+ if (!disconnectAccessibilityCallbacks())
+ return;
+
+ // Ensure that accessibility is initialized for the WebView by querying for
+ // the root accessible object, which will create the full hierarchy.
+#if PLATFORM(GTK)
+ DumpRenderTreeSupportGtk::getRootAccessibleElement(mainFrame);
+#elif PLATFORM(EFL)
+ DumpRenderTreeSupportEfl::rootAccessibleElement(browser->mainFrame());
+#endif
+
+ // Add global listeners for AtkObject's signals.
+ stateChangeListenerId = atk_add_global_event_listener(axObjectEventListener, "ATK:AtkObject:state-change");
+ focusEventListenerId = atk_add_global_event_listener(axObjectEventListener, "ATK:AtkObject:focus-event");
+ activeDescendantChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "ATK:AtkObject:active-descendant-changed");
+ childrenChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "ATK:AtkObject:children-changed");
+ propertyChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "ATK:AtkObject:property-change");
+ visibleDataChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "ATK:AtkObject:visible-data-changed");
+ loadCompleteListenerId = atk_add_global_event_listener(axObjectEventListener, "ATK:AtkDocument:load-complete");
+
+ // 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);
+}
+
+bool disconnectAccessibilityCallbacks()
+{
+ // Only disconnect if logging is off and there is no notification handler.
+ if (loggingAccessibilityEvents || !notificationHandlers.isEmpty() || globalNotificationHandler)
+ return false;
+
+ // 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;
+ }
+ if (loadCompleteListenerId) {
+ atk_remove_global_event_listener(loadCompleteListenerId);
+ loadCompleteListenerId = 0;
+ }
+
+ return true;
+}
+
+void addAccessibilityNotificationHandler(AccessibilityNotificationHandler* notificationHandler)
+{
+ if (!notificationHandler)
+ return;
+
+#if PLATFORM(GTK)
+ JSGlobalContextRef jsContext = webkit_web_frame_get_global_context(mainFrame);
+#elif PLATFORM(EFL)
+ JSGlobalContextRef jsContext = DumpRenderTreeSupportEfl::globalContextRefForFrame(browser->mainFrame());
+#else
+ JSContextRef jsContext = 0;
+#endif
+ if (!jsContext)
+ return;
+
+ JSValueProtect(jsContext, notificationHandler->notificationFunctionCallback());
+ // Check if this notification handler is related to a specific element.
+ if (notificationHandler->platformElement()) {
+ NotificationHandlersMap::iterator currentNotificationHandler = notificationHandlers.find(notificationHandler->platformElement());
+ if (currentNotificationHandler != notificationHandlers.end()) {
+ ASSERT(currentNotificationHandler->value->platformElement());
+ JSValueUnprotect(jsContext, currentNotificationHandler->value->notificationFunctionCallback());
+ notificationHandlers.remove(currentNotificationHandler->value->platformElement());
+ }
+ notificationHandlers.add(notificationHandler->platformElement(), notificationHandler);
+ } else {
+ if (globalNotificationHandler)
+ JSValueUnprotect(jsContext, globalNotificationHandler->notificationFunctionCallback());
+ globalNotificationHandler = notificationHandler;
+ }
+
+ connectAccessibilityCallbacks();
+}
+
+void removeAccessibilityNotificationHandler(AccessibilityNotificationHandler* notificationHandler)
+{
+ if (!notificationHandler)
+ return;
+
+#if PLATFORM(GTK)
+ JSGlobalContextRef jsContext = webkit_web_frame_get_global_context(mainFrame);
+#elif PLATFORM(EFL)
+ JSGlobalContextRef jsContext = DumpRenderTreeSupportEfl::globalContextRefForFrame(browser->mainFrame());
+#else
+ JSGlobalContextRef jsContext = 0;
+#endif
+ if (!jsContext)
+ return;
+
+ if (globalNotificationHandler == notificationHandler) {
+ JSValueUnprotect(jsContext, globalNotificationHandler->notificationFunctionCallback());
+ globalNotificationHandler = 0;
+ } else if (notificationHandler->platformElement()) {
+ NotificationHandlersMap::iterator removeNotificationHandler = notificationHandlers.find(notificationHandler->platformElement());
+ if (removeNotificationHandler != notificationHandlers.end()) {
+ JSValueUnprotect(jsContext, removeNotificationHandler->value->notificationFunctionCallback());
+ notificationHandlers.remove(removeNotificationHandler);
+ }
+ }
+}
+
+#endif
diff --git a/Tools/DumpRenderTree/atk/AccessibilityControllerAtk.cpp b/Tools/DumpRenderTree/atk/AccessibilityControllerAtk.cpp
new file mode 100644
index 000000000..d8d0fc96c
--- /dev/null
+++ b/Tools/DumpRenderTree/atk/AccessibilityControllerAtk.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Jan Michael Alonzo
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityController.h"
+
+#if HAVE(ACCESSIBILITY)
+
+#include "AccessibilityCallbacks.h"
+#include "AccessibilityUIElement.h"
+#include "DumpRenderTree.h"
+
+#include <atk/atk.h>
+
+bool loggingAccessibilityEvents = false;
+
+AccessibilityController::AccessibilityController()
+ : m_globalNotificationHandler(nullptr)
+{
+}
+
+AccessibilityController::~AccessibilityController()
+{
+}
+
+AccessibilityUIElement AccessibilityController::elementAtPoint(int x, int y)
+{
+ // FIXME: implement
+ return nullptr;
+}
+
+void AccessibilityController::platformResetToConsistentState()
+{
+}
+
+void AccessibilityController::setLogFocusEvents(bool)
+{
+}
+
+void AccessibilityController::setLogScrollingStartEvents(bool)
+{
+}
+
+void AccessibilityController::setLogValueChangeEvents(bool)
+{
+}
+
+void AccessibilityController::setLogAccessibilityEvents(bool logAccessibilityEvents)
+{
+ if (logAccessibilityEvents == loggingAccessibilityEvents)
+ return;
+
+ if (!logAccessibilityEvents) {
+ loggingAccessibilityEvents = false;
+ disconnectAccessibilityCallbacks();
+ return;
+ }
+
+ connectAccessibilityCallbacks();
+ loggingAccessibilityEvents = true;
+}
+
+bool AccessibilityController::addNotificationListener(JSObjectRef functionCallback)
+{
+ if (!functionCallback)
+ return false;
+
+ // Only one global notification listener.
+ if (m_globalNotificationHandler)
+ return false;
+
+ m_globalNotificationHandler = AccessibilityNotificationHandler::create();
+ m_globalNotificationHandler->setNotificationFunctionCallback(functionCallback);
+
+ return true;
+}
+
+void AccessibilityController::removeNotificationListener()
+{
+ // Programmers should not be trying to remove a listener that's already removed.
+ ASSERT(m_globalNotificationHandler);
+
+ m_globalNotificationHandler = nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityController::platformName() const
+{
+ JSRetainPtr<JSStringRef> platformName(Adopt, JSStringCreateWithUTF8CString("atk"));
+ return platformName;
+}
+
+AtkObject* AccessibilityController::childElementById(AtkObject* parent, const char* id)
+{
+ if (!ATK_IS_OBJECT(parent))
+ return nullptr;
+
+ bool parentFound = false;
+ AtkAttributeSet* attributeSet(atk_object_get_attributes(parent));
+ for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) {
+ AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data);
+ if (!strcmp(attribute->name, "html-id")) {
+ if (!strcmp(attribute->value, id))
+ parentFound = true;
+ break;
+ }
+ }
+ atk_attribute_set_free(attributeSet);
+
+ if (parentFound)
+ return parent;
+
+ int childCount = atk_object_get_n_accessible_children(parent);
+ for (int i = 0; i < childCount; i++) {
+ AtkObject* result = childElementById(atk_object_ref_accessible_child(parent, i), id);
+ if (ATK_IS_OBJECT(result))
+ return result;
+ }
+
+ return nullptr;
+}
+
+#endif
diff --git a/Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.cpp b/Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.cpp
new file mode 100644
index 000000000..4565d5506
--- /dev/null
+++ b/Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "AccessibilityNotificationHandlerAtk.h"
+
+#if HAVE(ACCESSIBILITY)
+
+#include "AccessibilityCallbacks.h"
+
+AccessibilityNotificationHandler::AccessibilityNotificationHandler(void)
+ : m_platformElement(nullptr)
+ , m_notificationFunctionCallback(nullptr)
+{
+}
+
+AccessibilityNotificationHandler::~AccessibilityNotificationHandler()
+{
+ removeAccessibilityNotificationHandler(this);
+ disconnectAccessibilityCallbacks();
+}
+
+void AccessibilityNotificationHandler::setNotificationFunctionCallback(JSObjectRef notificationFunctionCallback)
+{
+ if (!notificationFunctionCallback) {
+ removeAccessibilityNotificationHandler(this);
+ disconnectAccessibilityCallbacks();
+ return;
+ }
+
+ if (m_notificationFunctionCallback)
+ removeAccessibilityNotificationHandler(this);
+
+ m_notificationFunctionCallback = notificationFunctionCallback;
+ connectAccessibilityCallbacks();
+ addAccessibilityNotificationHandler(this);
+}
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.h b/Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.h
new file mode 100644
index 000000000..9018e7290
--- /dev/null
+++ b/Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef AccessibilityNotificationHandlerAtk_h
+#define AccessibilityNotificationHandlerAtk_h
+
+#if HAVE(ACCESSIBILITY)
+
+#include <JavaScriptCore/JSObjectRef.h>
+#include <atk/atk.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+class AccessibilityNotificationHandler : public RefCounted<AccessibilityNotificationHandler> {
+public:
+ static PassRefPtr<AccessibilityNotificationHandler> create()
+ {
+ return adoptRef(new AccessibilityNotificationHandler());
+ }
+ AccessibilityNotificationHandler(void);
+ ~AccessibilityNotificationHandler();
+
+ void setPlatformElement(AtkObject* platformElement) { m_platformElement = platformElement; }
+ AtkObject* platformElement(void) const { return m_platformElement; }
+ void setNotificationFunctionCallback(JSObjectRef);
+ JSObjectRef notificationFunctionCallback(void) const { return m_notificationFunctionCallback; }
+
+private:
+ AtkObject* m_platformElement;
+ JSObjectRef m_notificationFunctionCallback;
+};
+
+#endif // HAVE(ACCESSIBILITY)
+
+#endif // AccessibilityNotificationHandlerAtk_h
diff --git a/Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp b/Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp
new file mode 100644
index 000000000..41317bdd1
--- /dev/null
+++ b/Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp
@@ -0,0 +1,1604 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Jan Michael Alonzo
+ * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityUIElement.h"
+
+#if HAVE(ACCESSIBILITY)
+
+#include "AccessibilityNotificationHandlerAtk.h"
+#include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/OpaqueJSString.h>
+#include <atk/atk.h>
+#include <wtf/Assertions.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/WTFString.h>
+#include <wtf/unicode/CharacterNames.h>
+
+namespace {
+
+enum AtkAttributeType {
+ ObjectAttributeType,
+ TextAttributeType
+};
+
+enum AttributeDomain {
+ CoreDomain = 0,
+ AtkDomain
+};
+
+enum AttributesIndex {
+ // Attribute names.
+ InvalidNameIndex = 0,
+ PlaceholderNameIndex,
+ SortNameIndex,
+
+ // Attribute values.
+ SortAscendingValueIndex,
+ SortDescendingValueIndex,
+ SortUnknownValueIndex,
+
+ NumberOfAttributes
+};
+
+// Attribute names & Values (keep on sync with enum AttributesIndex).
+const String attributesMap[][2] = {
+ // Attribute names.
+ { "AXInvalid", "invalid" },
+ { "AXPlaceholderValue", "placeholder-text" } ,
+ { "AXSortDirection", "sort" },
+
+ // Attribute values.
+ { "AXAscendingSortDirection", "ascending" },
+ { "AXDescendingSortDirection", "descending" },
+ { "AXUnknownSortDirection", "unknown" }
+};
+
+#if ATK_CHECK_VERSION(2, 11, 3)
+const char* landmarkStringBanner = "AXLandmarkBanner";
+const char* landmarkStringComplementary = "AXLandmarkComplementary";
+const char* landmarkStringContentinfo = "AXLandmarkContentInfo";
+const char* landmarkStringMain = "AXLandmarkMain";
+const char* landmarkStringNavigation = "AXLandmarkNavigation";
+const char* landmarkStringSearch = "AXLandmarkSearch";
+#endif
+
+String jsStringToWTFString(JSStringRef attribute)
+{
+ size_t bufferSize = JSStringGetMaximumUTF8CStringSize(attribute);
+ GUniquePtr<gchar> buffer(static_cast<gchar*>(g_malloc(bufferSize)));
+ JSStringGetUTF8CString(attribute, buffer.get(), bufferSize);
+
+ return String::fromUTF8(buffer.get());
+}
+
+String coreAttributeToAtkAttribute(JSStringRef attribute)
+{
+ String attributeString = jsStringToWTFString(attribute);
+ for (int i = 0; i < NumberOfAttributes; ++i) {
+ if (attributesMap[i][CoreDomain] == attributeString)
+ return attributesMap[i][AtkDomain];
+ }
+
+ return attributeString;
+}
+
+String atkAttributeValueToCoreAttributeValue(AtkAttributeType type, const String& id, const String& value)
+{
+ if (type == ObjectAttributeType) {
+ // We need to translate ATK values exposed for 'aria-sort' (e.g. 'ascending')
+ // into those expected by the layout tests (e.g. 'AXAscendingSortDirection').
+ if (id == attributesMap[SortNameIndex][AtkDomain] && !value.isEmpty()) {
+ if (value == attributesMap[SortAscendingValueIndex][AtkDomain])
+ return attributesMap[SortAscendingValueIndex][CoreDomain];
+ if (value == attributesMap[SortDescendingValueIndex][AtkDomain])
+ return attributesMap[SortDescendingValueIndex][CoreDomain];
+
+ return attributesMap[SortUnknownValueIndex][CoreDomain];
+ }
+ } else if (type == TextAttributeType) {
+ // In case of 'aria-invalid' when the attribute empty or has "false" for ATK
+ // it should not be mapped at all, but layout tests will expect 'false'.
+ if (id == attributesMap[InvalidNameIndex][AtkDomain] && value.isEmpty())
+ return "false";
+ }
+
+ return value;
+}
+
+AtkAttributeSet* getAttributeSet(AtkObject* accessible, AtkAttributeType type)
+{
+ if (type == ObjectAttributeType)
+ return atk_object_get_attributes(accessible);
+
+ if (type == TextAttributeType) {
+ if (!ATK_IS_TEXT(accessible))
+ return nullptr;
+
+ return atk_text_get_default_attributes(ATK_TEXT(accessible));
+ }
+
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+String getAttributeSetValueForId(AtkObject* accessible, AtkAttributeType type, String id)
+{
+ AtkAttributeSet* attributeSet = getAttributeSet(accessible, type);
+ if (!attributeSet)
+ return String();
+
+ String attributeValue;
+ for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) {
+ AtkAttribute* atkAttribute = static_cast<AtkAttribute*>(attributes->data);
+ if (id == atkAttribute->name) {
+ attributeValue = String::fromUTF8(atkAttribute->value);
+ break;
+ }
+ }
+ atk_attribute_set_free(attributeSet);
+
+ return atkAttributeValueToCoreAttributeValue(type, id, attributeValue);
+}
+
+String getAtkAttributeSetAsString(AtkObject* accessible, AtkAttributeType type)
+{
+ AtkAttributeSet* attributeSet = getAttributeSet(accessible, type);
+ if (!attributeSet)
+ return String();
+
+ StringBuilder builder;
+ for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) {
+ AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data);
+ GUniquePtr<gchar> attributeData(g_strconcat(attribute->name, ":", attribute->value, NULL));
+ builder.append(attributeData.get());
+ if (attributes->next)
+ builder.append(", ");
+ }
+ atk_attribute_set_free(attributeSet);
+
+ return builder.toString();
+}
+
+const char* roleToString(AtkObject* object)
+{
+ AtkRole role = atk_object_get_role(object);
+
+#if ATK_CHECK_VERSION(2, 11, 3)
+ if (role == ATK_ROLE_LANDMARK) {
+ String xmlRolesValue = getAttributeSetValueForId(object, ObjectAttributeType, "xml-roles");
+ if (equalIgnoringCase(xmlRolesValue, "banner"))
+ return landmarkStringBanner;
+ if (equalIgnoringCase(xmlRolesValue, "complementary"))
+ return landmarkStringComplementary;
+ if (equalIgnoringCase(xmlRolesValue, "contentinfo"))
+ return landmarkStringContentinfo;
+ if (equalIgnoringCase(xmlRolesValue, "main"))
+ return landmarkStringMain;
+ if (equalIgnoringCase(xmlRolesValue, "navigation"))
+ return landmarkStringNavigation;
+ if (equalIgnoringCase(xmlRolesValue, "search"))
+ return landmarkStringSearch;
+ }
+#endif
+
+ switch (role) {
+ case ATK_ROLE_ALERT:
+ return "AXAlert";
+ case ATK_ROLE_DIALOG:
+ return "AXDialog";
+ case ATK_ROLE_CANVAS:
+ return "AXCanvas";
+ case ATK_ROLE_CHECK_BOX:
+ return "AXCheckBox";
+ case ATK_ROLE_COLOR_CHOOSER:
+ return "AXColorWell";
+ case ATK_ROLE_COLUMN_HEADER:
+ return "AXColumnHeader";
+ case ATK_ROLE_COMBO_BOX:
+ return "AXComboBox";
+ case ATK_ROLE_COMMENT:
+ return "AXComment";
+ case ATK_ROLE_DOCUMENT_FRAME:
+ return "AXDocument";
+ case ATK_ROLE_DOCUMENT_WEB:
+ return "AXWebArea";
+ case ATK_ROLE_EMBEDDED:
+ return "AXEmbedded";
+ case ATK_ROLE_ENTRY:
+ return "AXTextField";
+ case ATK_ROLE_FOOTER:
+ return "AXFooter";
+ case ATK_ROLE_FORM:
+ return "AXForm";
+ case ATK_ROLE_GROUPING:
+ return "AXGroup";
+ case ATK_ROLE_HEADING:
+ return "AXHeading";
+ case ATK_ROLE_IMAGE:
+ return "AXImage";
+ case ATK_ROLE_IMAGE_MAP:
+ return "AXImageMap";
+ case ATK_ROLE_LABEL:
+ return "AXLabel";
+ case ATK_ROLE_LINK:
+ return "AXLink";
+ case ATK_ROLE_LIST:
+ return "AXList";
+ case ATK_ROLE_LIST_BOX:
+ return "AXListBox";
+ case ATK_ROLE_LIST_ITEM:
+ return "AXListItem";
+ case ATK_ROLE_MENU:
+ return "AXMenu";
+ case ATK_ROLE_MENU_BAR:
+ return "AXMenuBar";
+ case ATK_ROLE_MENU_ITEM:
+ return "AXMenuItem";
+ case ATK_ROLE_PAGE_TAB:
+ return "AXTab";
+ case ATK_ROLE_PAGE_TAB_LIST:
+ return "AXTabGroup";
+ case ATK_ROLE_PANEL:
+ return "AXGroup";
+ case ATK_ROLE_PARAGRAPH:
+ return "AXParagraph";
+ case ATK_ROLE_PASSWORD_TEXT:
+ return "AXPasswordField";
+ case ATK_ROLE_PROGRESS_BAR:
+ return "AXProgressIndicator";
+ case ATK_ROLE_PUSH_BUTTON:
+ return "AXButton";
+ case ATK_ROLE_RADIO_BUTTON:
+ return "AXRadioButton";
+ case ATK_ROLE_RADIO_MENU_ITEM:
+ return "AXRadioMenuItem";
+ case ATK_ROLE_ROW_HEADER:
+ return "AXRowHeader";
+ case ATK_ROLE_CHECK_MENU_ITEM:
+ return "AXCheckMenuItem";
+ case ATK_ROLE_RULER:
+ return "AXRuler";
+ case ATK_ROLE_SCROLL_BAR:
+ return "AXScrollBar";
+ case ATK_ROLE_SCROLL_PANE:
+ return "AXScrollArea";
+ case ATK_ROLE_SECTION:
+ return "AXSection";
+ case ATK_ROLE_SEPARATOR:
+ return "AXSeparator";
+ case ATK_ROLE_SLIDER:
+ return "AXSlider";
+ case ATK_ROLE_SPIN_BUTTON:
+ return "AXSpinButton";
+ case ATK_ROLE_STATUSBAR:
+ return "AXStatusBar";
+ case ATK_ROLE_TABLE:
+ return "AXTable";
+ case ATK_ROLE_TABLE_CELL:
+ return "AXCell";
+ case ATK_ROLE_TABLE_COLUMN_HEADER:
+ return "AXColumnHeader";
+ case ATK_ROLE_TABLE_ROW:
+ return "AXRow";
+ case ATK_ROLE_TABLE_ROW_HEADER:
+ return "AXRowHeader";
+ case ATK_ROLE_TOGGLE_BUTTON:
+ return "AXToggleButton";
+ case ATK_ROLE_TOOL_BAR:
+ return "AXToolbar";
+ case ATK_ROLE_TOOL_TIP:
+ return "AXUserInterfaceTooltip";
+ case ATK_ROLE_TREE:
+ return "AXTree";
+ case ATK_ROLE_TREE_TABLE:
+ return "AXTreeGrid";
+ case ATK_ROLE_TREE_ITEM:
+ return "AXTreeItem";
+ case ATK_ROLE_WINDOW:
+ return "AXWindow";
+ case ATK_ROLE_UNKNOWN:
+ return "AXUnknown";
+#if ATK_CHECK_VERSION(2, 11, 3)
+ case ATK_ROLE_ARTICLE:
+ return "AXArticle";
+ case ATK_ROLE_DEFINITION:
+ return "AXDefinition";
+ case ATK_ROLE_LOG:
+ return "AXLog";
+ case ATK_ROLE_MARQUEE:
+ return "AXMarquee";
+ case ATK_ROLE_MATH:
+ return "AXMath";
+ case ATK_ROLE_TIMER:
+ return "AXTimer";
+#endif
+#if ATK_CHECK_VERSION(2, 11, 4)
+ case ATK_ROLE_DESCRIPTION_LIST:
+ return "AXDescriptionList";
+ case ATK_ROLE_DESCRIPTION_TERM:
+ return "AXDescriptionTerm";
+ case ATK_ROLE_DESCRIPTION_VALUE:
+ return "AXDescriptionValue";
+#endif
+ default:
+ // We want to distinguish ATK_ROLE_UNKNOWN from a known AtkRole which
+ // our DRT isn't properly handling.
+ return "FIXME not identified";
+ }
+}
+
+inline gchar* replaceCharactersForResults(gchar* str)
+{
+ String uString = String::fromUTF8(str);
+
+ // The object replacement character is passed along to ATs so we need to be
+ // able to test for their presence and do so without causing test failures.
+ uString.replace(objectReplacementCharacter, "<obj>");
+
+ // The presence of newline characters in accessible text of a single object
+ // is appropriate, but it makes test results (especially the accessible tree)
+ // harder to read.
+ uString.replace("\n", "<\\n>");
+
+ return g_strdup(uString.utf8().data());
+}
+
+bool checkElementState(PlatformUIElement element, AtkStateType stateType)
+{
+ if (!ATK_IS_OBJECT(element))
+ return false;
+
+ GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(element)));
+ return atk_state_set_contains_state(stateSet.get(), stateType);
+}
+
+String attributesOfElement(AccessibilityUIElement* element)
+{
+ StringBuilder builder;
+
+ builder.append(String::format("%s\n", element->role()->string().utf8().data()));
+
+ // For the parent we print its role and its name, if available.
+ builder.append("AXParent: ");
+ AccessibilityUIElement parent = element->parentElement();
+ if (AtkObject* atkParent = parent.platformUIElement()) {
+ builder.append(roleToString(atkParent));
+ const char* parentName = atk_object_get_name(atkParent);
+ if (parentName && g_utf8_strlen(parentName, -1))
+ builder.append(String::format(": %s", parentName));
+ } else
+ builder.append("(null)");
+ builder.append("\n");
+
+ builder.append(String::format("AXChildren: %d\n", element->childrenCount()));
+ builder.append(String::format("AXPosition: { %f, %f }\n", element->x(), element->y()));
+ builder.append(String::format("AXSize: { %f, %f }\n", element->width(), element->height()));
+
+ String title = element->title()->string();
+ if (!title.isEmpty())
+ builder.append(String::format("%s\n", title.utf8().data()));
+
+ String description = element->description()->string();
+ if (!description.isEmpty())
+ builder.append(String::format("%s\n", description.utf8().data()));
+
+ String value = element->stringValue()->string();
+ if (!value.isEmpty())
+ builder.append(String::format("%s\n", value.utf8().data()));
+
+ builder.append(String::format("AXFocusable: %d\n", element->isFocusable()));
+ builder.append(String::format("AXFocused: %d\n", element->isFocused()));
+ builder.append(String::format("AXSelectable: %d\n", element->isSelectable()));
+ builder.append(String::format("AXSelected: %d\n", element->isSelected()));
+ builder.append(String::format("AXMultiSelectable: %d\n", element->isMultiSelectable()));
+ builder.append(String::format("AXEnabled: %d\n", element->isEnabled()));
+ builder.append(String::format("AXExpanded: %d\n", element->isExpanded()));
+ builder.append(String::format("AXRequired: %d\n", element->isRequired()));
+ builder.append(String::format("AXChecked: %d\n", element->isChecked()));
+
+ String url = element->url()->string();
+ if (!url.isEmpty())
+ builder.append(String::format("%s\n", url.utf8().data()));
+
+ // We append the ATK specific attributes as a single line at the end.
+ builder.append("AXPlatformAttributes: ");
+ builder.append(getAtkAttributeSetAsString(element->platformUIElement(), ObjectAttributeType));
+
+ return builder.toString();
+}
+
+static JSStringRef createStringWithAttributes(const Vector<AccessibilityUIElement>& elements)
+{
+ StringBuilder builder;
+
+ for (Vector<AccessibilityUIElement>::const_iterator it = elements.begin(); it != elements.end(); ++it) {
+ builder.append(attributesOfElement(const_cast<AccessibilityUIElement*>(it)));
+ builder.append("\n------------\n");
+ }
+
+ return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
+}
+
+static Vector<AccessibilityUIElement> getRowHeaders(AtkTable* accessible)
+{
+ Vector<AccessibilityUIElement> rowHeaders;
+
+ int rowsCount = atk_table_get_n_rows(accessible);
+ for (int row = 0; row < rowsCount; ++row)
+ rowHeaders.append(AccessibilityUIElement(atk_table_get_row_header(accessible, row)));
+
+ return rowHeaders;
+}
+
+static Vector<AccessibilityUIElement> getColumnHeaders(AtkTable* accessible)
+{
+ Vector<AccessibilityUIElement> columnHeaders;
+
+ int columnsCount = atk_table_get_n_columns(accessible);
+ for (int column = 0; column < columnsCount; ++column)
+ columnHeaders.append(AccessibilityUIElement(atk_table_get_column_header(accessible, column)));
+
+ return columnHeaders;
+}
+
+static Vector<AccessibilityUIElement> getVisibleCells(AccessibilityUIElement* element)
+{
+ Vector<AccessibilityUIElement> visibleCells;
+
+ AtkTable* accessible = ATK_TABLE(element->platformUIElement());
+ int rowsCount = atk_table_get_n_rows(accessible);
+ int columnsCount = atk_table_get_n_columns(accessible);
+
+ for (int row = 0; row < rowsCount; ++row) {
+ for (int column = 0; column < columnsCount; ++column)
+ visibleCells.append(element->cellForColumnAndRow(column, row));
+ }
+
+ return visibleCells;
+}
+
+} // namespace
+
+JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)
+{
+ GUniquePtr<gchar> rangeString(g_strdup("{0, 0}"));
+
+ if (!ATK_IS_OBJECT(element))
+ return JSStringCreateWithUTF8CString(rangeString.get());
+
+ AtkObject* axTable = atk_object_get_parent(ATK_OBJECT(element));
+ if (!axTable || !ATK_IS_TABLE(axTable))
+ return JSStringCreateWithUTF8CString(rangeString.get());
+
+ // Look for the cell in the table.
+ gint indexInParent = atk_object_get_index_in_parent(ATK_OBJECT(element));
+ if (indexInParent == -1)
+ return JSStringCreateWithUTF8CString(rangeString.get());
+
+ int row = -1;
+ int column = -1;
+ row = atk_table_get_row_at_index(ATK_TABLE(axTable), indexInParent);
+ column = atk_table_get_column_at_index(ATK_TABLE(axTable), indexInParent);
+
+ // Get the actual values, if row and columns are valid values.
+ if (row != -1 && column != -1) {
+ int base = 0;
+ int length = 0;
+ if (isRowRange) {
+ base = row;
+ length = atk_table_get_row_extent_at(ATK_TABLE(axTable), row, column);
+ } else {
+ base = column;
+ length = atk_table_get_column_extent_at(ATK_TABLE(axTable), row, column);
+ }
+ rangeString.reset(g_strdup_printf("{%d, %d}", base, length));
+ }
+
+ return JSStringCreateWithUTF8CString(rangeString.get());
+}
+
+void alterCurrentValue(PlatformUIElement element, int factor)
+{
+ if (!ATK_IS_VALUE(element))
+ return;
+
+ GValue currentValue = G_VALUE_INIT;
+ atk_value_get_current_value(ATK_VALUE(element), &currentValue);
+
+ GValue increment = G_VALUE_INIT;
+ atk_value_get_minimum_increment(ATK_VALUE(element), &increment);
+
+ GValue newValue = G_VALUE_INIT;
+ g_value_init(&newValue, G_TYPE_FLOAT);
+
+ g_value_set_float(&newValue, g_value_get_float(&currentValue) + factor * g_value_get_float(&increment));
+ atk_value_set_current_value(ATK_VALUE(element), &newValue);
+
+ g_value_unset(&newValue);
+ g_value_unset(&increment);
+ g_value_unset(&currentValue);
+}
+
+AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
+ : m_element(element)
+{
+ if (m_element)
+ g_object_ref(m_element);
+}
+
+AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
+ : m_element(other.m_element)
+{
+ if (m_element)
+ g_object_ref(m_element);
+}
+
+AccessibilityUIElement::~AccessibilityUIElement()
+{
+ if (m_element)
+ g_object_unref(m_element);
+}
+
+void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elements)
+{
+ // FIXME: implement
+}
+
+void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>&)
+{
+ // FIXME: implement
+}
+
+void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& children)
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return;
+
+ int count = childrenCount();
+ for (int i = 0; i < count; i++) {
+ AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i);
+ children.append(AccessibilityUIElement(child));
+ }
+}
+
+void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned start, unsigned end)
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return;
+
+ for (unsigned i = start; i < end; i++) {
+ AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i);
+ elementVector.append(AccessibilityUIElement(child));
+ }
+}
+
+int AccessibilityUIElement::rowCount()
+{
+ if (!ATK_IS_TABLE(m_element))
+ return 0;
+
+ return atk_table_get_n_rows(ATK_TABLE(m_element));
+}
+
+int AccessibilityUIElement::columnCount()
+{
+ if (!ATK_IS_TABLE(m_element))
+ return 0;
+
+ return atk_table_get_n_columns(ATK_TABLE(m_element));
+}
+
+int AccessibilityUIElement::childrenCount()
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return 0;
+
+ return atk_object_get_n_accessible_children(ATK_OBJECT(m_element));
+}
+
+AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y)
+{
+ if (!ATK_IS_COMPONENT(m_element))
+ return nullptr;
+
+ GRefPtr<AtkObject> objectAtPoint = adoptGRef(atk_component_ref_accessible_at_point(ATK_COMPONENT(m_element), x, y, ATK_XY_WINDOW));
+ return AccessibilityUIElement(objectAtPoint ? objectAtPoint.get() : m_element);
+}
+
+AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
+{
+ // FIXME: implement
+ return nullptr;
+}
+
+AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return nullptr;
+
+ Vector<AccessibilityUIElement> children;
+ getChildrenWithRange(children, index, index + 1);
+
+ if (children.size() == 1)
+ return children.at(0);
+
+ return nullptr;
+}
+
+unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
+{
+ // FIXME: implement
+ return 0;
+}
+
+JSStringRef AccessibilityUIElement::allAttributes()
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ return JSStringCreateWithUTF8CString(attributesOfElement(this).utf8().data());
+}
+
+JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
+{
+ // FIXME: implement
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
+{
+ // FIXME: implement
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+AccessibilityUIElement AccessibilityUIElement::titleUIElement()
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return nullptr;
+
+ AtkRelationSet* set = atk_object_ref_relation_set(ATK_OBJECT(m_element));
+ if (!set)
+ return nullptr;
+
+ AtkObject* target = nullptr;
+ int count = atk_relation_set_get_n_relations(set);
+ for (int i = 0; i < count; i++) {
+ AtkRelation* relation = atk_relation_set_get_relation(set, i);
+ if (atk_relation_get_relation_type(relation) == ATK_RELATION_LABELLED_BY) {
+ GPtrArray* targetList = atk_relation_get_target(relation);
+ if (targetList->len)
+ target = static_cast<AtkObject*>(g_ptr_array_index(targetList, 0));
+ }
+ }
+
+ g_object_unref(set);
+ return target ? AccessibilityUIElement(target) : nullptr;
+}
+
+AccessibilityUIElement AccessibilityUIElement::parentElement()
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return nullptr;
+
+ AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element));
+ return parent ? AccessibilityUIElement(parent) : nullptr;
+}
+
+JSStringRef AccessibilityUIElement::attributesOfChildren()
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ Vector<AccessibilityUIElement> children;
+ getChildren(children);
+
+ return createStringWithAttributes(children);
+}
+
+JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
+{
+ // FIXME: implement
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::role()
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ if (!atk_object_get_role(ATK_OBJECT(m_element)))
+ return JSStringCreateWithCharacters(0, 0);
+
+ GUniquePtr<char> roleStringWithPrefix(g_strdup_printf("AXRole: %s", roleToString(ATK_OBJECT(m_element))));
+ return JSStringCreateWithUTF8CString(roleStringWithPrefix.get());
+}
+
+JSStringRef AccessibilityUIElement::subrole()
+{
+ return nullptr;
+}
+
+JSStringRef AccessibilityUIElement::roleDescription()
+{
+ return nullptr;
+}
+
+JSStringRef AccessibilityUIElement::title()
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ const gchar* name = atk_object_get_name(ATK_OBJECT(m_element));
+ GUniquePtr<gchar> axTitle(g_strdup_printf("AXTitle: %s", name ? name : ""));
+
+ return JSStringCreateWithUTF8CString(axTitle.get());
+}
+
+JSStringRef AccessibilityUIElement::description()
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ const gchar* description = atk_object_get_description(ATK_OBJECT(m_element));
+ if (!description)
+ return JSStringCreateWithCharacters(0, 0);
+
+ GUniquePtr<gchar> axDesc(g_strdup_printf("AXDescription: %s", description));
+
+ return JSStringCreateWithUTF8CString(axDesc.get());
+}
+
+JSStringRef AccessibilityUIElement::stringValue()
+{
+ if (!ATK_IS_TEXT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ GUniquePtr<gchar> text(atk_text_get_text(ATK_TEXT(m_element), 0, -1));
+ GUniquePtr<gchar> textWithReplacedCharacters(replaceCharactersForResults(text.get()));
+ GUniquePtr<gchar> axValue(g_strdup_printf("AXValue: %s", textWithReplacedCharacters.get()));
+
+ return JSStringCreateWithUTF8CString(axValue.get());
+}
+
+JSStringRef AccessibilityUIElement::language()
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ const gchar* locale = atk_object_get_object_locale(ATK_OBJECT(m_element));
+ if (!locale)
+ return JSStringCreateWithCharacters(0, 0);
+
+ GUniquePtr<char> axValue(g_strdup_printf("AXLanguage: %s", locale));
+ return JSStringCreateWithUTF8CString(axValue.get());
+}
+
+JSStringRef AccessibilityUIElement::helpText() const
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ AtkRelationSet* relationSet = atk_object_ref_relation_set(ATK_OBJECT(m_element));
+ if (!relationSet)
+ return nullptr;
+
+ AtkRelation* relation = atk_relation_set_get_relation_by_type(relationSet, ATK_RELATION_DESCRIBED_BY);
+ if (!relation)
+ return nullptr;
+
+ GPtrArray* targetList = atk_relation_get_target(relation);
+ if (!targetList || !targetList->len)
+ return nullptr;
+
+ StringBuilder builder;
+ builder.append("AXHelp: ");
+
+ for (int targetCount = 0; targetCount < targetList->len; targetCount++) {
+ if (AtkObject* target = static_cast<AtkObject*>(g_ptr_array_index(targetList, targetCount))) {
+ GUniquePtr<gchar> text(atk_text_get_text(ATK_TEXT(target), 0, -1));
+ if (!builder.isEmpty())
+ builder.append(" ");
+ builder.append(text.get());
+ }
+ }
+
+ g_object_unref(relationSet);
+
+ return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
+
+}
+
+double AccessibilityUIElement::x()
+{
+ if (!ATK_IS_COMPONENT(m_element))
+ return 0;
+
+ int x, y;
+ atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN);
+
+ return x;
+}
+
+double AccessibilityUIElement::y()
+{
+ if (!ATK_IS_COMPONENT(m_element))
+ return 0;
+
+ int x, y;
+ atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN);
+
+ return y;
+}
+
+double AccessibilityUIElement::width()
+{
+ if (!ATK_IS_COMPONENT(m_element))
+ return 0;
+
+ int width, height;
+ atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
+
+ return width;
+}
+
+double AccessibilityUIElement::height()
+{
+ if (!ATK_IS_COMPONENT(m_element))
+ return 0;
+
+ int width, height;
+ atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
+
+ return height;
+}
+
+double AccessibilityUIElement::clickPointX()
+{
+ if (!ATK_IS_COMPONENT(m_element))
+ return 0;
+
+ int x, y;
+ atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_WINDOW);
+
+ int width, height;
+ atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
+
+ return x + width / 2.0;
+}
+
+double AccessibilityUIElement::clickPointY()
+{
+ if (!ATK_IS_COMPONENT(m_element))
+ return 0;
+
+ int x, y;
+ atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_WINDOW);
+
+ int width, height;
+ atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
+
+ return y + height / 2.0;
+}
+
+JSStringRef AccessibilityUIElement::orientation() const
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ const char* axOrientation = nullptr;
+ if (checkElementState(m_element, ATK_STATE_HORIZONTAL))
+ axOrientation = "AXOrientation: AXHorizontalOrientation";
+ else if (checkElementState(m_element, ATK_STATE_VERTICAL))
+ axOrientation = "AXOrientation: AXVerticalOrientation";
+
+ if (!axOrientation)
+ return JSStringCreateWithCharacters(0, 0);
+
+ return JSStringCreateWithUTF8CString(axOrientation);
+}
+
+double AccessibilityUIElement::intValue() const
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return 0;
+
+ if (ATK_IS_VALUE(m_element)) {
+ GValue value = G_VALUE_INIT;
+ atk_value_get_current_value(ATK_VALUE(m_element), &value);
+ if (!G_VALUE_HOLDS_FLOAT(&value))
+ return 0;
+ return g_value_get_float(&value);
+ }
+
+ // Consider headings as an special case when returning the "int value" of
+ // an AccessibilityUIElement, so we can reuse some tests to check the level
+ // both for HTML headings and objects with the aria-level attribute.
+ if (atk_object_get_role(ATK_OBJECT(m_element)) == ATK_ROLE_HEADING) {
+ String headingLevel = getAttributeSetValueForId(ATK_OBJECT(m_element), ObjectAttributeType, "level");
+ bool ok;
+ double headingLevelValue = headingLevel.toDouble(&ok);
+ if (ok)
+ return headingLevelValue;
+ }
+
+ return 0;
+}
+
+double AccessibilityUIElement::minValue()
+{
+ if (!ATK_IS_VALUE(m_element))
+ return 0;
+
+ GValue value = G_VALUE_INIT;
+ atk_value_get_minimum_value(ATK_VALUE(m_element), &value);
+ if (!G_VALUE_HOLDS_FLOAT(&value))
+ return 0;
+ return g_value_get_float(&value);
+}
+
+double AccessibilityUIElement::maxValue()
+{
+ if (!ATK_IS_VALUE(m_element))
+ return 0;
+
+ GValue value = G_VALUE_INIT;
+ atk_value_get_maximum_value(ATK_VALUE(m_element), &value);
+ if (!G_VALUE_HOLDS_FLOAT(&value))
+ return 0;
+ return g_value_get_float(&value);
+}
+
+JSStringRef AccessibilityUIElement::valueDescription()
+{
+ // FIXME: implement after it has been implemented in ATK.
+ // See: https://bugzilla.gnome.org/show_bug.cgi?id=684576
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+bool AccessibilityUIElement::isEnabled()
+{
+ return checkElementState(m_element, ATK_STATE_ENABLED);
+}
+
+int AccessibilityUIElement::insertionPointLineNumber()
+{
+ // FIXME: implement
+ return 0;
+}
+
+bool AccessibilityUIElement::isPressActionSupported()
+{
+ if (!ATK_IS_ACTION(m_element))
+ return false;
+
+ const gchar* actionName = atk_action_get_name(ATK_ACTION(m_element), 0);
+ return equalIgnoringCase(actionName, String("press")) || equalIgnoringCase(actionName, String("jump"));
+}
+
+bool AccessibilityUIElement::isIncrementActionSupported()
+{
+ // FIXME: implement
+ return false;
+}
+
+bool AccessibilityUIElement::isDecrementActionSupported()
+{
+ // FIXME: implement
+ return false;
+}
+
+bool AccessibilityUIElement::isRequired() const
+{
+ return checkElementState(m_element, ATK_STATE_REQUIRED);
+}
+
+bool AccessibilityUIElement::isFocused() const
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return false;
+
+ GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
+ gboolean isFocused = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSED);
+
+ return isFocused;
+}
+
+bool AccessibilityUIElement::isSelected() const
+{
+ return checkElementState(m_element, ATK_STATE_SELECTED);
+}
+
+int AccessibilityUIElement::hierarchicalLevel() const
+{
+ // FIXME: implement
+ return 0;
+}
+
+bool AccessibilityUIElement::ariaIsGrabbed() const
+{
+ return false;
+}
+
+JSStringRef AccessibilityUIElement::ariaDropEffects() const
+{
+ return nullptr;
+}
+
+bool AccessibilityUIElement::isExpanded() const
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return false;
+
+ GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
+ gboolean isExpanded = atk_state_set_contains_state(stateSet.get(), ATK_STATE_EXPANDED);
+
+ return isExpanded;
+}
+
+bool AccessibilityUIElement::isChecked() const
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return false;
+
+ GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
+ gboolean isChecked = atk_state_set_contains_state(stateSet.get(), ATK_STATE_CHECKED);
+
+ return isChecked;
+}
+
+bool AccessibilityUIElement::isIndeterminate() const
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return false;
+
+ GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
+ return atk_state_set_contains_state(stateSet.get(), ATK_STATE_INDETERMINATE);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
+{
+ if (!ATK_IS_TABLE(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ Vector<AccessibilityUIElement> columnHeaders = getColumnHeaders(ATK_TABLE(m_element));
+ return createStringWithAttributes(columnHeaders);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
+{
+ if (!ATK_IS_TABLE(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ Vector<AccessibilityUIElement> rowHeaders = getRowHeaders(ATK_TABLE(m_element));
+ return createStringWithAttributes(rowHeaders);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumns()
+{
+ // FIXME: implement
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRows()
+{
+ // FIXME: implement
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
+{
+ if (!ATK_IS_TABLE(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ Vector<AccessibilityUIElement> visibleCells = getVisibleCells(this);
+ return createStringWithAttributes(visibleCells);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfHeader()
+{
+ // FIXME: implement
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+int AccessibilityUIElement::indexInTable()
+{
+ // FIXME: implement
+ return 0;
+}
+
+JSStringRef AccessibilityUIElement::rowIndexRange()
+{
+ // Range in table for rows.
+ return indexRangeInTable(m_element, true);
+}
+
+JSStringRef AccessibilityUIElement::columnIndexRange()
+{
+ // Range in table for columns.
+ return indexRangeInTable(m_element, false);
+}
+
+int AccessibilityUIElement::lineForIndex(int index)
+{
+ if (!ATK_IS_TEXT(m_element))
+ return -1;
+
+ if (index < 0 || index > atk_text_get_character_count(ATK_TEXT(m_element)))
+ return -1;
+
+ GUniquePtr<gchar> text(atk_text_get_text(ATK_TEXT(m_element), 0, index));
+ int lineNo = 0;
+ for (gchar* offset = text.get(); *offset; ++offset) {
+ if (*offset == '\n')
+ ++lineNo;
+ }
+
+ return lineNo;
+}
+
+JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
+{
+ // FIXME: implement
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
+{
+ if (!ATK_IS_TEXT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ String string = atk_text_get_text(ATK_TEXT(m_element), location, location + length);
+ return JSStringCreateWithUTF8CString(string.utf8().data());
+}
+
+JSStringRef AccessibilityUIElement::attributedStringForRange(unsigned, unsigned)
+{
+ // FIXME: implement
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
+{
+ // FIXME: implement
+ return false;
+}
+
+unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
+{
+ // FIXME: implement
+ return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
+{
+ // FIXME: implement
+ return nullptr;
+}
+
+AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row)
+{
+ if (!ATK_IS_TABLE(m_element))
+ return nullptr;
+
+ // Adopt the AtkObject representing the cell because
+ // at_table_ref_at() transfers full ownership.
+ GRefPtr<AtkObject> foundCell = adoptGRef(atk_table_ref_at(ATK_TABLE(m_element), row, column));
+ return foundCell ? AccessibilityUIElement(foundCell.get()) : nullptr;
+}
+
+JSStringRef AccessibilityUIElement::selectedTextRange()
+{
+ if (!ATK_IS_TEXT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ gint start, end;
+ g_free(atk_text_get_selection(ATK_TEXT(m_element), 0, &start, &end));
+
+ GUniquePtr<gchar> selection(g_strdup_printf("{%d, %d}", start, end - start));
+ return JSStringCreateWithUTF8CString(selection.get());
+}
+
+void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
+{
+ if (!ATK_IS_TEXT(m_element))
+ return;
+
+ atk_text_set_selection(ATK_TEXT(m_element), 0, location, location + length);
+}
+
+JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ String atkAttributeName = coreAttributeToAtkAttribute(attribute);
+
+ // Try object attributes first.
+ String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), ObjectAttributeType, atkAttributeName);
+
+ // Try text attributes if the requested one was not found and we have an AtkText object.
+ if (attributeValue.isEmpty() && ATK_IS_TEXT(m_element))
+ attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), TextAttributeType, atkAttributeName);
+
+ // Additional check to make sure that the exposure of the state ATK_STATE_INVALID_ENTRY
+ // is consistent with the exposure of aria-invalid as a text attribute, if present.
+ if (atkAttributeName == attributesMap[InvalidNameIndex][AtkDomain]) {
+ bool isInvalidState = checkElementState(m_element, ATK_STATE_INVALID_ENTRY);
+ if (attributeValue.isEmpty())
+ return JSStringCreateWithUTF8CString(isInvalidState ? "true" : "false");
+
+ // If the text attribute was there, check that it's consistent with
+ // what the state says or force the test to fail otherwise.
+ bool isAriaInvalid = attributeValue != "false";
+ if (isInvalidState != isAriaInvalid)
+ return JSStringCreateWithCharacters(0, 0);
+ }
+
+ return JSStringCreateWithUTF8CString(attributeValue.utf8().data());
+}
+
+double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
+{
+ // FIXME: implement
+ return 0;
+}
+
+bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
+{
+ // FIXME: implement
+ return false;
+}
+
+bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return false;
+
+ String attributeString = jsStringToWTFString(attribute);
+ if (attributeString == "AXValue")
+ return checkElementState(m_element, ATK_STATE_EDITABLE);
+
+ return false;
+}
+
+bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return false;
+
+ String atkAttributeName = coreAttributeToAtkAttribute(attribute);
+ if (atkAttributeName.isEmpty())
+ return false;
+
+ // For now, an attribute is supported whether it's exposed as a object or a text attribute.
+ String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), ObjectAttributeType, atkAttributeName);
+ if (attributeValue.isEmpty())
+ attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), TextAttributeType, atkAttributeName);
+
+ return !attributeValue.isEmpty();
+}
+
+void AccessibilityUIElement::increment()
+{
+ alterCurrentValue(m_element, 1);
+}
+
+void AccessibilityUIElement::decrement()
+{
+ alterCurrentValue(m_element, -1);
+}
+
+void AccessibilityUIElement::press()
+{
+ if (!ATK_IS_ACTION(m_element))
+ return;
+
+ // Only one action per object is supported so far.
+ atk_action_do_action(ATK_ACTION(m_element), 0);
+}
+
+void AccessibilityUIElement::showMenu()
+{
+ // FIXME: implement
+}
+
+AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
+{
+ return nullptr;
+}
+
+AccessibilityUIElement AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
+{
+ return nullptr;
+}
+
+AccessibilityUIElement AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return nullptr;
+
+ AtkRelationSet* relationSet = atk_object_ref_relation_set(ATK_OBJECT(m_element));
+ if (!relationSet)
+ return nullptr;
+
+ AtkRelation* relation = atk_relation_set_get_relation_by_type(relationSet, ATK_RELATION_FLOWS_TO);
+ if (!relation)
+ return nullptr;
+
+ GPtrArray* targetList = atk_relation_get_target(relation);
+ if (!targetList || !targetList->len || index >= targetList->len)
+ return nullptr;
+
+ g_object_unref(relationSet);
+
+ AtkObject* target = static_cast<AtkObject*>(g_ptr_array_index(targetList, index));
+ return target ? AccessibilityUIElement(target) : nullptr;
+}
+
+AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
+{
+ return nullptr;
+}
+
+AccessibilityUIElement AccessibilityUIElement::rowAtIndex(unsigned index)
+{
+ return nullptr;
+}
+
+AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
+{
+ return nullptr;
+}
+
+JSStringRef AccessibilityUIElement::accessibilityValue() const
+{
+ // FIXME: implement
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::documentEncoding()
+{
+ if (!ATK_IS_DOCUMENT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
+ if (role != ATK_ROLE_DOCUMENT_FRAME)
+ return JSStringCreateWithCharacters(0, 0);
+
+ return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "Encoding"));
+}
+
+JSStringRef AccessibilityUIElement::documentURI()
+{
+ if (!ATK_IS_DOCUMENT(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
+ if (role != ATK_ROLE_DOCUMENT_FRAME)
+ return JSStringCreateWithCharacters(0, 0);
+
+ return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "URI"));
+}
+
+JSStringRef AccessibilityUIElement::url()
+{
+ if (!ATK_IS_HYPERLINK_IMPL(m_element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ AtkHyperlink* hyperlink = atk_hyperlink_impl_get_hyperlink(ATK_HYPERLINK_IMPL(m_element));
+ GUniquePtr<char> hyperlinkURI(atk_hyperlink_get_uri(hyperlink, 0));
+
+ // Build the result string, stripping the absolute URL paths if present.
+ char* localURI = g_strstr_len(hyperlinkURI.get(), -1, "LayoutTests");
+ String axURL = String::format("AXURL: %s", localURI ? localURI : hyperlinkURI.get());
+ return JSStringCreateWithUTF8CString(axURL.utf8().data());
+}
+
+bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
+{
+ if (!functionCallback)
+ return false;
+
+ // Only one notification listener per element.
+ if (m_notificationHandler)
+ return false;
+
+ m_notificationHandler = AccessibilityNotificationHandler::create();
+ m_notificationHandler->setPlatformElement(platformUIElement());
+ m_notificationHandler->setNotificationFunctionCallback(functionCallback);
+
+ return true;
+}
+
+void AccessibilityUIElement::removeNotificationListener()
+{
+ // Programmers should not be trying to remove a listener that's already removed.
+ ASSERT(m_notificationHandler);
+
+ m_notificationHandler = nullptr;
+}
+
+bool AccessibilityUIElement::isFocusable() const
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return false;
+
+ GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
+ gboolean isFocusable = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSABLE);
+
+ return isFocusable;
+}
+
+bool AccessibilityUIElement::isSelectable() const
+{
+ return checkElementState(m_element, ATK_STATE_SELECTABLE);
+}
+
+bool AccessibilityUIElement::isMultiSelectable() const
+{
+ return checkElementState(m_element, ATK_STATE_MULTISELECTABLE);
+}
+
+bool AccessibilityUIElement::isSelectedOptionActive() const
+{
+ return checkElementState(m_element, ATK_STATE_ACTIVE);
+}
+
+bool AccessibilityUIElement::isVisible() const
+{
+ // FIXME: implement
+ return false;
+}
+
+bool AccessibilityUIElement::isOffScreen() const
+{
+ // FIXME: implement
+ return false;
+}
+
+bool AccessibilityUIElement::isCollapsed() const
+{
+ // FIXME: implement
+ return false;
+}
+
+bool AccessibilityUIElement::isIgnored() const
+{
+ // FIXME: implement
+ return false;
+}
+
+bool AccessibilityUIElement::hasPopup() const
+{
+ if (!ATK_IS_OBJECT(m_element))
+ return false;
+
+ String hasPopupValue = getAttributeSetValueForId(ATK_OBJECT(m_element), ObjectAttributeType, "haspopup");
+ return equalIgnoringCase(hasPopupValue, "true");
+}
+
+void AccessibilityUIElement::takeFocus()
+{
+ // FIXME: implement
+}
+
+void AccessibilityUIElement::takeSelection()
+{
+ // FIXME: implement
+}
+
+void AccessibilityUIElement::addSelection()
+{
+ // FIXME: implement
+}
+
+void AccessibilityUIElement::removeSelection()
+{
+ // FIXME: implement
+}
+
+void AccessibilityUIElement::scrollToMakeVisible()
+{
+ // FIXME: implement
+}
+
+void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height)
+{
+ // FIXME: implement
+}
+
+void AccessibilityUIElement::scrollToGlobalPoint(int x, int y)
+{
+ // FIXME: implement
+}
+
+JSStringRef AccessibilityUIElement::classList() const
+{
+ // FIXME: implement
+ return nullptr;
+}
+
+JSStringRef stringAtOffset(PlatformUIElement element, AtkTextBoundary boundary, int offset)
+{
+ if (!ATK_IS_TEXT(element))
+ return JSStringCreateWithCharacters(0, 0);
+
+ gint startOffset, endOffset;
+ StringBuilder builder;
+
+#if ATK_CHECK_VERSION(2, 10, 0)
+ AtkTextGranularity granularity;
+ switch (boundary) {
+ case ATK_TEXT_BOUNDARY_CHAR:
+ granularity = ATK_TEXT_GRANULARITY_CHAR;
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_START:
+ granularity = ATK_TEXT_GRANULARITY_WORD;
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ granularity = ATK_TEXT_GRANULARITY_LINE;
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_START:
+ granularity = ATK_TEXT_GRANULARITY_SENTENCE;
+ break;
+ default:
+ return JSStringCreateWithCharacters(0, 0);
+ }
+
+ builder.append(atk_text_get_string_at_offset(ATK_TEXT(element), offset, granularity, &startOffset, &endOffset));
+#else
+ builder.append(atk_text_get_text_at_offset(ATK_TEXT(element), offset, boundary, &startOffset, &endOffset));
+#endif
+ builder.append(String::format(", %i, %i", startOffset, endOffset));
+ return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
+}
+
+JSStringRef AccessibilityUIElement::characterAtOffset(int offset)
+{
+ return stringAtOffset(m_element, ATK_TEXT_BOUNDARY_CHAR, offset);
+}
+
+JSStringRef AccessibilityUIElement::wordAtOffset(int offset)
+{
+ return stringAtOffset(m_element, ATK_TEXT_BOUNDARY_WORD_START, offset);
+}
+
+JSStringRef AccessibilityUIElement::lineAtOffset(int offset)
+{
+ return stringAtOffset(m_element, ATK_TEXT_BOUNDARY_LINE_START, offset);
+}
+
+JSStringRef AccessibilityUIElement::sentenceAtOffset(int offset)
+{
+ return stringAtOffset(m_element, ATK_TEXT_BOUNDARY_SENTENCE_START, offset);
+}
+
+#endif
diff --git a/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp b/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp
index 9c8931075..fe6046c68 100644
--- a/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp
+++ b/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp
@@ -12,7 +12,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
diff --git a/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.h b/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.h
index a2fac882b..071e874d0 100644
--- a/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.h
+++ b/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.h
@@ -11,7 +11,7 @@
* 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 Inc. ("Apple") nor the names of
+ * 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.
*
diff --git a/Tools/DumpRenderTree/config.h b/Tools/DumpRenderTree/config.h
index 9e0fe4fd4..ddb1d5195 100644
--- a/Tools/DumpRenderTree/config.h
+++ b/Tools/DumpRenderTree/config.h
@@ -20,11 +20,16 @@
#define Config_H
-#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H && defined(BUILDING_WITH_CMAKE)
+#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H
+#if defined(BUILDING_WITH_CMAKE)
#include "cmakeconfig.h"
+#else
+#include "autotoolsconfig.h"
+#endif
#endif
-#include <WebCore/PlatformExportMacros.h>
+#include <wtf/Platform.h>
+#include <wtf/ExportMacros.h>
#include <runtime/JSExportMacros.h>
#ifdef __cplusplus
@@ -33,25 +38,39 @@
#include <wtf/FastMalloc.h>
#endif
-#if PLATFORM(COCOA)
-#define USE_CF 1
-#endif
+#if PLATFORM(MAC)
+#define WTF_USE_CF 1
+
+// FIXME: These can be removed after sufficient time has passed since the removal of BUILDING_ON / TARGETING macros.
+
+#define ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MIN_REQUIRED 0 / 0
+#define ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MAX_ALLOWED 0 / 0
+
+#define BUILDING_ON_LEOPARD ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MIN_REQUIRED
+#define BUILDING_ON_SNOW_LEOPARD ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MIN_REQUIRED
+#define BUILDING_ON_LION ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MIN_REQUIRED
+
+#define TARGETING_LEOPARD ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MAX_ALLOWED
+#define TARGETING_SNOW_LEOPARD ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MAX_ALLOWED
+#define TARGETING_LION ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MAX_ALLOWED
+
+#endif // PLATFORM(MAC)
#if PLATFORM(WIN)
-#define USE_CF 1
+#define WTF_USE_CF 1
#if PLATFORM(WIN_CAIRO)
-#define USE_CAIRO 1
-#define USE_CURL 1
+#define WTF_USE_CAIRO 1
+#define WTF_USE_CURL 1
#else
-#define USE_CG 1
-#define USE_CFNETWORK 1
+#define WTF_USE_CG 1
+#define WTF_USE_CFNETWORK 1
#endif
#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x601
+#define _WIN32_WINNT 0x0502
#undef WINVER
-#define WINVER 0x0601
+#define WINVER 0x0502
#undef _WINSOCKAPI_
#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h
diff --git a/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp b/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp
new file mode 100644
index 000000000..7ee1d9460
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Jan Michael Alonzo
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if HAVE(ACCESSIBILITY)
+
+#include "AccessibilityController.h"
+
+#include "AccessibilityCallbacks.h"
+#include "AccessibilityUIElement.h"
+#include "DumpRenderTree.h"
+#include "WebCoreSupport/DumpRenderTreeSupportGtk.h"
+
+#include <atk/atk.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+#include <wtf/gobject/GUniquePtr.h>
+
+AccessibilityUIElement AccessibilityController::focusedElement()
+{
+ AtkObject* accessible = DumpRenderTreeSupportGtk::getFocusedAccessibleElement(mainFrame);
+ if (!accessible)
+ return 0;
+
+ return AccessibilityUIElement(accessible);
+}
+
+AccessibilityUIElement AccessibilityController::rootElement()
+{
+ AtkObject* accessible = DumpRenderTreeSupportGtk::getRootAccessibleElement(mainFrame);
+ if (!accessible)
+ return 0;
+
+ return AccessibilityUIElement(accessible);
+}
+
+AccessibilityUIElement AccessibilityController::accessibleElementById(JSStringRef id)
+{
+ AtkObject* root = DumpRenderTreeSupportGtk::getRootAccessibleElement(mainFrame);
+ if (!root)
+ return 0;
+
+ size_t bufferSize = JSStringGetMaximumUTF8CStringSize(id);
+ GUniquePtr<gchar> idBuffer(static_cast<gchar*>(g_malloc(bufferSize)));
+ JSStringGetUTF8CString(id, idBuffer.get(), bufferSize);
+
+ AtkObject* result = childElementById(root, idBuffer.get());
+ if (ATK_IS_OBJECT(result))
+ return AccessibilityUIElement(result);
+
+ return 0;
+
+}
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp
new file mode 100644
index 000000000..73d710a04
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp
@@ -0,0 +1,1557 @@
+/*
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2008 Alp Toker <alp@nuanti.com>
+ * Copyright (C) 2009 Jan Alonzo <jmalonzo@gmail.com>
+ * Copyright (C) 2010, 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 "DumpRenderTree.h"
+
+#include "AccessibilityController.h"
+#include "EditingCallbacks.h"
+#include "EventSender.h"
+#include "GCController.h"
+#include "PixelDumpSupport.h"
+#include "SelfScrollingWebKitWebView.h"
+#include "TestRunner.h"
+#include "TextInputController.h"
+#include "WebCoreSupport/DumpRenderTreeSupportGtk.h"
+#include "WebCoreTestSupport.h"
+#include "WorkQueue.h"
+#include "WorkQueueItem.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <WebCore/platform/network/soup/GUniquePtrSoup.h>
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+#include <getopt.h>
+#include <gtk/gtk.h>
+#include <locale.h>
+#include <webkit/webkit.h>
+#include <wtf/Assertions.h>
+#include <wtf/gobject/GlibUtilities.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(X11)
+#include <fontconfig/fontconfig.h>
+#endif
+
+
+using namespace std;
+
+extern "C" {
+// This API is not yet public.
+extern gchar* webkit_web_history_item_get_target(WebKitWebHistoryItem*);
+extern gboolean webkit_web_history_item_is_target_item(WebKitWebHistoryItem*);
+extern GList* webkit_web_history_item_get_children(WebKitWebHistoryItem*);
+extern void webkit_web_settings_add_extra_plugin_directory(WebKitWebView* view, const gchar* directory);
+extern gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame);
+}
+
+volatile bool done;
+static bool printSeparators;
+static int dumpPixelsForAllTests = false;
+static bool dumpPixelsForCurrentTest;
+static int dumpTree = 1;
+static int useTimeoutWatchdog = 1;
+
+#if HAVE(ACCESSIBILITY)
+AccessibilityController* axController = 0;
+#endif
+RefPtr<TestRunner> gTestRunner;
+static GCController* gcController = 0;
+static WebKitWebView* webView;
+static GtkWidget* window;
+static GtkWidget* container;
+static GtkWidget* webInspectorWindow;
+WebKitWebFrame* mainFrame = 0;
+WebKitWebFrame* topLoadingFrame = 0;
+guint waitToDumpWatchdog = 0;
+bool waitForPolicy = false;
+
+// This is a list of opened webviews
+GSList* webViewList = 0;
+
+// current b/f item at the end of the previous test
+static WebKitWebHistoryItem* prevTestBFItem = NULL;
+
+const unsigned historyItemIndent = 8;
+
+static void runTest(const string& inputLine);
+
+static void didRunInsecureContent(WebKitWebFrame*, WebKitSecurityOrigin*, const char* url);
+
+static bool shouldLogFrameLoadDelegates(const string& pathOrURL)
+{
+ return pathOrURL.find("loading/") != string::npos;
+}
+
+static bool shouldOpenWebInspector(const string& pathOrURL)
+{
+ return pathOrURL.find("inspector/") != string::npos;
+}
+
+static bool shouldDumpAsText(const string& pathOrURL)
+{
+ return pathOrURL.find("dumpAsText/") != string::npos;
+}
+
+static bool shouldEnableDeveloperExtras(const string& pathOrURL)
+{
+ return true;
+}
+
+void dumpFrameScrollPosition(WebKitWebFrame* frame)
+{
+ WebKitDOMDocument* document = webkit_web_frame_get_dom_document(frame);
+ if (!document)
+ return;
+
+ WebKitDOMDOMWindow* domWindow = webkit_dom_document_get_default_view(document);
+ if (!domWindow)
+ return;
+
+ glong x = webkit_dom_dom_window_get_page_x_offset(domWindow);
+ glong y = webkit_dom_dom_window_get_page_y_offset(domWindow);
+
+ if (abs(x) > 0 || abs(y) > 0) {
+ if (webkit_web_frame_get_parent(frame))
+ printf("frame '%s' ", webkit_web_frame_get_name(frame));
+ printf("scrolled to %ld,%ld\n", x, y);
+ }
+
+ if (gTestRunner->dumpChildFrameScrollPositions()) {
+ GSList* children = DumpRenderTreeSupportGtk::getFrameChildren(frame);
+ for (GSList* child = children; child; child = g_slist_next(child))
+ dumpFrameScrollPosition(static_cast<WebKitWebFrame*>(child->data));
+ g_slist_free(children);
+ }
+}
+
+void displayWebView()
+{
+ DumpRenderTreeSupportGtk::forceWebViewPaint(webView);
+ DumpRenderTreeSupportGtk::setTracksRepaints(mainFrame, true);
+ DumpRenderTreeSupportGtk::resetTrackedRepaints(mainFrame);
+}
+
+static void appendString(gchar*& target, const gchar* string)
+{
+ gchar* oldString = target;
+ target = g_strconcat(target, string, NULL);
+ g_free(oldString);
+}
+
+static void initializeGtkFontSettings(const char* testURL)
+{
+ GtkSettings* settings = gtk_settings_get_default();
+ if (!settings)
+ return;
+ g_object_set(settings,
+ "gtk-xft-dpi", 98304, // This is 96 * 1024 or 96 DPI according to the GTK+ docs.
+ "gtk-xft-antialias", 1,
+ "gtk-xft-hinting", 0,
+ "gtk-font-name", "Liberation Sans 12",
+ "gtk-icon-theme-name", "gnome",
+ NULL);
+ gdk_screen_set_resolution(gdk_screen_get_default(), 96.0);
+
+ // One test needs subpixel anti-aliasing turned on, but generally we
+ // want all text in other tests to use to grayscale anti-aliasing.
+ if (testURL && strstr(testURL, "xsettings_antialias_settings.html"))
+ g_object_set(settings, "gtk-xft-rgba", "rgb", NULL);
+ else
+ g_object_set(settings, "gtk-xft-rgba", "none", NULL);
+}
+
+CString getTopLevelPath()
+{
+ if (const gchar* topLevel = g_getenv("WEBKIT_TOP_LEVEL"))
+ return topLevel;
+
+ g_setenv("WEBKIT_TOP_LEVEL", TOP_LEVEL_DIR, FALSE);
+ return TOP_LEVEL_DIR;
+}
+
+CString getOutputDir()
+{
+ const char* webkitOutputDir = g_getenv("WEBKIT_OUTPUTDIR");
+ if (webkitOutputDir)
+ return webkitOutputDir;
+
+ CString topLevelPath = getTopLevelPath();
+ GUniquePtr<char> outputDir(g_build_filename(topLevelPath.data(), "WebKitBuild", NULL));
+ return outputDir.get();
+}
+
+static CString getFontsPath()
+{
+ CString webkitOutputDir = getOutputDir();
+ GUniquePtr<char> fontsPath(g_build_filename(webkitOutputDir.data(), "Dependencies", "Root", "webkitgtk-test-fonts", NULL));
+ if (g_file_test(fontsPath.get(), static_cast<GFileTest>(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+ return fontsPath.get();
+
+ // Try alternative fonts path.
+ fontsPath.reset(g_build_filename(webkitOutputDir.data(), "webkitgtk-test-fonts", NULL));
+ if (g_file_test(fontsPath.get(), static_cast<GFileTest>(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+ return fontsPath.get();
+
+ return CString();
+}
+
+static void initializeFonts(const char* testURL = 0)
+{
+#if PLATFORM(X11)
+ initializeGtkFontSettings(testURL);
+
+ FcInit();
+
+ // If a test resulted a font being added or removed via the @font-face rule, then
+ // we want to reset the FontConfig configuration to prevent it from affecting other tests.
+ static int numFonts = 0;
+ FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication);
+ if (appFontSet && numFonts && appFontSet->nfont == numFonts)
+ return;
+
+ // Load our configuration file, which sets up proper aliases for family
+ // names like sans, serif and monospace.
+ FcConfig* config = FcConfigCreate();
+ GUniquePtr<gchar> fontConfigFilename(g_build_filename(FONTS_CONF_DIR, "fonts.conf", nullptr));
+ if (!FcConfigParseAndLoad(config, reinterpret_cast<FcChar8*>(fontConfigFilename.get()), true))
+ g_error("Couldn't load font configuration file from: %s", fontConfigFilename.get());
+
+ CString fontsPath = getFontsPath();
+ if (fontsPath.isNull())
+ g_error("Could not locate test fonts at $WEBKIT_TOP_LEVEL/WebKitBuild/Dependencies/Root/webkitgtk-test-fonts. "
+ "WEBKIT_TOP_LEVEL is your WebKit checkout by default, and can be overridden by setting it as an environment variable.");
+
+ GUniquePtr<GDir> fontsDirectory(g_dir_open(fontsPath.data(), 0, nullptr));
+ while (const char* directoryEntry = g_dir_read_name(fontsDirectory.get())) {
+ if (!g_str_has_suffix(directoryEntry, ".ttf") && !g_str_has_suffix(directoryEntry, ".otf"))
+ continue;
+ GUniquePtr<gchar> fontPath(g_build_filename(fontsPath.data(), directoryEntry, nullptr));
+ if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8*>(fontPath.get())))
+ g_error("Could not load font at %s!", fontPath.get());
+
+ }
+
+ // Ahem is used by many layout tests.
+ GUniquePtr<gchar> ahemFontFilename(g_build_filename(FONTS_CONF_DIR, "AHEM____.TTF", nullptr));
+ if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(ahemFontFilename.get())))
+ g_error("Could not load font at %s!", ahemFontFilename.get());
+
+ for (int i = 1; i <= 9; i++) {
+ GUniquePtr<gchar> fontFilename(g_strdup_printf("WebKitWeightWatcher%i00.ttf", i));
+ GUniquePtr<gchar> fontPath(g_build_filename(FONTS_CONF_DIR, "..", "..", "fonts", fontFilename.get(), nullptr));
+ if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontPath.get())))
+ g_error("Could not load font at %s!", fontPath.get());
+ }
+
+ // A font with no valid Fontconfig encoding to test https://bugs.webkit.org/show_bug.cgi?id=47452
+ GUniquePtr<gchar> fontWithNoValidEncodingFilename(g_build_filename(FONTS_CONF_DIR, "FontWithNoValidEncoding.fon", nullptr));
+ if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontWithNoValidEncodingFilename.get())))
+ g_error("Could not load font at %s!", fontWithNoValidEncodingFilename.get());
+
+ if (!FcConfigSetCurrent(config))
+ g_error("Could not set the current font configuration!");
+
+ numFonts = FcConfigGetFonts(config, FcSetApplication)->nfont;
+#endif
+}
+
+static gchar* dumpFramesAsText(WebKitWebFrame* frame)
+{
+ gchar* result = 0;
+
+ // Add header for all but the main frame.
+ bool isMainFrame = (webkit_web_view_get_main_frame(webView) == frame);
+
+ CString innerText = DumpRenderTreeSupportGtk::getInnerText(frame);
+ if (isMainFrame)
+ result = g_strdup_printf("%s\n", innerText.data());
+ else {
+ const gchar* frameName = webkit_web_frame_get_name(frame);
+ result = g_strdup_printf("\n--------\nFrame: '%s'\n--------\n%s\n", frameName, innerText.data());
+ }
+
+ if (gTestRunner->dumpChildFramesAsText()) {
+ GSList* children = DumpRenderTreeSupportGtk::getFrameChildren(frame);
+ for (GSList* child = children; child; child = g_slist_next(child)) {
+ GUniquePtr<gchar> childData(dumpFramesAsText(static_cast<WebKitWebFrame*>(child->data)));
+ appendString(result, childData.get());
+ }
+ g_slist_free(children);
+ }
+
+ return result;
+}
+
+static gint compareHistoryItems(gpointer* item1, gpointer* item2)
+{
+ GUniquePtr<gchar> firstItemTarget(webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item1)));
+ GUniquePtr<gchar> secondItemTarget(webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item2)));
+ return g_ascii_strcasecmp(firstItemTarget.get(), secondItemTarget.get());
+}
+
+static void dumpHistoryItem(WebKitWebHistoryItem* item, int indent, bool current)
+{
+ ASSERT(item != NULL);
+ int start = 0;
+ g_object_ref(item);
+ if (current) {
+ printf("curr->");
+ start = 6;
+ }
+ for (int i = start; i < indent; i++)
+ putchar(' ');
+
+ // normalize file URLs.
+ const gchar* uri = webkit_web_history_item_get_uri(item);
+ gchar* uriScheme = g_uri_parse_scheme(uri);
+ if (g_strcmp0(uriScheme, "file") == 0) {
+ gchar* pos = g_strstr_len(uri, -1, "/LayoutTests/");
+ if (!pos) {
+ g_free(uriScheme);
+ return;
+ }
+
+ GString* result = g_string_sized_new(strlen(uri));
+ result = g_string_append(result, "(file test):");
+ result = g_string_append(result, pos + strlen("/LayoutTests/"));
+ printf("%s", result->str);
+ g_string_free(result, TRUE);
+ } else
+ printf("%s", uri);
+
+ g_free(uriScheme);
+
+ GUniquePtr<gchar> target(webkit_web_history_item_get_target(item));
+ if (target.get() && strlen(target.get()) > 0)
+ printf(" (in frame \"%s\")", target.get());
+ if (webkit_web_history_item_is_target_item(item))
+ printf(" **nav target**");
+ putchar('\n');
+
+ if (GList* kids = webkit_web_history_item_get_children(item)) {
+ // must sort to eliminate arbitrary result ordering which defeats reproducible testing
+ for (GList* kid = g_list_sort(kids, (GCompareFunc) compareHistoryItems); kid; kid = g_list_next(kid)) {
+ WebKitWebHistoryItem* item = WEBKIT_WEB_HISTORY_ITEM(kid->data);
+ dumpHistoryItem(item, indent + 4, FALSE);
+ g_object_unref(item);
+ }
+ g_list_free(kids);
+ }
+ g_object_unref(item);
+}
+
+static void dumpBackForwardListForWebView(WebKitWebView* view)
+{
+ printf("\n============== Back Forward List ==============\n");
+ WebKitWebBackForwardList* bfList = webkit_web_view_get_back_forward_list(view);
+
+ // Print out all items in the list after prevTestBFItem, which was from the previous test
+ // Gather items from the end of the list, the print them out from oldest to newest
+ GList* itemsToPrint = NULL;
+ gint forwardListCount = webkit_web_back_forward_list_get_forward_length(bfList);
+ for (int i = forwardListCount; i > 0; i--) {
+ WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i);
+ // something is wrong if the item from the last test is in the forward part of the b/f list
+ ASSERT(item != prevTestBFItem);
+ g_object_ref(item);
+ itemsToPrint = g_list_prepend(itemsToPrint, item);
+ }
+
+ WebKitWebHistoryItem* currentItem = webkit_web_back_forward_list_get_current_item(bfList);
+ g_object_ref(currentItem);
+ itemsToPrint = g_list_prepend(itemsToPrint, currentItem);
+
+ gint backListCount = webkit_web_back_forward_list_get_back_length(bfList);
+ for (int i = -1; i >= -(backListCount); i--) {
+ WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i);
+ if (item == prevTestBFItem)
+ break;
+ g_object_ref(item);
+ itemsToPrint = g_list_prepend(itemsToPrint, item);
+ }
+
+ for (GList* itemToPrint = itemsToPrint; itemToPrint; itemToPrint = g_list_next(itemToPrint)) {
+ WebKitWebHistoryItem* item = WEBKIT_WEB_HISTORY_ITEM(itemToPrint->data);
+ dumpHistoryItem(item, historyItemIndent, item == currentItem);
+ g_object_unref(item);
+ }
+
+ g_list_free(itemsToPrint);
+ printf("===============================================\n");
+}
+
+static void dumpBackForwardListForAllWebViews()
+{
+ // Dump the back forward list of the main WebView first
+ dumpBackForwardListForWebView(webView);
+
+ // The view list is prepended. Reverse the list so we get the order right.
+ for (GSList* currentView = g_slist_reverse(webViewList); currentView; currentView = g_slist_next(currentView))
+ dumpBackForwardListForWebView(WEBKIT_WEB_VIEW(currentView->data));
+}
+
+void setWaitToDumpWatchdog(guint timer)
+{
+ waitToDumpWatchdog = timer;
+}
+
+bool shouldSetWaitToDumpWatchdog()
+{
+ return !waitToDumpWatchdog && useTimeoutWatchdog;
+}
+
+CString soupURIToStringPreservingPassword(SoupURI* soupURI)
+{
+ if (!soupURI->password) {
+ GUniquePtr<char> uriString(soup_uri_to_string(soupURI, FALSE));
+ return uriString.get();
+ }
+
+ // soup_uri_to_string does not insert the password into the string, so we need to create the
+ // URI string and then reinsert any credentials that were present in the SoupURI. All tests that
+ // use URL-embedded credentials use HTTP, so it's safe here.
+ GUniquePtr<char> password(soupURI->password);
+ GUniquePtr<char> user(soupURI->user);
+ soupURI->password = 0;
+ soupURI->user = 0;
+
+ GUniquePtr<char> uriString(soup_uri_to_string(soupURI, FALSE));
+ String absoluteURIWithoutCredentialString = String::fromUTF8(uriString.get());
+ String protocolAndCredential = String::format("http://%s:%s@", user ? user.get() : "", password.get());
+ return absoluteURIWithoutCredentialString.replace("http://", protocolAndCredential).utf8();
+}
+
+static void invalidateAnyPreviousWaitToDumpWatchdog()
+{
+ if (waitToDumpWatchdog) {
+ g_source_remove(waitToDumpWatchdog);
+ waitToDumpWatchdog = 0;
+ }
+
+ waitForPolicy = false;
+}
+
+static void resetDefaultsToConsistentValues()
+{
+ WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
+ GUniquePtr<gchar> localStoragePath(g_build_filename(g_get_user_data_dir(), "DumpRenderTreeGtk", "databases", nullptr));
+ g_object_set(G_OBJECT(settings),
+ "enable-accelerated-compositing", FALSE,
+ "enable-private-browsing", FALSE,
+ "enable-developer-extras", FALSE,
+ "enable-spell-checking", TRUE,
+ "enable-html5-database", TRUE,
+ "enable-html5-local-storage", TRUE,
+ "html5-local-storage-database-path", localStoragePath.get(),
+ "enable-xss-auditor", FALSE,
+ "enable-spatial-navigation", FALSE,
+ "javascript-can-access-clipboard", TRUE,
+ "javascript-can-open-windows-automatically", TRUE,
+ "enable-offline-web-application-cache", TRUE,
+ "enable-universal-access-from-file-uris", TRUE,
+ "enable-file-access-from-file-uris", TRUE,
+ "enable-scripts", TRUE,
+ "enable-dom-paste", TRUE,
+ "default-font-family", "Times",
+ "monospace-font-family", "Courier",
+ "serif-font-family", "Times",
+ "sans-serif-font-family", "Helvetica",
+ "cursive-font-family", "cursive",
+ "fantasy-font-family", "fantasy",
+ "default-font-size", 12,
+ "default-monospace-font-size", 10,
+ "minimum-font-size", 0,
+ "enable-caret-browsing", FALSE,
+ "enable-page-cache", FALSE,
+ "auto-resize-window", TRUE,
+ "auto-load-images", TRUE,
+ "enable-java-applet", FALSE,
+ "enable-plugins", TRUE,
+ "enable-hyperlink-auditing", FALSE,
+ "editing-behavior", WEBKIT_EDITING_BEHAVIOR_UNIX,
+ "enable-fullscreen", TRUE,
+ "enable-mediasource", TRUE,
+ NULL);
+ webkit_web_view_set_settings(webView, settings);
+ webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER);
+
+ DumpRenderTreeSupportGtk::clearMainFrameName(mainFrame);
+ DumpRenderTreeSupportGtk::scalePageBy(webView, 1, 0, 0);
+
+ WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView);
+ g_object_set(G_OBJECT(inspector), "javascript-profiling-enabled", FALSE, NULL);
+
+ webkit_web_view_set_zoom_level(webView, 1.0);
+
+ DumpRenderTreeSupportGtk::resetOriginAccessWhiteLists();
+
+ WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView);
+ webkit_web_back_forward_list_clear(list);
+
+ SoupSession* session = webkit_get_default_session();
+ SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR));
+
+ // We only create the jar when the soup backend needs to do
+ // 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);
+
+ setlocale(LC_ALL, "");
+
+ DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(true);
+ webkit_icon_database_set_path(webkit_get_icon_database(), 0);
+ DumpRenderTreeSupportGtk::setDefersLoading(webView, false);
+ DumpRenderTreeSupportGtk::setSerializeHTTPLoads(false);
+
+#if HAVE(ACCESSIBILITY)
+ if (axController)
+ axController->resetToConsistentState();
+#endif
+
+ DumpRenderTreeSupportGtk::clearOpener(mainFrame);
+ DumpRenderTreeSupportGtk::setTracksRepaints(mainFrame, false);
+
+ DumpRenderTreeSupportGtk::resetGeolocationClientMock(webView);
+
+ DumpRenderTreeSupportGtk::setCSSGridLayoutEnabled(webView, false);
+ DumpRenderTreeSupportGtk::setCSSRegionsEnabled(webView, true);
+ DumpRenderTreeSupportGtk::setExperimentalContentSecurityPolicyFeaturesEnabled(true);
+ DumpRenderTreeSupportGtk::setSeamlessIFramesEnabled(true);
+ DumpRenderTreeSupportGtk::setShadowDOMEnabled(true);
+
+ if (gTestRunner) {
+ gTestRunner->setAuthenticationPassword("");
+ gTestRunner->setAuthenticationUsername("");
+ gTestRunner->setHandlesAuthenticationChallenges(false);
+ }
+
+ gtk_widget_set_direction(GTK_WIDGET(webView), GTK_TEXT_DIR_NONE);
+}
+
+static bool useLongRunningServerMode(int argc, char *argv[])
+{
+ // This assumes you've already called getopt_long
+ return (argc == optind+1 && !strcmp(argv[optind], "-"));
+}
+
+static void runTestingServerLoop()
+{
+ // When DumpRenderTree runs in server mode, we just wait around for file names
+ // to be passed to us and read each in turn, passing the results back to the client
+ char filenameBuffer[2048];
+ while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
+ char* newLineCharacter = strchr(filenameBuffer, '\n');
+ if (newLineCharacter)
+ *newLineCharacter = '\0';
+
+ if (!strlen(filenameBuffer))
+ continue;
+
+ runTest(filenameBuffer);
+ }
+}
+
+static void initializeGlobalsFromCommandLineOptions(int argc, char *argv[])
+{
+ struct option options[] = {
+ {"notree", no_argument, &dumpTree, false},
+ {"pixel-tests", no_argument, &dumpPixelsForAllTests, true},
+ {"tree", no_argument, &dumpTree, true},
+ {"no-timeout", no_argument, &useTimeoutWatchdog, false},
+ {NULL, 0, NULL, 0}
+ };
+
+ int option;
+ while ((option = getopt_long(argc, (char * const *)argv, "", options, NULL)) != -1) {
+ switch (option) {
+ case '?': // unknown or ambiguous option
+ case ':': // missing argument
+ exit(1);
+ break;
+ }
+ }
+}
+
+
+void dump()
+{
+ invalidateAnyPreviousWaitToDumpWatchdog();
+
+ // Grab widget focus before dumping the contents of a widget, in
+ // case it was lost in the course of the test.
+ gtk_widget_grab_focus(GTK_WIDGET(webView));
+
+ if (dumpTree) {
+ char* result = 0;
+ gchar* responseMimeType = webkit_web_frame_get_response_mime_type(mainFrame);
+
+ if (g_str_equal(responseMimeType, "text/plain")) {
+ gTestRunner->setDumpAsText(true);
+ gTestRunner->setGeneratePixelResults(false);
+ }
+ g_free(responseMimeType);
+
+ if (gTestRunner->dumpAsText())
+ result = dumpFramesAsText(mainFrame);
+ else {
+ // Widget resizing is done asynchronously in GTK+. We pump the main
+ // loop here, to flush any pending resize requests. This prevents
+ // timing issues which affect the size of elements in the output.
+ // We only enable this workaround for tests that print the render tree
+ // because this seems to break some dumpAsText tests: see bug 39988
+ // After fixing that test, we should apply this approach to all dumps.
+ while (gtk_events_pending())
+ gtk_main_iteration();
+
+ result = g_strdup(DumpRenderTreeSupportGtk::dumpRenderTree(mainFrame).data());
+ }
+
+ if (!result) {
+ const char* errorMessage;
+ if (gTestRunner->dumpAsText())
+ errorMessage = "[documentElement innerText]";
+ else if (gTestRunner->dumpDOMAsWebArchive())
+ errorMessage = "[[mainFrame DOMDocument] webArchive]";
+ else if (gTestRunner->dumpSourceAsWebArchive())
+ errorMessage = "[[mainFrame dataSource] webArchive]";
+ else
+ errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";
+ printf("ERROR: nil result from %s", errorMessage);
+ } else {
+ printf("%s", result);
+ g_free(result);
+ if (!gTestRunner->dumpAsText() && !gTestRunner->dumpDOMAsWebArchive() && !gTestRunner->dumpSourceAsWebArchive())
+ dumpFrameScrollPosition(mainFrame);
+
+ if (gTestRunner->dumpBackForwardList())
+ dumpBackForwardListForAllWebViews();
+ }
+
+ if (printSeparators) {
+ puts("#EOF"); // terminate the content block
+ fputs("#EOF\n", stderr);
+ fflush(stdout);
+ fflush(stderr);
+ }
+ }
+
+ if (dumpPixelsForCurrentTest
+ && gTestRunner->generatePixelResults()
+ && !gTestRunner->dumpDOMAsWebArchive()
+ && !gTestRunner->dumpSourceAsWebArchive()) {
+ DumpRenderTreeSupportGtk::forceWebViewPaint(webView);
+ dumpWebViewAsPixelsAndCompareWithExpected(gTestRunner->expectedPixelHash());
+ }
+
+ // FIXME: call displayWebView here when we support --paint
+
+ done = true;
+ gtk_main_quit();
+}
+
+static CString temporaryDatabaseDirectory()
+{
+ const char* directoryFromEnvironment = g_getenv("DUMPRENDERTREE_TEMP");
+ if (directoryFromEnvironment)
+ return directoryFromEnvironment;
+ GUniquePtr<char> fallback(g_build_filename(g_get_user_data_dir(), "gtkwebkitdrt", "databases", NULL));
+ return fallback.get();
+}
+
+static void setDefaultsToConsistentStateValuesForTesting()
+{
+ resetDefaultsToConsistentValues();
+
+#if PLATFORM(X11)
+ webkit_web_settings_add_extra_plugin_directory(webView, TEST_PLUGIN_DIR);
+#endif
+
+ webkit_set_web_database_directory_path(temporaryDatabaseDirectory().data());
+
+#if defined(GTK_API_VERSION_2)
+ gtk_rc_parse_string("style \"nix_scrollbar_spacing\" "
+ "{ "
+ " GtkScrolledWindow::scrollbar-spacing = 0 "
+ "} "
+ "class \"GtkWidget\" style \"nix_scrollbar_spacing\"");
+
+#else
+ GtkCssProvider* cssProvider = gtk_css_provider_new();
+ gtk_css_provider_load_from_data(cssProvider,
+ "@binding-set NoKeyboardNavigation { "
+ " unbind \"<shift>F10\"; "
+ "} "
+ " * { "
+ " -GtkScrolledWindow-scrollbar-spacing: 0;"
+ " gtk-key-bindings: NoKeyboardNavigation; "
+ "} ",
+ -1, 0);
+ gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()),
+ GTK_STYLE_PROVIDER(cssProvider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ g_object_unref(cssProvider);
+#endif
+}
+
+static void sendPixelResultsEOF()
+{
+ puts("#EOF");
+
+ fflush(stdout);
+ fflush(stderr);
+}
+
+static void runTest(const string& inputLine)
+{
+ ASSERT(!inputLine.empty());
+
+ TestCommand command = parseInputLine(inputLine);
+ string& testURL = command.pathOrURL;
+ dumpPixelsForCurrentTest = command.shouldDumpPixels || dumpPixelsForAllTests;
+
+ // Convert the path into a full file URL if it does not look
+ // like an HTTP/S URL (doesn't start with http:// or https://).
+ if (testURL.find("http://") && testURL.find("https://")) {
+ GFile* testFile = g_file_new_for_path(testURL.c_str());
+ gchar* testURLCString = g_file_get_uri(testFile);
+ testURL = testURLCString;
+ g_free(testURLCString);
+ g_object_unref(testFile);
+ }
+
+ resetDefaultsToConsistentValues();
+
+ gTestRunner = TestRunner::create(testURL, command.expectedPixelHash);
+ topLoadingFrame = 0;
+ done = false;
+
+ gTestRunner->setIconDatabaseEnabled(false);
+
+ if (shouldLogFrameLoadDelegates(testURL))
+ gTestRunner->setDumpFrameLoadCallbacks(true);
+
+ if (shouldEnableDeveloperExtras(testURL)) {
+ gTestRunner->setDeveloperExtrasEnabled(true);
+ if (shouldOpenWebInspector(testURL))
+ gTestRunner->showWebInspector();
+ if (shouldDumpAsText(testURL)) {
+ gTestRunner->setDumpAsText(true);
+ gTestRunner->setGeneratePixelResults(false);
+ }
+ }
+
+ WorkQueue::shared()->clear();
+ WorkQueue::shared()->setFrozen(false);
+
+ bool isSVGW3CTest = (testURL.find("svg/W3C-SVG-1.1") != string::npos);
+ GtkAllocation size;
+ size.x = size.y = 0;
+ size.width = isSVGW3CTest ? TestRunner::w3cSVGViewWidth : TestRunner::viewWidth;
+ size.height = isSVGW3CTest ? TestRunner::w3cSVGViewHeight : TestRunner::viewHeight;
+ gtk_window_resize(GTK_WINDOW(window), size.width, size.height);
+ gtk_widget_size_allocate(container, &size);
+
+ if (prevTestBFItem)
+ g_object_unref(prevTestBFItem);
+ WebKitWebBackForwardList* bfList = webkit_web_view_get_back_forward_list(webView);
+ prevTestBFItem = webkit_web_back_forward_list_get_current_item(bfList);
+ if (prevTestBFItem)
+ g_object_ref(prevTestBFItem);
+
+ initializeFonts(testURL.c_str());
+
+ // Focus the web view before loading the test to avoid focusing problems
+ gtk_widget_grab_focus(GTK_WIDGET(webView));
+ webkit_web_view_open(webView, testURL.c_str());
+
+ gtk_main();
+
+ // If developer extras enabled Web Inspector may have been open by the test.
+ if (shouldEnableDeveloperExtras(testURL)) {
+ gTestRunner->closeWebInspector();
+ gTestRunner->setDeveloperExtrasEnabled(false);
+ }
+
+ // Also check if we still have opened webViews and free them.
+ if (gTestRunner->closeRemainingWindowsWhenComplete() || webViewList) {
+ while (webViewList) {
+ g_object_unref(WEBKIT_WEB_VIEW(webViewList->data));
+ webViewList = g_slist_next(webViewList);
+ }
+ g_slist_free(webViewList);
+ webViewList = 0;
+ }
+
+ WebCoreTestSupport::resetInternalsObject(webkit_web_frame_get_global_context(mainFrame));
+ DumpRenderTreeSupportGtk::clearMemoryCache();
+ DumpRenderTreeSupportGtk::clearApplicationCache();
+
+ // A blank load seems to be necessary to reset state after certain tests.
+ webkit_web_view_open(webView, "about:blank");
+
+ gTestRunner.clear();
+
+ // terminate the (possibly empty) pixels block after all the state reset
+ sendPixelResultsEOF();
+}
+
+void webViewLoadStarted(WebKitWebView* view, WebKitWebFrame* frame, void*)
+{
+ // Make sure we only set this once per test. If it gets cleared, and then set again, we might
+ // end up doing two dumps for one test.
+ if (!topLoadingFrame && !done)
+ topLoadingFrame = frame;
+}
+
+static gboolean processWork(void* data)
+{
+ // if we finish all the commands, we're ready to dump state
+ if (WorkQueue::shared()->processWork() && !gTestRunner->waitToDump())
+ dump();
+
+ return FALSE;
+}
+
+static char* getFrameNameSuitableForTestResult(WebKitWebView* view, WebKitWebFrame* frame)
+{
+ char* frameName = g_strdup(webkit_web_frame_get_name(frame));
+
+ if (frame == webkit_web_view_get_main_frame(view)) {
+ // This is a bit strange. Shouldn't web_frame_get_name return NULL?
+ if (frameName && (frameName[0] != '\0')) {
+ char* tmp = g_strdup_printf("main frame \"%s\"", frameName);
+ g_free(frameName);
+ frameName = tmp;
+ } else {
+ g_free(frameName);
+ frameName = g_strdup("main frame");
+ }
+ } else if (!frameName || (frameName[0] == '\0')) {
+ g_free(frameName);
+ frameName = g_strdup("frame (anonymous)");
+ } else {
+ char* tmp = g_strdup_printf("frame \"%s\"", frameName);
+ g_free(frameName);
+ frameName = tmp;
+ }
+
+ return frameName;
+}
+
+static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*)
+{
+ // The deprecated "load-finished" signal is triggered by postProgressFinishedNotification(),
+ // so we can use it here in the DRT to provide the correct dump.
+ if (frame != topLoadingFrame)
+ return;
+ if (gTestRunner->dumpProgressFinishedCallback())
+ printf("postProgressFinishedNotification\n");
+}
+
+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 && gTestRunner->dumpFrameLoadCallbacks()) {
+ char* frameName = getFrameNameSuitableForTestResult(view, frame);
+ printf("%s - didFinishDocumentLoadForFrame\n", frameName);
+ g_free(frameName);
+ } else if (!done) {
+ guint pendingFrameUnloadEvents = DumpRenderTreeSupportGtk::getPendingUnloadEventCount(frame);
+ if (pendingFrameUnloadEvents) {
+ char* frameName = getFrameNameSuitableForTestResult(view, frame);
+ printf("%s - has %u onunload handler(s)\n", frameName, pendingFrameUnloadEvents);
+ g_free(frameName);
+ }
+ }
+}
+
+static void webViewOnloadEvent(WebKitWebView* view, WebKitWebFrame* frame, void*)
+{
+ if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
+ char* frameName = getFrameNameSuitableForTestResult(view, frame);
+ printf("%s - didHandleOnloadEventsForFrame\n", frameName);
+ g_free(frameName);
+ }
+}
+
+static void addControllerToWindow(JSContextRef context, JSObjectRef windowObject, const char* controllerName, JSValueRef controller)
+{
+ JSStringRef controllerNameStr = JSStringCreateWithUTF8CString(controllerName);
+ JSObjectSetProperty(context, windowObject, controllerNameStr, controller, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0);
+ JSStringRelease(controllerNameStr);
+}
+
+static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* frame, JSGlobalContextRef context, JSObjectRef windowObject, gpointer data)
+{
+ JSValueRef exception = 0;
+ ASSERT(gTestRunner);
+
+ gTestRunner->makeWindowObject(context, windowObject, &exception);
+ ASSERT(!exception);
+
+ gcController->makeWindowObject(context, windowObject, &exception);
+ ASSERT(!exception);
+
+#if HAVE(ACCESSIBILITY)
+ axController->makeWindowObject(context, windowObject, &exception);
+ ASSERT(!exception);
+#endif
+
+ addControllerToWindow(context, windowObject, "eventSender", makeEventSender(context, !webkit_web_frame_get_parent(frame)));
+ addControllerToWindow(context, windowObject, "textInputController", makeTextInputController(context));
+ WebCoreTestSupport::injectInternalsObject(context);
+}
+
+static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data)
+{
+ gchar* testMessage = 0;
+ const gchar* uriScheme;
+
+ // Tests expect only the filename part of local URIs
+ uriScheme = g_strstr_len(message, -1, "file://");
+ if (uriScheme) {
+ GString* tempString = g_string_sized_new(strlen(message));
+ gchar* filename = g_strrstr(uriScheme, G_DIR_SEPARATOR_S);
+
+ if (filename) {
+ // If the path is a lone slash, keep it to avoid empty output.
+ if (strlen(filename) > 1)
+ filename += strlen(G_DIR_SEPARATOR_S);
+ tempString = g_string_append_len(tempString, message, (uriScheme - message));
+ tempString = g_string_append_len(tempString, filename, strlen(filename));
+ testMessage = g_string_free(tempString, FALSE);
+ }
+ }
+
+ fprintf(stdout, "CONSOLE MESSAGE: ");
+ if (line)
+ fprintf(stdout, "line %d: ", line);
+ fprintf(stdout, "%s\n", testMessage ? testMessage : message);
+ g_free(testMessage);
+
+ return TRUE;
+}
+
+
+static gboolean webViewScriptAlert(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gpointer data)
+{
+ fprintf(stdout, "ALERT: %s\n", message);
+ fflush(stdout);
+ return TRUE;
+}
+
+static gboolean webViewScriptPrompt(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, const gchar* defaultValue, gchar** value, gpointer data)
+{
+ fprintf(stdout, "PROMPT: %s, default text: %s\n", message, defaultValue);
+ *value = g_strdup(defaultValue);
+ return TRUE;
+}
+
+static gboolean webViewScriptConfirm(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gboolean* didConfirm, gpointer data)
+{
+ fprintf(stdout, "CONFIRM: %s\n", message);
+ *didConfirm = TRUE;
+ return TRUE;
+}
+
+static void webViewTitleChanged(WebKitWebView* view, WebKitWebFrame* frame, const gchar* title, gpointer data)
+{
+ if (gTestRunner->dumpFrameLoadCallbacks() && !done) {
+ GUniquePtr<char> frameName(getFrameNameSuitableForTestResult(view, frame));
+ printf("%s - didReceiveTitle: %s\n", frameName.get(), title ? title : "");
+ }
+
+ if (gTestRunner->dumpTitleChanges() && !done)
+ printf("TITLE CHANGED: '%s'\n", title ? title : "");
+}
+
+static bool webViewNavigationPolicyDecisionRequested(WebKitWebView* view, WebKitWebFrame* frame,
+ WebKitNetworkRequest* request,
+ WebKitWebNavigationAction* navAction,
+ WebKitWebPolicyDecision* policyDecision)
+{
+ // Use the default handler if we're not waiting for policy,
+ // i.e., TestRunner::waitForPolicyDelegate
+ if (!waitForPolicy)
+ return FALSE;
+
+ gchar* typeDescription;
+ WebKitWebNavigationReason reason;
+ g_object_get(G_OBJECT(navAction), "reason", &reason, NULL);
+
+ switch(reason) {
+ case WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED:
+ typeDescription = g_strdup("link clicked");
+ break;
+ case WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED:
+ typeDescription = g_strdup("form submitted");
+ break;
+ case WEBKIT_WEB_NAVIGATION_REASON_BACK_FORWARD:
+ typeDescription = g_strdup("back/forward");
+ break;
+ case WEBKIT_WEB_NAVIGATION_REASON_RELOAD:
+ typeDescription = g_strdup("reload");
+ break;
+ case WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED:
+ typeDescription = g_strdup("form resubmitted");
+ break;
+ case WEBKIT_WEB_NAVIGATION_REASON_OTHER:
+ typeDescription = g_strdup("other");
+ break;
+ default:
+ typeDescription = g_strdup("illegal value");
+ }
+
+ printf("Policy delegate: attempt to load %s with navigation type '%s'\n", webkit_network_request_get_uri(request), typeDescription);
+ g_free(typeDescription);
+
+ webkit_web_policy_decision_ignore(policyDecision);
+ gTestRunner->notifyDone();
+
+ return TRUE;
+}
+
+static void webViewStatusBarTextChanged(WebKitWebView* view, const gchar* message, gpointer data)
+{
+ // Are we doing anything wrong? One test that does not call
+ // dumpStatusCallbacks gets true here
+ if (gTestRunner->dumpStatusCallbacks())
+ printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", message);
+}
+
+static gboolean webViewClose(WebKitWebView* view)
+{
+ ASSERT(view);
+
+ webViewList = g_slist_remove(webViewList, view);
+ g_object_unref(view);
+
+ return TRUE;
+}
+
+static void databaseQuotaExceeded(WebKitWebView* view, WebKitWebFrame* frame, WebKitWebDatabase *database)
+{
+ ASSERT(view);
+ ASSERT(frame);
+ ASSERT(database);
+
+ WebKitSecurityOrigin* origin = webkit_web_database_get_security_origin(database);
+ if (gTestRunner->dumpDatabaseCallbacks()) {
+ printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n",
+ webkit_security_origin_get_protocol(origin),
+ webkit_security_origin_get_host(origin),
+ webkit_security_origin_get_port(origin),
+ webkit_web_database_get_name(database));
+ }
+ webkit_security_origin_set_web_database_quota(origin, 5 * 1024 * 1024);
+}
+
+static bool
+geolocationPolicyDecisionRequested(WebKitWebView*, WebKitWebFrame*, WebKitGeolocationPolicyDecision* decision)
+{
+ if (!gTestRunner->isGeolocationPermissionSet())
+ return FALSE;
+ if (gTestRunner->geolocationPermission())
+ webkit_geolocation_policy_allow(decision);
+ else
+ webkit_geolocation_policy_deny(decision);
+
+ return TRUE;
+}
+
+
+static WebKitWebView* webViewCreate(WebKitWebView*, WebKitWebFrame*);
+
+static gboolean webInspectorShowWindow(WebKitWebInspector*, gpointer data)
+{
+ gtk_window_set_default_size(GTK_WINDOW(webInspectorWindow), TestRunner::viewWidth, TestRunner::viewHeight);
+ gtk_widget_show_all(webInspectorWindow);
+ return TRUE;
+}
+
+static gboolean webInspectorCloseWindow(WebKitWebInspector*, gpointer data)
+{
+ gtk_widget_destroy(webInspectorWindow);
+ webInspectorWindow = 0;
+ return TRUE;
+}
+
+static WebKitWebView* webInspectorInspectWebView(WebKitWebInspector*, gpointer data)
+{
+ webInspectorWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ GtkWidget* webView = self_scrolling_webkit_web_view_new();
+ gtk_container_add(GTK_CONTAINER(webInspectorWindow),
+ webView);
+
+ return WEBKIT_WEB_VIEW(webView);
+}
+
+static void topLoadingFrameLoadFinished()
+{
+ topLoadingFrame = 0;
+ WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
+ if (gTestRunner->waitToDump())
+ return;
+
+ if (WorkQueue::shared()->count())
+ g_idle_add_full(G_PRIORITY_DEFAULT, processWork, 0, 0);
+ else
+ dump();
+}
+
+static void webFrameLoadStatusNotified(WebKitWebFrame* frame, gpointer user_data)
+{
+ WebKitLoadStatus loadStatus = webkit_web_frame_get_load_status(frame);
+
+ if (gTestRunner->dumpFrameLoadCallbacks()) {
+ GUniquePtr<char> frameName(getFrameNameSuitableForTestResult(webkit_web_frame_get_web_view(frame), frame));
+
+ switch (loadStatus) {
+ case WEBKIT_LOAD_PROVISIONAL:
+ if (!done)
+ printf("%s - didStartProvisionalLoadForFrame\n", frameName.get());
+ break;
+ case WEBKIT_LOAD_COMMITTED:
+ if (!done)
+ printf("%s - didCommitLoadForFrame\n", frameName.get());
+ break;
+ case WEBKIT_LOAD_FINISHED:
+ if (!done)
+ printf("%s - didFinishLoadForFrame\n", frameName.get());
+ break;
+ case WEBKIT_LOAD_FAILED:
+ if (!done)
+ printf("%s - didFailLoadWithError\n", frameName.get());
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((loadStatus == WEBKIT_LOAD_FINISHED || loadStatus == WEBKIT_LOAD_FAILED)
+ && frame == topLoadingFrame)
+ topLoadingFrameLoadFinished();
+}
+
+static void frameCreatedCallback(WebKitWebView* webView, WebKitWebFrame* webFrame, gpointer user_data)
+{
+ g_signal_connect(webFrame, "notify::load-status", G_CALLBACK(webFrameLoadStatusNotified), NULL);
+ g_signal_connect(webFrame, "insecure-content-run", G_CALLBACK(didRunInsecureContent), NULL);
+}
+
+static String pathFromSoupURI(SoupURI* uri)
+{
+ if (!uri)
+ return "(null)";
+
+ if (!g_str_equal(uri->scheme, "file"))
+ return soupURIToStringPreservingPassword(uri).data();
+
+ String pathString = uri->path;
+ GUniquePtr<gchar> pathBasename(g_path_get_basename(pathString.utf8().data()));
+
+ WebKitWebFrame* mainFrame = webkit_web_view_get_main_frame(webView);
+ GUniquePtr<SoupURI> mainFrameUri(soup_uri_new(webkit_web_frame_get_uri(mainFrame)));
+
+ String mainFrameUriPathString = mainFrameUri.get()->path;
+ String basePath = mainFrameUriPathString.substring(0, mainFrameUriPathString.reverseFind('/') + 1);
+
+ if (!basePath.isEmpty() && pathString.startsWith(basePath))
+ return pathString.substring(basePath.length());
+
+ return pathBasename.get();
+}
+
+static CString convertSoupMessageToURLPath(SoupMessage* soupMessage)
+{
+ if (!soupMessage)
+ return CString("(null)");
+ if (SoupURI* requestURI = soup_message_get_uri(soupMessage))
+ return pathFromSoupURI(requestURI).utf8();
+ return CString("(null)");
+}
+
+static CString convertNetworkRequestToURLPath(WebKitNetworkRequest* request)
+{
+ return convertSoupMessageToURLPath(webkit_network_request_get_message(request));
+}
+
+static CString convertWebResourceToURLPath(WebKitWebResource* webResource)
+{
+ GUniquePtr<SoupURI> uri(soup_uri_new(webkit_web_resource_get_uri(webResource)));
+ return pathFromSoupURI(uri.get()).utf8();
+}
+
+static CString urlSuitableForTestResult(const char* uriString)
+{
+ if (!g_str_has_prefix(uriString, "file://"))
+ return CString(uriString);
+
+ GUniquePtr<gchar> basename(g_path_get_basename(uriString));
+ return CString(basename.get());
+}
+
+static CString descriptionSuitableForTestResult(SoupURI* uri)
+{
+ if (!uri)
+ return CString("(null)");
+
+ GUniquePtr<char> uriString(soup_uri_to_string(uri, false));
+ return urlSuitableForTestResult(uriString.get());
+}
+
+static CString descriptionSuitableForTestResult(GError* error, WebKitWebResource* webResource)
+{
+ const gchar* errorDomain = g_quark_to_string(error->domain);
+ CString resourceURIString(urlSuitableForTestResult(webkit_web_resource_get_uri(webResource)));
+
+ if (g_str_equal(errorDomain, "webkit-network-error-quark") || g_str_equal(errorDomain, "soup_http_error_quark"))
+ errorDomain = "NSURLErrorDomain";
+
+ if (g_str_equal(errorDomain, "WebKitPolicyError"))
+ errorDomain = "WebKitErrorDomain";
+
+ // TODO: the other ports get the failingURL from the ResourceError
+ GUniquePtr<char> errorString(g_strdup_printf("<NSError domain %s, code %d, failing URL \"%s\">",
+ errorDomain, error->code, resourceURIString.data()));
+ return CString(errorString.get());
+}
+
+static CString descriptionSuitableForTestResult(WebKitNetworkRequest* request)
+{
+ SoupMessage* soupMessage = webkit_network_request_get_message(request);
+
+ if (!soupMessage)
+ return CString("(null)");
+
+ SoupURI* mainDocumentURI = soup_message_get_first_party(soupMessage);
+ CString mainDocumentURIString(descriptionSuitableForTestResult(mainDocumentURI));
+ CString path(convertNetworkRequestToURLPath(request));
+ GUniquePtr<char> description(g_strdup_printf("<NSURLRequest URL %s, main document URL %s, http method %s>",
+ path.data(), mainDocumentURIString.data(), soupMessage->method));
+ return CString(description.get());
+}
+
+static CString descriptionSuitableForTestResult(WebKitNetworkResponse* response)
+{
+ if (!response)
+ return CString("(null)");
+
+ int statusCode = 0;
+ CString responseURIString(urlSuitableForTestResult(webkit_network_response_get_uri(response)));
+ SoupMessage* soupMessage = webkit_network_response_get_message(response);
+ CString path;
+
+ if (soupMessage) {
+ statusCode = soupMessage->status_code;
+ path = convertSoupMessageToURLPath(soupMessage);
+ } else
+ path = CString("(null)");
+
+ GUniquePtr<char> description(g_strdup_printf("<NSURLResponse %s, http status code %d>", path.data(), statusCode));
+ return CString(description.get());
+}
+
+static void willSendRequestCallback(WebKitWebView* webView, WebKitWebFrame* webFrame, WebKitWebResource* resource, WebKitNetworkRequest* request, WebKitNetworkResponse* response)
+{
+
+
+ if (!done && gTestRunner->willSendRequestReturnsNull()) {
+ // As requested by the TestRunner, don't perform the request.
+ webkit_network_request_set_uri(request, "about:blank");
+ return;
+ }
+
+ if (!done && gTestRunner->dumpResourceLoadCallbacks())
+ printf("%s - willSendRequest %s redirectResponse %s\n",
+ convertNetworkRequestToURLPath(request).data(),
+ descriptionSuitableForTestResult(request).data(),
+ descriptionSuitableForTestResult(response).data());
+
+ SoupMessage* soupMessage = webkit_network_request_get_message(request);
+ SoupURI* uri = soup_uri_new(webkit_network_request_get_uri(request));
+
+ if (SOUP_URI_IS_VALID(uri)) {
+ GUniquePtr<char> uriString(soup_uri_to_string(uri, FALSE));
+
+ if (SOUP_URI_VALID_FOR_HTTP(uri) && g_strcmp0(uri->host, "127.0.0.1")
+ && g_strcmp0(uri->host, "255.255.255.255")
+ && g_ascii_strncasecmp(uri->host, "localhost", 9)) {
+ printf("Blocked access to external URL %s\n", uriString.get());
+ // Cancel load of blocked resource to avoid potential
+ // network-related timeouts in tests.
+ webkit_network_request_set_uri(request, "about:blank");
+ soup_uri_free(uri);
+ return;
+ }
+
+ const string& destination = gTestRunner->redirectionDestinationForURL(uriString.get());
+ if (!destination.empty())
+ webkit_network_request_set_uri(request, destination.c_str());
+ }
+
+ if (uri)
+ soup_uri_free(uri);
+
+ if (soupMessage) {
+ const set<string>& clearHeaders = gTestRunner->willSendRequestClearHeaders();
+ for (set<string>::const_iterator header = clearHeaders.begin(); header != clearHeaders.end(); ++header)
+ soup_message_headers_remove(soupMessage->request_headers, header->c_str());
+ }
+}
+
+
+static void didReceiveResponse(WebKitWebView* webView, WebKitWebFrame*, WebKitWebResource* webResource, WebKitNetworkResponse* response)
+{
+ if (!done && gTestRunner->dumpResourceLoadCallbacks()) {
+ CString responseDescription(descriptionSuitableForTestResult(response));
+ CString path(convertWebResourceToURLPath(webResource));
+ printf("%s - didReceiveResponse %s\n", path.data(), responseDescription.data());
+ }
+
+ // TODO: add "has MIME type" whenever dumpResourceResponseMIMETypes() is supported.
+ // See https://bugs.webkit.org/show_bug.cgi?id=58222.
+}
+
+static void didFinishLoading(WebKitWebView* webView, WebKitWebFrame* webFrame, WebKitWebResource* webResource)
+{
+ if (!done && gTestRunner->dumpResourceLoadCallbacks())
+ printf("%s - didFinishLoading\n", convertWebResourceToURLPath(webResource).data());
+}
+
+static void didFailLoadingWithError(WebKitWebView* webView, WebKitWebFrame* webFrame, WebKitWebResource* webResource, GError* webError)
+{
+ if (!done && gTestRunner->dumpResourceLoadCallbacks()) {
+ CString webErrorString(descriptionSuitableForTestResult(webError, webResource));
+ printf("%s - didFailLoadingWithError: %s\n", convertWebResourceToURLPath(webResource).data(),
+ webErrorString.data());
+ }
+}
+
+static void didRunInsecureContent(WebKitWebFrame*, WebKitSecurityOrigin*, const char* url)
+{
+ if (!done && gTestRunner->dumpFrameLoadCallbacks())
+ printf("didRunInsecureContent\n");
+}
+
+static gboolean webViewRunFileChooser(WebKitWebView*, WebKitFileChooserRequest*)
+{
+ // We return TRUE to not propagate the event further so the
+ // default file chooser dialog is not shown.
+ return TRUE;
+}
+
+static void frameLoadEventCallback(WebKitWebFrame* frame, DumpRenderTreeSupportGtk::FrameLoadEvent event, const char* url)
+{
+ if (done || !gTestRunner->dumpFrameLoadCallbacks())
+ return;
+
+ GUniquePtr<char> frameName(getFrameNameSuitableForTestResult(webkit_web_frame_get_web_view(frame), frame));
+ switch (event) {
+ case DumpRenderTreeSupportGtk::WillPerformClientRedirectToURL:
+ ASSERT(url);
+ printf("%s - willPerformClientRedirectToURL: %s \n", frameName.get(), url);
+ break;
+ case DumpRenderTreeSupportGtk::DidCancelClientRedirect:
+ printf("%s - didCancelClientRedirectForFrame\n", frameName.get());
+ break;
+ case DumpRenderTreeSupportGtk::DidReceiveServerRedirectForProvisionalLoad:
+ printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", frameName.get());
+ break;
+ case DumpRenderTreeSupportGtk::DidDisplayInsecureContent:
+ printf ("didDisplayInsecureContent\n");
+ break;
+ case DumpRenderTreeSupportGtk::DidDetectXSS:
+ printf ("didDetectXSS\n");
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+static bool authenticationCallback(CString& username, CString& password, WebKitWebResource* webResource)
+{
+ CString description(convertWebResourceToURLPath(webResource));
+
+ if (!gTestRunner->handlesAuthenticationChallenges()) {
+ printf("%s - didReceiveAuthenticationChallenge - Simulating cancelled authentication sheet\n", description.data());
+ return false;
+ }
+
+ username = gTestRunner->authenticationUsername().c_str();
+ password = gTestRunner->authenticationPassword().c_str();
+ printf("%s - didReceiveAuthenticationChallenge - Responding with %s:%s\n", description.data(), username.data(), password.data());
+ return true;
+}
+
+static WebKitWebView* createWebView()
+{
+ // It is important to declare DRT is running early so when creating
+ // web view mock clients are used instead of proper ones.
+ DumpRenderTreeSupportGtk::setDumpRenderTreeModeEnabled(true);
+
+ DumpRenderTreeSupportGtk::setFrameLoadEventCallback(frameLoadEventCallback);
+ DumpRenderTreeSupportGtk::setAuthenticationCallback(authenticationCallback);
+
+ WebKitWebView* view = WEBKIT_WEB_VIEW(self_scrolling_webkit_web_view_new());
+
+ 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,
+ "signal::script-prompt", webViewScriptPrompt, 0,
+ "signal::script-confirm", webViewScriptConfirm, 0,
+ "signal::title-changed", webViewTitleChanged, 0,
+ "signal::navigation-policy-decision-requested", webViewNavigationPolicyDecisionRequested, 0,
+ "signal::status-bar-text-changed", webViewStatusBarTextChanged, 0,
+ "signal::create-web-view", webViewCreate, 0,
+ "signal::close-web-view", webViewClose, 0,
+ "signal::database-quota-exceeded", databaseQuotaExceeded, 0,
+ "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,
+ "signal::frame-created", frameCreatedCallback, 0,
+ "signal::resource-request-starting", willSendRequestCallback, 0,
+ "signal::resource-response-received", didReceiveResponse, 0,
+ "signal::resource-load-finished", didFinishLoading, 0,
+ "signal::resource-load-failed", didFailLoadingWithError, 0,
+ "signal::run-file-chooser", webViewRunFileChooser, 0,
+ NULL);
+ connectEditingCallbacks(view);
+
+ WebKitWebInspector* inspector = webkit_web_view_get_inspector(view);
+ g_object_connect(G_OBJECT(inspector),
+ "signal::inspect-web-view", webInspectorInspectWebView, 0,
+ "signal::show-window", webInspectorShowWindow, 0,
+ "signal::close-window", webInspectorCloseWindow, 0,
+ NULL);
+
+ if (webView) {
+ WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
+ webkit_web_view_set_settings(view, settings);
+ }
+
+ // frame-created is not issued for main frame. That's why we must do this here
+ WebKitWebFrame* frame = webkit_web_view_get_main_frame(view);
+ g_signal_connect(frame, "notify::load-status", G_CALLBACK(webFrameLoadStatusNotified), NULL);
+ g_signal_connect(frame, "insecure-content-run", G_CALLBACK(didRunInsecureContent), NULL);
+
+ return view;
+}
+
+static WebKitWebView* webViewCreate(WebKitWebView* view, WebKitWebFrame* frame)
+{
+ if (!gTestRunner->canOpenWindows())
+ return 0;
+
+ // Make sure that waitUntilDone has been called.
+ ASSERT(gTestRunner->waitToDump());
+
+ WebKitWebView* newWebView = createWebView();
+ g_object_ref_sink(G_OBJECT(newWebView));
+ webViewList = g_slist_prepend(webViewList, newWebView);
+ return newWebView;
+}
+
+static void logHandler(const gchar* domain, GLogLevelFlags level, const gchar* message, gpointer data)
+{
+ if (level < G_LOG_LEVEL_DEBUG)
+ fprintf(stderr, "%s\n", message);
+}
+
+int main(int argc, char* argv[])
+{
+ gtk_init(&argc, &argv);
+
+ // Some plugins might try to use the GLib logger for printing debug
+ // messages. This will cause tests to fail because of unexpected output.
+ // We squelch all debug messages sent to the logger.
+ g_log_set_default_handler(logHandler, 0);
+
+ initializeGlobalsFromCommandLineOptions(argc, argv);
+ initializeFonts();
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+#ifdef GTK_API_VERSION_2
+ container = gtk_hbox_new(TRUE, 0);
+#else
+ container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_set_homogeneous(GTK_BOX(container), TRUE);
+#endif
+ gtk_container_add(GTK_CONTAINER(window), container);
+ gtk_widget_show_all(window);
+
+ webView = createWebView();
+ gtk_box_pack_start(GTK_BOX(container), GTK_WIDGET(webView), TRUE, TRUE, 0);
+ gtk_widget_realize(GTK_WIDGET(webView));
+ gtk_widget_show_all(container);
+ mainFrame = webkit_web_view_get_main_frame(webView);
+
+ setDefaultsToConsistentStateValuesForTesting();
+
+ gcController = new GCController();
+#if HAVE(ACCESSIBILITY)
+ axController = new AccessibilityController();
+#endif
+
+ if (useLongRunningServerMode(argc, argv)) {
+ printSeparators = true;
+ runTestingServerLoop();
+ } else {
+ printSeparators = (optind < argc-1 || (dumpPixelsForCurrentTest && dumpTree));
+ for (int i = optind; i != argc; ++i)
+ runTest(argv[i]);
+ }
+
+ delete gcController;
+ gcController = 0;
+
+#if HAVE(ACCESSIBILITY)
+ delete axController;
+ axController = 0;
+#endif
+
+ gtk_widget_destroy(window);
+
+ return 0;
+}
diff --git a/Tools/DumpRenderTree/gtk/DumpRenderTreeGtk.h b/Tools/DumpRenderTree/gtk/DumpRenderTreeGtk.h
new file mode 100644
index 000000000..4b33458f3
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/DumpRenderTreeGtk.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 DumpRenderTreeGtk_h
+#define DumpRenderTreeGtk_h
+
+#include <JavaScriptCore/JSBase.h>
+#include <glib.h>
+#include <libsoup/soup.h>
+#include <webkit/webkitdefines.h>
+#include <wtf/text/CString.h>
+
+extern WebKitWebFrame* mainFrame;
+extern WebKitWebFrame* topLoadingFrame;
+extern bool waitForPolicy;
+extern GSList* webViewList;
+
+gchar* JSStringCopyUTF8CString(JSStringRef jsString);
+CString getTopLevelPath();
+
+void setWaitToDumpWatchdog(guint timer);
+bool shouldSetWaitToDumpWatchdog();
+CString soupURIToStringPreservingPassword(SoupURI* soupURI);
+
+#endif // DumpRenderTreeGtk_h
diff --git a/Tools/DumpRenderTree/gtk/EditingCallbacks.cpp b/Tools/DumpRenderTree/gtk/EditingCallbacks.cpp
new file mode 100644
index 000000000..3c08f80b3
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/EditingCallbacks.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2010 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 "EditingCallbacks.h"
+
+#include "DumpRenderTree.h"
+#include "TestRunner.h"
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/text/CString.h>
+
+static CString dumpNodePath(WebKitDOMNode* node)
+{
+ GUniquePtr<gchar> nodeName(webkit_dom_node_get_node_name(node));
+ GString* path = g_string_new(nodeName.get());
+
+ WebKitDOMNode* parent = webkit_dom_node_get_parent_node(node);
+ while (parent) {
+ GUniquePtr<gchar> parentName(webkit_dom_node_get_node_name(parent));
+
+ g_string_append(path, " > ");
+ g_string_append(path, parentName.get());
+ parent = webkit_dom_node_get_parent_node(parent);
+ }
+
+ GUniquePtr<gchar> pathBuffer(g_string_free(path, FALSE));
+ return pathBuffer.get();
+}
+
+static CString dumpRange(WebKitDOMRange* range)
+{
+ if (!range)
+ return "(null)";
+
+ GUniquePtr<gchar> dump(g_strdup_printf("range from %li of %s to %li of %s",
+ webkit_dom_range_get_start_offset(range, 0),
+ dumpNodePath(webkit_dom_range_get_start_container(range, 0)).data(),
+ webkit_dom_range_get_end_offset(range, 0),
+ dumpNodePath(webkit_dom_range_get_end_container(range, 0)).data()));
+
+ return dump.get();
+}
+
+static const char* insertActionString(WebKitInsertAction action)
+{
+ switch (action) {
+ case WEBKIT_INSERT_ACTION_TYPED:
+ return "WebViewInsertActionTyped";
+ case WEBKIT_INSERT_ACTION_PASTED:
+ return "WebViewInsertActionPasted";
+ case WEBKIT_INSERT_ACTION_DROPPED:
+ return "WebViewInsertActionDropped";
+ }
+ ASSERT_NOT_REACHED();
+ return "WebViewInsertActionTyped";
+}
+
+static const char* selectionAffinityString(WebKitSelectionAffinity affinity)
+{
+ switch (affinity) {
+ case WEBKIT_SELECTION_AFFINITY_UPSTREAM:
+ return "NSSelectionAffinityUpstream";
+ case WEBKIT_SELECTION_AFFINITY_DOWNSTREAM:
+ return "NSSelectionAffinityDownstream";
+ }
+ ASSERT_NOT_REACHED();
+ return "NSSelectionAffinityUpstream";
+}
+
+gboolean shouldBeginEditing(WebKitWebView* webView, WebKitDOMRange* range)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n", dumpRange(range).data());
+ return TRUE;
+}
+
+gboolean shouldEndEditing(WebKitWebView* webView, WebKitDOMRange* range)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n", dumpRange(range).data());
+ return TRUE;
+}
+
+gboolean shouldInsertNode(WebKitWebView* webView, WebKitDOMNode* node, WebKitDOMRange* range, WebKitInsertAction action)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks()) {
+ printf("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n",
+ dumpNodePath(node).data(), dumpRange(range).data(), insertActionString(action));
+ }
+ return TRUE;
+}
+
+gboolean shouldInsertText(WebKitWebView* webView, const gchar* text, WebKitDOMRange* range, WebKitInsertAction action)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks()) {
+ printf("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n",
+ text, dumpRange(range).data(), insertActionString(action));
+ }
+ return TRUE;
+}
+
+gboolean shouldDeleteRange(WebKitWebView* webView, WebKitDOMRange* range)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldDeleteDOMRange:%s\n", dumpRange(range).data());
+ return TRUE;
+}
+
+gboolean shouldShowDeleteInterfaceForElement(WebKitWebView* webView, WebKitDOMHTMLElement* element)
+{
+ return FALSE;
+}
+
+gboolean shouldChangeSelectedRange(WebKitWebView* webView, WebKitDOMRange* fromRange, WebKitDOMRange* toRange, WebKitSelectionAffinity affinity, gboolean stillSelecting)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks()) {
+ printf("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n",
+ dumpRange(fromRange).data(), dumpRange(toRange).data(), selectionAffinityString(affinity),
+ stillSelecting ? "TRUE" : "FALSE");
+ }
+ return TRUE;
+}
+
+gboolean shouldApplyStyle(WebKitWebView* webView, WebKitDOMCSSStyleDeclaration* style, WebKitDOMRange* range)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks()) {
+ GUniquePtr<gchar> styleText(webkit_dom_css_style_declaration_get_css_text(style));
+ printf("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n",
+ styleText.get(), dumpRange(range).data());
+ }
+ return TRUE;
+}
+
+void editingBegan(WebKitWebView*)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification\n");
+}
+
+void userChangedContents(WebKitWebView*)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification\n");
+}
+
+void editingEnded(WebKitWebView*)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification\n");
+}
+
+void selectionChanged(WebKitWebView*)
+{
+ if (!done && gTestRunner->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification\n");
+}
+
+void connectEditingCallbacks(WebKitWebView* webView)
+{
+ g_object_connect(G_OBJECT(webView),
+ "signal::should-begin-editing", shouldBeginEditing, 0,
+ "signal::should-end-editing", shouldEndEditing, 0,
+ "signal::should-insert-node", shouldInsertNode, 0,
+ "signal::should-insert-text", shouldInsertText, 0,
+ "signal::should-delete-range", shouldDeleteRange, 0,
+ "signal::should-show-delete-interface-for-element", shouldShowDeleteInterfaceForElement, 0,
+ "signal::should-change-selected-range", shouldChangeSelectedRange, 0,
+ "signal::should-apply-style", shouldApplyStyle, 0,
+ "signal::editing-began", editingBegan, 0,
+ "signal::user-changed-contents", userChangedContents, 0,
+ "signal::editing-ended", editingEnded, 0,
+ "signal::selection-changed", selectionChanged, 0,
+ NULL);
+}
+
diff --git a/Tools/DumpRenderTree/gtk/EditingCallbacks.h b/Tools/DumpRenderTree/gtk/EditingCallbacks.h
new file mode 100644
index 000000000..7a9514917
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/EditingCallbacks.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 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 EditingCallbacks_h
+#define EditingCallbacks_h
+
+typedef struct _WebKitWebView WebKitWebView;
+void connectEditingCallbacks(WebKitWebView*);
+
+#endif
diff --git a/Tools/DumpRenderTree/gtk/EventSender.cpp b/Tools/DumpRenderTree/gtk/EventSender.cpp
new file mode 100644
index 000000000..bd8e4fb8f
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/EventSender.cpp
@@ -0,0 +1,1004 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Zan Dobersek <zandobersek@gmail.com>
+ * Copyright (C) 2009 Holger Hans Peter Freyther
+ * Copyright (C) 2010 Igalia S.L.
+ * Copyright (C) 2012 ChangSeok Oh <shivamidow@gmail.com>
+ *
+ * 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 "EventSender.h"
+
+#include "DumpRenderTree.h"
+#include "WebCoreSupport/DumpRenderTreeSupportGtk.h"
+#include <GRefPtrGtk.h>
+#include <GtkVersioning.h>
+#include <JavaScriptCore/JSObjectRef.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <cstring>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <webkit/webkitwebframe.h>
+#include <webkit/webkitwebview.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/Platform.h>
+#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/text/CString.h>
+
+extern "C" {
+ extern GtkMenu* webkit_web_view_get_context_menu(WebKitWebView*);
+}
+
+static bool dragMode;
+static int timeOffset = 0;
+
+static int lastMousePositionX;
+static int lastMousePositionY;
+static int lastClickPositionX;
+static int lastClickPositionY;
+static int lastClickTimeOffset;
+static int lastClickButton;
+static unsigned buttonCurrentlyDown;
+static int clickCount;
+GdkDragContext* currentDragSourceContext;
+
+struct DelayedMessage {
+ GdkEvent* event;
+ gulong delay;
+};
+
+static DelayedMessage msgQueue[1024];
+
+static unsigned endOfQueue;
+static unsigned startOfQueue;
+
+static const float zoomMultiplierRatio = 1.2f;
+
+// WebCore and layout tests assume this value.
+static const float pixelsPerScrollTick = 40;
+
+// Key event location code defined in DOM Level 3.
+enum KeyLocationCode {
+ DOM_KEY_LOCATION_STANDARD = 0x00,
+ DOM_KEY_LOCATION_LEFT = 0x01,
+ DOM_KEY_LOCATION_RIGHT = 0x02,
+ DOM_KEY_LOCATION_NUMPAD = 0x03
+};
+
+static void sendOrQueueEvent(GdkEvent*, bool = true);
+static void dispatchEvent(GdkEvent* event);
+static guint getStateFlags();
+
+static JSValueRef getDragModeCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ return JSValueMakeBoolean(context, dragMode);
+}
+
+static bool setDragModeCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ dragMode = JSValueToBoolean(context, value);
+ return true;
+}
+
+static JSValueRef leapForwardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount > 0) {
+ msgQueue[endOfQueue].delay = JSValueToNumber(context, arguments[0], exception);
+ timeOffset += msgQueue[endOfQueue].delay;
+ ASSERT(!exception || !*exception);
+ }
+
+ return JSValueMakeUndefined(context);
+}
+
+bool prepareMouseButtonEvent(GdkEvent* event, int eventSenderButtonNumber, guint modifiers)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ if (!view)
+ return false;
+
+ // The logic for mapping EventSender button numbers to GDK button
+ // numbers originates from the Windows EventSender.
+ int gdkButtonNumber = 3;
+ if (eventSenderButtonNumber >= 0 && eventSenderButtonNumber <= 2)
+ gdkButtonNumber = eventSenderButtonNumber + 1;
+
+ // fast/events/mouse-click-events expects the 4th button
+ // to be event->button = 1, so send a middle-button event.
+ else if (eventSenderButtonNumber == 3)
+ gdkButtonNumber = 2;
+
+ event->button.button = gdkButtonNumber;
+ event->button.x = lastMousePositionX;
+ event->button.y = lastMousePositionY;
+ event->button.window = gtk_widget_get_window(GTK_WIDGET(view));
+ g_object_ref(event->button.window);
+ event->button.device = getDefaultGDKPointerDevice(event->button.window);
+ event->button.state = modifiers | getStateFlags();
+ event->button.time = GDK_CURRENT_TIME;
+ event->button.axes = 0;
+
+ int xRoot, yRoot;
+ gdk_window_get_root_coords(gtk_widget_get_window(GTK_WIDGET(view)), lastMousePositionX, lastMousePositionY, &xRoot, &yRoot);
+ event->button.x_root = xRoot;
+ event->button.y_root = yRoot;
+
+ return true;
+}
+
+static JSValueRef getMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ GtkWidget* widget = GTK_WIDGET(JSObjectGetPrivate(object));
+ CString label;
+ if (GTK_IS_SEPARATOR_MENU_ITEM(widget))
+ label = "<separator>";
+ else
+ label = gtk_menu_item_get_label(GTK_MENU_ITEM(widget));
+
+ JSRetainPtr<JSStringRef> itemText(Adopt, JSStringCreateWithUTF8CString(label.data()));
+ return JSValueMakeString(context, itemText.get());
+}
+
+static bool setMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ return true;
+}
+
+static JSValueRef menuItemClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ GtkMenuItem* item = GTK_MENU_ITEM(JSObjectGetPrivate(thisObject));
+ gtk_menu_item_activate(item);
+ return JSValueMakeUndefined(context);
+}
+
+static JSStaticFunction staticMenuItemFunctions[] = {
+ { "click", menuItemClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+};
+
+static JSStaticValue staticMenuItemValues[] = {
+ { "title", getMenuItemTitleCallback, setMenuItemTitleCallback, kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+};
+
+static JSClassRef getMenuItemClass()
+{
+ static JSClassRef menuItemClass = 0;
+
+ if (!menuItemClass) {
+ JSClassDefinition classDefinition = {
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ classDefinition.staticFunctions = staticMenuItemFunctions;
+ classDefinition.staticValues = staticMenuItemValues;
+
+ menuItemClass = JSClassCreate(&classDefinition);
+ }
+
+ return menuItemClass;
+}
+
+
+static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ GdkEvent* pressEvent = gdk_event_new(GDK_BUTTON_PRESS);
+
+ if (!prepareMouseButtonEvent(pressEvent, 2, 0)) {
+ gdk_event_free(pressEvent);
+ return JSObjectMakeArray(context, 0, 0, 0);
+ }
+
+ GdkEvent* releaseEvent = gdk_event_copy(pressEvent);
+ sendOrQueueEvent(pressEvent);
+
+ JSValueRef valueRef = JSObjectMakeArray(context, 0, 0, 0);
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ GtkMenu* gtkMenu = webkit_web_view_get_context_menu(view);
+ if (gtkMenu) {
+ GUniquePtr<GList> items(gtk_container_get_children(GTK_CONTAINER(gtkMenu)));
+ JSValueRef arrayValues[g_list_length(items.get())];
+ int index = 0;
+ for (GList* item = g_list_first(items.get()); item; item = g_list_next(item)) {
+ arrayValues[index] = JSObjectMake(context, getMenuItemClass(), item->data);
+ index++;
+ }
+ if (index)
+ valueRef = JSObjectMakeArray(context, index - 1, arrayValues, 0);
+ }
+
+ releaseEvent->type = GDK_BUTTON_RELEASE;
+ sendOrQueueEvent(releaseEvent);
+ return valueRef;
+}
+
+static gboolean sendClick(gpointer)
+{
+ GdkEvent* pressEvent = gdk_event_new(GDK_BUTTON_PRESS);
+
+ if (!prepareMouseButtonEvent(pressEvent, 1, 0)) {
+ gdk_event_free(pressEvent);
+ return FALSE;
+ }
+
+ GdkEvent* releaseEvent = gdk_event_copy(pressEvent);
+ dispatchEvent(pressEvent);
+ releaseEvent->type = GDK_BUTTON_RELEASE;
+ dispatchEvent(releaseEvent);
+
+ return FALSE;
+}
+
+static JSValueRef scheduleAsynchronousClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ g_idle_add_full(G_PRIORITY_DEFAULT, sendClick, 0, 0);
+ return JSValueMakeUndefined(context);
+}
+
+static void updateClickCount(int button)
+{
+ if (lastClickPositionX != lastMousePositionX
+ || lastClickPositionY != lastMousePositionY
+ || lastClickButton != button
+ || timeOffset - lastClickTimeOffset >= 1)
+ clickCount = 1;
+ else
+ 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/PlatformMouseEventGtk.cpp
+ // is GDK_META_MASK. This code must be kept in sync with that file.
+ else if (JSStringIsEqualToUTF8CString(string, "metaKey"))
+ gdkModifier = GDK_META_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;
+ JSRetainPtr<JSStringRef> lengthProperty(Adopt, JSStringCreateWithUTF8CString("length"));
+ int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty.get(), 0), 0);
+ for (int i = 0; i < modifiersCount; ++i)
+ gdkModifiers |= gdkModifierFromJSValue(context, JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0));
+ return gdkModifiers;
+}
+
+static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ int button = 0;
+ if (argumentCount == 1) {
+ button = static_cast<int>(JSValueToNumber(context, arguments[0], exception));
+ g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
+ }
+ guint modifiers = argumentCount >= 2 ? gdkModifersFromJSValue(context, arguments[1]) : 0;
+
+ GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS);
+ if (!prepareMouseButtonEvent(event, button, modifiers)) {
+ gdk_event_free(event);
+ return JSValueMakeUndefined(context);
+ }
+
+ // If the same mouse button is already in the down position don't send another event as it may confuse Xvfb.
+ if (buttonCurrentlyDown == event->button.button) {
+ gdk_event_free(event);
+ return JSValueMakeUndefined(context);
+ }
+
+ buttonCurrentlyDown = event->button.button;
+
+ // Normally GDK will send both GDK_BUTTON_PRESS and GDK_2BUTTON_PRESS for
+ // the second button press during double-clicks. WebKit GTK+ selectively
+ // ignores the first GDK_BUTTON_PRESS of that pair using gdk_event_peek.
+ // Since our events aren't ever going onto the GDK event queue, WebKit won't
+ // be able to filter out the first GDK_BUTTON_PRESS, so we just don't send
+ // it here. Eventually this code should probably figure out a way to get all
+ // appropriate events onto the event queue and this work-around should be
+ // removed.
+ updateClickCount(event->button.button);
+ if (clickCount == 2)
+ event->type = GDK_2BUTTON_PRESS;
+ else if (clickCount == 3)
+ event->type = GDK_3BUTTON_PRESS;
+
+ sendOrQueueEvent(event);
+ return JSValueMakeUndefined(context);
+}
+
+static guint getStateFlags()
+{
+ if (buttonCurrentlyDown == 1)
+ return GDK_BUTTON1_MASK;
+ if (buttonCurrentlyDown == 2)
+ return GDK_BUTTON2_MASK;
+ if (buttonCurrentlyDown == 3)
+ return GDK_BUTTON3_MASK;
+ return 0;
+}
+
+static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ int button = 0;
+ if (argumentCount == 1) {
+ button = static_cast<int>(JSValueToNumber(context, arguments[0], exception));
+ g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
+ }
+ guint modifiers = argumentCount >= 2 ? gdkModifersFromJSValue(context, arguments[1]) : 0;
+
+ GdkEvent* event = gdk_event_new(GDK_BUTTON_RELEASE);
+ if (!prepareMouseButtonEvent(event, button, modifiers)) {
+ gdk_event_free(event);
+ return JSValueMakeUndefined(context);
+ }
+
+ lastClickPositionX = lastMousePositionX;
+ lastClickPositionY = lastMousePositionY;
+ lastClickButton = buttonCurrentlyDown;
+ lastClickTimeOffset = timeOffset;
+ buttonCurrentlyDown = 0;
+
+ sendOrQueueEvent(event);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef mouseMoveToCallback(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);
+
+ lastMousePositionX = (int)JSValueToNumber(context, arguments[0], exception);
+ g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
+ lastMousePositionY = (int)JSValueToNumber(context, arguments[1], exception);
+ g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
+
+ GdkEvent* event = gdk_event_new(GDK_MOTION_NOTIFY);
+ event->motion.x = lastMousePositionX;
+ event->motion.y = lastMousePositionY;
+
+ event->motion.time = GDK_CURRENT_TIME;
+ event->motion.window = gtk_widget_get_window(GTK_WIDGET(view));
+ g_object_ref(event->motion.window);
+ event->button.device = getDefaultGDKPointerDevice(event->motion.window);
+
+ guint modifiers = argumentCount >= 3 ? gdkModifersFromJSValue(context, arguments[2]) : 0;
+ event->motion.state = modifiers | getStateFlags();
+ event->motion.axes = 0;
+
+ int xRoot, yRoot;
+ gdk_window_get_root_coords(gtk_widget_get_window(GTK_WIDGET(view)), lastMousePositionX, lastMousePositionY, &xRoot, &yRoot);
+ event->motion.x_root = xRoot;
+ event->motion.y_root = yRoot;
+
+ sendOrQueueEvent(event, false);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef mouseScrollByCallback(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 horizontal = (int)JSValueToNumber(context, arguments[0], exception);
+ g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
+ int vertical = (int)JSValueToNumber(context, arguments[1], exception);
+ g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
+
+ // Copy behaviour of Qt and EFL - just return in case of (0,0) mouse scroll
+ if (!horizontal && !vertical)
+ return JSValueMakeUndefined(context);
+
+ GdkEvent* event = gdk_event_new(GDK_SCROLL);
+ event->scroll.x = lastMousePositionX;
+ event->scroll.y = lastMousePositionY;
+ event->scroll.time = GDK_CURRENT_TIME;
+ event->scroll.window = gtk_widget_get_window(GTK_WIDGET(view));
+ g_object_ref(event->scroll.window);
+
+ // GTK+ only supports one tick in each scroll event that is not smooth. For the cases of more than one direction,
+ // and more than one step in a direction, we can only use smooth events, supported from Gtk 3.3.18.
+#if GTK_CHECK_VERSION(3, 3, 18)
+ if ((horizontal && vertical) || horizontal > 1 || horizontal < -1 || vertical > 1 || vertical < -1) {
+ event->scroll.direction = GDK_SCROLL_SMOOTH;
+ event->scroll.delta_x = -horizontal;
+ event->scroll.delta_y = -vertical;
+
+ sendOrQueueEvent(event);
+ return JSValueMakeUndefined(context);
+ }
+#else
+ g_return_val_if_fail((!vertical || !horizontal), JSValueMakeUndefined(context));
+#endif
+
+ if (horizontal < 0)
+ event->scroll.direction = GDK_SCROLL_RIGHT;
+ else if (horizontal > 0)
+ event->scroll.direction = GDK_SCROLL_LEFT;
+ else if (vertical < 0)
+ event->scroll.direction = GDK_SCROLL_DOWN;
+ else if (vertical > 0)
+ event->scroll.direction = GDK_SCROLL_UP;
+ else
+ g_assert_not_reached();
+
+ sendOrQueueEvent(event);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef continuousMouseScrollByCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+#if GTK_CHECK_VERSION(3, 3, 18)
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ if (!view)
+ return JSValueMakeUndefined(context);
+
+ if (argumentCount < 2)
+ return JSValueMakeUndefined(context);
+
+ int horizontal = JSValueToNumber(context, arguments[0], exception);
+ g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
+ int vertical = JSValueToNumber(context, arguments[1], exception);
+ g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
+
+ // We do not yet support continuous scrolling by page.
+ if (argumentCount >= 3 && JSValueToBoolean(context, arguments[2]))
+ return JSValueMakeUndefined(context);
+
+ GdkEvent* event = gdk_event_new(GDK_SCROLL);
+ event->scroll.x = lastMousePositionX;
+ event->scroll.y = lastMousePositionY;
+ event->scroll.time = GDK_CURRENT_TIME;
+ event->scroll.window = gtk_widget_get_window(GTK_WIDGET(view));
+ g_object_ref(event->scroll.window);
+
+ event->scroll.direction = GDK_SCROLL_SMOOTH;
+ event->scroll.delta_x = -horizontal / pixelsPerScrollTick;
+ event->scroll.delta_y = -vertical / pixelsPerScrollTick;
+
+ sendOrQueueEvent(event);
+#endif
+ return JSValueMakeUndefined(context);
+}
+
+static void dragWithFilesDragDataGetCallback(GtkWidget*, GdkDragContext*, GtkSelectionData *data, guint, guint, gpointer userData)
+{
+ gtk_selection_data_set_uris(data, static_cast<gchar**>(userData));
+}
+
+static void dragWithFilesDragEndCallback(GtkWidget* widget, GdkDragContext*, gpointer userData)
+{
+ g_signal_handlers_disconnect_by_func(widget, reinterpret_cast<void*>(dragWithFilesDragEndCallback), userData);
+ g_signal_handlers_disconnect_by_func(widget, reinterpret_cast<void*>(dragWithFilesDragDataGetCallback), userData);
+ g_strfreev(static_cast<gchar**>(userData));
+}
+
+static JSValueRef beginDragWithFilesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSObjectRef filesArray = JSValueToObject(context, arguments[0], exception);
+ ASSERT(!exception || !*exception);
+
+ const gchar* mainFrameURI = webkit_web_frame_get_uri(mainFrame);
+ GRefPtr<GFile> testFile(adoptGRef(g_file_new_for_uri(mainFrameURI)));
+ GRefPtr<GFile> parentDirectory(g_file_get_parent(testFile.get()));
+ if (!parentDirectory)
+ return JSValueMakeUndefined(context);
+
+ // If this is an HTTP test, we still need to pass a local file path
+ // to WebCore. Even though the file doesn't exist, this should be fine
+ // for most tests.
+ GUniquePtr<gchar> scheme(g_file_get_uri_scheme(parentDirectory.get()));
+ if (g_str_equal(scheme.get(), "http") || g_str_equal(scheme.get(), "https")) {
+ GUniquePtr<gchar> currentDirectory(g_get_current_dir());
+ parentDirectory = adoptGRef(g_file_new_for_path(currentDirectory.get()));
+ }
+
+ JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");
+ int filesArrayLength = JSValueToNumber(context, JSObjectGetProperty(context, filesArray, lengthProperty, 0), 0);
+ JSStringRelease(lengthProperty);
+
+ gchar** draggedFilesURIList = g_new0(gchar*, filesArrayLength + 1);
+ for (int i = 0; i < filesArrayLength; ++i) {
+ JSStringRef filenameString = JSValueToStringCopy(context,
+ JSObjectGetPropertyAtIndex(context, filesArray, i, 0), 0);
+ size_t bufferSize = JSStringGetMaximumUTF8CStringSize(filenameString);
+ GUniquePtr<gchar> filenameBuffer(static_cast<gchar*>(g_malloc(bufferSize)));
+ JSStringGetUTF8CString(filenameString, filenameBuffer.get(), bufferSize);
+ JSStringRelease(filenameString);
+
+ GRefPtr<GFile> dragFile(g_file_get_child(parentDirectory.get(), filenameBuffer.get()));
+ draggedFilesURIList[i] = g_file_get_uri(dragFile.get());
+ }
+
+ GtkWidget* view = GTK_WIDGET(webkit_web_frame_get_web_view(mainFrame));
+ g_object_connect(G_OBJECT(view),
+ "signal::drag-end", dragWithFilesDragEndCallback, draggedFilesURIList,
+ "signal::drag-data-get", dragWithFilesDragDataGetCallback, draggedFilesURIList,
+ NULL);
+
+ GdkEvent event;
+ GdkWindow* viewGDKWindow = gtk_widget_get_window(view);
+ memset(&event, 0, sizeof(event));
+ event.type = GDK_MOTION_NOTIFY;
+ event.motion.x = lastMousePositionX;
+ event.motion.y = lastMousePositionY;
+ event.motion.time = GDK_CURRENT_TIME;
+ event.motion.window = viewGDKWindow;
+ event.motion.device = getDefaultGDKPointerDevice(viewGDKWindow);
+ event.motion.state = GDK_BUTTON1_MASK;
+
+ int xRoot, yRoot;
+ gdk_window_get_root_coords(viewGDKWindow, lastMousePositionX, lastMousePositionY, &xRoot, &yRoot);
+ event.motion.x_root = xRoot;
+ event.motion.y_root = yRoot;
+
+ GtkTargetList* targetList = gtk_target_list_new(0, 0);
+ gtk_target_list_add_uri_targets(targetList, 0);
+ gtk_drag_begin(view, targetList, GDK_ACTION_COPY, 1, &event);
+ gtk_target_list_unref(targetList);
+
+ return JSValueMakeUndefined(context);
+}
+
+static void sendOrQueueEvent(GdkEvent* event, bool shouldReplaySavedEvents)
+{
+ // Mouse move events are queued if the previous event was queued or if a
+ // delay was set up by leapForward().
+ if ((dragMode && buttonCurrentlyDown) || endOfQueue != startOfQueue || msgQueue[endOfQueue].delay) {
+ msgQueue[endOfQueue++].event = event;
+
+ if (shouldReplaySavedEvents)
+ replaySavedEvents();
+
+ return;
+ }
+
+ dispatchEvent(event);
+}
+
+static void dispatchEvent(GdkEvent* event)
+{
+ DumpRenderTreeSupportGtk::layoutFrame(mainFrame);
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ if (!view) {
+ gdk_event_free(event);
+ return;
+ }
+
+ // The widget focus may have been lost in the course of the test,
+ // so force another explicit focus grab here.
+ gtk_widget_grab_focus(GTK_WIDGET(view));
+ gtk_main_do_event(event);
+
+ if (!currentDragSourceContext) {
+ gdk_event_free(event);
+ 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 = gtk_widget_get_window(parentWidget);
+ gdk_drag_motion(currentDragSourceContext, parentWidgetWindow, GDK_DRAG_PROTO_XDND,
+ event->motion.x_root, event->motion.y_root,
+ gdk_drag_context_get_selected_action(currentDragSourceContext),
+ gdk_drag_context_get_actions(currentDragSourceContext),
+ 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();
+ }
+
+ gdk_event_free(event);
+}
+
+void replaySavedEvents()
+{
+ // First send all the events that are ready to be sent
+ while (startOfQueue < endOfQueue) {
+ if (msgQueue[startOfQueue].delay) {
+ g_usleep(msgQueue[startOfQueue].delay * 1000);
+ msgQueue[startOfQueue].delay = 0;
+ }
+
+ dispatchEvent(msgQueue[startOfQueue++].event);
+ }
+
+ startOfQueue = 0;
+ endOfQueue = 0;
+}
+
+static GdkEvent* createKeyPressEvent(JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ g_return_val_if_fail(argumentCount >= 1, 0);
+ guint modifiers = argumentCount >= 2 ? gdkModifersFromJSValue(context, arguments[1]) : 0;
+
+ // handle location argument.
+ int location = DOM_KEY_LOCATION_STANDARD;
+ if (argumentCount > 2)
+ location = (int)JSValueToNumber(context, arguments[2], exception);
+
+ JSStringRef character = JSValueToStringCopy(context, arguments[0], exception);
+ g_return_val_if_fail((!exception || !*exception), 0);
+
+ int gdkKeySym = GDK_VoidSymbol;
+ if (location == DOM_KEY_LOCATION_NUMPAD) {
+ if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
+ gdkKeySym = GDK_KP_Left;
+ else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
+ gdkKeySym = GDK_KP_Right;
+ else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
+ gdkKeySym = GDK_KP_Up;
+ else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
+ gdkKeySym = GDK_KP_Down;
+ else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
+ gdkKeySym = GDK_KP_Page_Up;
+ else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
+ gdkKeySym = GDK_KP_Page_Down;
+ else if (JSStringIsEqualToUTF8CString(character, "home"))
+ gdkKeySym = GDK_KP_Home;
+ else if (JSStringIsEqualToUTF8CString(character, "end"))
+ gdkKeySym = GDK_KP_End;
+ else if (JSStringIsEqualToUTF8CString(character, "insert"))
+ gdkKeySym = GDK_KP_Insert;
+ else if (JSStringIsEqualToUTF8CString(character, "delete"))
+ gdkKeySym = GDK_KP_Delete;
+ else
+ // If we get some other key specified with the numpad location,
+ // crash here, so we add it sooner rather than later.
+ g_assert_not_reached();
+ } else {
+ if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
+ gdkKeySym = GDK_Left;
+ else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
+ gdkKeySym = GDK_Right;
+ else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
+ gdkKeySym = GDK_Up;
+ else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
+ gdkKeySym = GDK_Down;
+ else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
+ gdkKeySym = GDK_Page_Up;
+ else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
+ gdkKeySym = GDK_Page_Down;
+ else if (JSStringIsEqualToUTF8CString(character, "home"))
+ gdkKeySym = GDK_Home;
+ else if (JSStringIsEqualToUTF8CString(character, "end"))
+ gdkKeySym = GDK_End;
+ else if (JSStringIsEqualToUTF8CString(character, "insert"))
+ gdkKeySym = GDK_Insert;
+ else if (JSStringIsEqualToUTF8CString(character, "delete"))
+ gdkKeySym = GDK_Delete;
+ else if (JSStringIsEqualToUTF8CString(character, "printScreen"))
+ gdkKeySym = GDK_Print;
+ else if (JSStringIsEqualToUTF8CString(character, "menu"))
+ gdkKeySym = GDK_Menu;
+ else if (JSStringIsEqualToUTF8CString(character, "F1"))
+ gdkKeySym = GDK_F1;
+ else if (JSStringIsEqualToUTF8CString(character, "F2"))
+ gdkKeySym = GDK_F2;
+ else if (JSStringIsEqualToUTF8CString(character, "F3"))
+ gdkKeySym = GDK_F3;
+ else if (JSStringIsEqualToUTF8CString(character, "F4"))
+ gdkKeySym = GDK_F4;
+ else if (JSStringIsEqualToUTF8CString(character, "F5"))
+ gdkKeySym = GDK_F5;
+ else if (JSStringIsEqualToUTF8CString(character, "F6"))
+ gdkKeySym = GDK_F6;
+ else if (JSStringIsEqualToUTF8CString(character, "F7"))
+ gdkKeySym = GDK_F7;
+ else if (JSStringIsEqualToUTF8CString(character, "F8"))
+ gdkKeySym = GDK_F8;
+ else if (JSStringIsEqualToUTF8CString(character, "F9"))
+ gdkKeySym = GDK_F9;
+ else if (JSStringIsEqualToUTF8CString(character, "F10"))
+ gdkKeySym = GDK_F10;
+ else if (JSStringIsEqualToUTF8CString(character, "F11"))
+ gdkKeySym = GDK_F11;
+ else if (JSStringIsEqualToUTF8CString(character, "F12"))
+ gdkKeySym = GDK_F12;
+ else if (JSStringIsEqualToUTF8CString(character, "leftAlt"))
+ gdkKeySym = GDK_Alt_L;
+ else if (JSStringIsEqualToUTF8CString(character, "leftControl"))
+ gdkKeySym = GDK_Control_L;
+ else if (JSStringIsEqualToUTF8CString(character, "leftShift"))
+ gdkKeySym = GDK_Shift_L;
+ else if (JSStringIsEqualToUTF8CString(character, "rightAlt"))
+ gdkKeySym = GDK_Alt_R;
+ else if (JSStringIsEqualToUTF8CString(character, "rightControl"))
+ gdkKeySym = GDK_Control_R;
+ else if (JSStringIsEqualToUTF8CString(character, "rightShift"))
+ gdkKeySym = GDK_Shift_R;
+ else {
+ int charCode = JSStringGetCharactersPtr(character)[0];
+ if (charCode == '\n' || charCode == '\r')
+ gdkKeySym = GDK_Return;
+ else if (charCode == '\t')
+ gdkKeySym = GDK_Tab;
+ else if (charCode == '\x8')
+ gdkKeySym = GDK_BackSpace;
+ else {
+ gdkKeySym = gdk_unicode_to_keyval(charCode);
+ if (WTF::isASCIIUpper(charCode))
+ modifiers |= GDK_SHIFT_MASK;
+ }
+ }
+ }
+ JSStringRelease(character);
+
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ g_return_val_if_fail(view, 0);
+
+ GdkEvent* pressEvent = gdk_event_new(GDK_KEY_PRESS);
+ pressEvent->key.keyval = gdkKeySym;
+ pressEvent->key.state = modifiers;
+ pressEvent->key.window = gtk_widget_get_window(GTK_WIDGET(view));
+ g_object_ref(pressEvent->key.window);
+#ifndef GTK_API_VERSION_2
+ gdk_event_set_device(pressEvent, getDefaultGDKPointerDevice(pressEvent->key.window));
+#endif
+
+ // When synthesizing an event, an invalid hardware_keycode value
+ // can cause it to be badly processed by Gtk+.
+ GUniqueOutPtr<GdkKeymapKey> keys;
+ gint nKeys;
+ if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeySym, &keys.outPtr(), &nKeys))
+ pressEvent->key.hardware_keycode = keys.get()[0].keycode;
+
+ return pressEvent;
+}
+
+static void sendKeyDown(GdkEvent* pressEvent)
+{
+ g_return_if_fail(pressEvent);
+ GdkEvent* releaseEvent = gdk_event_copy(pressEvent);
+ releaseEvent->type = GDK_KEY_RELEASE;
+
+ dispatchEvent(pressEvent);
+ dispatchEvent(releaseEvent);
+
+ DumpRenderTreeSupportGtk::deliverAllMutationsIfNecessary();
+}
+
+static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ GdkEvent* pressEvent = createKeyPressEvent(context, argumentCount, arguments, exception);
+ sendKeyDown(pressEvent);
+
+ return JSValueMakeUndefined(context);
+}
+
+static void zoomIn(gboolean fullContentsZoom)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ if (!view)
+ return;
+
+ webkit_web_view_set_full_content_zoom(view, fullContentsZoom);
+ gfloat currentZoom = webkit_web_view_get_zoom_level(view);
+ webkit_web_view_set_zoom_level(view, currentZoom * zoomMultiplierRatio);
+}
+
+static void zoomOut(gboolean fullContentsZoom)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ if (!view)
+ return;
+
+ webkit_web_view_set_full_content_zoom(view, fullContentsZoom);
+ gfloat currentZoom = webkit_web_view_get_zoom_level(view);
+ webkit_web_view_set_zoom_level(view, currentZoom / zoomMultiplierRatio);
+}
+
+static JSValueRef textZoomInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ zoomIn(FALSE);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef textZoomOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ zoomOut(FALSE);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef zoomPageInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ zoomIn(TRUE);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef zoomPageOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ zoomOut(TRUE);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef scalePageByCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 3)
+ return JSValueMakeUndefined(context);
+
+ float scaleFactor = JSValueToNumber(context, arguments[0], exception);
+ float x = JSValueToNumber(context, arguments[1], exception);
+ float y = JSValueToNumber(context, arguments[2], exception);
+
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ if (!view)
+ return JSValueMakeUndefined(context);
+
+ DumpRenderTreeSupportGtk::scalePageBy(view, scaleFactor, x, y);
+
+ return JSValueMakeUndefined(context);
+}
+
+static gboolean sendAsynchronousKeyDown(gpointer userData)
+{
+ sendKeyDown(static_cast<GdkEvent*>(userData));
+ return FALSE;
+}
+
+static JSValueRef scheduleAsynchronousKeyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ GdkEvent* pressEvent = createKeyPressEvent(context, argumentCount, arguments, exception);
+ if (pressEvent)
+ g_idle_add_full(G_PRIORITY_DEFAULT, sendAsynchronousKeyDown, static_cast<gpointer>(pressEvent), 0);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef clearTouchPointsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ return JSValueMakeUndefined(context);
+}
+
+static JSStaticFunction staticFunctions[] = {
+ { "mouseScrollBy", mouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "continuousMouseScrollBy", continuousMouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "contextClick", contextClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "mouseDown", mouseDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "mouseUp", mouseUpCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "mouseMoveTo", mouseMoveToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "beginDragWithFiles", beginDragWithFilesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "leapForward", leapForwardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "keyDown", keyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "textZoomIn", textZoomInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "zoomPageIn", zoomPageInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "zoomPageOut", zoomPageOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "scheduleAsynchronousClick", scheduleAsynchronousClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "scalePageBy", scalePageByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "scheduleAsynchronousKeyDown", scheduleAsynchronousKeyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+
+ { 0, 0, 0 }
+};
+
+static JSStaticValue staticValues[] = {
+ { "dragMode", getDragModeCallback, setDragModeCallback, kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+};
+
+static JSClassRef getClass(JSContextRef context)
+{
+ static JSClassRef eventSenderClass = 0;
+
+ if (!eventSenderClass) {
+ JSClassDefinition classDefinition = {
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ classDefinition.staticFunctions = staticFunctions;
+ classDefinition.staticValues = staticValues;
+
+ eventSenderClass = JSClassCreate(&classDefinition);
+ }
+
+ return eventSenderClass;
+}
+
+JSObjectRef makeEventSender(JSContextRef context, bool isTopFrame)
+{
+ if (isTopFrame) {
+ dragMode = true;
+
+ // Fly forward in time one second when the main frame loads. This will
+ // ensure that when a test begins clicking in the same location as
+ // a previous test, those clicks won't be interpreted as continuations
+ // of the previous test's click sequences.
+ timeOffset += 1000;
+
+ lastMousePositionX = lastMousePositionY = 0;
+ lastClickPositionX = lastClickPositionY = 0;
+ lastClickTimeOffset = 0;
+ lastClickButton = 0;
+ buttonCurrentlyDown = 0;
+ clickCount = 0;
+
+ 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/Tools/DumpRenderTree/gtk/EventSender.h b/Tools/DumpRenderTree/gtk/EventSender.h
new file mode 100644
index 000000000..f440f0d3d
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/EventSender.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Holger Hans Peter Freyther
+ *
+ * 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 EventSender_h
+#define EventSender_h
+
+typedef const struct OpaqueJSContext* JSContextRef;
+typedef struct OpaqueJSValue* JSObjectRef;
+
+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/Tools/DumpRenderTree/gtk/GCControllerGtk.cpp b/Tools/DumpRenderTree/gtk/GCControllerGtk.cpp
new file mode 100644
index 000000000..4eb5d6ec9
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/GCControllerGtk.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * 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 "GCController.h"
+
+#include "WebCoreSupport/DumpRenderTreeSupportGtk.h"
+
+#include <glib.h>
+#include <webkit/webkit.h>
+
+void GCController::collect() const
+{
+ DumpRenderTreeSupportGtk::gcCollectJavascriptObjects();
+}
+
+void GCController::collectOnAlternateThread(bool waitUntilDone) const
+{
+ DumpRenderTreeSupportGtk::gcCollectJavascriptObjectsOnAlternateThread(waitUntilDone);
+}
+
+size_t GCController::getJSObjectCount() const
+{
+ return DumpRenderTreeSupportGtk::gcCountJavascriptObjects();
+}
diff --git a/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp b/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp
new file mode 100644
index 000000000..0a800ec13
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2009 Zan Dobersek <zandobersek@gmail.com>
+ * Copyright (C) 2010 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 "DumpRenderTree.h"
+#include "GtkVersioning.h"
+#include "PixelDumpSupportCairo.h"
+#include "WebCoreSupport/DumpRenderTreeSupportGtk.h"
+#include <webkit/webkit.h>
+
+static void paintOverlay(cairo_surface_t* surface)
+{
+ cairo_t* context = cairo_create(surface);
+
+ // Paint a transparent black overlay from which the repainted rectangles are then cleared.
+ // The alpha component of the overlay should have a value of 0.66, as on other ports.
+ cairo_set_source_rgba(context, 0.0, 0.0, 0.0, 0.66);
+ cairo_rectangle(context, 0, 0, cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface));
+ cairo_fill(context);
+
+ GSList* trackedRectsList = DumpRenderTreeSupportGtk::trackedRepaintRects(mainFrame);
+ for (GSList* listElement = trackedRectsList; listElement; listElement = g_slist_next(listElement)) {
+ GdkRectangle* rect = static_cast<GdkRectangle*>(listElement->data);
+
+ cairo_set_operator(context, CAIRO_OPERATOR_CLEAR);
+ cairo_rectangle(context, rect->x, rect->y, rect->width, rect->height);
+ cairo_fill(context);
+ }
+
+ g_slist_free_full(trackedRectsList, g_free);
+ cairo_destroy(context);
+}
+
+static void fillRepaintOverlayIntoContext(cairo_t* context, gint width, gint height)
+{
+ cairo_surface_t* overlaySurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ paintOverlay(overlaySurface);
+
+ cairo_set_source_surface(context, overlaySurface, 0, 0);
+ cairo_rectangle(context, 0, 0, width, height);
+ cairo_fill(context);
+
+ cairo_surface_destroy(overlaySurface);
+}
+
+PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool, bool, bool, bool drawSelectionRect)
+{
+ 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(viewContainer, 0);
+ gdk_pixmap_get_size(pixmap, &width, &height);
+#else
+ width = gtk_widget_get_allocated_width(viewContainer);
+ height = gtk_widget_get_allocated_height(viewContainer);
+#endif
+
+ while (gtk_events_pending())
+ gtk_main_iteration();
+
+ cairo_surface_t* imageSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cairo_t* context = cairo_create(imageSurface);
+
+#ifdef GTK_API_VERSION_2
+ gdk_cairo_set_source_pixmap(context, pixmap, 0, 0);
+ cairo_paint(context);
+ g_object_unref(pixmap);
+#else
+ gtk_widget_draw(viewContainer, context);
+#endif
+
+ if (DumpRenderTreeSupportGtk::isTrackingRepaints(mainFrame))
+ fillRepaintOverlayIntoContext(context, width, height);
+
+ if (drawSelectionRect) {
+ cairo_rectangle_int_t rectangle;
+ DumpRenderTreeSupportGtk::rectangleForSelection(mainFrame, &rectangle);
+
+ cairo_set_line_width(context, 1.0);
+ cairo_rectangle(context, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+ cairo_set_source_rgba(context, 1.0, 0.0, 0.0, 1.0);
+ cairo_stroke(context);
+ }
+
+ cairo_surface_destroy(imageSurface);
+ return BitmapContext::createByAdoptingBitmapAndContext(0, context);
+}
diff --git a/Tools/DumpRenderTree/gtk/SelfScrollingWebKitWebView.cpp b/Tools/DumpRenderTree/gtk/SelfScrollingWebKitWebView.cpp
new file mode 100644
index 000000000..d77cfd5f1
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/SelfScrollingWebKitWebView.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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 "SelfScrollingWebKitWebView.h"
+
+#include <webkit/webkit.h>
+
+G_BEGIN_DECLS
+
+#ifdef GTK_API_VERSION_2
+static void sizeRequestMethod(GtkWidget*, GtkRequisition*);
+#else
+static void getPreferredSizeMethod(GtkWidget*, gint* minimum, gint* natural);
+#endif
+
+G_DEFINE_TYPE(SelfScrollingWebKitWebView, self_scrolling_webkit_web_view, WEBKIT_TYPE_WEB_VIEW)
+
+static void self_scrolling_webkit_web_view_class_init(SelfScrollingWebKitWebViewClass* klass)
+{
+ GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(klass);
+#ifdef GTK_API_VERSION_2
+ widgetClass->size_request = sizeRequestMethod;
+#else
+ widgetClass->get_preferred_width = getPreferredSizeMethod;
+ widgetClass->get_preferred_height = getPreferredSizeMethod;
+#endif
+}
+
+static void self_scrolling_webkit_web_view_init(SelfScrollingWebKitWebView* webView)
+{
+}
+
+GtkWidget* self_scrolling_webkit_web_view_new()
+{
+ return GTK_WIDGET(g_object_new(self_scrolling_webkit_web_view_get_type(), "self-scrolling", TRUE, NULL));
+}
+
+#ifdef GTK_API_VERSION_2
+static void sizeRequestMethod(GtkWidget*, GtkRequisition* requisition)
+{
+ requisition->width = 1;
+ requisition->height = 1;
+}
+#else
+static void getPreferredSizeMethod(GtkWidget*, gint* minimum, gint* natural)
+{
+ *minimum = 1;
+ *natural = 1;
+}
+#endif
+
+G_END_DECLS
diff --git a/Tools/DumpRenderTree/gtk/SelfScrollingWebKitWebView.h b/Tools/DumpRenderTree/gtk/SelfScrollingWebKitWebView.h
new file mode 100644
index 000000000..648d38c97
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/SelfScrollingWebKitWebView.h
@@ -0,0 +1,51 @@
+/*
+ * 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 SelfScrollingWebKitWebView_h
+#define SelfScrollingWebKitWebView_h
+
+#include <webkit/webkit.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SelfScrollingWebKitWebView SelfScrollingWebKitWebView;
+typedef struct _SelfScrollingWebKitWebViewClass SelfScrollingWebKitWebViewClass;
+
+struct _SelfScrollingWebKitWebView {
+ WebKitWebView web_view;
+};
+
+struct _SelfScrollingWebKitWebViewClass {
+ WebKitWebViewClass parent_class;
+};
+
+GtkWidget* self_scrolling_webkit_web_view_new();
+
+G_END_DECLS
+
+#endif // SelfScrollingWebKitWebView_h
diff --git a/Tools/DumpRenderTree/gtk/TestRunnerGtk.cpp b/Tools/DumpRenderTree/gtk/TestRunnerGtk.cpp
new file mode 100644
index 000000000..c0b2deca2
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/TestRunnerGtk.cpp
@@ -0,0 +1,914 @@
+/*
+ * Copyright (C) 2007, 2012 Apple Inc. All rights reserved.
+ * 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,2011 Collabora Ltd.
+ * Copyright (C) 2010 Joone Hur <joone@kldp.org>
+ *
+ * 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 "TestRunner.h"
+
+#include "DumpRenderTree.h"
+#include "WebCoreSupport/DumpRenderTreeSupportGtk.h"
+#include "WorkQueue.h"
+#include "WorkQueueItem.h"
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <cstring>
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <glib.h>
+#include <libsoup/soup.h>
+#include <webkit/webkit.h>
+#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/text/WTFString.h>
+
+extern "C" {
+void webkit_web_inspector_execute_script(WebKitWebInspector* inspector, long callId, const gchar* script);
+}
+
+TestRunner::~TestRunner()
+{
+ // FIXME: implement
+}
+
+void TestRunner::addDisallowedURL(JSStringRef url)
+{
+ // FIXME: implement
+}
+
+void TestRunner::clearBackForwardList()
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView);
+ WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_current_item(list);
+ g_object_ref(item);
+
+ // We clear the history by setting the back/forward list's capacity to 0
+ // then restoring it back and adding back the current item.
+ gint limit = webkit_web_back_forward_list_get_limit(list);
+ webkit_web_back_forward_list_set_limit(list, 0);
+ webkit_web_back_forward_list_set_limit(list, limit);
+ webkit_web_back_forward_list_add_item(list, item);
+ webkit_web_back_forward_list_go_to_item(list, item);
+ g_object_unref(item);
+}
+
+JSStringRef TestRunner::copyDecodedHostName(JSStringRef name)
+{
+ // FIXME: implement
+ return 0;
+}
+
+JSStringRef TestRunner::copyEncodedHostName(JSStringRef name)
+{
+ // FIXME: implement
+ return 0;
+}
+
+void TestRunner::dispatchPendingLoadRequests()
+{
+ // FIXME: Implement for testing fix for 6727495
+}
+
+void TestRunner::display()
+{
+ displayWebView();
+}
+
+void TestRunner::keepWebHistory()
+{
+ // FIXME: implement
+}
+
+size_t TestRunner::webHistoryItemCount()
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView);
+
+ if (!list)
+ return -1;
+
+ // We do not add the current page to the total count as it's not
+ // considered in DRT tests
+ return webkit_web_back_forward_list_get_back_length(list) +
+ webkit_web_back_forward_list_get_forward_length(list);
+}
+
+void TestRunner::notifyDone()
+{
+ if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
+ dump();
+ m_waitToDump = false;
+ waitForPolicy = false;
+}
+
+JSStringRef TestRunner::pathToLocalResource(JSContextRef context, JSStringRef url)
+{
+ GUniquePtr<char> urlCString(JSStringCopyUTF8CString(url));
+ if (!g_str_has_prefix(urlCString.get(), "file:///tmp/LayoutTests/"))
+ return JSStringRetain(url);
+
+ const char* layoutTestsSuffix = urlCString.get() + strlen("file:///tmp/");
+ GUniquePtr<char> testPath(g_build_filename(getTopLevelPath().data(), layoutTestsSuffix, nullptr));
+ GUniquePtr<char> testURI(g_filename_to_uri(testPath.get(), 0, 0));
+ return JSStringCreateWithUTF8CString(testURI.get());
+}
+
+void TestRunner::queueLoad(JSStringRef url, JSStringRef target)
+{
+ GUniquePtr<gchar> relativeURL(JSStringCopyUTF8CString(url));
+ SoupURI* baseURI = soup_uri_new(webkit_web_frame_get_uri(mainFrame));
+ SoupURI* absoluteURI = soup_uri_new_with_base(baseURI, relativeURL.get());
+ soup_uri_free(baseURI);
+
+ if (!absoluteURI) {
+ WorkQueue::shared()->queue(new LoadItem(url, target));
+ return;
+ }
+
+ CString absoluteURIString = soupURIToStringPreservingPassword(absoluteURI);
+ JSRetainPtr<JSStringRef> absoluteURL(Adopt, JSStringCreateWithUTF8CString(absoluteURIString.data()));
+ WorkQueue::shared()->queue(new LoadItem(absoluteURL.get(), target));
+ soup_uri_free(absoluteURI);
+}
+
+void TestRunner::setAcceptsEditing(bool acceptsEditing)
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ webkit_web_view_set_editable(webView, acceptsEditing);
+}
+
+void TestRunner::setAlwaysAcceptCookies(bool alwaysAcceptCookies)
+{
+ SoupSession* session = webkit_get_default_session();
+ SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR));
+
+ /* If the jar was not created - we create it on demand, i.e, just
+ in case we have HTTP requests - then we must create it here in
+ order to set the proper accept policy */
+ if (!jar) {
+ jar = soup_cookie_jar_new();
+ soup_session_add_feature(session, SOUP_SESSION_FEATURE(jar));
+ g_object_unref(jar);
+ }
+
+ SoupCookieJarAcceptPolicy policy;
+
+ if (alwaysAcceptCookies)
+ policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
+ else
+ policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
+
+ g_object_set(G_OBJECT(jar), SOUP_COOKIE_JAR_ACCEPT_POLICY, policy, NULL);
+}
+
+void TestRunner::setCustomPolicyDelegate(bool setDelegate, bool permissive)
+{
+ // FIXME: implement
+}
+
+void TestRunner::waitForPolicyDelegate()
+{
+ waitForPolicy = true;
+ setWaitToDump(true);
+}
+
+void TestRunner::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy)
+{
+ // FIXME: implement
+}
+
+void TestRunner::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef protocol, JSStringRef host, bool includeSubdomains)
+{
+ gchar* sourceOriginGChar = JSStringCopyUTF8CString(sourceOrigin);
+ gchar* protocolGChar = JSStringCopyUTF8CString(protocol);
+ gchar* hostGChar = JSStringCopyUTF8CString(host);
+ DumpRenderTreeSupportGtk::whiteListAccessFromOrigin(sourceOriginGChar, protocolGChar, hostGChar, includeSubdomains);
+ g_free(sourceOriginGChar);
+ g_free(protocolGChar);
+ g_free(hostGChar);
+}
+
+void TestRunner::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef protocol, JSStringRef host, bool includeSubdomains)
+{
+ GUniquePtr<gchar> sourceOriginGChar(JSStringCopyUTF8CString(sourceOrigin));
+ GUniquePtr<gchar> protocolGChar(JSStringCopyUTF8CString(protocol));
+ GUniquePtr<gchar> hostGChar(JSStringCopyUTF8CString(host));
+ DumpRenderTreeSupportGtk::removeWhiteListAccessFromOrigin(sourceOriginGChar.get(), protocolGChar.get(), hostGChar.get(), includeSubdomains);
+}
+
+void TestRunner::setMainFrameIsFirstResponder(bool flag)
+{
+ // FIXME: implement
+}
+
+void TestRunner::setTabKeyCyclesThroughElements(bool cycles)
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
+ g_object_set(G_OBJECT(settings), "tab-key-cycles-through-elements", cycles, NULL);
+}
+
+void TestRunner::setUseDashboardCompatibilityMode(bool flag)
+{
+ // FIXME: implement
+}
+
+static gchar* userStyleSheet = NULL;
+static gboolean userStyleSheetEnabled = TRUE;
+
+void TestRunner::setUserStyleSheetEnabled(bool flag)
+{
+ userStyleSheetEnabled = flag;
+
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
+ if (flag && userStyleSheet)
+ g_object_set(G_OBJECT(settings), "user-stylesheet-uri", userStyleSheet, NULL);
+ else
+ g_object_set(G_OBJECT(settings), "user-stylesheet-uri", "", NULL);
+}
+
+void TestRunner::setUserStyleSheetLocation(JSStringRef path)
+{
+ g_free(userStyleSheet);
+ userStyleSheet = JSStringCopyUTF8CString(path);
+ if (userStyleSheetEnabled)
+ setUserStyleSheetEnabled(true);
+}
+
+void TestRunner::setValueForUser(JSContextRef context, JSValueRef nodeObject, JSStringRef value)
+{
+ DumpRenderTreeSupportGtk::setValueForUser(context, nodeObject, value);
+}
+
+void TestRunner::setViewModeMediaFeature(JSStringRef mode)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ char* viewMode = JSStringCopyUTF8CString(mode);
+
+ if (!g_strcmp0(viewMode, "windowed"))
+ webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_WINDOWED);
+ else if (!g_strcmp0(viewMode, "floating"))
+ webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_FLOATING);
+ else if (!g_strcmp0(viewMode, "fullscreen"))
+ webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_FULLSCREEN);
+ else if (!g_strcmp0(viewMode, "maximized"))
+ webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_MAXIMIZED);
+ else if (!g_strcmp0(viewMode, "minimized"))
+ webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_MINIMIZED);
+
+ g_free(viewMode);
+}
+
+void TestRunner::setWindowIsKey(bool windowIsKey)
+{
+ // FIXME: implement
+}
+
+static gboolean waitToDumpWatchdogFired(void*)
+{
+ setWaitToDumpWatchdog(0);
+ gTestRunner->waitToDumpWatchdogTimerFired();
+ return FALSE;
+}
+
+void TestRunner::setWaitToDump(bool waitUntilDone)
+{
+ static const int timeoutSeconds = 30;
+
+ m_waitToDump = waitUntilDone;
+ if (m_waitToDump && shouldSetWaitToDumpWatchdog()) {
+ guint id = g_timeout_add_seconds(timeoutSeconds, waitToDumpWatchdogFired, 0);
+ g_source_set_name_by_id(id, "[WebKit] waitToDumpWatchdogFired");
+ setWaitToDumpWatchdog(id);
+ }
+}
+
+int TestRunner::windowCount()
+{
+ // +1 -> including the main view
+ return g_slist_length(webViewList) + 1;
+}
+
+void TestRunner::setPrivateBrowsingEnabled(bool flag)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(G_OBJECT(settings), "enable-private-browsing", flag, NULL);
+}
+
+void TestRunner::setJavaScriptCanAccessClipboard(bool flag)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(G_OBJECT(settings), "javascript-can-access-clipboard", flag, NULL);
+}
+
+void TestRunner::setXSSAuditorEnabled(bool flag)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(G_OBJECT(settings), "enable-xss-auditor", flag, NULL);
+}
+
+void TestRunner::setSpatialNavigationEnabled(bool flag)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(G_OBJECT(settings), "enable-spatial-navigation", flag, NULL);
+}
+
+void TestRunner::setAllowUniversalAccessFromFileURLs(bool flag)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(G_OBJECT(settings), "enable-universal-access-from-file-uris", flag, NULL);
+}
+
+void TestRunner::setAllowFileAccessFromFileURLs(bool flag)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(G_OBJECT(settings), "enable-file-access-from-file-uris", flag, NULL);
+}
+
+void TestRunner::setAuthorAndUserStylesEnabled(bool flag)
+{
+ // FIXME: implement
+}
+
+void TestRunner::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
+{
+ // FIXME: Implement for DeviceOrientation layout tests.
+ // See https://bugs.webkit.org/show_bug.cgi?id=30335.
+}
+
+void TestRunner::setMockGeolocationPosition(double latitude, double longitude, double accuracy, bool, double, bool, double, bool, double, bool, double)
+{
+ WebKitWebView* view = WEBKIT_WEB_VIEW(g_slist_nth_data(webViewList, 0));
+ if (!view)
+ view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ DumpRenderTreeSupportGtk::setMockGeolocationPosition(view, latitude, longitude, accuracy);
+}
+
+void TestRunner::setMockGeolocationPositionUnavailableError(JSStringRef message)
+{
+ WebKitWebView* view = WEBKIT_WEB_VIEW(g_slist_nth_data(webViewList, 0));
+ if (!view)
+ view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ GUniquePtr<gchar> cMessage(JSStringCopyUTF8CString(message));
+ DumpRenderTreeSupportGtk::setMockGeolocationPositionUnavailableError(view, cMessage.get());
+}
+
+void TestRunner::setGeolocationPermission(bool allow)
+{
+ setGeolocationPermissionCommon(allow);
+ WebKitWebView* view = WEBKIT_WEB_VIEW(g_slist_nth_data(webViewList, 0));
+ if (!view)
+ view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ DumpRenderTreeSupportGtk::setMockGeolocationPermission(view, allow);
+}
+
+int TestRunner::numberOfPendingGeolocationPermissionRequests()
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ if (!view)
+ view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ return DumpRenderTreeSupportGtk::numberOfPendingGeolocationPermissionRequests(view);
+}
+
+void TestRunner::addMockSpeechInputResult(JSStringRef result, double confidence, JSStringRef language)
+{
+ // FIXME: Implement for speech input layout tests.
+ // See https://bugs.webkit.org/show_bug.cgi?id=39485.
+}
+
+void TestRunner::setMockSpeechInputDumpRect(bool flag)
+{
+ // FIXME: Implement for speech input layout tests.
+ // See https://bugs.webkit.org/show_bug.cgi?id=39485.
+}
+
+void TestRunner::startSpeechInput(JSContextRef inputElement)
+{
+ // FIXME: Implement for speech input layout tests.
+ // See https://bugs.webkit.org/show_bug.cgi?id=39485.
+}
+
+void TestRunner::setIconDatabaseEnabled(bool enabled)
+{
+ WebKitIconDatabase* database = webkit_get_icon_database();
+ if (enabled) {
+ GUniquePtr<gchar> iconDatabasePath(g_build_filename(g_get_tmp_dir(), "DumpRenderTree", "icondatabase", nullptr));
+ webkit_icon_database_set_path(database, iconDatabasePath.get());
+ } else
+ webkit_icon_database_set_path(database, 0);
+}
+
+void TestRunner::setPopupBlockingEnabled(bool flag)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(G_OBJECT(settings), "javascript-can-open-windows-automatically", !flag, NULL);
+
+}
+
+void TestRunner::setPluginsEnabled(bool flag)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(G_OBJECT(settings), "enable-plugins", flag, NULL);
+}
+
+void TestRunner::execCommand(JSStringRef name, JSStringRef value)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ gchar* cName = JSStringCopyUTF8CString(name);
+ gchar* cValue = JSStringCopyUTF8CString(value);
+ DumpRenderTreeSupportGtk::executeCoreCommandByName(view, cName, cValue);
+ g_free(cName);
+ g_free(cValue);
+}
+
+bool TestRunner::findString(JSContextRef context, JSStringRef target, JSObjectRef optionsArray)
+{
+ 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;
+
+ GUniquePtr<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 TestRunner::isCommandEnabled(JSStringRef name)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ gchar* cName = JSStringCopyUTF8CString(name);
+ bool result = DumpRenderTreeSupportGtk::isCommandEnabled(view, cName);
+ g_free(cName);
+ return result;
+}
+
+void TestRunner::setCacheModel(int cacheModel)
+{
+ // 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 2:
+ webkit_set_cache_model(WEBKIT_CACHE_MODEL_WEB_BROWSER);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void TestRunner::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
+{
+ // FIXME: implement
+}
+
+void TestRunner::clearPersistentUserStyleSheet()
+{
+ // FIXME: implement
+}
+
+void TestRunner::clearAllApplicationCaches()
+{
+ // FIXME: Implement to support application cache quotas.
+}
+
+void TestRunner::clearApplicationCacheForOrigin(OpaqueJSString*)
+{
+ // FIXME: Implement to support deleting all application caches for an origin.
+}
+
+long long TestRunner::localStorageDiskUsageForOrigin(JSStringRef originIdentifier)
+{
+ // FIXME: Implement to support getting disk usage in bytes for an origin.
+ return 0;
+}
+
+JSValueRef TestRunner::originsWithApplicationCache(JSContextRef context)
+{
+ // FIXME: Implement to get origins that contain application caches.
+ return JSValueMakeUndefined(context);
+}
+
+long long TestRunner::applicationCacheDiskUsageForOrigin(JSStringRef name)
+{
+ // FIXME: implement
+ return 0;
+}
+
+void TestRunner::clearAllDatabases()
+{
+ webkit_remove_all_web_databases();
+}
+
+void TestRunner::setDatabaseQuota(unsigned long long quota)
+{
+ WebKitSecurityOrigin* origin = webkit_web_frame_get_security_origin(mainFrame);
+ webkit_security_origin_set_web_database_quota(origin, quota);
+}
+
+JSValueRef TestRunner::originsWithLocalStorage(JSContextRef context)
+{
+ // FIXME: implement
+ return JSValueMakeUndefined(context);
+}
+
+void TestRunner::deleteAllLocalStorage()
+{
+ // FIXME: implement
+}
+
+void TestRunner::deleteLocalStorageForOrigin(JSStringRef originIdentifier)
+{
+ // FIXME: implement
+}
+
+void TestRunner::observeStorageTrackerNotifications(unsigned number)
+{
+ // FIXME: implement
+}
+
+void TestRunner::syncLocalStorage()
+{
+ // FIXME: implement
+}
+
+void TestRunner::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme)
+{
+ GUniquePtr<gchar> urlScheme(JSStringCopyUTF8CString(scheme));
+ DumpRenderTreeSupportGtk::setDomainRelaxationForbiddenForURLScheme(forbidden, urlScheme.get());
+}
+
+void TestRunner::goBack()
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ webkit_web_view_go_back(webView);
+}
+
+void TestRunner::setDefersLoading(bool defers)
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ DumpRenderTreeSupportGtk::setDefersLoading(webView, defers);
+}
+
+void TestRunner::setAppCacheMaximumSize(unsigned long long size)
+{
+ webkit_application_cache_set_maximum_size(size);
+}
+
+static gboolean booleanFromValue(gchar* value)
+{
+ return !g_ascii_strcasecmp(value, "true") || !g_ascii_strcasecmp(value, "1");
+}
+
+void TestRunner::overridePreference(JSStringRef key, JSStringRef value)
+{
+ GUniquePtr<gchar> originalName(JSStringCopyUTF8CString(key));
+ GUniquePtr<gchar> valueAsString(JSStringCopyUTF8CString(value));
+
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ // This transformation could be handled by a hash table (and it once was), but
+ // having it prominent, makes it easier for people from other ports to keep the
+ // list up to date.
+ const gchar* propertyName = 0;
+ if (g_str_equal(originalName.get(), "WebKitJavaScriptEnabled"))
+ propertyName = "enable-scripts";
+ else if (g_str_equal(originalName.get(), "WebKitDefaultFontSize"))
+ propertyName = "default-font-size";
+ else if (g_str_equal(originalName.get(), "WebKitEnableCaretBrowsing"))
+ propertyName = "enable-caret-browsing";
+ else if (g_str_equal(originalName.get(), "WebKitUsesPageCachePreferenceKey"))
+ propertyName = "enable-page-cache";
+ else if (g_str_equal(originalName.get(), "WebKitPluginsEnabled"))
+ propertyName = "enable-plugins";
+ else if (g_str_equal(originalName.get(), "WebKitHyperlinkAuditingEnabled"))
+ propertyName = "enable-hyperlink-auditing";
+ else if (g_str_equal(originalName.get(), "WebKitWebGLEnabled"))
+ propertyName = "enable-webgl";
+ else if (g_str_equal(originalName.get(), "WebKitWebAudioEnabled"))
+ propertyName = "enable-webaudio";
+ else if (g_str_equal(originalName.get(), "WebKitDisplayImagesKey"))
+ propertyName = "auto-load-images";
+ else if (g_str_equal(originalName.get(), "WebKitShouldRespectImageOrientation"))
+ propertyName = "respect-image-orientation";
+ else if (g_str_equal(originalName.get(), "WebKitMediaSourceEnabled"))
+ propertyName = "enable-mediasource";
+ else if (g_str_equal(originalName.get(), "WebKitTabToLinksPreferenceKey")) {
+ DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(booleanFromValue(valueAsString.get()));
+ return;
+ } else if (g_str_equal(originalName.get(), "WebKitPageCacheSupportsPluginsPreferenceKey")) {
+ DumpRenderTreeSupportGtk::setPageCacheSupportsPlugins(webkit_web_frame_get_web_view(mainFrame), booleanFromValue(valueAsString.get()));
+ return;
+ } else if (g_str_equal(originalName.get(), "WebKitCSSGridLayoutEnabled")) {
+ DumpRenderTreeSupportGtk::setCSSGridLayoutEnabled(webkit_web_frame_get_web_view(mainFrame), booleanFromValue(valueAsString.get()));
+ return;
+ } else if (g_str_equal(originalName.get(), "WebKitCSSRegionsEnabled")) {
+ DumpRenderTreeSupportGtk::setCSSRegionsEnabled(webkit_web_frame_get_web_view(mainFrame), booleanFromValue(valueAsString.get()));
+ return;
+ } else {
+ fprintf(stderr, "TestRunner::overridePreference tried to override "
+ "unknown preference '%s'.\n", originalName.get());
+ return;
+ }
+
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ GParamSpec* pspec = g_object_class_find_property(G_OBJECT_CLASS(
+ WEBKIT_WEB_SETTINGS_GET_CLASS(settings)), propertyName);
+ GValue currentPropertyValue = { 0, { { 0 } } };
+ g_value_init(&currentPropertyValue, pspec->value_type);
+
+ if (G_VALUE_HOLDS_STRING(&currentPropertyValue))
+ g_object_set(settings, propertyName, valueAsString.get(), NULL);
+ else if (G_VALUE_HOLDS_BOOLEAN(&currentPropertyValue))
+ g_object_set(G_OBJECT(settings), propertyName, booleanFromValue(valueAsString.get()), NULL);
+ else if (G_VALUE_HOLDS_INT(&currentPropertyValue))
+ g_object_set(G_OBJECT(settings), propertyName, atoi(valueAsString.get()), NULL);
+ else if (G_VALUE_HOLDS_FLOAT(&currentPropertyValue)) {
+ gfloat newValue = g_ascii_strtod(valueAsString.get(), 0);
+ g_object_set(G_OBJECT(settings), propertyName, newValue, NULL);
+ } else
+ fprintf(stderr, "TestRunner::overridePreference failed to override "
+ "preference '%s'.\n", originalName.get());
+}
+
+void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
+{
+ GUniquePtr<gchar> sourceCode(JSStringCopyUTF8CString(source));
+ DumpRenderTreeSupportGtk::addUserScript(mainFrame, sourceCode.get(), runAtStart, allFrames);
+}
+
+void TestRunner::addUserStyleSheet(JSStringRef source, bool allFrames)
+{
+ GUniquePtr<gchar> sourceCode(JSStringCopyUTF8CString(source));
+ DumpRenderTreeSupportGtk::addUserStyleSheet(mainFrame, sourceCode.get(), allFrames);
+ // FIXME: needs more investigation why userscripts/user-style-top-frame-only.html fails when allFrames is false.
+
+}
+
+void TestRunner::setDeveloperExtrasEnabled(bool enabled)
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ WebKitWebSettings* webSettings = webkit_web_view_get_settings(webView);
+
+ g_object_set(webSettings, "enable-developer-extras", enabled, NULL);
+}
+
+void TestRunner::showWebInspector()
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView);
+
+ webkit_web_inspector_show(inspector);
+}
+
+void TestRunner::closeWebInspector()
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView);
+
+ webkit_web_inspector_close(inspector);
+}
+
+void TestRunner::evaluateInWebInspector(long callId, JSStringRef script)
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView);
+ char* scriptString = JSStringCopyUTF8CString(script);
+
+ webkit_web_inspector_execute_script(inspector, callId, scriptString);
+ g_free(scriptString);
+}
+
+void TestRunner::evaluateScriptInIsolatedWorldAndReturnValue(unsigned worldID, JSObjectRef globalObject, JSStringRef script)
+{
+ // FIXME: Implement this.
+}
+
+void TestRunner::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script)
+{
+ // FIXME: Implement this.
+}
+
+void TestRunner::removeAllVisitedLinks()
+{
+ // FIXME: Implement this.
+}
+
+bool TestRunner::callShouldCloseOnWebView()
+{
+ return DumpRenderTreeSupportGtk::shouldClose(mainFrame);
+}
+
+void TestRunner::apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data, JSStringRef baseURL)
+{
+
+}
+
+void TestRunner::apiTestGoToCurrentBackForwardItem()
+{
+
+}
+
+void TestRunner::setWebViewEditable(bool)
+{
+}
+
+void TestRunner::authenticateSession(JSStringRef, JSStringRef, JSStringRef)
+{
+}
+
+void TestRunner::abortModal()
+{
+}
+
+void TestRunner::setSerializeHTTPLoads(bool serialize)
+{
+ DumpRenderTreeSupportGtk::setSerializeHTTPLoads(serialize);
+}
+
+void TestRunner::setTextDirection(JSStringRef direction)
+{
+ GUniquePtr<gchar> writingDirection(JSStringCopyUTF8CString(direction));
+
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ if (g_str_equal(writingDirection.get(), "auto"))
+ gtk_widget_set_direction(GTK_WIDGET(view), GTK_TEXT_DIR_NONE);
+ else if (g_str_equal(writingDirection.get(), "ltr"))
+ gtk_widget_set_direction(GTK_WIDGET(view), GTK_TEXT_DIR_LTR);
+ else if (g_str_equal(writingDirection.get(), "rtl"))
+ gtk_widget_set_direction(GTK_WIDGET(view), GTK_TEXT_DIR_RTL);
+ else
+ fprintf(stderr, "TestRunner::setTextDirection called with unknown direction: '%s'.\n", writingDirection.get());
+}
+
+void TestRunner::addChromeInputField()
+{
+}
+
+void TestRunner::removeChromeInputField()
+{
+}
+
+void TestRunner::focusWebView()
+{
+}
+
+void TestRunner::setBackingScaleFactor(double)
+{
+}
+
+void TestRunner::grantWebNotificationPermission(JSStringRef origin)
+{
+}
+
+void TestRunner::denyWebNotificationPermission(JSStringRef jsOrigin)
+{
+}
+
+void TestRunner::removeAllWebNotificationPermissions()
+{
+}
+
+void TestRunner::simulateWebNotificationClick(JSValueRef jsNotification)
+{
+}
+
+void TestRunner::simulateLegacyWebNotificationClick(JSStringRef title)
+{
+}
+
+void TestRunner::resetPageVisibility()
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ DumpRenderTreeSupportGtk::setPageVisibility(webView, WebCore::PageVisibilityStateVisible, true);
+}
+
+void TestRunner::setPageVisibility(const char* visibility)
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ String visibilityString(visibility);
+ WebCore::PageVisibilityState visibilityState = WebCore::PageVisibilityStateVisible;
+
+ if (visibilityString == "visible")
+ visibilityState = WebCore::PageVisibilityStateVisible;
+ else if (visibilityString == "hidden")
+ visibilityState = WebCore::PageVisibilityStateHidden;
+ else
+ return;
+
+ DumpRenderTreeSupportGtk::setPageVisibility(webView, visibilityState, false);
+}
+
+void TestRunner::setAutomaticLinkDetectionEnabled(bool)
+{
+ // FIXME: Implement this.
+}
+
+void TestRunner::setStorageDatabaseIdleInterval(double)
+{
+ // FIXME: Implement this.
+}
+
+void TestRunner::closeIdleLocalStorageDatabases()
+{
+}
diff --git a/Tools/DumpRenderTree/gtk/TextInputController.cpp b/Tools/DumpRenderTree/gtk/TextInputController.cpp
new file mode 100644
index 000000000..aee5597ed
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/TextInputController.cpp
@@ -0,0 +1,215 @@
+/*
+ * 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 <GUniquePtrGtk.h>
+#include <JavaScriptCore/JSObjectRef.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <cstring>
+#include <webkit/webkit.h>
+
+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);
+ ASSERT(view);
+ if (argumentCount < 3)
+ return JSValueMakeUndefined(context);
+
+ JSStringRef string = JSValueToStringCopy(context, arguments[0], exception);
+ ASSERT(!exception || !*exception);
+
+ size_t bufferSize = JSStringGetMaximumUTF8CStringSize(string);
+ GUniquePtr<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));
+ ASSERT(!exception || !*exception);
+
+ int length = static_cast<int>(JSValueToNumber(context, arguments[2], exception));
+ ASSERT(!exception || !*exception);
+
+ DumpRenderTreeSupportGtk::setComposition(view, stringBuffer.get(), start, length);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef hasMarkedTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+ return JSValueMakeBoolean(context, DumpRenderTreeSupportGtk::hasComposition(view));
+}
+
+static JSValueRef markedRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+
+ int start, length;
+ if (!DumpRenderTreeSupportGtk::compositionRange(view, &start, &length))
+ return JSValueMakeUndefined(context);
+
+ JSValueRef arrayValues[2];
+ arrayValues[0] = JSValueMakeNumber(context, start);
+ arrayValues[1] = JSValueMakeNumber(context, length);
+ JSObjectRef arrayObject = JSObjectMakeArray(context, 2, arrayValues, exception);
+ ASSERT(!exception || !*exception);
+ return arrayObject;
+}
+
+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);
+ ASSERT(view);
+
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSStringRef string = JSValueToStringCopy(context, arguments[0], exception);
+ ASSERT(!exception || !*exception);
+
+ size_t bufferSize = JSStringGetMaximumUTF8CStringSize(string);
+ GUniquePtr<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);
+ ASSERT(view);
+
+ 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);
+ ASSERT(view);
+ if (argumentCount < 2)
+ return JSValueMakeUndefined(context);
+
+ int location = static_cast<int>(JSValueToNumber(context, arguments[0], exception));
+ ASSERT(!exception || !*exception);
+
+ int length = static_cast<int>(JSValueToNumber(context, arguments[1], exception));
+ ASSERT(!exception || !*exception);
+
+ cairo_rectangle_int_t 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);
+ ASSERT(!exception || !*exception);
+
+ 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);
+ ASSERT(view);
+
+ int start, length;
+ if (!DumpRenderTreeSupportGtk::selectedRange(view, &start, &length))
+ return JSValueMakeUndefined(context);
+
+ JSValueRef arrayValues[2];
+ arrayValues[0] = JSValueMakeNumber(context, start);
+ arrayValues[1] = JSValueMakeNumber(context, length);
+ JSObjectRef arrayObject = JSObjectMakeArray(context, 2, arrayValues, exception);
+ ASSERT(!exception || !*exception);
+
+ return arrayObject;
+}
+
+static JSValueRef doCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
+ ASSERT(view);
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSStringRef string = JSValueToStringCopy(context, arguments[0], exception);
+ ASSERT(!exception || !*exception);
+
+ size_t bufferSize = JSStringGetMaximumUTF8CStringSize(string);
+ GUniquePtr<gchar> stringBuffer(static_cast<gchar*>(g_malloc(bufferSize)));
+ JSStringGetUTF8CString(string, stringBuffer.get(), bufferSize);
+ JSStringRelease(string);
+
+ DumpRenderTreeSupportGtk::doCommand(view, stringBuffer.get());
+ return JSValueMakeUndefined(context);
+}
+
+static JSStaticFunction staticFunctions[] = {
+ { "setMarkedText", setMarkedTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "hasMarkedText", hasMarkedTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "markedRange", markedRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "insertText", insertTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "unmarkText", unmarkTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "firstRectForCharacterRange", firstRectForCharacterRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "selectedRange", selectedRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "doCommand", doCommandCallback, 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 000000000..53793f637
--- /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/gtk/WorkQueueItemGtk.cpp b/Tools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp
new file mode 100644
index 000000000..95461276e
--- /dev/null
+++ b/Tools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WorkQueueItem.h"
+
+#include "DumpRenderTree.h"
+
+#include <JavaScriptCore/JSStringRef.h>
+#include <string.h>
+#include <webkit/webkit.h>
+#include <wtf/gobject/GUniquePtr.h>
+
+// Returns a newly allocated UTF-8 character buffer which must be freed with g_free()
+gchar* JSStringCopyUTF8CString(JSStringRef jsString)
+{
+ size_t dataSize = JSStringGetMaximumUTF8CStringSize(jsString);
+ gchar* utf8 = (gchar*)g_malloc(dataSize);
+ JSStringGetUTF8CString(jsString, utf8, dataSize);
+
+ return utf8;
+}
+
+bool LoadItem::invoke() const
+{
+ gchar* targetString = JSStringCopyUTF8CString(m_target.get());
+
+ WebKitWebFrame* targetFrame;
+ if (!strlen(targetString))
+ targetFrame = mainFrame;
+ else
+ targetFrame = webkit_web_frame_find_frame(mainFrame, targetString);
+ g_free(targetString);
+
+ gchar* urlString = JSStringCopyUTF8CString(m_url.get());
+ WebKitNetworkRequest* request = webkit_network_request_new(urlString);
+ g_free(urlString);
+ webkit_web_frame_load_request(targetFrame, request);
+ g_object_unref(request);
+
+ return true;
+}
+
+bool LoadHTMLStringItem::invoke() const
+{
+ GUniquePtr<gchar> content(JSStringCopyUTF8CString(m_content.get()));
+ GUniquePtr<gchar> baseURL(JSStringCopyUTF8CString(m_baseURL.get()));
+
+ if (m_unreachableURL) {
+ GUniquePtr<gchar> unreachableURL(JSStringCopyUTF8CString(m_unreachableURL.get()));
+ webkit_web_frame_load_alternate_string(mainFrame, content.get(), baseURL.get(), unreachableURL.get());
+ return true;
+ }
+ webkit_web_frame_load_string(mainFrame, content.get(), 0, 0, baseURL.get());
+ return true;
+}
+
+bool ReloadItem::invoke() const
+{
+ webkit_web_frame_reload(mainFrame);
+ return true;
+}
+
+bool ScriptItem::invoke() const
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ gchar* scriptString = JSStringCopyUTF8CString(m_script.get());
+ webkit_web_view_execute_script(webView, scriptString);
+ g_free(scriptString);
+ return true;
+}
+
+bool BackForwardItem::invoke() const
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ if (m_howFar == 1)
+ webkit_web_view_go_forward(webView);
+ else if (m_howFar == -1)
+ webkit_web_view_go_back(webView);
+ else {
+ WebKitWebBackForwardList* webBackForwardList = webkit_web_view_get_back_forward_list(webView);
+ WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(webBackForwardList, m_howFar);
+ webkit_web_view_go_to_back_forward_item(webView, item);
+ }
+ return true;
+}