summaryrefslogtreecommitdiffstats
path: root/WebKitTools/DumpRenderTree
diff options
context:
space:
mode:
Diffstat (limited to 'WebKitTools/DumpRenderTree')
-rw-r--r--WebKitTools/DumpRenderTree/AccessibilityController.cpp70
-rw-r--r--WebKitTools/DumpRenderTree/AccessibilityController.h48
-rw-r--r--WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp303
-rw-r--r--WebKitTools/DumpRenderTree/AccessibilityUIElement.h111
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.h66
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.sln47
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj795
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTreePrefix.h38
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/ASCIICType.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Assertions.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashMap.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashSet.h1
-rwxr-xr-xWebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashTraits.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Locker.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/MathExtras.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Noncopyable.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/OwnPtr.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/PassRefPtr.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Platform.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RefCounted.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RefPtr.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RetainPtr.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/StringExtras.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Threading.h1
-rw-r--r--WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Vector.h1
-rw-r--r--WebKitTools/DumpRenderTree/GCController.cpp108
-rw-r--r--WebKitTools/DumpRenderTree/GCController.h51
-rw-r--r--WebKitTools/DumpRenderTree/JavaScriptThreading.h40
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.cpp780
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.h192
-rw-r--r--WebKitTools/DumpRenderTree/Makefile2
-rw-r--r--WebKitTools/DumpRenderTree/PixelDumpSupport.h46
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/Info.plist60
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp676
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h50
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp135
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.h29
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp328
-rw-r--r--WebKitTools/DumpRenderTree/WorkQueue.cpp89
-rw-r--r--WebKitTools/DumpRenderTree/WorkQueue.h51
-rw-r--r--WebKitTools/DumpRenderTree/WorkQueueItem.h108
-rw-r--r--WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp253
-rw-r--r--WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp134
-rw-r--r--WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h80
-rw-r--r--WebKitTools/DumpRenderTree/config.h47
-rw-r--r--WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher100.ttfbin0 -> 28512 bytes
-rw-r--r--WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher200.ttfbin0 -> 28512 bytes
-rw-r--r--WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher300.ttfbin0 -> 28492 bytes
-rw-r--r--WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher400.ttfbin0 -> 28440 bytes
-rw-r--r--WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher500.ttfbin0 -> 28424 bytes
-rw-r--r--WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher600.ttfbin0 -> 28460 bytes
-rw-r--r--WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher700.ttfbin0 -> 28384 bytes
-rw-r--r--WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher800.ttfbin0 -> 28492 bytes
-rw-r--r--WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher900.ttfbin0 -> 28492 bytes
-rw-r--r--WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp407
-rw-r--r--WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h41
-rw-r--r--WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp43
-rw-r--r--WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp270
-rw-r--r--WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp74
-rw-r--r--WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm54
-rw-r--r--WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm425
-rw-r--r--WebKitTools/DumpRenderTree/mac/AppleScriptController.h39
-rw-r--r--WebKitTools/DumpRenderTree/mac/AppleScriptController.m126
-rw-r--r--WebKitTools/DumpRenderTree/mac/CheckedMalloc.cpp59
-rw-r--r--WebKitTools/DumpRenderTree/mac/CheckedMalloc.h31
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig17
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig7
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig4
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/ImageDiff.xcconfig1
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/TestNetscapePlugIn.xcconfig6
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm1093
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.h53
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm108
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h63
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h38
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m205
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.h36
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm86
-rw-r--r--WebKitTools/DumpRenderTree/mac/EditingDelegate.h38
-rw-r--r--WebKitTools/DumpRenderTree/mac/EditingDelegate.mm191
-rw-r--r--WebKitTools/DumpRenderTree/mac/EventSendingController.h53
-rw-r--r--WebKitTools/DumpRenderTree/mac/EventSendingController.mm667
-rw-r--r--WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h39
-rw-r--r--WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm351
-rw-r--r--WebKitTools/DumpRenderTree/mac/GCControllerMac.mm47
-rw-r--r--WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm311
-rw-r--r--WebKitTools/DumpRenderTree/mac/NavigationController.h39
-rw-r--r--WebKitTools/DumpRenderTree/mac/NavigationController.m109
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCController.h38
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCController.m239
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCPlugin.h36
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCPlugin.m206
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.h34
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.m37
-rw-r--r--WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm241
-rw-r--r--WebKitTools/DumpRenderTree/mac/PolicyDelegate.h35
-rw-r--r--WebKitTools/DumpRenderTree/mac/PolicyDelegate.mm45
-rw-r--r--WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.h35
-rw-r--r--WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm194
-rw-r--r--WebKitTools/DumpRenderTree/mac/TextInputController.h42
-rw-r--r--WebKitTools/DumpRenderTree/mac/TextInputController.m423
-rw-r--r--WebKitTools/DumpRenderTree/mac/UIDelegate.h37
-rw-r--r--WebKitTools/DumpRenderTree/mac/UIDelegate.mm163
-rw-r--r--WebKitTools/DumpRenderTree/mac/WorkQueueItemMac.mm77
-rw-r--r--WebKitTools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp137
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp332
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTree.h101
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro22
-rw-r--r--WebKitTools/DumpRenderTree/qt/fonts.conf258
-rw-r--r--WebKitTools/DumpRenderTree/qt/fonts/AHEM____.TTFbin0 -> 12480 bytes
-rw-r--r--WebKitTools/DumpRenderTree/qt/jsobjects.cpp363
-rw-r--r--WebKitTools/DumpRenderTree/qt/jsobjects.h140
-rw-r--r--WebKitTools/DumpRenderTree/qt/main.cpp174
-rw-r--r--WebKitTools/DumpRenderTree/qt/testplugin.cpp67
-rw-r--r--WebKitTools/DumpRenderTree/qt/testplugin.h45
-rw-r--r--WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp84
-rw-r--r--WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp266
-rw-r--r--WebKitTools/DumpRenderTree/win/DraggingInfo.h62
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp1127
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj411
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h55
-rw-r--r--WebKitTools/DumpRenderTree/win/EditingDelegate.cpp355
-rw-r--r--WebKitTools/DumpRenderTree/win/EditingDelegate.h176
-rw-r--r--WebKitTools/DumpRenderTree/win/EventSender.cpp597
-rw-r--r--WebKitTools/DumpRenderTree/win/EventSender.h42
-rw-r--r--WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp314
-rw-r--r--WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h139
-rw-r--r--WebKitTools/DumpRenderTree/win/GCControllerWin.cpp60
-rw-r--r--WebKitTools/DumpRenderTree/win/ImageDiff.vcproj163
-rw-r--r--WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp630
-rw-r--r--WebKitTools/DumpRenderTree/win/MD5.cpp78
-rw-r--r--WebKitTools/DumpRenderTree/win/MD5.h45
-rw-r--r--WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp68
-rw-r--r--WebKitTools/DumpRenderTree/win/PolicyDelegate.cpp87
-rw-r--r--WebKitTools/DumpRenderTree/win/PolicyDelegate.h74
-rw-r--r--WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp257
-rw-r--r--WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h103
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.def6
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.rc101
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj263
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.c183
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp215
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/resource.h14
-rwxr-xr-xWebKitTools/DumpRenderTree/win/UIDelegate.cpp444
-rwxr-xr-xWebKitTools/DumpRenderTree/win/UIDelegate.h321
-rw-r--r--WebKitTools/DumpRenderTree/win/WorkQueueItemWin.cpp134
146 files changed, 20280 insertions, 0 deletions
diff --git a/WebKitTools/DumpRenderTree/AccessibilityController.cpp b/WebKitTools/DumpRenderTree/AccessibilityController.cpp
new file mode 100644
index 0000000..d2ed2a6
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/AccessibilityController.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008 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. ``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"
+
+#include "AccessibilityUIElement.h"
+#include <JavaScriptCore/JSRetainPtr.h>
+
+// Static Value Getters
+
+static JSValueRef getFocusedElementCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ AccessibilityController* controller = reinterpret_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
+ return AccessibilityUIElement::makeJSAccessibilityUIElement(context, controller->focusedElement());
+}
+
+static JSValueRef getRootElementCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ AccessibilityController* controller = reinterpret_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
+ return AccessibilityUIElement::makeJSAccessibilityUIElement(context, controller->rootElement());
+}
+
+// Object Creation
+
+void AccessibilityController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> accessibilityControllerStr(Adopt, JSStringCreateWithUTF8CString("accessibilityController"));
+ JSValueRef accessibilityControllerObject = JSObjectMake(context, getJSClass(), this);
+ JSObjectSetProperty(context, windowObject, accessibilityControllerStr.get(), accessibilityControllerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
+}
+
+JSClassRef AccessibilityController::getJSClass()
+{
+ static JSStaticValue staticValues[] = {
+ { "focusedElement", getFocusedElementCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "rootElement", getRootElementCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0, 0 }
+ };
+
+ static JSClassDefinition classDefinition = {
+ 0, kJSClassAttributeNone, "AccessibilityController", 0, staticValues, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ static JSClassRef accessibilityControllerClass = JSClassCreate(&classDefinition);
+ return accessibilityControllerClass;
+}
diff --git a/WebKitTools/DumpRenderTree/AccessibilityController.h b/WebKitTools/DumpRenderTree/AccessibilityController.h
new file mode 100644
index 0000000..0af6613
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/AccessibilityController.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 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. ``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.
+ */
+
+#ifndef AccessibilityController_h
+#define AccessibilityController_h
+
+#include <JavaScriptCore/JSObjectRef.h>
+
+class AccessibilityUIElement;
+
+class AccessibilityController {
+public:
+ AccessibilityController();
+ ~AccessibilityController();
+
+ void makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception);
+
+ // Controller Methods - platform-independent implementations
+ AccessibilityUIElement rootElement();
+ AccessibilityUIElement focusedElement();
+
+private:
+ static JSClassRef getJSClass();
+};
+
+#endif // AccessibilityController_h
diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
new file mode 100644
index 0000000..02d2dfa
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2008 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. ``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"
+
+#include <JavaScriptCore/JSRetainPtr.h>
+
+// Static Functions
+
+static AccessibilityUIElement* toAXElement(JSObjectRef object)
+{
+ // FIXME: We should ASSERT that it is the right class here.
+ return reinterpret_cast<AccessibilityUIElement*>(JSObjectGetPrivate(object));
+}
+
+static JSValueRef allAttributesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributes(Adopt, toAXElement(thisObject)->allAttributes());
+ return JSValueMakeString(context, attributes.get());
+}
+
+static JSValueRef attributesOfLinkedUIElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> linkedUIDescription(Adopt, toAXElement(thisObject)->attributesOfLinkedUIElements());
+ return JSValueMakeString(context, linkedUIDescription.get());
+}
+
+static JSValueRef attributesOfDocumentLinksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> linkedUIDescription(Adopt, toAXElement(thisObject)->attributesOfDocumentLinks());
+ return JSValueMakeString(context, linkedUIDescription.get());
+}
+
+static JSValueRef attributesOfChildrenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> childrenDescription(Adopt, toAXElement(thisObject)->attributesOfChildren());
+ return JSValueMakeString(context, childrenDescription.get());
+}
+
+static JSValueRef parameterizedAttributeNamesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> parameterizedAttributeNames(Adopt, toAXElement(thisObject)->parameterizedAttributeNames());
+ return JSValueMakeString(context, parameterizedAttributeNames.get());
+}
+
+static JSValueRef attributesOfColumnHeadersCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfColumnHeaders(Adopt, toAXElement(thisObject)->attributesOfColumnHeaders());
+ return JSValueMakeString(context, attributesOfColumnHeaders.get());
+}
+
+static JSValueRef attributesOfRowHeadersCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfRowHeaders(Adopt, toAXElement(thisObject)->attributesOfRowHeaders());
+ return JSValueMakeString(context, attributesOfRowHeaders.get());
+}
+
+static JSValueRef attributesOfColumnsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfColumns(Adopt, toAXElement(thisObject)->attributesOfColumns());
+ return JSValueMakeString(context, attributesOfColumns.get());
+}
+
+static JSValueRef attributesOfRowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfRows(Adopt, toAXElement(thisObject)->attributesOfRows());
+ return JSValueMakeString(context, attributesOfRows.get());
+}
+
+static JSValueRef attributesOfVisibleCellsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfVisibleCells(Adopt, toAXElement(thisObject)->attributesOfVisibleCells());
+ return JSValueMakeString(context, attributesOfVisibleCells.get());
+}
+
+static JSValueRef attributesOfHeaderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfHeader(Adopt, toAXElement(thisObject)->attributesOfHeader());
+ return JSValueMakeString(context, attributesOfHeader.get());
+}
+
+static JSValueRef indexInTableCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ return JSValueMakeNumber(context, toAXElement(thisObject)->indexInTable());
+}
+
+static JSValueRef rowIndexRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> rowIndexRange(Adopt, toAXElement(thisObject)->rowIndexRange());
+ return JSValueMakeString(context, rowIndexRange.get());
+}
+
+static JSValueRef columnIndexRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> columnIndexRange(Adopt, toAXElement(thisObject)->columnIndexRange());
+ return JSValueMakeString(context, columnIndexRange.get());
+}
+
+static JSValueRef lineForIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ int indexNumber = -1;
+ if (argumentCount == 1)
+ indexNumber = JSValueToNumber(context, arguments[0], exception);
+
+ return JSValueMakeNumber(context, toAXElement(thisObject)->lineForIndex(indexNumber));
+}
+
+static JSValueRef boundsForRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ unsigned location = UINT_MAX, length = 0;
+ if (argumentCount == 2) {
+ location = JSValueToNumber(context, arguments[0], exception);
+ length = JSValueToNumber(context, arguments[1], exception);
+ }
+
+ JSRetainPtr<JSStringRef> boundsDescription(Adopt, toAXElement(thisObject)->boundsForRange(location, length));
+ return JSValueMakeString(context, boundsDescription.get());
+}
+
+static JSValueRef childAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ int indexNumber = -1;
+ if (argumentCount == 1)
+ indexNumber = JSValueToNumber(context, arguments[0], exception);
+
+ return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->getChildAtIndex(indexNumber));
+}
+
+static JSValueRef cellForColumnAndRowCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ unsigned column = 0, row = 0;
+ if (argumentCount == 2) {
+ column = JSValueToNumber(context, arguments[0], exception);
+ row = JSValueToNumber(context, arguments[1], exception);
+ }
+
+ return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->cellForColumnAndRow(column, row));
+}
+
+static JSValueRef titleUIElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->titleUIElement());
+}
+
+static JSValueRef setSelectedTextRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ unsigned location = UINT_MAX, length = 0;
+ if (argumentCount == 2) {
+ location = JSValueToNumber(context, arguments[0], exception);
+ length = JSValueToNumber(context, arguments[1], exception);
+ }
+
+ toAXElement(thisObject)->setSelectedTextRange(location, length);
+ return 0;
+}
+
+// Static Value Getters
+
+static JSValueRef getRoleCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> role(Adopt, toAXElement(thisObject)->role());
+ return JSValueMakeString(context, role.get());
+}
+
+static JSValueRef getTitleCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> title(Adopt, toAXElement(thisObject)->title());
+ return JSValueMakeString(context, title.get());
+}
+
+static JSValueRef getDescriptionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> description(Adopt, toAXElement(thisObject)->description());
+ return JSValueMakeString(context, description.get());
+}
+
+static JSValueRef getWidthCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ return JSValueMakeNumber(context, toAXElement(thisObject)->width());
+}
+
+static JSValueRef getHeightCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ return JSValueMakeNumber(context, toAXElement(thisObject)->height());
+}
+
+static JSValueRef getIntValueCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ return JSValueMakeNumber(context, toAXElement(thisObject)->intValue());
+}
+
+static JSValueRef getMinValueCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ return JSValueMakeNumber(context, toAXElement(thisObject)->minValue());
+}
+
+static JSValueRef getMaxValueCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ return JSValueMakeNumber(context, toAXElement(thisObject)->maxValue());
+}
+
+static JSValueRef getInsertionPointLineNumberCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ return JSValueMakeNumber(context, toAXElement(thisObject)->insertionPointLineNumber());
+}
+
+static JSValueRef getSelectedTextRangeCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> selectedTextRange(Adopt, toAXElement(thisObject)->selectedTextRange());
+ return JSValueMakeString(context, selectedTextRange.get());
+}
+
+static JSValueRef getSupportsPressActionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ return JSValueMakeBoolean(context, toAXElement(thisObject)->supportsPressAction());
+}
+
+// Destruction
+
+static void finalize(JSObjectRef thisObject)
+{
+ delete toAXElement(thisObject);
+}
+
+// Object Creation
+
+JSObjectRef AccessibilityUIElement::makeJSAccessibilityUIElement(JSContextRef context, const AccessibilityUIElement& element)
+{
+ return JSObjectMake(context, AccessibilityUIElement::getJSClass(), new AccessibilityUIElement(element));
+}
+
+JSClassRef AccessibilityUIElement::getJSClass()
+{
+ static JSStaticValue staticValues[] = {
+ { "role", getRoleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "title", getTitleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "description", getDescriptionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "width", getWidthCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "height", getHeightCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "intValue", getIntValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "minValue", getMinValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "maxValue", getMaxValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "insertionPointLineNumber", getInsertionPointLineNumberCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "selectedTextRange", getSelectedTextRangeCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "supportsPressAction", getSupportsPressActionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0, 0 }
+ };
+
+ static JSStaticFunction staticFunctions[] = {
+ { "allAttributes", allAttributesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfLinkedUIElements", attributesOfLinkedUIElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfDocumentLinks", attributesOfDocumentLinksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfChildren", attributesOfChildrenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "parameterizedAttributeNames", parameterizedAttributeNamesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "lineForIndex", lineForIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "boundsForRange", boundsForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfColumnHeaders", attributesOfColumnHeadersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfRowHeaders", attributesOfRowHeadersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfColumns", attributesOfColumnsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfRows", attributesOfRowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfVisibleCells", attributesOfVisibleCellsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfHeader", attributesOfHeaderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "indexInTable", indexInTableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "rowIndexRange", rowIndexRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "columnIndexRange", columnIndexRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "cellForColumnAndRow", cellForColumnAndRowCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "titleUIElement", titleUIElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setSelectedTextRange", setSelectedTextRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+ };
+
+ static JSClassDefinition classDefinition = {
+ 0, kJSClassAttributeNone, "AccessibilityUIElement", 0, staticValues, staticFunctions,
+ 0, finalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ static JSClassRef accessibilityUIElementClass = JSClassCreate(&classDefinition);
+ return accessibilityUIElementClass;
+}
diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
new file mode 100644
index 0000000..064829f
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2008 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. ``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.
+ */
+
+#ifndef AccessibilityUIElement_h
+#define AccessibilityUIElement_h
+
+#include <JavaScriptCore/JSObjectRef.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(MAC)
+#ifdef __OBJC__
+typedef id PlatformUIElement;
+#else
+typedef struct objc_object* PlatformUIElement;
+#endif
+#elif PLATFORM(WIN)
+#undef _WINSOCKAPI_
+#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h
+
+#include <oleacc.h>
+#include <WebCore/COMPtr.h>
+
+typedef COMPtr<IAccessible> PlatformUIElement;
+#else
+typedef void* PlatformUIElement;
+#endif
+
+class AccessibilityUIElement {
+public:
+ AccessibilityUIElement(PlatformUIElement);
+ AccessibilityUIElement(const AccessibilityUIElement&);
+ ~AccessibilityUIElement();
+
+ PlatformUIElement platformUIElement() { return m_element; }
+
+ static JSObjectRef makeJSAccessibilityUIElement(JSContextRef, const AccessibilityUIElement&);
+
+ void getLinkedUIElements(Vector<AccessibilityUIElement>&);
+ void getDocumentLinks(Vector<AccessibilityUIElement>&);
+ void getChildren(Vector<AccessibilityUIElement>&);
+ AccessibilityUIElement getChildAtIndex(unsigned);
+ AccessibilityUIElement titleUIElement();
+
+ // Methods - platform-independent implementations
+ JSStringRef allAttributes();
+ JSStringRef attributesOfLinkedUIElements();
+ JSStringRef attributesOfDocumentLinks();
+ JSStringRef attributesOfChildren();
+ JSStringRef parameterizedAttributeNames();
+
+ // Attributes - platform-independent implementations
+ JSStringRef role();
+ JSStringRef title();
+ JSStringRef description();
+ double width();
+ double height();
+ double intValue();
+ double minValue();
+ double maxValue();
+ int insertionPointLineNumber();
+ JSStringRef selectedTextRange();
+ bool supportsPressAction();
+
+ // Table-specific attributes
+ JSStringRef attributesOfColumnHeaders();
+ JSStringRef attributesOfRowHeaders();
+ JSStringRef attributesOfColumns();
+ JSStringRef attributesOfRows();
+ JSStringRef attributesOfVisibleCells();
+ JSStringRef attributesOfHeader();
+ int indexInTable();
+ JSStringRef rowIndexRange();
+ JSStringRef columnIndexRange();
+
+ // Parameterized attributes
+ int lineForIndex(int);
+ JSStringRef boundsForRange(unsigned location, unsigned length);
+ void setSelectedTextRange(unsigned location, unsigned length);
+
+ // Table-specific
+ AccessibilityUIElement cellForColumnAndRow(unsigned column, unsigned row);
+
+private:
+ static JSClassRef getJSClass();
+
+ PlatformUIElement m_element;
+};
+
+#endif // AccessibilityUIElement_h
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.h b/WebKitTools/DumpRenderTree/DumpRenderTree.h
new file mode 100644
index 0000000..9336a04
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006, 2007 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.
+ * 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 DumpRenderTree_h
+#define DumpRenderTree_h
+
+// FIXME: Remove this when all platforms are using config.h
+#ifndef Config_H
+#include <wtf/Platform.h>
+#endif
+
+#if PLATFORM(MAC)
+#include "DumpRenderTreeMac.h"
+#elif PLATFORM(WIN)
+#include "DumpRenderTreeWin.h"
+#elif PLATFORM(GTK)
+#include "DumpRenderTreeGtk.h"
+#endif
+
+#if PLATFORM(CF)
+#include <CoreFoundation/CoreFoundation.h>
+extern CFRunLoopTimerRef waitToDumpWatchdog;
+#endif
+
+#include <string>
+
+#if !PLATFORM(OPENBSD)
+std::wstring urlSuitableForTestResult(const std::wstring& url);
+#endif
+
+class LayoutTestController;
+
+extern volatile bool done;
+
+// FIXME: This is a bad abstraction. We should insted pass this to other controller objects which need access to it.
+extern LayoutTestController* gLayoutTestController;
+
+void dump();
+void displayWebView();
+
+#endif // DumpRenderTree_h
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.sln b/WebKitTools/DumpRenderTree/DumpRenderTree.sln
new file mode 100644
index 0000000..5a6a35f
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.sln
@@ -0,0 +1,47 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C++ Express 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DumpRenderTree", "win\DumpRenderTree.vcproj", "{6567DFD4-D6DE-4CD5-825D-17E353D160E1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestNetscapePlugin", "win\TestNetscapePlugin\TestNetscapePlugin.vcproj", "{C0737398-3565-439E-A2B8-AB2BE4D5430C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindSafari", "..\FindSafari\FindSafari.vcproj", "{DA31DA52-6675-48D4-89E0-333A7144397C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageDiff", "win\ImageDiff.vcproj", "{59CC0547-70AC-499C-9B19-EC01C6F61137}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_Internal|Win32 = Debug_Internal|Win32
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
+ {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Debug_Internal|Win32.Build.0 = Debug_Internal|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}.Release|Win32.ActiveCfg = Release|Win32
+ {6567DFD4-D6DE-4CD5-825D-17E353D160E1}.Release|Win32.Build.0 = Release|Win32
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Debug_Internal|Win32.Build.0 = Debug_Internal|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}.Release|Win32.ActiveCfg = Release|Win32
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C}.Release|Win32.Build.0 = Release|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_Internal|Win32.ActiveCfg = Debug|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug_Internal|Win32.Build.0 = Debug|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Debug|Win32.Build.0 = Debug|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release|Win32.ActiveCfg = Release|Win32
+ {DA31DA52-6675-48D4-89E0-333A7144397C}.Release|Win32.Build.0 = Release|Win32
+ {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug_Internal|Win32.ActiveCfg = Debug|Win32
+ {59CC0547-70AC-499C-9B19-EC01C6F61137}.Debug_Internal|Win32.Build.0 = Debug|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}.Release|Win32.ActiveCfg = Release|Win32
+ {59CC0547-70AC-499C-9B19-EC01C6F61137}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..ca7bdcd
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
@@ -0,0 +1,795 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ A84F608D08B1370600E9745F /* All */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = A84F609208B1371400E9745F /* Build configuration list for PBXAggregateTarget "All" */;
+ buildPhases = (
+ );
+ dependencies = (
+ A84F609108B1370E00E9745F /* PBXTargetDependency */,
+ A84F608F08B1370E00E9745F /* PBXTargetDependency */,
+ 141BF238096A451E00E0753C /* PBXTargetDependency */,
+ );
+ name = All;
+ productName = All;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 141BF435096A455900E0753C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9335435F03D75502008635CE /* WebKit.framework */; };
+ 141BF436096A455900E0753C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A84F608908B136DA00E9745F /* Cocoa.framework */; };
+ 141BF438096A455900E0753C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A817090308B164D300CCB9FB /* JavaScriptCore.framework */; };
+ 141BF439096A455900E0753C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE8257EF08D22389000507AB /* Carbon.framework */; };
+ 141BF453096A45EB00E0753C /* PluginObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 141BF447096A45C800E0753C /* PluginObject.h */; };
+ 14770FE20A22ADF7009342EE /* GCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 14770FE00A22ADF7009342EE /* GCController.h */; };
+ 1A8F02E80BB9B4EC008CFA34 /* TestObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8F024C0BB9B056008CFA34 /* TestObject.h */; };
+ 1AC6C8490D07638600CD3161 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C77F0D07589B00CD3161 /* main.cpp */; };
+ 1AC6C84A0D07638600CD3161 /* PluginObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C7800D07589B00CD3161 /* PluginObject.cpp */; };
+ 1AC6C84B0D07638600CD3161 /* TestObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C7810D07589B00CD3161 /* TestObject.cpp */; };
+ 23BCB8900EA57623003C6289 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23BCB88F0EA57623003C6289 /* OpenGL.framework */; };
+ 9340994C08540CAE007F3BC8 /* DumpRenderTreePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A70AAB03705E1F00C91783 /* DumpRenderTreePrefix.h */; };
+ 9340995108540CAE007F3BC8 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9335435F03D75502008635CE /* WebKit.framework */; };
+ A817090008B163EF00CCB9FB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A84F608908B136DA00E9745F /* Cocoa.framework */; };
+ A817090408B164D300CCB9FB /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A817090308B164D300CCB9FB /* JavaScriptCore.framework */; };
+ A84F608A08B136DA00E9745F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A84F608908B136DA00E9745F /* Cocoa.framework */; };
+ A8B91ADA0CF3B32F008F91FF /* DumpRenderTreePasteboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A8B91AD70CF3B32F008F91FF /* DumpRenderTreePasteboard.m */; };
+ A8B91ADC0CF3B32F008F91FF /* DumpRenderTreeWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = A8B91AD90CF3B32F008F91FF /* DumpRenderTreeWindow.mm */; };
+ A8B91AE00CF3B372008F91FF /* DumpRenderTreeWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B91ADD0CF3B372008F91FF /* DumpRenderTreeWindow.h */; };
+ A8B91AE20CF3B372008F91FF /* DumpRenderTreePasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B91ADF0CF3B372008F91FF /* DumpRenderTreePasteboard.h */; };
+ A8B91BFD0CF522B4008F91FF /* CheckedMalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8B91BF70CF522B4008F91FF /* CheckedMalloc.cpp */; };
+ A8B91BFF0CF522B4008F91FF /* CheckedMalloc.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B91BF90CF522B4008F91FF /* CheckedMalloc.h */; };
+ AE8259F308D22463000507AB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE8257EF08D22389000507AB /* Carbon.framework */; };
+ AE8259F408D22463000507AB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE8257EF08D22389000507AB /* Carbon.framework */; };
+ B5A752A208AF5D1F00138E45 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5A752A108AF5D1F00138E45 /* QuartzCore.framework */; };
+ BC0131DA0C9772010087317D /* LayoutTestController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0131D80C9772010087317D /* LayoutTestController.cpp */; };
+ BC0131DB0C9772010087317D /* LayoutTestController.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0131D90C9772010087317D /* LayoutTestController.h */; };
+ BC0E24E00E2D9451001B6BC2 /* AccessibilityUIElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0E24DE0E2D9451001B6BC2 /* AccessibilityUIElement.h */; };
+ BC0E24E10E2D9451001B6BC2 /* AccessibilityUIElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0E24DF0E2D9451001B6BC2 /* AccessibilityUIElement.cpp */; };
+ BC0E26150E2DA4C6001B6BC2 /* AccessibilityUIElementMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC0E26140E2DA4C6001B6BC2 /* AccessibilityUIElementMac.mm */; };
+ BC47412A0D038A4C0072B006 /* JavaScriptThreading.h in Headers */ = {isa = PBXBuildFile; fileRef = BC4741290D038A4C0072B006 /* JavaScriptThreading.h */; };
+ BC4741410D038A570072B006 /* JavaScriptThreadingPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC4741400D038A570072B006 /* JavaScriptThreadingPthreads.cpp */; };
+ BC9D90240C97472E0099A4A3 /* WorkQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */; };
+ BC9D90250C97472E0099A4A3 /* WorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9D90220C97472E0099A4A3 /* WorkQueue.h */; };
+ BC9D90260C97472E0099A4A3 /* WorkQueueItem.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9D90230C97472E0099A4A3 /* WorkQueueItem.h */; };
+ BCA18B230C9B014B00114369 /* GCControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B210C9B014B00114369 /* GCControllerMac.mm */; };
+ BCA18B240C9B014B00114369 /* LayoutTestControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B220C9B014B00114369 /* LayoutTestControllerMac.mm */; };
+ BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B250C9B015C00114369 /* WorkQueueItemMac.mm */; };
+ BCA18B310C9B01B400114369 /* ObjCController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B2F0C9B01B400114369 /* ObjCController.h */; };
+ BCA18B320C9B01B400114369 /* ObjCController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B300C9B01B400114369 /* ObjCController.m */; };
+ BCA18B380C9B021900114369 /* AppleScriptController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B360C9B021900114369 /* AppleScriptController.h */; };
+ BCA18B390C9B021900114369 /* AppleScriptController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B370C9B021900114369 /* AppleScriptController.m */; };
+ BCA18B3C0C9B024900114369 /* TextInputController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B3A0C9B024900114369 /* TextInputController.h */; };
+ BCA18B490C9B02C400114369 /* TextInputController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B480C9B02C400114369 /* TextInputController.m */; };
+ BCA18B610C9B08C200114369 /* EditingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B570C9B08C200114369 /* EditingDelegate.h */; };
+ BCA18B620C9B08C200114369 /* EditingDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B580C9B08C200114369 /* EditingDelegate.mm */; };
+ BCA18B630C9B08C200114369 /* FrameLoadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B590C9B08C200114369 /* FrameLoadDelegate.h */; };
+ BCA18B640C9B08C200114369 /* FrameLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5A0C9B08C200114369 /* FrameLoadDelegate.mm */; };
+ BCA18B650C9B08C200114369 /* PolicyDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B5B0C9B08C200114369 /* PolicyDelegate.h */; };
+ BCA18B660C9B08C200114369 /* PolicyDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5C0C9B08C200114369 /* PolicyDelegate.mm */; };
+ BCA18B670C9B08C200114369 /* ResourceLoadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B5D0C9B08C200114369 /* ResourceLoadDelegate.h */; };
+ BCA18B680C9B08C200114369 /* ResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B5E0C9B08C200114369 /* ResourceLoadDelegate.mm */; };
+ BCA18B690C9B08C200114369 /* UIDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B5F0C9B08C200114369 /* UIDelegate.h */; };
+ BCA18B6A0C9B08C200114369 /* UIDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B600C9B08C200114369 /* UIDelegate.mm */; };
+ BCA18B6F0C9B08DB00114369 /* EventSendingController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B6B0C9B08DB00114369 /* EventSendingController.h */; };
+ BCA18B700C9B08DB00114369 /* EventSendingController.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B6C0C9B08DB00114369 /* EventSendingController.mm */; };
+ BCA18B710C9B08DB00114369 /* NavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B6D0C9B08DB00114369 /* NavigationController.h */; };
+ BCA18B720C9B08DB00114369 /* NavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B6E0C9B08DB00114369 /* NavigationController.m */; };
+ BCA18B7A0C9B08F100114369 /* DumpRenderTreeDraggingInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B730C9B08F100114369 /* DumpRenderTreeDraggingInfo.h */; };
+ BCA18B7B0C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B740C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm */; };
+ BCA18B7D0C9B08F100114369 /* ObjCPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B760C9B08F100114369 /* ObjCPlugin.h */; };
+ BCA18B7E0C9B08F100114369 /* ObjCPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B770C9B08F100114369 /* ObjCPlugin.m */; };
+ BCA18B7F0C9B08F100114369 /* ObjCPluginFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18B780C9B08F100114369 /* ObjCPluginFunction.h */; };
+ BCA18B800C9B08F100114369 /* ObjCPluginFunction.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA18B790C9B08F100114369 /* ObjCPluginFunction.m */; };
+ BCA18C0B0C9B59EF00114369 /* DumpRenderTreeMac.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA18C0A0C9B59EF00114369 /* DumpRenderTreeMac.h */; };
+ BCA18C470C9B5B9400114369 /* DumpRenderTree.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCA18C460C9B5B9400114369 /* DumpRenderTree.mm */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
+ BCB284C70CFA83C4007E533E /* PixelDumpSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB2848A0CFA820F007E533E /* PixelDumpSupport.h */; };
+ BCB284CD0CFA83C8007E533E /* PixelDumpSupportCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB284880CFA8202007E533E /* PixelDumpSupportCG.cpp */; };
+ BCB284D00CFA83CC007E533E /* PixelDumpSupportCG.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB284890CFA8202007E533E /* PixelDumpSupportCG.h */; };
+ BCB284D60CFA83D1007E533E /* PixelDumpSupportMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCB2848C0CFA8221007E533E /* PixelDumpSupportMac.mm */; };
+ BCB284F60CFA84F8007E533E /* ImageDiffCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB284F30CFA84F2007E533E /* ImageDiffCG.cpp */; };
+ BCD08B3A0E1057EF00A7D0C1 /* AccessibilityController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */; };
+ BCD08B710E1059D200A7D0C1 /* AccessibilityControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */; };
+ BCF6C6500C98E9C000AC063E /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF6C64F0C98E9C000AC063E /* GCController.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 141BF237096A451E00E0753C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 141BF21E096A441D00E0753C;
+ remoteInfo = TestNetscapePlugIn;
+ };
+ A84F608E08B1370E00E9745F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B5A7525A08AF4A4A00138E45;
+ remoteInfo = ImageDiff;
+ };
+ A84F609008B1370E00E9745F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 9340994A08540CAE007F3BC8;
+ remoteInfo = DumpRenderTree;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 141BF233096A44CF00E0753C /* TestNetscapePlugIn.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestNetscapePlugIn.plugin; sourceTree = BUILT_PRODUCTS_DIR; };
+ 141BF447096A45C800E0753C /* PluginObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PluginObject.h; sourceTree = "<group>"; };
+ 141BF448096A45C800E0753C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 14770FE00A22ADF7009342EE /* GCController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCController.h; sourceTree = "<group>"; };
+ 1A8F024C0BB9B056008CFA34 /* TestObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestObject.h; sourceTree = "<group>"; };
+ 1AC6C77F0D07589B00CD3161 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ 1AC6C7800D07589B00CD3161 /* PluginObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginObject.cpp; sourceTree = "<group>"; };
+ 1AC6C7810D07589B00CD3161 /* TestObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestObject.cpp; sourceTree = "<group>"; };
+ 23BCB88F0EA57623003C6289 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
+ 32A70AAB03705E1F00C91783 /* DumpRenderTreePrefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DumpRenderTreePrefix.h; sourceTree = "<group>"; };
+ 375F09710DAC3CB600C8B4E5 /* WebKitWeightWatcher100.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher100.ttf; path = fonts/WebKitWeightWatcher100.ttf; sourceTree = "<group>"; };
+ 375F09720DAC3CB600C8B4E5 /* WebKitWeightWatcher200.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher200.ttf; path = fonts/WebKitWeightWatcher200.ttf; sourceTree = "<group>"; };
+ 375F09730DAC3CB600C8B4E5 /* WebKitWeightWatcher300.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher300.ttf; path = fonts/WebKitWeightWatcher300.ttf; sourceTree = "<group>"; };
+ 375F09740DAC3CB600C8B4E5 /* WebKitWeightWatcher400.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher400.ttf; path = fonts/WebKitWeightWatcher400.ttf; sourceTree = "<group>"; };
+ 375F09750DAC3CB600C8B4E5 /* WebKitWeightWatcher500.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher500.ttf; path = fonts/WebKitWeightWatcher500.ttf; sourceTree = "<group>"; };
+ 375F09760DAC3CB600C8B4E5 /* WebKitWeightWatcher600.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher600.ttf; path = fonts/WebKitWeightWatcher600.ttf; sourceTree = "<group>"; };
+ 375F09770DAC3CB600C8B4E5 /* WebKitWeightWatcher700.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher700.ttf; path = fonts/WebKitWeightWatcher700.ttf; sourceTree = "<group>"; };
+ 375F09780DAC3CB600C8B4E5 /* WebKitWeightWatcher800.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher800.ttf; path = fonts/WebKitWeightWatcher800.ttf; sourceTree = "<group>"; };
+ 375F09790DAC3CB600C8B4E5 /* WebKitWeightWatcher900.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher900.ttf; path = fonts/WebKitWeightWatcher900.ttf; sourceTree = "<group>"; };
+ 9335435F03D75502008635CE /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9340995408540CAF007F3BC8 /* DumpRenderTree */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = DumpRenderTree; sourceTree = BUILT_PRODUCTS_DIR; };
+ A803FF7409CAAD08009B2A37 /* DumpRenderTree.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = DumpRenderTree.h; sourceTree = "<group>"; };
+ A817090308B164D300CCB9FB /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = JavaScriptCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ A84F608908B136DA00E9745F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ A8B91AD70CF3B32F008F91FF /* DumpRenderTreePasteboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DumpRenderTreePasteboard.m; path = mac/DumpRenderTreePasteboard.m; sourceTree = "<group>"; };
+ A8B91AD90CF3B32F008F91FF /* DumpRenderTreeWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = DumpRenderTreeWindow.mm; path = mac/DumpRenderTreeWindow.mm; sourceTree = "<group>"; };
+ A8B91ADD0CF3B372008F91FF /* DumpRenderTreeWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreeWindow.h; path = mac/DumpRenderTreeWindow.h; sourceTree = "<group>"; };
+ A8B91ADF0CF3B372008F91FF /* DumpRenderTreePasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreePasteboard.h; path = mac/DumpRenderTreePasteboard.h; sourceTree = "<group>"; };
+ A8B91BF70CF522B4008F91FF /* CheckedMalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckedMalloc.cpp; path = mac/CheckedMalloc.cpp; sourceTree = "<group>"; };
+ A8B91BF90CF522B4008F91FF /* CheckedMalloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CheckedMalloc.h; path = mac/CheckedMalloc.h; sourceTree = "<group>"; };
+ AA7F10C20CB3C1030003BDC9 /* AHEM____.TTF */ = {isa = PBXFileReference; lastKnownFileType = file; name = "AHEM____.TTF"; path = "qt/fonts/AHEM____.TTF"; sourceTree = "<group>"; };
+ AE8257EF08D22389000507AB /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
+ B5A7526708AF4A4A00138E45 /* ImageDiff */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ImageDiff; sourceTree = BUILT_PRODUCTS_DIR; };
+ B5A752A108AF5D1F00138E45 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; };
+ BC0131D80C9772010087317D /* LayoutTestController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = LayoutTestController.cpp; sourceTree = "<group>"; };
+ BC0131D90C9772010087317D /* LayoutTestController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LayoutTestController.h; sourceTree = "<group>"; };
+ BC0E24DE0E2D9451001B6BC2 /* AccessibilityUIElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityUIElement.h; sourceTree = "<group>"; };
+ BC0E24DF0E2D9451001B6BC2 /* AccessibilityUIElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityUIElement.cpp; sourceTree = "<group>"; };
+ BC0E26140E2DA4C6001B6BC2 /* AccessibilityUIElementMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityUIElementMac.mm; path = mac/AccessibilityUIElementMac.mm; sourceTree = "<group>"; };
+ BC4741290D038A4C0072B006 /* JavaScriptThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptThreading.h; sourceTree = "<group>"; };
+ BC4741400D038A570072B006 /* JavaScriptThreadingPthreads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JavaScriptThreadingPthreads.cpp; path = pthreads/JavaScriptThreadingPthreads.cpp; sourceTree = "<group>"; };
+ BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = WorkQueue.cpp; sourceTree = "<group>"; };
+ BC9D90220C97472E0099A4A3 /* WorkQueue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WorkQueue.h; sourceTree = "<group>"; };
+ BC9D90230C97472E0099A4A3 /* WorkQueueItem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WorkQueueItem.h; sourceTree = "<group>"; };
+ BCA18B210C9B014B00114369 /* GCControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = GCControllerMac.mm; path = mac/GCControllerMac.mm; sourceTree = "<group>"; };
+ BCA18B220C9B014B00114369 /* LayoutTestControllerMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = LayoutTestControllerMac.mm; path = mac/LayoutTestControllerMac.mm; sourceTree = "<group>"; };
+ BCA18B250C9B015C00114369 /* WorkQueueItemMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = WorkQueueItemMac.mm; path = mac/WorkQueueItemMac.mm; sourceTree = "<group>"; };
+ BCA18B2F0C9B01B400114369 /* ObjCController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ObjCController.h; path = mac/ObjCController.h; sourceTree = "<group>"; };
+ BCA18B300C9B01B400114369 /* ObjCController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = ObjCController.m; path = mac/ObjCController.m; sourceTree = "<group>"; };
+ BCA18B360C9B021900114369 /* AppleScriptController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleScriptController.h; path = mac/AppleScriptController.h; sourceTree = "<group>"; };
+ BCA18B370C9B021900114369 /* AppleScriptController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = AppleScriptController.m; path = mac/AppleScriptController.m; sourceTree = "<group>"; };
+ BCA18B3A0C9B024900114369 /* TextInputController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextInputController.h; path = mac/TextInputController.h; sourceTree = "<group>"; };
+ BCA18B480C9B02C400114369 /* TextInputController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = TextInputController.m; path = mac/TextInputController.m; sourceTree = "<group>"; };
+ BCA18B570C9B08C200114369 /* EditingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = EditingDelegate.h; path = mac/EditingDelegate.h; sourceTree = "<group>"; };
+ BCA18B580C9B08C200114369 /* EditingDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = EditingDelegate.mm; path = mac/EditingDelegate.mm; sourceTree = "<group>"; };
+ BCA18B590C9B08C200114369 /* FrameLoadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FrameLoadDelegate.h; path = mac/FrameLoadDelegate.h; sourceTree = "<group>"; };
+ BCA18B5A0C9B08C200114369 /* FrameLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = FrameLoadDelegate.mm; path = mac/FrameLoadDelegate.mm; sourceTree = "<group>"; };
+ BCA18B5B0C9B08C200114369 /* PolicyDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PolicyDelegate.h; path = mac/PolicyDelegate.h; sourceTree = "<group>"; };
+ BCA18B5C0C9B08C200114369 /* PolicyDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = PolicyDelegate.mm; path = mac/PolicyDelegate.mm; sourceTree = "<group>"; };
+ BCA18B5D0C9B08C200114369 /* ResourceLoadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ResourceLoadDelegate.h; path = mac/ResourceLoadDelegate.h; sourceTree = "<group>"; };
+ BCA18B5E0C9B08C200114369 /* ResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = ResourceLoadDelegate.mm; path = mac/ResourceLoadDelegate.mm; sourceTree = "<group>"; };
+ BCA18B5F0C9B08C200114369 /* UIDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UIDelegate.h; path = mac/UIDelegate.h; sourceTree = "<group>"; };
+ BCA18B600C9B08C200114369 /* UIDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = UIDelegate.mm; path = mac/UIDelegate.mm; sourceTree = "<group>"; };
+ BCA18B6B0C9B08DB00114369 /* EventSendingController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = EventSendingController.h; path = mac/EventSendingController.h; sourceTree = "<group>"; };
+ BCA18B6C0C9B08DB00114369 /* EventSendingController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = EventSendingController.mm; path = mac/EventSendingController.mm; sourceTree = "<group>"; };
+ BCA18B6D0C9B08DB00114369 /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NavigationController.h; path = mac/NavigationController.h; sourceTree = "<group>"; };
+ BCA18B6E0C9B08DB00114369 /* NavigationController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = NavigationController.m; path = mac/NavigationController.m; sourceTree = "<group>"; };
+ BCA18B730C9B08F100114369 /* DumpRenderTreeDraggingInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreeDraggingInfo.h; path = mac/DumpRenderTreeDraggingInfo.h; sourceTree = "<group>"; };
+ BCA18B740C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = DumpRenderTreeDraggingInfo.mm; path = mac/DumpRenderTreeDraggingInfo.mm; sourceTree = "<group>"; };
+ BCA18B760C9B08F100114369 /* ObjCPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ObjCPlugin.h; path = mac/ObjCPlugin.h; sourceTree = "<group>"; };
+ BCA18B770C9B08F100114369 /* ObjCPlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = ObjCPlugin.m; path = mac/ObjCPlugin.m; sourceTree = "<group>"; };
+ BCA18B780C9B08F100114369 /* ObjCPluginFunction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ObjCPluginFunction.h; path = mac/ObjCPluginFunction.h; sourceTree = "<group>"; };
+ BCA18B790C9B08F100114369 /* ObjCPluginFunction.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = ObjCPluginFunction.m; path = mac/ObjCPluginFunction.m; sourceTree = "<group>"; };
+ BCA18C0A0C9B59EF00114369 /* DumpRenderTreeMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreeMac.h; path = mac/DumpRenderTreeMac.h; sourceTree = "<group>"; };
+ BCA18C460C9B5B9400114369 /* DumpRenderTree.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = DumpRenderTree.mm; path = mac/DumpRenderTree.mm; sourceTree = "<group>"; };
+ BCB281EE0CFA713D007E533E /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = Base.xcconfig; path = mac/Configurations/Base.xcconfig; sourceTree = "<group>"; };
+ BCB281F00CFA713D007E533E /* DumpRenderTree.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = DumpRenderTree.xcconfig; path = mac/Configurations/DumpRenderTree.xcconfig; sourceTree = "<group>"; };
+ BCB282F40CFA7450007E533E /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = DebugRelease.xcconfig; path = mac/Configurations/DebugRelease.xcconfig; sourceTree = "<group>"; };
+ BCB283D80CFA7AFD007E533E /* ImageDiff.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = ImageDiff.xcconfig; path = mac/Configurations/ImageDiff.xcconfig; sourceTree = "<group>"; };
+ BCB283DE0CFA7C20007E533E /* TestNetscapePlugIn.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = TestNetscapePlugIn.xcconfig; path = mac/Configurations/TestNetscapePlugIn.xcconfig; sourceTree = "<group>"; };
+ BCB284880CFA8202007E533E /* PixelDumpSupportCG.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; name = PixelDumpSupportCG.cpp; path = cg/PixelDumpSupportCG.cpp; sourceTree = "<group>"; };
+ BCB284890CFA8202007E533E /* PixelDumpSupportCG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PixelDumpSupportCG.h; path = cg/PixelDumpSupportCG.h; sourceTree = "<group>"; };
+ BCB2848A0CFA820F007E533E /* PixelDumpSupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PixelDumpSupport.h; sourceTree = "<group>"; };
+ BCB2848C0CFA8221007E533E /* PixelDumpSupportMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = PixelDumpSupportMac.mm; path = mac/PixelDumpSupportMac.mm; sourceTree = "<group>"; };
+ BCB284B20CFA82CB007E533E /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
+ BCB284F30CFA84F2007E533E /* ImageDiffCG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ImageDiffCG.cpp; path = cg/ImageDiffCG.cpp; sourceTree = "<group>"; };
+ BCD08A580E10496B00A7D0C1 /* AccessibilityController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityController.h; sourceTree = "<group>"; };
+ BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityController.cpp; sourceTree = "<group>"; };
+ BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityControllerMac.mm; path = mac/AccessibilityControllerMac.mm; sourceTree = "<group>"; };
+ BCF6C64F0C98E9C000AC063E /* GCController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = GCController.cpp; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 141BF21D096A441D00E0753C /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 141BF439096A455900E0753C /* Carbon.framework in Frameworks */,
+ 141BF436096A455900E0753C /* Cocoa.framework in Frameworks */,
+ 141BF438096A455900E0753C /* JavaScriptCore.framework in Frameworks */,
+ 141BF435096A455900E0753C /* WebKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 9340994F08540CAE007F3BC8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AE8259F308D22463000507AB /* Carbon.framework in Frameworks */,
+ A84F608A08B136DA00E9745F /* Cocoa.framework in Frameworks */,
+ A817090408B164D300CCB9FB /* JavaScriptCore.framework in Frameworks */,
+ 9340995108540CAE007F3BC8 /* WebKit.framework in Frameworks */,
+ 23BCB8900EA57623003C6289 /* OpenGL.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B5A7525F08AF4A4A00138E45 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AE8259F408D22463000507AB /* Carbon.framework in Frameworks */,
+ A817090008B163EF00CCB9FB /* Cocoa.framework in Frameworks */,
+ B5A752A208AF5D1F00138E45 /* QuartzCore.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 08FB7794FE84155DC02AAC07 /* DumpRenderTree */ = {
+ isa = PBXGroup;
+ children = (
+ 32A70AAB03705E1F00C91783 /* DumpRenderTreePrefix.h */,
+ 1422A2750AF6F4BD00E1A883 /* Delegates */,
+ 1422A2690AF6F45200E1A883 /* Controllers */,
+ BCB284870CFA81ED007E533E /* PixelDump */,
+ A803FF7409CAAD08009B2A37 /* DumpRenderTree.h */,
+ BCA18C460C9B5B9400114369 /* DumpRenderTree.mm */,
+ A8B91BF70CF522B4008F91FF /* CheckedMalloc.cpp */,
+ A8B91BF90CF522B4008F91FF /* CheckedMalloc.h */,
+ BC4741290D038A4C0072B006 /* JavaScriptThreading.h */,
+ BC4741400D038A570072B006 /* JavaScriptThreadingPthreads.cpp */,
+ BCA18C0A0C9B59EF00114369 /* DumpRenderTreeMac.h */,
+ BCA18B730C9B08F100114369 /* DumpRenderTreeDraggingInfo.h */,
+ BCA18B740C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm */,
+ BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */,
+ BC9D90220C97472E0099A4A3 /* WorkQueue.h */,
+ BC9D90230C97472E0099A4A3 /* WorkQueueItem.h */,
+ A8B91AD20CF3B305008F91FF /* AppKit Overrides */,
+ A8B91AC40CF3B170008F91FF /* ObjCPlugin */,
+ 141BF1F5096A439800E0753C /* TestNetscapePlugIn.subproj */,
+ 9345229B0BD12B2C0086EDA0 /* Resources */,
+ A803FF6409CAACC1009B2A37 /* Frameworks */,
+ 9340995508540CAF007F3BC8 /* Products */,
+ BCB281ED0CFA711D007E533E /* Configurations */,
+ );
+ name = DumpRenderTree;
+ sourceTree = "<group>";
+ };
+ 141BF1F5096A439800E0753C /* TestNetscapePlugIn.subproj */ = {
+ isa = PBXGroup;
+ children = (
+ 1AC6C77F0D07589B00CD3161 /* main.cpp */,
+ 1AC6C7800D07589B00CD3161 /* PluginObject.cpp */,
+ 141BF447096A45C800E0753C /* PluginObject.h */,
+ 1AC6C7810D07589B00CD3161 /* TestObject.cpp */,
+ 1A8F024C0BB9B056008CFA34 /* TestObject.h */,
+ 141BF448096A45C800E0753C /* Info.plist */,
+ );
+ path = TestNetscapePlugIn.subproj;
+ sourceTree = "<group>";
+ };
+ 1422A2690AF6F45200E1A883 /* Controllers */ = {
+ isa = PBXGroup;
+ children = (
+ BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */,
+ BCD08A580E10496B00A7D0C1 /* AccessibilityController.h */,
+ BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */,
+ BC0E24DF0E2D9451001B6BC2 /* AccessibilityUIElement.cpp */,
+ BC0E24DE0E2D9451001B6BC2 /* AccessibilityUIElement.h */,
+ BC0E26140E2DA4C6001B6BC2 /* AccessibilityUIElementMac.mm */,
+ BCA18B360C9B021900114369 /* AppleScriptController.h */,
+ BCA18B370C9B021900114369 /* AppleScriptController.m */,
+ BCA18B6B0C9B08DB00114369 /* EventSendingController.h */,
+ BCA18B6C0C9B08DB00114369 /* EventSendingController.mm */,
+ BCF6C64F0C98E9C000AC063E /* GCController.cpp */,
+ 14770FE00A22ADF7009342EE /* GCController.h */,
+ BCA18B210C9B014B00114369 /* GCControllerMac.mm */,
+ BC0131D80C9772010087317D /* LayoutTestController.cpp */,
+ BC0131D90C9772010087317D /* LayoutTestController.h */,
+ BCA18B220C9B014B00114369 /* LayoutTestControllerMac.mm */,
+ BCA18B6D0C9B08DB00114369 /* NavigationController.h */,
+ BCA18B6E0C9B08DB00114369 /* NavigationController.m */,
+ BCA18B2F0C9B01B400114369 /* ObjCController.h */,
+ BCA18B300C9B01B400114369 /* ObjCController.m */,
+ BCA18B3A0C9B024900114369 /* TextInputController.h */,
+ BCA18B480C9B02C400114369 /* TextInputController.m */,
+ );
+ name = Controllers;
+ sourceTree = "<group>";
+ usesTabs = 0;
+ };
+ 1422A2750AF6F4BD00E1A883 /* Delegates */ = {
+ isa = PBXGroup;
+ children = (
+ BCA18B570C9B08C200114369 /* EditingDelegate.h */,
+ BCA18B580C9B08C200114369 /* EditingDelegate.mm */,
+ BCA18B590C9B08C200114369 /* FrameLoadDelegate.h */,
+ BCA18B5A0C9B08C200114369 /* FrameLoadDelegate.mm */,
+ BCA18B5B0C9B08C200114369 /* PolicyDelegate.h */,
+ BCA18B5C0C9B08C200114369 /* PolicyDelegate.mm */,
+ BCA18B5D0C9B08C200114369 /* ResourceLoadDelegate.h */,
+ BCA18B5E0C9B08C200114369 /* ResourceLoadDelegate.mm */,
+ BCA18B5F0C9B08C200114369 /* UIDelegate.h */,
+ BCA18B600C9B08C200114369 /* UIDelegate.mm */,
+ );
+ name = Delegates;
+ sourceTree = "<group>";
+ };
+ 9340995508540CAF007F3BC8 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 9340995408540CAF007F3BC8 /* DumpRenderTree */,
+ B5A7526708AF4A4A00138E45 /* ImageDiff */,
+ 141BF233096A44CF00E0753C /* TestNetscapePlugIn.plugin */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 9345229B0BD12B2C0086EDA0 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 375F09710DAC3CB600C8B4E5 /* WebKitWeightWatcher100.ttf */,
+ 375F09720DAC3CB600C8B4E5 /* WebKitWeightWatcher200.ttf */,
+ 375F09730DAC3CB600C8B4E5 /* WebKitWeightWatcher300.ttf */,
+ 375F09740DAC3CB600C8B4E5 /* WebKitWeightWatcher400.ttf */,
+ 375F09750DAC3CB600C8B4E5 /* WebKitWeightWatcher500.ttf */,
+ 375F09760DAC3CB600C8B4E5 /* WebKitWeightWatcher600.ttf */,
+ 375F09770DAC3CB600C8B4E5 /* WebKitWeightWatcher700.ttf */,
+ 375F09780DAC3CB600C8B4E5 /* WebKitWeightWatcher800.ttf */,
+ 375F09790DAC3CB600C8B4E5 /* WebKitWeightWatcher900.ttf */,
+ AA7F10C20CB3C1030003BDC9 /* AHEM____.TTF */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ A803FF6409CAACC1009B2A37 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ BCB284B20CFA82CB007E533E /* ApplicationServices.framework */,
+ AE8257EF08D22389000507AB /* Carbon.framework */,
+ A84F608908B136DA00E9745F /* Cocoa.framework */,
+ A817090308B164D300CCB9FB /* JavaScriptCore.framework */,
+ B5A752A108AF5D1F00138E45 /* QuartzCore.framework */,
+ 9335435F03D75502008635CE /* WebKit.framework */,
+ 23BCB88F0EA57623003C6289 /* OpenGL.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ A8B91AC40CF3B170008F91FF /* ObjCPlugin */ = {
+ isa = PBXGroup;
+ children = (
+ BCA18B250C9B015C00114369 /* WorkQueueItemMac.mm */,
+ BCA18B760C9B08F100114369 /* ObjCPlugin.h */,
+ BCA18B770C9B08F100114369 /* ObjCPlugin.m */,
+ BCA18B780C9B08F100114369 /* ObjCPluginFunction.h */,
+ BCA18B790C9B08F100114369 /* ObjCPluginFunction.m */,
+ );
+ name = ObjCPlugin;
+ sourceTree = "<group>";
+ };
+ A8B91AD20CF3B305008F91FF /* AppKit Overrides */ = {
+ isa = PBXGroup;
+ children = (
+ A8B91ADF0CF3B372008F91FF /* DumpRenderTreePasteboard.h */,
+ A8B91AD70CF3B32F008F91FF /* DumpRenderTreePasteboard.m */,
+ A8B91ADD0CF3B372008F91FF /* DumpRenderTreeWindow.h */,
+ A8B91AD90CF3B32F008F91FF /* DumpRenderTreeWindow.mm */,
+ );
+ name = "AppKit Overrides";
+ sourceTree = "<group>";
+ };
+ BCB281ED0CFA711D007E533E /* Configurations */ = {
+ isa = PBXGroup;
+ children = (
+ BCB281EE0CFA713D007E533E /* Base.xcconfig */,
+ BCB282F40CFA7450007E533E /* DebugRelease.xcconfig */,
+ BCB281F00CFA713D007E533E /* DumpRenderTree.xcconfig */,
+ BCB283D80CFA7AFD007E533E /* ImageDiff.xcconfig */,
+ BCB283DE0CFA7C20007E533E /* TestNetscapePlugIn.xcconfig */,
+ );
+ name = Configurations;
+ sourceTree = "<group>";
+ };
+ BCB284870CFA81ED007E533E /* PixelDump */ = {
+ isa = PBXGroup;
+ children = (
+ BCB284F30CFA84F2007E533E /* ImageDiffCG.cpp */,
+ BCB2848A0CFA820F007E533E /* PixelDumpSupport.h */,
+ BCB284880CFA8202007E533E /* PixelDumpSupportCG.cpp */,
+ BCB284890CFA8202007E533E /* PixelDumpSupportCG.h */,
+ BCB2848C0CFA8221007E533E /* PixelDumpSupportMac.mm */,
+ );
+ name = PixelDump;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 141BF44E096A45DD00E0753C /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 141BF453096A45EB00E0753C /* PluginObject.h in Headers */,
+ 1A8F02E80BB9B4EC008CFA34 /* TestObject.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 9340994B08540CAE007F3BC8 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BCA18B380C9B021900114369 /* AppleScriptController.h in Headers */,
+ BCA18B7A0C9B08F100114369 /* DumpRenderTreeDraggingInfo.h in Headers */,
+ BCA18C0B0C9B59EF00114369 /* DumpRenderTreeMac.h in Headers */,
+ 9340994C08540CAE007F3BC8 /* DumpRenderTreePrefix.h in Headers */,
+ BCA18B610C9B08C200114369 /* EditingDelegate.h in Headers */,
+ BCA18B6F0C9B08DB00114369 /* EventSendingController.h in Headers */,
+ BCA18B630C9B08C200114369 /* FrameLoadDelegate.h in Headers */,
+ 14770FE20A22ADF7009342EE /* GCController.h in Headers */,
+ BC0131DB0C9772010087317D /* LayoutTestController.h in Headers */,
+ BCA18B710C9B08DB00114369 /* NavigationController.h in Headers */,
+ BCA18B310C9B01B400114369 /* ObjCController.h in Headers */,
+ BCA18B7D0C9B08F100114369 /* ObjCPlugin.h in Headers */,
+ BCA18B7F0C9B08F100114369 /* ObjCPluginFunction.h in Headers */,
+ BCA18B650C9B08C200114369 /* PolicyDelegate.h in Headers */,
+ BCA18B670C9B08C200114369 /* ResourceLoadDelegate.h in Headers */,
+ BCA18B3C0C9B024900114369 /* TextInputController.h in Headers */,
+ BCA18B690C9B08C200114369 /* UIDelegate.h in Headers */,
+ BC9D90250C97472E0099A4A3 /* WorkQueue.h in Headers */,
+ BC9D90260C97472E0099A4A3 /* WorkQueueItem.h in Headers */,
+ A8B91AE00CF3B372008F91FF /* DumpRenderTreeWindow.h in Headers */,
+ A8B91AE20CF3B372008F91FF /* DumpRenderTreePasteboard.h in Headers */,
+ A8B91BFF0CF522B4008F91FF /* CheckedMalloc.h in Headers */,
+ BCB284C70CFA83C4007E533E /* PixelDumpSupport.h in Headers */,
+ BCB284D00CFA83CC007E533E /* PixelDumpSupportCG.h in Headers */,
+ BC47412A0D038A4C0072B006 /* JavaScriptThreading.h in Headers */,
+ BC0E24E00E2D9451001B6BC2 /* AccessibilityUIElement.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B5A7525B08AF4A4A00138E45 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 141BF21E096A441D00E0753C /* TestNetscapePlugIn */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 141BF221096A441E00E0753C /* Build configuration list for PBXNativeTarget "TestNetscapePlugIn" */;
+ buildPhases = (
+ 141BF21B096A441D00E0753C /* Resources */,
+ 141BF44E096A45DD00E0753C /* Headers */,
+ 141BF21C096A441D00E0753C /* Sources */,
+ 141BF21D096A441D00E0753C /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = TestNetscapePlugIn;
+ productName = TestNetscapePlugIn.plugin;
+ productReference = 141BF233096A44CF00E0753C /* TestNetscapePlugIn.plugin */;
+ productType = "com.apple.product-type.bundle";
+ };
+ 9340994A08540CAE007F3BC8 /* DumpRenderTree */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 149C29BF08902C6D008A9EFC /* Build configuration list for PBXNativeTarget "DumpRenderTree" */;
+ buildPhases = (
+ 9340994B08540CAE007F3BC8 /* Headers */,
+ 9340994D08540CAE007F3BC8 /* Sources */,
+ 9340994F08540CAE007F3BC8 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DumpRenderTree;
+ productInstallPath = "$(HOME)/bin";
+ productName = DumpRenderTree;
+ productReference = 9340995408540CAF007F3BC8 /* DumpRenderTree */;
+ productType = "com.apple.product-type.tool";
+ };
+ B5A7525A08AF4A4A00138E45 /* ImageDiff */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B5A7526408AF4A4A00138E45 /* Build configuration list for PBXNativeTarget "ImageDiff" */;
+ buildPhases = (
+ B5A7525B08AF4A4A00138E45 /* Headers */,
+ B5A7525D08AF4A4A00138E45 /* Sources */,
+ B5A7525F08AF4A4A00138E45 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ImageDiff;
+ productInstallPath = "$(HOME)/bin";
+ productName = DumpRenderTree;
+ productReference = B5A7526708AF4A4A00138E45 /* ImageDiff */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 08FB7793FE84155DC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 149C29C308902C6D008A9EFC /* Build configuration list for PBXProject "DumpRenderTree" */;
+ compatibilityVersion = "Xcode 2.4";
+ hasScannedForEncodings = 1;
+ mainGroup = 08FB7794FE84155DC02AAC07 /* DumpRenderTree */;
+ productRefGroup = 9340995508540CAF007F3BC8 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ A84F608D08B1370600E9745F /* All */,
+ 9340994A08540CAE007F3BC8 /* DumpRenderTree */,
+ B5A7525A08AF4A4A00138E45 /* ImageDiff */,
+ 141BF21E096A441D00E0753C /* TestNetscapePlugIn */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 141BF21B096A441D00E0753C /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 141BF21C096A441D00E0753C /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1AC6C8490D07638600CD3161 /* main.cpp in Sources */,
+ 1AC6C84A0D07638600CD3161 /* PluginObject.cpp in Sources */,
+ 1AC6C84B0D07638600CD3161 /* TestObject.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 9340994D08540CAE007F3BC8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BCA18B390C9B021900114369 /* AppleScriptController.m in Sources */,
+ BCA18C470C9B5B9400114369 /* DumpRenderTree.mm in Sources */,
+ BCA18B7B0C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm in Sources */,
+ BCA18B620C9B08C200114369 /* EditingDelegate.mm in Sources */,
+ BCA18B700C9B08DB00114369 /* EventSendingController.mm in Sources */,
+ BCA18B640C9B08C200114369 /* FrameLoadDelegate.mm in Sources */,
+ BCF6C6500C98E9C000AC063E /* GCController.cpp in Sources */,
+ BCA18B230C9B014B00114369 /* GCControllerMac.mm in Sources */,
+ BC0131DA0C9772010087317D /* LayoutTestController.cpp in Sources */,
+ BCA18B240C9B014B00114369 /* LayoutTestControllerMac.mm in Sources */,
+ BCA18B720C9B08DB00114369 /* NavigationController.m in Sources */,
+ BCA18B320C9B01B400114369 /* ObjCController.m in Sources */,
+ BCA18B7E0C9B08F100114369 /* ObjCPlugin.m in Sources */,
+ BCA18B800C9B08F100114369 /* ObjCPluginFunction.m in Sources */,
+ BCA18B660C9B08C200114369 /* PolicyDelegate.mm in Sources */,
+ BCA18B680C9B08C200114369 /* ResourceLoadDelegate.mm in Sources */,
+ BCA18B490C9B02C400114369 /* TextInputController.m in Sources */,
+ BCA18B6A0C9B08C200114369 /* UIDelegate.mm in Sources */,
+ BC9D90240C97472E0099A4A3 /* WorkQueue.cpp in Sources */,
+ BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */,
+ A8B91ADA0CF3B32F008F91FF /* DumpRenderTreePasteboard.m in Sources */,
+ A8B91ADC0CF3B32F008F91FF /* DumpRenderTreeWindow.mm in Sources */,
+ A8B91BFD0CF522B4008F91FF /* CheckedMalloc.cpp in Sources */,
+ BCB284CD0CFA83C8007E533E /* PixelDumpSupportCG.cpp in Sources */,
+ BCB284D60CFA83D1007E533E /* PixelDumpSupportMac.mm in Sources */,
+ BC4741410D038A570072B006 /* JavaScriptThreadingPthreads.cpp in Sources */,
+ BCD08B3A0E1057EF00A7D0C1 /* AccessibilityController.cpp in Sources */,
+ BCD08B710E1059D200A7D0C1 /* AccessibilityControllerMac.mm in Sources */,
+ BC0E24E10E2D9451001B6BC2 /* AccessibilityUIElement.cpp in Sources */,
+ BC0E26150E2DA4C6001B6BC2 /* AccessibilityUIElementMac.mm in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B5A7525D08AF4A4A00138E45 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BCB284F60CFA84F8007E533E /* ImageDiffCG.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 141BF238096A451E00E0753C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 141BF21E096A441D00E0753C /* TestNetscapePlugIn */;
+ targetProxy = 141BF237096A451E00E0753C /* PBXContainerItemProxy */;
+ };
+ A84F608F08B1370E00E9745F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B5A7525A08AF4A4A00138E45 /* ImageDiff */;
+ targetProxy = A84F608E08B1370E00E9745F /* PBXContainerItemProxy */;
+ };
+ A84F609108B1370E00E9745F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 9340994A08540CAE007F3BC8 /* DumpRenderTree */;
+ targetProxy = A84F609008B1370E00E9745F /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 141BF222096A441E00E0753C /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB283DE0CFA7C20007E533E /* TestNetscapePlugIn.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 141BF223096A441E00E0753C /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB283DE0CFA7C20007E533E /* TestNetscapePlugIn.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ 149C29C008902C6D008A9EFC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB281F00CFA713D007E533E /* DumpRenderTree.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 149C29C108902C6D008A9EFC /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB281F00CFA713D007E533E /* DumpRenderTree.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ 149C29C408902C6D008A9EFC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB282F40CFA7450007E533E /* DebugRelease.xcconfig */;
+ buildSettings = {
+ GCC_OPTIMIZATION_LEVEL = 0;
+ };
+ name = Debug;
+ };
+ 149C29C508902C6D008A9EFC /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB282F40CFA7450007E533E /* DebugRelease.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ A84F609308B1371400E9745F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ OTHER_CFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = All;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = Debug;
+ };
+ A84F609408B1371400E9745F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ OTHER_CFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = All;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = Release;
+ };
+ B5A7526508AF4A4A00138E45 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB283D80CFA7AFD007E533E /* ImageDiff.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ B5A7526608AF4A4A00138E45 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = BCB283D80CFA7AFD007E533E /* ImageDiff.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 141BF221096A441E00E0753C /* Build configuration list for PBXNativeTarget "TestNetscapePlugIn" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 141BF222096A441E00E0753C /* Debug */,
+ 141BF223096A441E00E0753C /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 149C29BF08902C6D008A9EFC /* Build configuration list for PBXNativeTarget "DumpRenderTree" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 149C29C008902C6D008A9EFC /* Debug */,
+ 149C29C108902C6D008A9EFC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 149C29C308902C6D008A9EFC /* Build configuration list for PBXProject "DumpRenderTree" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 149C29C408902C6D008A9EFC /* Debug */,
+ 149C29C508902C6D008A9EFC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A84F609208B1371400E9745F /* Build configuration list for PBXAggregateTarget "All" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A84F609308B1371400E9745F /* Debug */,
+ A84F609408B1371400E9745F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B5A7526408AF4A4A00138E45 /* Build configuration list for PBXNativeTarget "ImageDiff" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B5A7526508AF4A4A00138E45 /* Debug */,
+ B5A7526608AF4A4A00138E45 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTreePrefix.h b/WebKitTools/DumpRenderTree/DumpRenderTreePrefix.h
new file mode 100644
index 0000000..1344754
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/DumpRenderTreePrefix.h
@@ -0,0 +1,38 @@
+/*
+ * 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
+ * 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.
+ */
+
+#ifdef __OBJC__
+
+#import <Foundation/Foundation.h>
+
+#endif
+
+// If we don't define these, they get defined in windef.h.
+// We want to use std::min and std::max
+#define max max
+#define min min
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/ASCIICType.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/ASCIICType.h
new file mode 100644
index 0000000..f2258d2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/ASCIICType.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/ASCIICType.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Assertions.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Assertions.h
new file mode 100644
index 0000000..2144410
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Assertions.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Assertions.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashMap.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashMap.h
new file mode 100644
index 0000000..9f262e2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashMap.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/HashMap.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashSet.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashSet.h
new file mode 100644
index 0000000..cfe2d80
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashSet.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/HashSet.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashTraits.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashTraits.h
new file mode 100755
index 0000000..412fa98
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/HashTraits.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/HashTraits.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Locker.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Locker.h
new file mode 100644
index 0000000..75b0acd
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Locker.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Locker.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/MathExtras.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/MathExtras.h
new file mode 100644
index 0000000..2955786
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/MathExtras.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/MathExtras.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Noncopyable.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Noncopyable.h
new file mode 100644
index 0000000..f8484d2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Noncopyable.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Noncopyable.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/OwnPtr.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/OwnPtr.h
new file mode 100644
index 0000000..9211d38
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/OwnPtr.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/OwnPtr.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/PassRefPtr.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/PassRefPtr.h
new file mode 100644
index 0000000..aafd1a2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/PassRefPtr.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/PassRefPtr.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Platform.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Platform.h
new file mode 100644
index 0000000..3b22955
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Platform.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Platform.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RefCounted.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RefCounted.h
new file mode 100644
index 0000000..628a63b
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RefCounted.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/RefCounted.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RefPtr.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RefPtr.h
new file mode 100644
index 0000000..0ff6213
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RefPtr.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/RefPtr.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RetainPtr.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RetainPtr.h
new file mode 100644
index 0000000..65fc27b
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/RetainPtr.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/RetainPtr.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/StringExtras.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/StringExtras.h
new file mode 100644
index 0000000..063d500
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/StringExtras.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/StringExtras.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Threading.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Threading.h
new file mode 100644
index 0000000..17359e5
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Threading.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Threading.h>
diff --git a/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Vector.h b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Vector.h
new file mode 100644
index 0000000..c6d15fd
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/ForwardingHeaders/wtf/Vector.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/Vector.h>
diff --git a/WebKitTools/DumpRenderTree/GCController.cpp b/WebKitTools/DumpRenderTree/GCController.cpp
new file mode 100644
index 0000000..e1a16f2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/GCController.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 <JavaScriptCore/JSObjectRef.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+
+GCController::GCController()
+{
+}
+
+GCController::~GCController()
+{
+}
+
+// Static Functions
+
+static JSValueRef collectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ GCController* controller = reinterpret_cast<GCController*>(JSObjectGetPrivate(thisObject));
+ controller->collect();
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef collectOnAlternateThreadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ bool waitUntilDone = false;
+ if (argumentCount > 0)
+ waitUntilDone = JSValueToBoolean(context, arguments[0]);
+
+ GCController* controller = reinterpret_cast<GCController*>(JSObjectGetPrivate(thisObject));
+ controller->collectOnAlternateThread(waitUntilDone);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef getJSObjectCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ GCController* controller = reinterpret_cast<GCController*>(JSObjectGetPrivate(thisObject));
+ size_t jsObjectCount = controller->getJSObjectCount();
+
+ return JSValueMakeNumber(context, jsObjectCount);
+}
+
+// Object Creation
+
+void GCController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> gcControllerStr(Adopt, JSStringCreateWithUTF8CString("GCController"));
+ JSValueRef gcControllerObject = JSObjectMake(context, getJSClass(), this);
+ JSObjectSetProperty(context, windowObject, gcControllerStr.get(), gcControllerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
+}
+
+JSClassRef GCController::getJSClass()
+{
+ static JSClassRef gcControllerClass = 0;
+
+ if (!gcControllerClass) {
+ JSStaticFunction* staticFunctions = GCController::staticFunctions();
+ JSClassDefinition classDefinition = {
+ 0, kJSClassAttributeNone, "GCController", 0, 0, staticFunctions,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ gcControllerClass = JSClassCreate(&classDefinition);
+ }
+
+ return gcControllerClass;
+}
+
+JSStaticFunction* GCController::staticFunctions()
+{
+ static JSStaticFunction staticFunctions[] = {
+ { "collect", collectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "collectOnAlternateThread", collectOnAlternateThreadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "getJSObjectCount", getJSObjectCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+ };
+
+ return staticFunctions;
+}
diff --git a/WebKitTools/DumpRenderTree/GCController.h b/WebKitTools/DumpRenderTree/GCController.h
new file mode 100644
index 0000000..4284275
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/GCController.h
@@ -0,0 +1,51 @@
+/*
+ * 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
+ * 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 GCController_h
+#define GCController_h
+
+#include <JavaScriptCore/JSObjectRef.h>
+
+class GCController {
+public:
+ GCController();
+ ~GCController();
+
+ void makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception);
+
+ // Controller Methods - platfrom independant implementations
+ void collect() const;
+ void collectOnAlternateThread(bool waitUntilDone) const;
+ size_t getJSObjectCount() const;
+
+private:
+ static JSClassRef getJSClass();
+ static JSStaticFunction* staticFunctions();
+};
+
+#endif // GCController_h
diff --git a/WebKitTools/DumpRenderTree/JavaScriptThreading.h b/WebKitTools/DumpRenderTree/JavaScriptThreading.h
new file mode 100644
index 0000000..43795a1
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/JavaScriptThreading.h
@@ -0,0 +1,40 @@
+/*
+ * 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>
+ *
+ * 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 JavaScriptThreading_h
+#define JavaScriptThreading_h
+
+/* These functions start/stop threads used to abuse the JavaScript interpreter
+ and assure that our JS implementation remains threadsafe */
+
+void startJavaScriptThreads();
+void stopJavaScriptThreads();
+
+#endif // JavaScriptThreading_h
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
new file mode 100644
index 0000000..f450543
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
@@ -0,0 +1,780 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 "LayoutTestController.h"
+
+#include <JavaScriptCore/JSObjectRef.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+
+LayoutTestController::LayoutTestController(const std::string& testPathOrURL, const std::string& expectedPixelHash)
+ : m_dumpAsText(false)
+ , m_dumpAsPDF(false)
+ , m_dumpBackForwardList(false)
+ , m_dumpChildFrameScrollPositions(false)
+ , m_dumpChildFramesAsText(false)
+ , m_dumpDatabaseCallbacks(false)
+ , m_dumpDOMAsWebArchive(false)
+ , m_dumpSelectionRect(false)
+ , m_dumpSourceAsWebArchive(false)
+ , m_dumpStatusCallbacks(false)
+ , m_dumpTitleChanges(false)
+ , m_dumpEditingCallbacks(false)
+ , m_dumpResourceLoadCallbacks(false)
+ , m_dumpFrameLoadCallbacks(false)
+ , m_addFileToPasteboardOnDrag(false)
+ , m_callCloseOnWebViews(true)
+ , m_canOpenWindows(false)
+ , m_closeRemainingWindowsWhenComplete(true)
+ , m_stopProvisionalFrameLoads(false)
+ , m_testOnscreen(false)
+ , m_testRepaint(false)
+ , m_testRepaintSweepHorizontally(false)
+ , m_waitToDump(false)
+ , m_windowIsKey(true)
+ , m_globalFlag(false)
+ , m_testPathOrURL(testPathOrURL)
+ , m_expectedPixelHash(expectedPixelHash)
+{
+}
+
+// Static Functions
+
+static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpAsText(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpAsPDF(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpBackForwardList(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpChildFramesAsText(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpChildFrameScrollPositions(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpDatabaseCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpDatabaseCallbacks(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpDOMAsWebArchive(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpEditingCallbacks(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpResourceLoadCallbacks(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpSelectionRect(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpSourceAsWebArchive(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpStatusCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpStatusCallbacks(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setDumpTitleChanges(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ JSRetainPtr<JSStringRef> localPath(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ JSRetainPtr<JSStringRef> convertedPath(Adopt, controller->pathToLocalResource(context, localPath.get()));
+ if (!convertedPath)
+ return JSValueMakeUndefined(context);
+
+ return JSValueMakeString(context, convertedPath.get());
+}
+
+static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setTestRepaintSweepHorizontally(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setCanOpenWindows(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef testOnscreenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setTestOnscreen(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setTestRepaint(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef addFileToPasteboardOnDragCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setAddFileToPasteboardOnDrag(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->addDisallowedURL(url.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->clearAllDatabases();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->clearBackForwardList();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef clearPersistentUserStyleSheetCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->clearPersistentUserStyleSheet();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
+ return JSValueMakeString(context, decodedHostName.get());
+}
+
+static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->display();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
+ return JSValueMakeString(context, encodedHostName.get());
+}
+
+static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has Mac & Windows implementations.
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ // Ignoring the second parameter (userInterface), as this command emulates a manual action.
+
+ JSRetainPtr<JSStringRef> value;
+ if (argumentCount >= 3) {
+ value.adopt(JSValueToStringCopy(context, arguments[2], exception));
+ ASSERT(!*exception);
+ } else
+ value.adopt(JSStringCreateWithUTF8CString(""));
+
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->execCommand(name.get(), value.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->keepWebHistory();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->notifyDone();
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ JSRetainPtr<JSStringRef> target;
+ if (argumentCount >= 2) {
+ target.adopt(JSValueToStringCopy(context, arguments[1], exception));
+ ASSERT(!*exception);
+ } else
+ target.adopt(JSStringCreateWithUTF8CString(""));
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueLoad(url.get(), target.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueReload();
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef queueScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ // May be able to be made platform independant by using shared WorkQueue
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->queueScript(script.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+
+ double quota = JSValueToNumber(context, arguments[0], NULL);
+ if (!isnan(quota))
+ controller->setDatabaseQuota(static_cast<unsigned long long>(quota));
+
+ return JSValueMakeUndefined(context);
+
+}
+
+static JSValueRef setJavaScriptProfilingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setJavaScriptProfilingEnabled(JSValueToBoolean(context, arguments[0]));
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setPersistentUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setPersistentUserStyleSheetLocation(path.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setUserStyleSheetLocation(path.get());
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setWaitToDump(true);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac implementation
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ int windows = controller->windowCount();
+ return JSValueMakeNumber(context, windows);
+}
+
+static JSValueRef setPopupBlockingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setPopupBlockingEnabled(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setSmartInsertDeleteEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setSmartInsertDeleteEnabled(JSValueToBoolean(context, arguments[0]));
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setStopProvisionalFrameLoads(true);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+ ASSERT(!*exception);
+
+ bool autoCompletes = controller->elementDoesAutoCompleteForElementWithId(elementId.get());
+
+ return JSValueMakeBoolean(context, autoCompletes);
+}
+
+// Static Values
+
+static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ return JSValueMakeBoolean(context, controller->globalFlag());
+}
+
+static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setGlobalFlag(JSValueToBoolean(context, value));
+ return true;
+}
+
+static void layoutTestControllerObjectFinalize(JSObjectRef object)
+{
+ LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(object));
+ controller->deref();
+}
+
+// Object Creation
+
+void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
+ ref();
+ JSValueRef layoutTestContollerObject = JSObjectMake(context, getJSClass(), this);
+ JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
+}
+
+JSClassRef LayoutTestController::getJSClass()
+{
+ static JSClassRef layoutTestControllerClass;
+
+ if (!layoutTestControllerClass) {
+ JSStaticValue* staticValues = LayoutTestController::staticValues();
+ JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
+ JSClassDefinition classDefinition = {
+ 0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
+ 0, layoutTestControllerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ layoutTestControllerClass = JSClassCreate(&classDefinition);
+ }
+
+ return layoutTestControllerClass;
+}
+
+JSStaticValue* LayoutTestController::staticValues()
+{
+ static JSStaticValue staticValues[] = {
+ { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+ };
+ return staticValues;
+
+}
+
+JSStaticFunction* LayoutTestController::staticFunctions()
+{
+ static JSStaticFunction staticFunctions[] = {
+ { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "addFileToPasteboardOnDrag", addFileToPasteboardOnDragCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "queueScript", queueScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setJavaScriptProfilingEnabled", setJavaScriptProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setSmartInsertDeleteEnabled", setSmartInsertDeleteEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "elementDoesAutoCompleteForElementWithId", elementDoesAutoCompleteForElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+ };
+
+ return staticFunctions;
+}
+
+
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.h b/WebKitTools/DumpRenderTree/LayoutTestController.h
new file mode 100644
index 0000000..f27c2c6
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 LayoutTestController_h
+#define LayoutTestController_h
+
+#include <JavaScriptCore/JSObjectRef.h>
+#include <wtf/RefCounted.h>
+#include <string>
+
+class LayoutTestController : public RefCounted<LayoutTestController> {
+public:
+ LayoutTestController(const std::string& testPathOrURL, const std::string& expectedPixelHash);
+ ~LayoutTestController();
+
+ void makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception);
+
+ // Controller Methods - platfrom independant implementations
+ void addDisallowedURL(JSStringRef url);
+ void clearAllDatabases();
+ void clearBackForwardList();
+ JSStringRef copyDecodedHostName(JSStringRef name);
+ JSStringRef copyEncodedHostName(JSStringRef name);
+ void execCommand(JSStringRef name, JSStringRef value);
+ void display();
+ void keepWebHistory();
+ void notifyDone();
+ JSStringRef pathToLocalResource(JSContextRef, JSStringRef url);
+ void queueBackNavigation(int howFarBackward);
+ void queueForwardNavigation(int howFarForward);
+ void queueLoad(JSStringRef url, JSStringRef target);
+ void queueReload();
+ void queueScript(JSStringRef url);
+ void setAcceptsEditing(bool acceptsEditing);
+ void setAuthorAndUserStylesEnabled(bool);
+ void setCustomPolicyDelegate(bool setDelegate);
+ void setDatabaseQuota(unsigned long long quota);
+ void setMainFrameIsFirstResponder(bool flag);
+ void setPrivateBrowsingEnabled(bool flag);
+ void setPopupBlockingEnabled(bool flag);
+ void setTabKeyCyclesThroughElements(bool cycles);
+ void setSmartInsertDeleteEnabled(bool flag);
+ void setJavaScriptProfilingEnabled(bool profilingEnabled);
+ void setUseDashboardCompatibilityMode(bool flag);
+ void setUserStyleSheetEnabled(bool flag);
+ void setUserStyleSheetLocation(JSStringRef path);
+ void setPersistentUserStyleSheetLocation(JSStringRef path);
+ void clearPersistentUserStyleSheet();
+ int windowCount();
+
+ bool elementDoesAutoCompleteForElementWithId(JSStringRef id);
+
+ bool dumpAsText() const { return m_dumpAsText; }
+ void setDumpAsText(bool dumpAsText) { m_dumpAsText = dumpAsText; }
+
+ bool dumpAsPDF() const { return m_dumpAsPDF; }
+ void setDumpAsPDF(bool dumpAsPDF) { m_dumpAsPDF = dumpAsPDF; }
+
+ bool dumpBackForwardList() const { return m_dumpBackForwardList; }
+ void setDumpBackForwardList(bool dumpBackForwardList) { m_dumpBackForwardList = dumpBackForwardList; }
+
+ bool dumpChildFrameScrollPositions() const { return m_dumpChildFrameScrollPositions; }
+ void setDumpChildFrameScrollPositions(bool dumpChildFrameScrollPositions) { m_dumpChildFrameScrollPositions = dumpChildFrameScrollPositions; }
+
+ bool dumpChildFramesAsText() const { return m_dumpChildFramesAsText; }
+ void setDumpChildFramesAsText(bool dumpChildFramesAsText) { m_dumpChildFramesAsText = dumpChildFramesAsText; }
+
+ bool dumpDatabaseCallbacks() const { return m_dumpDatabaseCallbacks; }
+ void setDumpDatabaseCallbacks(bool dumpDatabaseCallbacks) { m_dumpDatabaseCallbacks = dumpDatabaseCallbacks; }
+
+ bool dumpStatusCallbacks() const { return m_dumpStatusCallbacks; }
+ void setDumpStatusCallbacks(bool dumpStatusCallbacks) { m_dumpStatusCallbacks = dumpStatusCallbacks; }
+
+ bool dumpDOMAsWebArchive() const { return m_dumpDOMAsWebArchive; }
+ void setDumpDOMAsWebArchive(bool dumpDOMAsWebArchive) { m_dumpDOMAsWebArchive = dumpDOMAsWebArchive; }
+
+ bool dumpSelectionRect() const { return m_dumpSelectionRect; }
+ void setDumpSelectionRect(bool dumpSelectionRect) { m_dumpSelectionRect = dumpSelectionRect; }
+
+ bool dumpSourceAsWebArchive() const { return m_dumpSourceAsWebArchive; }
+ void setDumpSourceAsWebArchive(bool dumpSourceAsWebArchive) { m_dumpSourceAsWebArchive = dumpSourceAsWebArchive; }
+
+ bool dumpTitleChanges() const { return m_dumpTitleChanges; }
+ void setDumpTitleChanges(bool dumpTitleChanges) { m_dumpTitleChanges = dumpTitleChanges; }
+
+ bool dumpEditingCallbacks() const { return m_dumpEditingCallbacks; }
+ void setDumpEditingCallbacks(bool dumpEditingCallbacks) { m_dumpEditingCallbacks = dumpEditingCallbacks; }
+
+ bool dumpResourceLoadCallbacks() const { return m_dumpResourceLoadCallbacks; }
+ void setDumpResourceLoadCallbacks(bool dumpResourceLoadCallbacks) { m_dumpResourceLoadCallbacks = dumpResourceLoadCallbacks; }
+
+ bool dumpFrameLoadCallbacks() const { return m_dumpFrameLoadCallbacks; }
+ void setDumpFrameLoadCallbacks(bool dumpFrameLoadCallbacks) { m_dumpFrameLoadCallbacks = dumpFrameLoadCallbacks; }
+
+ bool addFileToPasteboardOnDrag() const { return m_addFileToPasteboardOnDrag; }
+ void setAddFileToPasteboardOnDrag(bool addFileToPasteboardOnDrag) { m_addFileToPasteboardOnDrag = addFileToPasteboardOnDrag; }
+
+ bool callCloseOnWebViews() const { return m_callCloseOnWebViews; }
+ void setCallCloseOnWebViews(bool callCloseOnWebViews) { m_callCloseOnWebViews = callCloseOnWebViews; }
+
+ bool canOpenWindows() const { return m_canOpenWindows; }
+ void setCanOpenWindows(bool canOpenWindows) { m_canOpenWindows = canOpenWindows; }
+
+ bool closeRemainingWindowsWhenComplete() const { return m_closeRemainingWindowsWhenComplete; }
+ void setCloseRemainingWindowsWhenComplete(bool closeRemainingWindowsWhenComplete) { m_closeRemainingWindowsWhenComplete = closeRemainingWindowsWhenComplete; }
+
+ bool stopProvisionalFrameLoads() const { return m_stopProvisionalFrameLoads; }
+ void setStopProvisionalFrameLoads(bool stopProvisionalFrameLoads) { m_stopProvisionalFrameLoads = stopProvisionalFrameLoads; }
+
+ bool testOnscreen() const { return m_testOnscreen; }
+ void setTestOnscreen(bool testOnscreen) { m_testOnscreen = testOnscreen; }
+
+ bool testRepaint() const { return m_testRepaint; }
+ void setTestRepaint(bool testRepaint) { m_testRepaint = testRepaint; }
+
+ bool testRepaintSweepHorizontally() const { return m_testRepaintSweepHorizontally; }
+ void setTestRepaintSweepHorizontally(bool testRepaintSweepHorizontally) { m_testRepaintSweepHorizontally = testRepaintSweepHorizontally; }
+
+ bool waitToDump() const { return m_waitToDump; }
+ void setWaitToDump(bool waitToDump);
+
+ bool windowIsKey() const { return m_windowIsKey; }
+ void setWindowIsKey(bool windowIsKey);
+
+ bool globalFlag() const { return m_globalFlag; }
+ void setGlobalFlag(bool globalFlag) { m_globalFlag = globalFlag; }
+
+ const std::string& testPathOrURL() const { return m_testPathOrURL; }
+ const std::string& expectedPixelHash() const { return m_expectedPixelHash; }
+
+private:
+ bool m_dumpAsText;
+ bool m_dumpAsPDF;
+ bool m_dumpBackForwardList;
+ bool m_dumpChildFrameScrollPositions;
+ bool m_dumpChildFramesAsText;
+ bool m_dumpDatabaseCallbacks;
+ bool m_dumpDOMAsWebArchive;
+ bool m_dumpSelectionRect;
+ bool m_dumpSourceAsWebArchive;
+ bool m_dumpStatusCallbacks;
+ bool m_dumpTitleChanges;
+ bool m_dumpEditingCallbacks;
+ bool m_dumpResourceLoadCallbacks;
+ bool m_dumpFrameLoadCallbacks;
+ bool m_addFileToPasteboardOnDrag;
+ bool m_callCloseOnWebViews;
+ bool m_canOpenWindows;
+ bool m_closeRemainingWindowsWhenComplete;
+ bool m_stopProvisionalFrameLoads;
+ bool m_testOnscreen;
+ bool m_testRepaint;
+ bool m_testRepaintSweepHorizontally;
+ bool m_waitToDump; // True if waitUntilDone() has been called, but notifyDone() has not yet been called.
+ bool m_windowIsKey;
+
+ bool m_globalFlag;
+
+ std::string m_testPathOrURL;
+ std::string m_expectedPixelHash; // empty string if no hash
+
+ static JSClassRef getJSClass();
+ static JSStaticValue* staticValues();
+ static JSStaticFunction* staticFunctions();
+};
+
+#endif // LayoutTestController_h
diff --git a/WebKitTools/DumpRenderTree/Makefile b/WebKitTools/DumpRenderTree/Makefile
new file mode 100644
index 0000000..1f1dbbc
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/Makefile
@@ -0,0 +1,2 @@
+SCRIPTS_PATH = ../Scripts
+include ../../Makefile.shared
diff --git a/WebKitTools/DumpRenderTree/PixelDumpSupport.h b/WebKitTools/DumpRenderTree/PixelDumpSupport.h
new file mode 100644
index 0000000..d4f8948
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/PixelDumpSupport.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 PixelDumpSupport_h
+#define PixelDumpSupport_h
+
+#include <string>
+
+void dumpWebViewAsPixelsAndCompareWithExpected(const std::string& expectedHash);
+
+#if PLATFORM(MAC)
+
+// Can be used as a signal handler
+void restoreMainDisplayColorProfile(int ignored);
+
+// May change your color space, requiring a call to restoreMainDisplayColorProfile
+void setupMainDisplayColorProfile();
+
+#endif
+
+#endif // PixelDumpSupport_h
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/Info.plist b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/Info.plist
new file mode 100644
index 0000000..1f4cfe3
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/Info.plist
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>TestNetscapePlugIn</string>
+ <key>CFBundleGetInfoString</key>
+ <string>420+, Copyright 2006 Apple Computer, Inc.</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.testnetscapeplugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BRPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CFPlugInDynamicRegisterFunction</key>
+ <string></string>
+ <key>CFPlugInDynamicRegistration</key>
+ <string>NO</string>
+ <key>CFPlugInFactories</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <string>MyFactoryFunction</string>
+ </dict>
+ <key>CFPlugInTypes</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <array>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </array>
+ </dict>
+ <key>CFPlugInUnloadFunction</key>
+ <string></string>
+ <key>WebPluginDescription</key>
+ <string>Simple Netscape plug-in that handles test content for WebKit</string>
+ <key>WebPluginMIMETypes</key>
+ <dict>
+ <key>application/x-webkit-test-netscape</key>
+ <dict>
+ <key>WebPluginExtensions</key>
+ <array>
+ <string>testnetscape</string>
+ </array>
+ <key>WebPluginTypeDescription</key>
+ <string>test netscape content</string>
+ </dict>
+ </dict>
+ <key>WebPluginName</key>
+ <string>WebKit Test PlugIn</string>
+</dict>
+</plist>
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp
new file mode 100644
index 0000000..11fb30d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp
@@ -0,0 +1,676 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 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. ``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 "PluginObject.h"
+
+#include "TestObject.h"
+#include <assert.h>
+#include <stdio.h>
+
+static void pluginInvalidate(NPObject*);
+static bool pluginHasProperty(NPObject*, NPIdentifier name);
+static bool pluginHasMethod(NPObject*, NPIdentifier name);
+static bool pluginGetProperty(NPObject*, NPIdentifier name, NPVariant*);
+static bool pluginSetProperty(NPObject*, NPIdentifier name, const NPVariant*);
+static bool pluginInvoke(NPObject*, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result);
+static bool pluginInvokeDefault(NPObject*, const NPVariant* args, uint32_t argCount, NPVariant* result);
+static NPObject* pluginAllocate(NPP npp, NPClass*);
+static void pluginDeallocate(NPObject*);
+
+NPNetscapeFuncs* browser;
+
+static NPClass pluginClass = {
+ NP_CLASS_STRUCT_VERSION,
+ pluginAllocate,
+ pluginDeallocate,
+ pluginInvalidate,
+ pluginHasMethod,
+ pluginInvoke,
+ pluginInvokeDefault,
+ pluginHasProperty,
+ pluginGetProperty,
+ pluginSetProperty,
+};
+
+NPClass *getPluginClass(void)
+{
+ return &pluginClass;
+}
+
+static bool identifiersInitialized = false;
+
+#define ID_PROPERTY_PROPERTY 0
+#define ID_PROPERTY_EVENT_LOGGING 1
+#define ID_PROPERTY_HAS_STREAM 2
+#define ID_PROPERTY_TEST_OBJECT 3
+#define ID_PROPERTY_LOG_DESTROY 4
+#define ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM 5
+#define NUM_PROPERTY_IDENTIFIERS 6
+
+static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
+static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
+ "property",
+ "eventLoggingEnabled",
+ "hasStream",
+ "testObject",
+ "logDestroy",
+ "returnErrorFromNewStream",
+};
+
+#define ID_TEST_CALLBACK_METHOD 0
+#define ID_TEST_GETURL 1
+#define ID_REMOVE_DEFAULT_METHOD 2
+#define ID_TEST_DOM_ACCESS 3
+#define ID_TEST_GET_URL_NOTIFY 4
+#define ID_TEST_INVOKE_DEFAULT 5
+#define ID_DESTROY_STREAM 6
+#define ID_TEST_ENUMERATE 7
+#define ID_TEST_GETINTIDENTIFIER 8
+#define ID_TEST_GET_PROPERTY 9
+#define ID_TEST_EVALUATE 10
+#define ID_TEST_GET_PROPERTY_RETURN_VALUE 11
+#define ID_TEST_IDENTIFIER_TO_STRING 12
+#define ID_TEST_IDENTIFIER_TO_INT 13
+#define ID_TEST_POSTURL_FILE 14
+#define ID_TEST_CONSTRUCT 15
+#define NUM_METHOD_IDENTIFIERS 16
+
+static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
+static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
+ "testCallback",
+ "getURL",
+ "removeDefaultMethod",
+ "testDOMAccess",
+ "getURLNotify",
+ "testInvokeDefault",
+ "destroyStream",
+ "testEnumerate",
+ "testGetIntIdentifier",
+ "testGetProperty",
+ "testEvaluate",
+ "testGetPropertyReturnValue",
+ "testIdentifierToString",
+ "testIdentifierToInt",
+ "testPostURLFile",
+ "testConstruct",
+};
+
+static NPUTF8* createCStringFromNPVariant(const NPVariant* variant)
+{
+ size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
+ NPUTF8* result = (NPUTF8*)malloc(length + 1);
+ memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
+ result[length] = '\0';
+ return result;
+}
+
+static void initializeIdentifiers(void)
+{
+ browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
+ browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
+}
+
+static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
+{
+ for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
+ if (name == pluginPropertyIdentifiers[i])
+ return true;
+ return false;
+}
+
+static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
+{
+ for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
+ if (name == pluginMethodIdentifiers[i])
+ return true;
+ return false;
+}
+
+static bool pluginGetProperty(NPObject* obj, NPIdentifier name, NPVariant* result)
+{
+ PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) {
+ STRINGZ_TO_NPVARIANT("property", *result);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
+ BOOLEAN_TO_NPVARIANT(plugin->eventLogging, *result);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
+ BOOLEAN_TO_NPVARIANT(plugin->logDestroy, *result);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
+ BOOLEAN_TO_NPVARIANT(plugin->stream != 0, *result);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
+ NPObject* testObject = plugin->testObject;
+ browser->retainobject(testObject);
+ OBJECT_TO_NPVARIANT(testObject, *result);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
+ BOOLEAN_TO_NPVARIANT(plugin->returnErrorFromNewStream, *result);
+ return true;
+ }
+ return false;
+}
+
+static bool pluginSetProperty(NPObject* obj, NPIdentifier name, const NPVariant* variant)
+{
+ PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
+ plugin->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
+ plugin->logDestroy = NPVARIANT_TO_BOOLEAN(*variant);
+ return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
+ plugin->returnErrorFromNewStream = NPVARIANT_TO_BOOLEAN(*variant);
+ return true;
+ }
+
+ return false;
+}
+
+static bool testDOMAccess(PluginObject* obj, const NPVariant*, uint32_t, NPVariant* result)
+{
+ // Get plug-in's DOM element
+ NPObject* elementObject;
+ if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) == NPERR_NO_ERROR) {
+ // Get style
+ NPVariant styleVariant;
+ NPIdentifier styleIdentifier = browser->getstringidentifier("style");
+ if (browser->getproperty(obj->npp, elementObject, styleIdentifier, &styleVariant) && NPVARIANT_IS_OBJECT(styleVariant)) {
+ // Set style.border
+ NPIdentifier borderIdentifier = browser->getstringidentifier("border");
+ NPVariant borderVariant;
+ STRINGZ_TO_NPVARIANT("3px solid red", borderVariant);
+ browser->setproperty(obj->npp, NPVARIANT_TO_OBJECT(styleVariant), borderIdentifier, &borderVariant);
+ browser->releasevariantvalue(&styleVariant);
+ }
+
+ browser->releaseobject(elementObject);
+ }
+ VOID_TO_NPVARIANT(*result);
+ return true;
+}
+
+static NPIdentifier stringVariantToIdentifier(NPVariant variant)
+{
+ assert(NPVARIANT_IS_STRING(variant));
+ NPUTF8* utf8String = createCStringFromNPVariant(&variant);
+ NPIdentifier identifier = browser->getstringidentifier(utf8String);
+ free(utf8String);
+ return identifier;
+}
+
+static NPIdentifier int32VariantToIdentifier(NPVariant variant)
+{
+ assert(NPVARIANT_IS_INT32(variant));
+ int32 integer = NPVARIANT_TO_INT32(variant);
+ return browser->getintidentifier(integer);
+}
+
+static NPIdentifier doubleVariantToIdentifier(NPVariant variant)
+{
+ assert(NPVARIANT_IS_DOUBLE(variant));
+ double value = NPVARIANT_TO_DOUBLE(variant);
+ // Sadly there is no "getdoubleidentifier"
+ int32 integer = static_cast<int32>(value);
+ return browser->getintidentifier(integer);
+}
+
+static NPIdentifier variantToIdentifier(NPVariant variant)
+{
+ if (NPVARIANT_IS_STRING(variant))
+ return stringVariantToIdentifier(variant);
+ else if (NPVARIANT_IS_INT32(variant))
+ return int32VariantToIdentifier(variant);
+ else if (NPVARIANT_IS_DOUBLE(variant))
+ return doubleVariantToIdentifier(variant);
+ return 0;
+}
+
+static bool testIdentifierToString(PluginObject*, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount != 1)
+ return false;
+ NPIdentifier identifier = variantToIdentifier(args[0]);
+ if (!identifier)
+ return false;
+ NPUTF8* utf8String = browser->utf8fromidentifier(identifier);
+ if (!utf8String)
+ return false;
+ STRINGZ_TO_NPVARIANT(utf8String, *result);
+ return true;
+}
+
+static bool testIdentifierToInt(PluginObject*, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount != 1)
+ return false;
+ NPIdentifier identifier = variantToIdentifier(args[0]);
+ if (!identifier)
+ return false;
+ int32 integer = browser->intfromidentifier(identifier);
+ INT32_TO_NPVARIANT(integer, *result);
+ return true;
+}
+
+static bool testCallback(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount == 0 || !NPVARIANT_IS_STRING(args[0]))
+ return false;
+
+ NPObject* windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
+ NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
+ free(callbackString);
+
+ NPVariant browserResult;
+ browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, 0, 0, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+
+ browser->releaseobject(windowScriptObject);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+}
+
+static bool getURL(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) {
+ NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
+ NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
+ NPError npErr = browser->geturl(obj->npp, urlString, targetString);
+ free(urlString);
+ free(targetString);
+
+ INT32_TO_NPVARIANT(npErr, *result);
+ return true;
+ } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
+ NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
+ NPError npErr = browser->geturl(obj->npp, urlString, 0);
+ free(urlString);
+
+ INT32_TO_NPVARIANT(npErr, *result);
+ return true;
+ }
+ return false;
+}
+
+static bool removeDefaultMethod(PluginObject*, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ pluginClass.invokeDefault = 0;
+ VOID_TO_NPVARIANT(*result);
+ return true;
+}
+
+static bool getURLNotify(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount != 3 || !NPVARIANT_IS_STRING(args[0])
+ || (!NPVARIANT_IS_STRING(args[1]) && !NPVARIANT_IS_NULL(args[1]))
+ || !NPVARIANT_IS_STRING(args[2]))
+ return false;
+
+ NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
+ NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : NULL);
+ NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
+
+ NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
+ browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier);
+
+ free(urlString);
+ free(targetString);
+ free(callbackString);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+}
+
+static bool testInvokeDefault(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (!NPVARIANT_IS_OBJECT(args[0]))
+ return false;
+
+ NPObject *callback = NPVARIANT_TO_OBJECT(args[0]);
+
+ NPVariant invokeArgs[1];
+ NPVariant browserResult;
+
+ STRINGZ_TO_NPVARIANT("test", invokeArgs[0]);
+ bool retval = browser->invokeDefault(obj->npp, callback, invokeArgs, 1, &browserResult);
+
+ if (retval)
+ browser->releasevariantvalue(&browserResult);
+
+ BOOLEAN_TO_NPVARIANT(retval, *result);
+ return true;
+}
+
+static bool destroyStream(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ NPError npError = browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK);
+ INT32_TO_NPVARIANT(npError, *result);
+ return true;
+}
+
+static bool testEnumerate(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_OBJECT(args[1]))
+ return false;
+
+ uint32_t count;
+ NPIdentifier* identifiers;
+ if (browser->enumerate(obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifiers, &count)) {
+ NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]);
+ NPIdentifier pushIdentifier = browser->getstringidentifier("push");
+
+ for (uint32_t i = 0; i < count; i++) {
+ NPUTF8* string = browser->utf8fromidentifier(identifiers[i]);
+
+ if (!string)
+ continue;
+
+ NPVariant args[1];
+ STRINGZ_TO_NPVARIANT(string, args[0]);
+ NPVariant browserResult;
+ browser->invoke(obj->npp, outArray, pushIdentifier, args, 1, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+ browser->memfree(string);
+ }
+
+ browser->memfree(identifiers);
+ }
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+}
+
+static bool testGetIntIdentifier(PluginObject*, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount != 1 || !NPVARIANT_IS_DOUBLE(args[0]))
+ return false;
+
+ NPIdentifier identifier = browser->getintidentifier((int)NPVARIANT_TO_DOUBLE(args[0]));
+ INT32_TO_NPVARIANT((int32)(long long)identifier, *result);
+ return true;
+}
+
+static bool testGetProperty(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount == 0)
+ return false;
+
+ NPObject *object;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &object);
+
+ for (uint32_t i = 0; i < argCount; i++) {
+ assert(NPVARIANT_IS_STRING(args[i]));
+ NPUTF8* propertyString = createCStringFromNPVariant(&args[i]);
+ NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
+ free(propertyString);
+
+ NPVariant variant;
+ bool retval = browser->getproperty(obj->npp, object, propertyIdentifier, &variant);
+ browser->releaseobject(object);
+
+ if (!retval)
+ break;
+
+ if (i + 1 < argCount) {
+ assert(NPVARIANT_IS_OBJECT(variant));
+ object = NPVARIANT_TO_OBJECT(variant);
+ } else {
+ *result = variant;
+ return true;
+ }
+ }
+
+ VOID_TO_NPVARIANT(*result);
+ return false;
+}
+
+static bool testEvaluate(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount != 1 || !NPVARIANT_IS_STRING(args[0]))
+ return false;
+ NPObject* windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString s = NPVARIANT_TO_STRING(args[0]);
+
+ bool retval = browser->evaluate(obj->npp, windowScriptObject, &s, result);
+ browser->releaseobject(windowScriptObject);
+ return retval;
+}
+
+static bool testGetPropertyReturnValue(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_STRING(args[1]))
+ return false;
+
+ NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
+ NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
+ free(propertyString);
+
+ NPVariant variant;
+ bool retval = browser->getproperty(obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier, &variant);
+ if (retval)
+ browser->releasevariantvalue(&variant);
+
+ BOOLEAN_TO_NPVARIANT(retval, *result);
+ return true;
+}
+
+static char* toCString(const NPString& string)
+{
+ char* result = static_cast<char*>(malloc(string.UTF8Length + 1));
+ memcpy(result, string.UTF8Characters, string.UTF8Length);
+ result[string.UTF8Length] = '\0';
+
+ return result;
+}
+
+static bool testPostURLFile(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount != 4 || !NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1]) || !NPVARIANT_IS_STRING(args[2]) || !NPVARIANT_IS_STRING(args[3]))
+ return false;
+
+ NPString urlString = NPVARIANT_TO_STRING(args[0]);
+ char* url = toCString(urlString);
+
+ NPString targetString = NPVARIANT_TO_STRING(args[1]);
+ char* target = toCString(targetString);
+
+ NPString pathString = NPVARIANT_TO_STRING(args[2]);
+ char* path = toCString(pathString);
+
+ NPString contentsString = NPVARIANT_TO_STRING(args[3]);
+
+ FILE* tempFile = fopen(path, "w");
+ if (!tempFile)
+ return false;
+
+ fwrite(contentsString.UTF8Characters, contentsString.UTF8Length, 1, tempFile);
+ fclose(tempFile);
+
+ NPError error = browser->posturl(obj->npp, url, target, pathString.UTF8Length, path, TRUE);
+
+ free(path);
+ free(target);
+ free(url);
+
+ BOOLEAN_TO_NPVARIANT(error == NPERR_NO_ERROR, *result);
+ return true;
+}
+
+static bool testConstruct(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (!argCount || !NPVARIANT_IS_OBJECT(args[0]))
+ return false;
+
+ return browser->construct(obj->npp, NPVARIANT_TO_OBJECT(args[0]), args + 1, argCount - 1, result);
+}
+
+static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
+ if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD])
+ return testCallback(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_GETURL])
+ return getURL(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_REMOVE_DEFAULT_METHOD])
+ return removeDefaultMethod(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS])
+ return testDOMAccess(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY])
+ return getURLNotify(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT])
+ return testInvokeDefault(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE])
+ return testEnumerate(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM])
+ return destroyStream(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER])
+ return testGetIntIdentifier(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE])
+ return testEvaluate(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY])
+ return testGetProperty(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE])
+ return testGetPropertyReturnValue(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING])
+ return testIdentifierToString(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT])
+ return testIdentifierToInt(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE])
+ return testPostURLFile(plugin, args, argCount, result);
+ else if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT])
+ return testConstruct(plugin, args, argCount, result);
+
+ return false;
+}
+
+static bool pluginInvokeDefault(NPObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ INT32_TO_NPVARIANT(1, *result);
+ return true;
+}
+
+static void pluginInvalidate(NPObject* obj)
+{
+}
+
+static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
+{
+ PluginObject* newInstance = (PluginObject*)malloc(sizeof(PluginObject));
+
+ if (!identifiersInitialized) {
+ identifiersInitialized = true;
+ initializeIdentifiers();
+ }
+
+ newInstance->npp = npp;
+ newInstance->testObject = browser->createobject(npp, getTestClass());
+ newInstance->eventLogging = FALSE;
+ newInstance->onStreamLoad = 0;
+ newInstance->onStreamDestroy = 0;
+ newInstance->onURLNotify = 0;
+ newInstance->logDestroy = FALSE;
+ newInstance->logSetWindow = FALSE;
+ newInstance->returnErrorFromNewStream = FALSE;
+ newInstance->stream = 0;
+
+ newInstance->firstUrl = NULL;
+ newInstance->firstHeaders = NULL;
+ newInstance->lastUrl = NULL;
+ newInstance->lastHeaders = NULL;
+
+ return (NPObject*)newInstance;
+}
+
+static void pluginDeallocate(NPObject* header)
+{
+ PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
+ browser->releaseobject(plugin->testObject);
+
+ free(plugin->firstUrl);
+ free(plugin->firstHeaders);
+ free(plugin->lastUrl);
+ free(plugin->lastHeaders);
+ free(plugin);
+}
+
+void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData)
+{
+ assert(object);
+
+ NPVariant args[2];
+
+ NPObject *windowScriptObject;
+ browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPIdentifier callbackIdentifier = notifyData;
+
+ INT32_TO_NPVARIANT(reason, args[0]);
+
+ char *strHdr = NULL;
+ if (object->firstUrl && object->firstHeaders && object->lastUrl && object->lastHeaders) {
+ // Format expected by JavaScript validator: four fields separated by \n\n:
+ // First URL; first header block; last URL; last header block.
+ // Note that header blocks already end with \n due to how NPStream::headers works.
+ int len = strlen(object->firstUrl) + 2
+ + strlen(object->firstHeaders) + 1
+ + strlen(object->lastUrl) + 2
+ + strlen(object->lastHeaders) + 1;
+ strHdr = (char*)malloc(len + 1);
+ snprintf(strHdr, len + 1, "%s\n\n%s\n%s\n\n%s\n",
+ object->firstUrl, object->firstHeaders, object->lastUrl, object->lastHeaders);
+ STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
+ } else
+ NULL_TO_NPVARIANT(args[1]);
+
+ NPVariant browserResult;
+ browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 2, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+
+ free(strHdr);
+}
+
+void notifyStream(PluginObject* object, const char *url, const char *headers)
+{
+ if (object->firstUrl == NULL) {
+ if (url)
+ object->firstUrl = strdup(url);
+ if (headers)
+ object->firstHeaders = strdup(headers);
+ } else {
+ free(object->lastUrl);
+ free(object->lastHeaders);
+ object->lastUrl = (url ? strdup(url) : NULL);
+ object->lastHeaders = (headers ? strdup(headers) : NULL);
+ }
+}
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h
new file mode 100644
index 0000000..a5441d8
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006, 2007 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. ``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 <WebKit/npfunctions.h>
+
+extern NPNetscapeFuncs *browser;
+
+typedef struct {
+ NPObject header;
+ NPP npp;
+ NPBool eventLogging;
+ NPBool logSetWindow;
+ NPBool logDestroy;
+ NPBool returnErrorFromNewStream;
+ NPObject* testObject;
+ NPStream* stream;
+ char* onStreamLoad;
+ char* onStreamDestroy;
+ char* onURLNotify;
+ char* firstUrl;
+ char* firstHeaders;
+ char* lastUrl;
+ char* lastHeaders;
+} PluginObject;
+
+extern NPClass *getPluginClass(void);
+extern void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData);
+extern void notifyStream(PluginObject* object, const char *url, const char *headers);
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp
new file mode 100644
index 0000000..3e85e2c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2007 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. ``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 "TestObject.h"
+#include "PluginObject.h"
+
+static bool testEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count);
+static bool testHasProperty(NPObject *obj, NPIdentifier name);
+static bool testGetProperty(NPObject*, NPIdentifier name, NPVariant*);
+static NPObject *testAllocate(NPP npp, NPClass *theClass);
+static void testDeallocate(NPObject *obj);
+static bool testConstruct(NPObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result);
+
+static NPClass testClass = {
+ NP_CLASS_STRUCT_VERSION,
+ testAllocate,
+ testDeallocate,
+ 0,
+ 0,
+ 0,
+ 0,
+ testHasProperty,
+ testGetProperty,
+ 0,
+ 0,
+ testEnumerate,
+ testConstruct
+};
+
+NPClass *getTestClass(void)
+{
+ return &testClass;
+}
+
+static bool identifiersInitialized = false;
+
+#define ID_OBJECT_POINTER 2
+
+#define NUM_ENUMERATABLE_TEST_IDENTIFIERS 2
+#define NUM_TEST_IDENTIFIERS 3
+
+static NPIdentifier testIdentifiers[NUM_TEST_IDENTIFIERS];
+static const NPUTF8 *testIdentifierNames[NUM_TEST_IDENTIFIERS] = {
+ "foo",
+ "bar",
+ "objectPointer",
+};
+
+static void initializeIdentifiers(void)
+{
+ browser->getstringidentifiers(testIdentifierNames, NUM_TEST_IDENTIFIERS, testIdentifiers);
+}
+
+static NPObject *testAllocate(NPP npp, NPClass *theClass)
+{
+ NPObject *newInstance = static_cast<NPObject*>(malloc(sizeof(NPObject)));
+
+ if (!identifiersInitialized) {
+ identifiersInitialized = true;
+ initializeIdentifiers();
+ }
+
+ return newInstance;
+}
+
+static void testDeallocate(NPObject *obj)
+{
+ free(obj);
+}
+
+static bool testHasProperty(NPObject *obj, NPIdentifier name)
+{
+ for (unsigned i = 0; i < NUM_TEST_IDENTIFIERS; i++) {
+ if (testIdentifiers[i] == name)
+ return true;
+ }
+
+ return false;
+}
+
+static bool testGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result)
+{
+ if (name == testIdentifiers[ID_OBJECT_POINTER]) {
+ int32_t objectPointer = static_cast<int32_t>(reinterpret_cast<long long>(npobj));
+
+ INT32_TO_NPVARIANT(objectPointer, *result);
+ return true;
+ }
+
+ return false;
+}
+
+
+static bool testEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
+{
+ *count = NUM_TEST_IDENTIFIERS;
+
+ *value = (NPIdentifier*)browser->memalloc(NUM_ENUMERATABLE_TEST_IDENTIFIERS * sizeof(NPIdentifier));
+ memcpy(*value, testIdentifiers, sizeof(NPIdentifier) * NUM_ENUMERATABLE_TEST_IDENTIFIERS);
+
+ return true;
+}
+
+static bool testConstruct(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ browser->retainobject(npobj);
+
+ // Just return the same object.
+ OBJECT_TO_NPVARIANT(npobj, *result);
+ return true;
+}
+
+
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.h
new file mode 100644
index 0000000..1295fb7
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/TestObject.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2007 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. ``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 <WebKit/npapi.h>
+#include <WebKit/npruntime.h>
+
+NPClass *getTestClass(void);
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp
new file mode 100644
index 0000000..bb98ba2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2006, 2007 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. ``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.
+ */
+
+#import "PluginObject.h"
+
+#if __LP64__
+#define USE_COCOA_EVENT_MODEL 1
+#endif
+
+// Mach-o entry points
+extern "C" {
+ NPError NP_Initialize(NPNetscapeFuncs *browserFuncs);
+ NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs);
+ void NP_Shutdown(void);
+}
+
+// Mach-o entry points
+NPError NP_Initialize(NPNetscapeFuncs *browserFuncs)
+{
+ browser = browserFuncs;
+ return NPERR_NO_ERROR;
+}
+
+NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs)
+{
+ pluginFuncs->version = 11;
+ pluginFuncs->size = sizeof(pluginFuncs);
+ pluginFuncs->newp = NPP_New;
+ pluginFuncs->destroy = NPP_Destroy;
+ pluginFuncs->setwindow = NPP_SetWindow;
+ pluginFuncs->newstream = NPP_NewStream;
+ pluginFuncs->destroystream = NPP_DestroyStream;
+ pluginFuncs->asfile = NPP_StreamAsFile;
+ pluginFuncs->writeready = NPP_WriteReady;
+ pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
+ pluginFuncs->print = NPP_Print;
+ pluginFuncs->event = NPP_HandleEvent;
+ pluginFuncs->urlnotify = NPP_URLNotify;
+ pluginFuncs->getvalue = NPP_GetValue;
+ pluginFuncs->setvalue = NPP_SetValue;
+
+ return NPERR_NO_ERROR;
+}
+
+void NP_Shutdown(void)
+{
+}
+
+NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved)
+{
+#if USE_COCOA_EVENT_MODEL
+ // If the browser supports the Cocoa event model, enable it.
+ NPBool supportsCocoa;
+ if (browser->getvalue(instance, NPNVsupportsCocoaBool, &supportsCocoa) != NPERR_NO_ERROR)
+ supportsCocoa = FALSE;
+
+ if (!supportsCocoa)
+ return NPERR_INCOMPATIBLE_VERSION_ERROR;
+
+ browser->setvalue(instance, NPPVpluginEventModel, (void *)NPEventModelCocoa);
+#endif
+
+ if (browser->version >= 14) {
+ PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
+
+ for (int i = 0; i < argc; i++) {
+ if (strcasecmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
+ obj->onStreamLoad = strdup(argv[i]);
+ else if (strcasecmp(argn[i], "onStreamDestroy") == 0 && !obj->onStreamDestroy)
+ obj->onStreamDestroy = strdup(argv[i]);
+ else if (strcasecmp(argn[i], "onURLNotify") == 0 && !obj->onURLNotify)
+ obj->onURLNotify = strdup(argv[i]);
+ else if (strcasecmp(argn[i], "src") == 0 &&
+ strcasecmp(argv[i], "data:application/x-webkit-test-netscape,returnerrorfromnewstream") == 0)
+ obj->returnErrorFromNewStream = TRUE;
+ else if (strcasecmp(argn[i], "logfirstsetwindow") == 0)
+ obj->logSetWindow = TRUE;
+ }
+
+ instance->pdata = obj;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_Destroy(NPP instance, NPSavedData **save)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+ if (obj) {
+ if (obj->onStreamLoad)
+ free(obj->onStreamLoad);
+
+ if (obj->onStreamDestroy)
+ free(obj->onStreamDestroy);
+
+ if (obj->onURLNotify)
+ free(obj->onURLNotify);
+
+ if (obj->logDestroy)
+ printf("PLUGIN: NPP_Destroy\n");
+
+ browser->releaseobject(&obj->header);
+ }
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_SetWindow(NPP instance, NPWindow *window)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+
+ if (obj) {
+ if (obj->logSetWindow) {
+ printf("PLUGIN: NPP_SetWindow: %d %d\n", (int)window->width, (int)window->height);
+ obj->logSetWindow = false;
+ }
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+static void executeScript(const PluginObject* obj, const char* script)
+{
+ NPObject *windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString npScript;
+ npScript.UTF8Characters = script;
+ npScript.UTF8Length = strlen(script);
+
+ NPVariant browserResult;
+ browser->evaluate(obj->npp, windowScriptObject, &npScript, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+}
+
+NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+ obj->stream = stream;
+ *stype = NP_ASFILEONLY;
+
+ if (obj->returnErrorFromNewStream)
+ return NPERR_GENERIC_ERROR;
+
+ if (browser->version >= NPVERS_HAS_RESPONSE_HEADERS)
+ notifyStream(obj, stream->url, stream->headers);
+
+ if (obj->onStreamLoad)
+ executeScript(obj, obj->onStreamLoad);
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
+{
+ PluginObject* obj = (PluginObject*)instance->pdata;
+
+ if (obj->onStreamDestroy)
+ executeScript(obj, obj->onStreamDestroy);
+
+ return NPERR_NO_ERROR;
+}
+
+int32 NPP_WriteReady(NPP instance, NPStream *stream)
+{
+ return 0;
+}
+
+int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
+{
+ return 0;
+}
+
+void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
+{
+}
+
+void NPP_Print(NPP instance, NPPrint *platformPrint)
+{
+}
+
+int16 NPP_HandleEvent(NPP instance, void *event)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+ if (!obj->eventLogging)
+ return 0;
+
+#if USE_COCOA_EVENT_MODEL
+ // FIXME: Generate output that will match the Carbon event model
+ // so that the layout tests using this plug-in will work in either model.
+ NPCocoaEvent *cocoaEvent = static_cast<NPCocoaEvent*>(event);
+ switch (cocoaEvent->type) {
+ case NPCocoaEventWindowFocusChanged:
+ case NPCocoaEventFocusChanged:
+ return 1;
+
+ case NPCocoaEventDrawRect:
+ return 1;
+
+ case NPCocoaEventKeyDown:
+ case NPCocoaEventKeyUp:
+ case NPCocoaEventFlagsChanged:
+ return 1;
+
+ case NPCocoaEventMouseDown:
+ case NPCocoaEventMouseUp:
+
+ case NPCocoaEventMouseMoved:
+ case NPCocoaEventMouseEntered:
+ case NPCocoaEventMouseExited:
+ case NPCocoaEventMouseDragged:
+ case NPCocoaEventScrollWheel:
+ return 1;
+ }
+#else
+ EventRecord* evt = static_cast<EventRecord*>(event);
+ Point pt = { evt->where.v, evt->where.h };
+ switch (evt->what) {
+ case nullEvent:
+ // these are delivered non-deterministically, don't log.
+ break;
+ case mouseDown:
+ GlobalToLocal(&pt);
+ printf("PLUGIN: mouseDown at (%d, %d)\n", pt.h, pt.v);
+ break;
+ case mouseUp:
+ GlobalToLocal(&pt);
+ printf("PLUGIN: mouseUp at (%d, %d)\n", pt.h, pt.v);
+ break;
+ case keyDown:
+ printf("PLUGIN: keyDown '%c'\n", (char)(evt->message & 0xFF));
+ break;
+ case keyUp:
+ printf("PLUGIN: keyUp '%c'\n", (char)(evt->message & 0xFF));
+ break;
+ case autoKey:
+ printf("PLUGIN: autoKey '%c'\n", (char)(evt->message & 0xFF));
+ break;
+ case updateEvt:
+ printf("PLUGIN: updateEvt\n");
+ break;
+ case diskEvt:
+ printf("PLUGIN: diskEvt\n");
+ break;
+ case activateEvt:
+ printf("PLUGIN: activateEvt\n");
+ break;
+ case osEvt:
+ printf("PLUGIN: osEvt - ");
+ switch ((evt->message & 0xFF000000) >> 24) {
+ case suspendResumeMessage:
+ printf("%s\n", (evt->message & 0x1) ? "resume" : "suspend");
+ break;
+ case mouseMovedMessage:
+ printf("mouseMoved\n");
+ break;
+ default:
+ printf("%08lX\n", evt->message);
+ }
+ break;
+ case kHighLevelEvent:
+ printf("PLUGIN: kHighLevelEvent\n");
+ break;
+ // NPAPI events
+ case getFocusEvent:
+ printf("PLUGIN: getFocusEvent\n");
+ break;
+ case loseFocusEvent:
+ printf("PLUGIN: loseFocusEvent\n");
+ break;
+ case adjustCursorEvent:
+ printf("PLUGIN: adjustCursorEvent\n");
+ break;
+ default:
+ printf("PLUGIN: event %d\n", evt->what);
+ }
+#endif
+ return 0;
+}
+
+void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
+{
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+
+ if (obj->onURLNotify)
+ executeScript(obj, obj->onURLNotify);
+
+ handleCallback(obj, url, reason, notifyData);
+}
+
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
+{
+ if (variable == NPPVpluginScriptableNPObject) {
+ void **v = (void **)value;
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+ // Return value is expected to be retained
+ browser->retainobject((NPObject *)obj);
+ *v = obj;
+ return NPERR_NO_ERROR;
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
+{
+ return NPERR_GENERIC_ERROR;
+}
diff --git a/WebKitTools/DumpRenderTree/WorkQueue.cpp b/WebKitTools/DumpRenderTree/WorkQueue.cpp
new file mode 100644
index 0000000..0891b9c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/WorkQueue.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 "WorkQueue.h"
+
+#include "WorkQueueItem.h"
+#include <wtf/Assertions.h>
+
+static const unsigned queueLength = 1024;
+
+static WorkQueueItem* theQueue[queueLength];
+static unsigned startOfQueue;
+static unsigned endOfQueue;
+
+WorkQueue* WorkQueue::shared()
+{
+ static WorkQueue* sharedInstance = new WorkQueue;
+ return sharedInstance;
+}
+
+WorkQueue::WorkQueue()
+ : m_frozen(false)
+{
+}
+
+void WorkQueue::queue(WorkQueueItem* item)
+{
+ ASSERT(endOfQueue < queueLength);
+ ASSERT(endOfQueue >= startOfQueue);
+
+ if (m_frozen) {
+ delete item;
+ return;
+ }
+
+ theQueue[endOfQueue++] = item;
+}
+
+WorkQueueItem* WorkQueue::dequeue()
+{
+ ASSERT(endOfQueue >= startOfQueue);
+
+ if (startOfQueue == endOfQueue)
+ return 0;
+
+ return theQueue[startOfQueue++];
+}
+
+unsigned WorkQueue::count()
+{
+ return endOfQueue - startOfQueue;
+}
+
+void WorkQueue::clear()
+{
+ for (unsigned i = startOfQueue; i < endOfQueue; ++i) {
+ delete theQueue[i];
+ theQueue[i] = 0;
+ }
+
+ startOfQueue = 0;
+ endOfQueue = 0;
+}
diff --git a/WebKitTools/DumpRenderTree/WorkQueue.h b/WebKitTools/DumpRenderTree/WorkQueue.h
new file mode 100644
index 0000000..c2850c5
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/WorkQueue.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 WorkQueue_h
+#define WorkQueue_h
+
+class WorkQueueItem;
+
+class WorkQueue {
+public:
+ static WorkQueue* shared();
+
+ void queue(WorkQueueItem*);
+ WorkQueueItem* dequeue();
+ void clear();
+ unsigned count();
+
+ void setFrozen(bool b) { m_frozen = b; }
+
+private:
+ WorkQueue();
+
+ bool m_frozen;
+};
+
+#endif // !defined(WorkQueue_h)
diff --git a/WebKitTools/DumpRenderTree/WorkQueueItem.h b/WebKitTools/DumpRenderTree/WorkQueueItem.h
new file mode 100644
index 0000000..fd15329
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/WorkQueueItem.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 WorkQueueItem_h
+#define WorkQueueItem_h
+
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSBase.h>
+
+class WorkQueueItem {
+public:
+ virtual ~WorkQueueItem() { }
+ virtual void invoke() const = 0;
+};
+
+class LoadItem : public WorkQueueItem {
+public:
+ LoadItem(const JSStringRef url, const JSStringRef target)
+ : m_url(url)
+ , m_target(target)
+ {
+ }
+
+ const JSStringRef url() const { return m_url.get(); }
+ const JSStringRef target() const { return m_target.get(); }
+
+ virtual void invoke() const;
+
+private:
+ JSRetainPtr<JSStringRef> m_url;
+ JSRetainPtr<JSStringRef> m_target;
+};
+
+class ReloadItem : public WorkQueueItem {
+public:
+ virtual void invoke() const;
+};
+
+class ScriptItem : public WorkQueueItem {
+public:
+ ScriptItem(const JSStringRef script)
+ : m_script(script)
+ {
+ }
+
+ const JSStringRef script() const { return m_script.get(); }
+
+ virtual void invoke() const;
+
+private:
+ JSRetainPtr<JSStringRef> m_script;
+};
+
+class BackForwardItem : public WorkQueueItem {
+public:
+ virtual void invoke() const;
+
+protected:
+ BackForwardItem(int howFar)
+ : m_howFar(howFar)
+ {
+ }
+
+ int m_howFar;
+};
+
+class BackItem : public BackForwardItem {
+public:
+ BackItem(unsigned howFar)
+ : BackForwardItem(-howFar)
+ {
+ }
+};
+
+class ForwardItem : public BackForwardItem {
+public:
+ ForwardItem(unsigned howFar)
+ : BackForwardItem(howFar)
+ {
+ }
+};
+
+#endif // !defined(WorkQueueItem_h)
diff --git a/WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp b/WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp
new file mode 100644
index 0000000..1e55e78
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2005 Ben La Monica <ben.lamonica@gmail.com>. 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 THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#define min min
+
+#include <CoreGraphics/CGBitmapContext.h>
+#include <CoreGraphics/CGImage.h>
+#include <ImageIO/CGImageDestination.h>
+#include <stdio.h>
+#include <wtf/Platform.h>
+#include <wtf/RetainPtr.h>
+
+#if PLATFORM(WIN)
+#include <fcntl.h>
+#include <io.h>
+#include <wtf/MathExtras.h>
+#endif
+
+#if PLATFORM(MAC)
+#include <LaunchServices/UTCoreTypes.h>
+#endif
+
+#ifndef CGFLOAT_DEFINED
+#ifdef __LP64__
+typedef double CGFloat;
+#else
+typedef float CGFloat;
+#endif
+#define CGFLOAT_DEFINED 1
+#endif
+
+using namespace std;
+
+#if PLATFORM(WIN)
+static inline float strtof(const char *nptr, char **endptr)
+{
+ return strtod(nptr, endptr);
+}
+static const CFStringRef kUTTypePNG = CFSTR("public.png");
+#endif
+
+static RetainPtr<CGImageRef> createImageFromStdin(int bytesRemaining)
+{
+ unsigned char buffer[2048];
+ RetainPtr<CFMutableDataRef> data(AdoptCF, CFDataCreateMutable(0, bytesRemaining));
+
+ while (bytesRemaining > 0) {
+ size_t bytesToRead = min(bytesRemaining, 2048);
+ size_t bytesRead = fread(buffer, 1, bytesToRead, stdin);
+ CFDataAppendBytes(data.get(), buffer, static_cast<CFIndex>(bytesRead));
+ bytesRemaining -= static_cast<int>(bytesRead);
+ }
+ RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
+ return RetainPtr<CGImageRef>(AdoptCF, CGImageCreateWithPNGDataProvider(dataProvider.get(), 0, false, kCGRenderingIntentDefault));
+}
+
+static void releaseMallocBuffer(void* info, const void* data, size_t size)
+{
+ free((void*)data);
+}
+
+static RetainPtr<CGImageRef> createDifferenceImage(CGImageRef baseImage, CGImageRef testImage, float& difference)
+{
+ static RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CGImageRef> diffImage;
+
+ size_t width = CGImageGetWidth(baseImage);
+ size_t height = CGImageGetHeight(baseImage);
+ size_t rowBytes = width * 4;
+
+ // Draw base image in bitmap context
+ void* baseBuffer = calloc(height, rowBytes);
+ CGContextRef baseContext = CGBitmapContextCreate(baseBuffer, width, height, 8, rowBytes, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
+ CGContextDrawImage(baseContext, CGRectMake(0, 0, width, height), baseImage);
+ CGContextRelease(baseContext);
+
+ // Draw test image in bitmap context
+ void* buffer = calloc(height, rowBytes);
+ CGContextRef context = CGBitmapContextCreate(buffer, width, height, 8, rowBytes, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
+ CGContextDrawImage(context, CGRectMake(0, 0, width, height), testImage);
+ CGContextRelease(context);
+
+ // Compare the content of the 2 bitmaps
+ void* diffBuffer = malloc(width * height);
+ float count = 0.0f;
+ float sum = 0.0f;
+ float maxDistance = 0.0f;
+ unsigned char* basePixel = (unsigned char*)baseBuffer;
+ unsigned char* pixel = (unsigned char*)buffer;
+ unsigned char* diff = (unsigned char*)diffBuffer;
+ for (size_t y = 0; y < height; ++y) {
+ for (size_t x = 0; x < width; ++x) {
+ float red = (pixel[0] - basePixel[0]) / max<float>(255 - basePixel[0], basePixel[0]);
+ float green = (pixel[1] - basePixel[1]) / max<float>(255 - basePixel[1], basePixel[1]);
+ float blue = (pixel[2] - basePixel[2]) / max<float>(255 - basePixel[2], basePixel[2]);
+ float alpha = (pixel[3] - basePixel[3]) / max<float>(255 - basePixel[3], basePixel[3]);
+ float distance = sqrtf(red * red + green * green + blue * blue + alpha * alpha) / 2.0f;
+
+ *diff++ = (unsigned char)(distance * 255.0f);
+
+ if (distance >= 1.0f / 255.0f) {
+ count += 1.0f;
+ sum += distance;
+ if (distance > maxDistance)
+ maxDistance = distance;
+ }
+
+ basePixel += 4;
+ pixel += 4;
+ }
+ }
+
+ // Compute the difference as a percentage combining both the number of different pixels and their difference amount i.e. the average distance over the entire image
+ if (count > 0.0f)
+ difference = 100.0f * sum / (height * width);
+ else
+ difference = 0.0f;
+
+ // Generate a normalized diff image if there is any difference
+ if (difference > 0.0f) {
+ if (maxDistance < 1.0f) {
+ diff = (unsigned char*)diffBuffer;
+ for(size_t p = 0; p < height * width; ++p)
+ diff[p] = diff[p] / maxDistance;
+ }
+
+ CGDataProviderRef provider = CGDataProviderCreateWithData(0, diffBuffer, width * height, releaseMallocBuffer);
+ CGColorSpaceRef diffColorspace = CGColorSpaceCreateDeviceGray();
+ diffImage.adoptCF(CGImageCreate(width, height, 8, 8, width, diffColorspace, 0, provider, 0, false, kCGRenderingIntentDefault));
+ CGColorSpaceRelease(diffColorspace);
+ CGDataProviderRelease(provider);
+ }
+ else
+ free(diffBuffer);
+
+ // Destroy drawing buffers
+ if (buffer)
+ free(buffer);
+ if (baseBuffer)
+ free(baseBuffer);
+
+ return diffImage;
+}
+
+static inline bool imageHasAlpha(CGImageRef image)
+{
+ CGImageAlphaInfo info = CGImageGetAlphaInfo(image);
+
+ return (info >= kCGImageAlphaPremultipliedLast) && (info <= kCGImageAlphaFirst);
+}
+
+int main(int argc, const char* argv[])
+{
+#if PLATFORM(WIN)
+ _setmode(0, _O_BINARY);
+ _setmode(1, _O_BINARY);
+#endif
+
+ float tolerance = 0.0f;
+
+ for (int i = 1; i < argc; ++i) {
+ if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--tolerance")) {
+ if (i >= argc - 1)
+ exit(1);
+ tolerance = strtof(argv[i + 1], 0);
+ ++i;
+ continue;
+ }
+ }
+
+ char buffer[2048];
+ RetainPtr<CGImageRef> actualImage;
+ RetainPtr<CGImageRef> baselineImage;
+
+ while (fgets(buffer, sizeof(buffer), stdin)) {
+ // remove the CR
+ char* newLineCharacter = strchr(buffer, '\n');
+ if (newLineCharacter)
+ *newLineCharacter = '\0';
+
+ if (!strncmp("Content-Length: ", buffer, 16)) {
+ strtok(buffer, " ");
+ int imageSize = strtol(strtok(0, " "), 0, 10);
+
+ if (imageSize > 0 && !actualImage)
+ actualImage = createImageFromStdin(imageSize);
+ else if (imageSize > 0 && !baselineImage)
+ baselineImage = createImageFromStdin(imageSize);
+ else
+ fputs("error, image size must be specified.\n", stdout);
+ }
+
+ if (actualImage && baselineImage) {
+ RetainPtr<CGImageRef> diffImage;
+ float difference = 100.0f;
+
+ if ((CGImageGetWidth(actualImage.get()) == CGImageGetWidth(baselineImage.get())) && (CGImageGetHeight(actualImage.get()) == CGImageGetHeight(baselineImage.get())) && (imageHasAlpha(actualImage.get()) == imageHasAlpha(baselineImage.get()))) {
+ diffImage = createDifferenceImage(actualImage.get(), baselineImage.get(), difference); // difference is passed by reference
+ if (difference <= tolerance)
+ difference = 0.0f;
+ else {
+ difference = roundf(difference * 100.0f) / 100.0f;
+ difference = max(difference, 0.01f); // round to 2 decimal places
+ }
+ } else
+ fputs("error, test and reference image have different properties.\n", stderr);
+
+ if (difference > 0.0f) {
+ if (diffImage) {
+ RetainPtr<CFMutableDataRef> imageData(AdoptCF, CFDataCreateMutable(0, 0));
+ RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0));
+ CGImageDestinationAddImage(imageDest.get(), diffImage.get(), 0);
+ CGImageDestinationFinalize(imageDest.get());
+ printf("Content-Length: %lu\n", CFDataGetLength(imageData.get()));
+ fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout);
+ }
+
+ fprintf(stdout, "diff: %01.2f%% failed\n", difference);
+ } else
+ fprintf(stdout, "diff: %01.2f%% passed\n", difference);
+
+ actualImage = 0;
+ baselineImage = 0;
+ }
+
+ fflush(stdout);
+ }
+
+ return 0;
+}
diff --git a/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp
new file mode 100644
index 0000000..2320e19
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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>
+ *
+ * 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 "PixelDumpSupportCG.h"
+
+#include "DumpRenderTree.h"
+#include "LayoutTestController.h"
+#include <ImageIO/CGImageDestination.h>
+#include <algorithm>
+#include <ctype.h>
+#include <wtf/Assertions.h>
+#include <wtf/RefPtr.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/StringExtras.h>
+
+#if PLATFORM(WIN)
+#include "MD5.h"
+#elif PLATFORM(MAC)
+#include <LaunchServices/UTCoreTypes.h>
+#define COMMON_DIGEST_FOR_OPENSSL
+#include <CommonCrypto/CommonDigest.h>
+#endif
+
+#if PLATFORM(WIN)
+static const CFStringRef kUTTypePNG = CFSTR("public.png");
+#endif
+
+static void printPNG(CGImageRef image)
+{
+ RetainPtr<CFMutableDataRef> imageData(AdoptCF, CFDataCreateMutable(0, 0));
+ RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0));
+ CGImageDestinationAddImage(imageDest.get(), image, 0);
+ CGImageDestinationFinalize(imageDest.get());
+
+ printf("Content-Type: %s\n", "image/png");
+ printf("Content-Length: %lu\n", CFDataGetLength(imageData.get()));
+
+ fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout);
+}
+
+static void computeMD5HashStringForBitmapContext(CGContextRef bitmapContext, char hashString[33])
+{
+ ASSERT(CGBitmapContextGetBitsPerPixel(bitmapContext) == 32); // ImageDiff assumes 32 bit RGBA, we must as well.
+ size_t pixelsHigh = CGBitmapContextGetHeight(bitmapContext);
+ size_t pixelsWide = CGBitmapContextGetWidth(bitmapContext);
+ size_t bytesPerRow = CGBitmapContextGetBytesPerRow(bitmapContext);
+
+ // We need to swap the bytes to ensure consistent hashes independently of endianness
+ MD5_CTX md5Context;
+ MD5_Init(&md5Context);
+ unsigned char* bitmapData = static_cast<unsigned char*>(CGBitmapContextGetData(bitmapContext));
+#if PLATFORM(MAC)
+ if ((CGBitmapContextGetBitmapInfo(bitmapContext) & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Big) {
+ for (unsigned row = 0; row < pixelsHigh; row++) {
+ uint32_t buffer[pixelsWide];
+ for (unsigned column = 0; column < pixelsWide; column++)
+ buffer[column] = OSReadLittleInt32(bitmapData, 4 * column);
+ MD5_Update(&md5Context, buffer, 4 * pixelsWide);
+ bitmapData += bytesPerRow;
+ }
+ } else
+#endif
+ {
+ for (unsigned row = 0; row < pixelsHigh; row++) {
+ MD5_Update(&md5Context, bitmapData, 4 * pixelsWide);
+ bitmapData += bytesPerRow;
+ }
+ }
+ unsigned char hash[16];
+ MD5_Final(hash, &md5Context);
+
+ hashString[0] = '\0';
+ for (int i = 0; i < 16; i++)
+ snprintf(hashString, 33, "%s%02x", hashString, hash[i]);
+}
+
+void dumpWebViewAsPixelsAndCompareWithExpected(const std::string& expectedHash)
+{
+ RefPtr<BitmapContext> context;
+
+#if PLATFORM(MAC)
+ context = createBitmapContextFromWebView(gLayoutTestController->testOnscreen(), gLayoutTestController->testRepaint(), gLayoutTestController->testRepaintSweepHorizontally(), gLayoutTestController->dumpSelectionRect());
+#endif
+ ASSERT(context);
+
+ // Compute the hash of the bitmap context pixels
+ char actualHash[33];
+ computeMD5HashStringForBitmapContext(context->cgContext(), actualHash);
+ printf("\nActualHash: %s\n", actualHash);
+
+ // Check the computed hash against the expected one and dump image on mismatch
+ bool dumpImage = true;
+ if (expectedHash.length() > 0) {
+ ASSERT(expectedHash.length() == 32);
+
+ printf("\nExpectedHash: %s\n", expectedHash.c_str());
+
+ if (expectedHash == actualHash) // FIXME: do case insensitive compare
+ dumpImage = false;
+ }
+
+ if (dumpImage) {
+ RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(context->cgContext()));
+ printPNG(image.get());
+ }
+}
diff --git a/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h
new file mode 100644
index 0000000..84350e8
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h
@@ -0,0 +1,80 @@
+/*
+ * 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>
+ *
+ * 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 PixelDumpSupportCG_h
+#define PixelDumpSupportCG_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RetainPtr.h>
+
+typedef struct CGContext* CGContextRef;
+
+#if PLATFORM(MAC)
+typedef void* PlatformBitmapBuffer;
+#elif PLATFORM(WIN)
+typedef HBITMAP PlatformBitmapBuffer;
+#endif
+
+class BitmapContext : public RefCounted<BitmapContext> {
+public:
+ static PassRefPtr<BitmapContext> createByAdoptingBitmapAndContext(PlatformBitmapBuffer buffer, CGContextRef context)
+ {
+ return adoptRef(new BitmapContext(buffer, context));
+ }
+
+ ~BitmapContext()
+ {
+ if (m_buffer)
+#if PLATFORM(MAC)
+ free(m_buffer);
+#elif PLATFORM(WIN)
+ DeleteObject(m_buffer);
+#endif
+ }
+
+ CGContextRef cgContext() const { return m_context.get(); }
+
+private:
+
+ BitmapContext(PlatformBitmapBuffer buffer, CGContextRef context)
+ : m_buffer(buffer)
+ , m_context(AdoptCF, context)
+ {
+ }
+
+ PlatformBitmapBuffer m_buffer;
+ RetainPtr<CGContextRef> m_context;
+
+};
+
+PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool onscreen, bool incrementalRepaint, bool sweepHorizontally, bool drawSelectionRect);
+
+#endif // PixelDumpSupportCG_h
diff --git a/WebKitTools/DumpRenderTree/config.h b/WebKitTools/DumpRenderTree/config.h
new file mode 100644
index 0000000..4775ae2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/config.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Nuanti Ltd.
+ *
+ * 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.
+ *
+ */
+
+#define Config_H
+
+#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H
+#include "autotoolsconfig.h"
+#endif
+
+#include <wtf/Platform.h>
+
+#if PLATFORM(WIN)
+#define WTF_PLATFORM_CF 1
+
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+
+#undef WINVER
+#define WINVER 0x0500
+
+// If we don't define these, they get defined in windef.h.
+// We want to use std::min and std::max
+#undef max
+#define max max
+#undef min
+#define min min
+
+#undef _WINSOCKAPI_
+#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h
+#endif // PLATFORM(WIN)
diff --git a/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher100.ttf b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher100.ttf
new file mode 100644
index 0000000..22b00de
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher100.ttf
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher200.ttf b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher200.ttf
new file mode 100644
index 0000000..1ccadba
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher200.ttf
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher300.ttf b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher300.ttf
new file mode 100644
index 0000000..ab5563d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher300.ttf
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher400.ttf b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher400.ttf
new file mode 100644
index 0000000..56d279e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher400.ttf
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher500.ttf b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher500.ttf
new file mode 100644
index 0000000..d827d7d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher500.ttf
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher600.ttf b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher600.ttf
new file mode 100644
index 0000000..9141596
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher600.ttf
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher700.ttf b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher700.ttf
new file mode 100644
index 0000000..a2d0505
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher700.ttf
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher800.ttf b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher800.ttf
new file mode 100644
index 0000000..d0f354b
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher800.ttf
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher900.ttf b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher900.ttf
new file mode 100644
index 0000000..6b895ca
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/fonts/WebKitWeightWatcher900.ttf
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
new file mode 100644
index 0000000..13b914d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2008 Alp Toker <alp@nuanti.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 "DumpRenderTree.h"
+
+#include "LayoutTestController.h"
+#include "WorkQueue.h"
+#include "WorkQueueItem.h"
+
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+#include <JavaScriptCore/JavaScript.h>
+
+#include <wtf/Assertions.h>
+
+#include <cassert>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+
+using namespace std;
+
+extern "C" {
+// This API is not yet public.
+extern GSList* webkit_web_frame_get_children(WebKitWebFrame* frame);
+extern gchar* webkit_web_frame_get_inner_text(WebKitWebFrame* frame);
+extern gchar* webkit_web_frame_dump_render_tree(WebKitWebFrame* frame);
+}
+
+volatile bool done;
+static bool printSeparators;
+static int dumpPixels;
+static int dumpTree = 1;
+
+LayoutTestController* gLayoutTestController = 0;
+static WebKitWebView* webView;
+WebKitWebFrame* mainFrame = 0;
+WebKitWebFrame* topLoadingFrame = 0;
+guint waitToDumpWatchdog = 0;
+
+const unsigned maxViewHeight = 600;
+const unsigned maxViewWidth = 800;
+
+static gchar* autocorrectURL(const gchar* url)
+{
+ if (strncmp("http://", url, 7) != 0 && strncmp("https://", url, 8) != 0) {
+ GString* string = g_string_new("file://");
+ g_string_append(string, url);
+ return g_string_free(string, FALSE);
+ }
+
+ return g_strdup(url);
+}
+
+static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
+{
+ return strstr(pathOrURL, "loading/");
+}
+
+void dumpFrameScrollPosition(WebKitWebFrame* frame)
+{
+
+}
+
+void displayWebView()
+{
+
+}
+
+static void appendString(gchar*& target, gchar* string)
+{
+ gchar* oldString = target;
+ target = g_strconcat(target, string, NULL);
+ g_free(oldString);
+}
+
+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);
+
+ gchar* innerText = webkit_web_frame_get_inner_text(frame);
+ if (isMainFrame)
+ result = g_strdup_printf("%s\n", innerText);
+ else {
+ const gchar* frameName = webkit_web_frame_get_name(frame);
+ result = g_strdup_printf("\n--------\nFrame: '%s'\n--------\n%s\n", frameName, innerText);
+ }
+ g_free(innerText);
+
+ if (gLayoutTestController->dumpChildFramesAsText()) {
+ GSList* children = webkit_web_frame_get_children(frame);
+ for (GSList* child = children; child; child = g_slist_next(child))
+ appendString(result, dumpFramesAsText((WebKitWebFrame*)children->data));
+ g_slist_free(children);
+ }
+
+ return result;
+}
+
+static void invalidateAnyPreviousWaitToDumpWatchdog()
+{
+ if (waitToDumpWatchdog) {
+ g_source_remove(waitToDumpWatchdog);
+ waitToDumpWatchdog = 0;
+ }
+}
+
+void dump()
+{
+ invalidateAnyPreviousWaitToDumpWatchdog();
+ if (dumpTree) {
+ char* result = 0;
+
+ bool dumpAsText = gLayoutTestController->dumpAsText();
+ // FIXME: Also dump text resuls as text.
+ gLayoutTestController->setDumpAsText(dumpAsText);
+ if (gLayoutTestController->dumpAsText())
+ result = dumpFramesAsText(mainFrame);
+ else {
+ bool isSVGW3CTest = (gLayoutTestController->testPathOrURL().find("svg/W3C-SVG-1.1") != string::npos);
+ GtkAllocation size;
+ size.width = isSVGW3CTest ? 480 : maxViewWidth;
+ size.height = isSVGW3CTest ? 360 : maxViewHeight;
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &size);
+
+ result = webkit_web_frame_dump_render_tree(mainFrame);
+ }
+
+ if (!result) {
+ const char* errorMessage;
+ if (gLayoutTestController->dumpAsText())
+ errorMessage = "[documentElement innerText]";
+ else if (gLayoutTestController->dumpDOMAsWebArchive())
+ errorMessage = "[[mainFrame DOMDocument] webArchive]";
+ else if (gLayoutTestController->dumpSourceAsWebArchive())
+ errorMessage = "[[mainFrame dataSource] webArchive]";
+ else
+ errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";
+ printf("ERROR: nil result from %s", errorMessage);
+ } else {
+ printf("%s", result);
+ g_free(result);
+ if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive())
+ dumpFrameScrollPosition(mainFrame);
+ }
+
+ if (gLayoutTestController->dumpBackForwardList()) {
+ // FIXME: not implemented
+ }
+
+ if (printSeparators) {
+ puts("#EOF"); // terminate the content block
+ fputs("#EOF\n", stderr);
+ fflush(stdout);
+ fflush(stderr);
+ }
+ }
+
+ if (dumpPixels) {
+ if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive()) {
+ // FIXME: Add support for dumping pixels
+ }
+ }
+
+ // FIXME: call displayWebView here when we support --paint
+
+ puts("#EOF"); // terminate the (possibly empty) pixels block
+
+ fflush(stdout);
+ fflush(stderr);
+
+ done = true;
+}
+
+static void setDefaultsToConsistentStateValuesForTesting()
+{
+ WebKitWebSettings *settings = webkit_web_view_get_settings(webView);
+
+ g_object_set(G_OBJECT(settings),
+ "default-font-family", "Times",
+ "monospace-font-family", "Courier",
+ "serif-font-family", "Times",
+ "sans-serif-font-family", "Helvetica",
+ "default-font-size", 16,
+ "default-monospace-font-size", 13,
+ "minimum-font-size", 1,
+ NULL);
+}
+
+static void runTest(const string& testPathOrURL)
+{
+ ASSERT(!testPathOrURL.empty());
+
+ // Look for "'" as a separator between the path or URL, and the pixel dump hash that follows.
+ string pathOrURL(testPathOrURL);
+ string expectedPixelHash;
+
+ size_t separatorPos = pathOrURL.find("'");
+ if (separatorPos != string::npos) {
+ pathOrURL = string(testPathOrURL, 0, separatorPos);
+ expectedPixelHash = string(testPathOrURL, separatorPos + 1);
+ }
+
+ gchar* url = autocorrectURL(pathOrURL.c_str());
+ const string testURL(url);
+
+ gLayoutTestController = new LayoutTestController(testURL, expectedPixelHash);
+ topLoadingFrame = 0;
+ done = false;
+
+ if (shouldLogFrameLoadDelegates(pathOrURL.c_str()))
+ gLayoutTestController->setDumpFrameLoadCallbacks(true);
+
+ WorkQueue::shared()->clear();
+ WorkQueue::shared()->setFrozen(false);
+
+ webkit_web_view_open(webView, url);
+
+ g_free(url);
+ url = NULL;
+
+ while (!done)
+ g_main_context_iteration(NULL, TRUE);
+
+ // A blank load seems to be necessary to reset state after certain tests.
+ webkit_web_view_open(webView, "about:blank");
+
+ gLayoutTestController->deref();
+ gLayoutTestController = 0;
+}
+
+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)
+{
+ // quit doing work once a load is in progress
+ while (WorkQueue::shared()->count() > 0 && !topLoadingFrame) {
+ WorkQueueItem* item = WorkQueue::shared()->dequeue();
+ ASSERT(item);
+ item->invoke();
+ delete item;
+ }
+
+ // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
+ if (!topLoadingFrame && !gLayoutTestController->waitToDump())
+ dump();
+
+ return FALSE;
+}
+
+static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*)
+{
+ if (frame != topLoadingFrame)
+ return;
+
+ topLoadingFrame = 0;
+ WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
+ if (gLayoutTestController->waitToDump())
+ return;
+
+ if (WorkQueue::shared()->count())
+ g_timeout_add(0, processWork, 0);
+ else
+ dump();
+}
+
+static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* frame, JSGlobalContextRef context, JSObjectRef windowObject, gpointer data)
+{
+ JSValueRef exception = 0;
+ assert(gLayoutTestController);
+
+ gLayoutTestController->makeWindowObject(context, windowObject, &exception);
+ assert(!exception);
+}
+
+static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data)
+{
+ fprintf(stdout, "CONSOLE MESSAGE: line %d: %s\n", line, message);
+ return TRUE;
+}
+
+
+static gboolean webViewScriptAlert(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gpointer data)
+{
+ fprintf(stdout, "ALERT: %s\n", message);
+ 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 (gLayoutTestController->dumpTitleChanges() && !done)
+ printf("TITLE CHANGED: %s\n", title ? title : "");
+}
+
+int main(int argc, char* argv[])
+{
+ g_thread_init(NULL);
+ gtk_init(&argc, &argv);
+
+ struct option options[] = {
+ {"notree", no_argument, &dumpTree, false},
+ {"pixel-tests", no_argument, &dumpPixels, true},
+ {"tree", no_argument, &dumpTree, true},
+ {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;
+ }
+
+ GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
+ GtkContainer* container = GTK_CONTAINER(gtk_fixed_new());
+ gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(container));
+ gtk_widget_realize(window);
+
+ webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ gtk_container_add(container, GTK_WIDGET(webView));
+ gtk_widget_realize(GTK_WIDGET(webView));
+ mainFrame = webkit_web_view_get_main_frame(webView);
+
+ g_signal_connect(G_OBJECT(webView), "load-started", G_CALLBACK(webViewLoadStarted), 0);
+ g_signal_connect(G_OBJECT(webView), "load-finished", G_CALLBACK(webViewLoadFinished), 0);
+ g_signal_connect(G_OBJECT(webView), "window-object-cleared", G_CALLBACK(webViewWindowObjectCleared), 0);
+ g_signal_connect(G_OBJECT(webView), "console-message", G_CALLBACK(webViewConsoleMessage), 0);
+ g_signal_connect(G_OBJECT(webView), "script-alert", G_CALLBACK(webViewScriptAlert), 0);
+ g_signal_connect(G_OBJECT(webView), "script-prompt", G_CALLBACK(webViewScriptPrompt), 0);
+ g_signal_connect(G_OBJECT(webView), "script-confirm", G_CALLBACK(webViewScriptConfirm), 0);
+ g_signal_connect(G_OBJECT(webView), "title-changed", G_CALLBACK(webViewTitleChanged), 0);
+
+ setDefaultsToConsistentStateValuesForTesting();
+
+ if (argc == optind+1 && strcmp(argv[optind], "-") == 0) {
+ char filenameBuffer[2048];
+ printSeparators = true;
+ while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
+ char* newLineCharacter = strchr(filenameBuffer, '\n');
+ if (newLineCharacter)
+ *newLineCharacter = '\0';
+
+ if (strlen(filenameBuffer) == 0)
+ continue;
+
+ runTest(filenameBuffer);
+ }
+ } else {
+ printSeparators = (optind < argc-1 || (dumpPixels && dumpTree));
+ for (int i = optind; i != argc; ++i)
+ runTest(argv[i]);
+ }
+
+ return 0;
+}
diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h b/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h
new file mode 100644
index 0000000..1d2f179
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h
@@ -0,0 +1,41 @@
+/*
+ * 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 <webkit/webkitdefines.h>
+#include <JavaScriptCore/JSBase.h>
+
+extern WebKitWebFrame* mainFrame;
+extern WebKitWebFrame* topLoadingFrame;
+extern guint waitToDumpWatchdog;
+
+gchar* JSStringCopyUTF8CString(JSStringRef jsString);
+
+#endif // DumpRenderTreeGtk_h
diff --git a/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp
new file mode 100644
index 0000000..35f1685
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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"
+
+void GCController::collect() const
+{
+}
+
+void GCController::collectOnAlternateThread(bool waitUntilDone) const
+{
+}
+
+size_t GCController::getJSObjectCount() const
+{
+ return 0;
+}
diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
new file mode 100644
index 0000000..3a01e60
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2008 Nuanti Ltd.
+ *
+ * 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 "LayoutTestController.h"
+
+#include "DumpRenderTree.h"
+#include "WorkQueue.h"
+#include "WorkQueueItem.h"
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSStringRef.h>
+
+#include <glib.h>
+#include <webkit/webkit.h>
+
+LayoutTestController::~LayoutTestController()
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::addDisallowedURL(JSStringRef url)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::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);
+ // FIXME: implement add_item()
+ //webkit_web_back_forward_list_add_item(list, item);
+ webkit_web_back_forward_list_go_to_item(list, item);
+ g_object_unref(item);
+}
+
+JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
+{
+ // FIXME: implement
+ return 0;
+}
+
+JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
+{
+ // FIXME: implement
+ return 0;
+}
+
+void LayoutTestController::display()
+{
+ displayWebView();
+}
+
+void LayoutTestController::keepWebHistory()
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::notifyDone()
+{
+ if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
+ dump();
+ m_waitToDump = false;
+}
+
+JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
+{
+ // Function introduced in r28690. This may need special-casing on Windows.
+ return JSStringRetain(url); // Do nothing on Unix.
+}
+
+void LayoutTestController::queueBackNavigation(int howFarBack)
+{
+ WorkQueue::shared()->queue(new BackItem(howFarBack));
+}
+
+void LayoutTestController::queueForwardNavigation(int howFarForward)
+{
+ WorkQueue::shared()->queue(new ForwardItem(howFarForward));
+}
+
+void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
+{
+ // FIXME: We need to resolve relative URLs here
+ WorkQueue::shared()->queue(new LoadItem(url, target));
+}
+
+void LayoutTestController::queueReload()
+{
+ WorkQueue::shared()->queue(new ReloadItem);
+}
+
+void LayoutTestController::queueScript(JSStringRef script)
+{
+ WorkQueue::shared()->queue(new ScriptItem(script));
+}
+
+void LayoutTestController::setAcceptsEditing(bool acceptsEditing)
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ webkit_web_view_set_editable(webView, acceptsEditing);
+}
+
+void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
+{
+ // FIXME: implement
+}
+
+static gchar* userStyleSheet = NULL;
+static gboolean userStyleSheetEnabled = TRUE;
+
+void LayoutTestController::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 LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
+{
+ g_free(userStyleSheet);
+ userStyleSheet = JSStringCopyUTF8CString(path);
+ if (userStyleSheetEnabled)
+ setUserStyleSheetEnabled(true);
+}
+
+void LayoutTestController::setWindowIsKey(bool windowIsKey)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setSmartInsertDeleteEnabled(bool flag)
+{
+ // FIXME: implement
+}
+
+static gboolean waitToDumpWatchdogFired(void*)
+{
+ const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
+ fprintf(stderr, "%s", message);
+ fprintf(stdout, "%s", message);
+ waitToDumpWatchdog = 0;
+ dump();
+ return FALSE;
+}
+
+void LayoutTestController::setWaitToDump(bool waitUntilDone)
+{
+ static const int timeoutSeconds = 10;
+
+ m_waitToDump = waitUntilDone;
+ if (m_waitToDump && !waitToDumpWatchdog)
+#if GLIB_CHECK_VERSION(2,14,0)
+ waitToDumpWatchdog = g_timeout_add_seconds(timeoutSeconds, waitToDumpWatchdogFired, 0);
+#else
+ waitToDumpWatchdog = g_timeout_add(timeoutSeconds * 1000, waitToDumpWatchdogFired, 0);
+#endif
+}
+
+int LayoutTestController::windowCount()
+{
+ // FIXME: implement
+ return 1;
+}
+
+void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setJavaScriptProfilingEnabled(bool flag)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setPopupBlockingEnabled(bool popupBlockingEnabled)
+{
+ // FIXME: implement
+}
+
+bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id)
+{
+ // FIXME: implement
+ return false;
+}
+
+void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::clearPersistentUserStyleSheet()
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::clearAllDatabases()
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::setDatabaseQuota(unsigned long long quota)
+{
+ // FIXME: implement
+}
+
diff --git a/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp b/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp
new file mode 100644
index 0000000..5526667
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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 <webkit/webkit.h>
+#include <string.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;
+}
+
+void LoadItem::invoke() const
+{
+ gchar* targetString = JSStringCopyUTF8CString(target());
+
+ WebKitWebFrame* targetFrame;
+ if (!strlen(targetString))
+ targetFrame = mainFrame;
+ else
+ targetFrame = webkit_web_frame_find_frame(mainFrame, targetString);
+ g_free(targetString);
+
+ gchar* urlString = JSStringCopyUTF8CString(url());
+ WebKitNetworkRequest* request = webkit_network_request_new(urlString);
+ g_free(urlString);
+ webkit_web_frame_load_request(targetFrame, request);
+ g_object_unref(request);
+}
+
+void ReloadItem::invoke() const
+{
+ webkit_web_frame_reload(mainFrame);
+}
+
+void ScriptItem::invoke() const
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ gchar* scriptString = JSStringCopyUTF8CString(script());
+ webkit_web_view_execute_script(webView, scriptString);
+ g_free(scriptString);
+}
+
+void BackForwardItem::invoke() const
+{
+ WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
+ webkit_web_view_go_back_or_forward(webView, m_howFar);
+}
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
new file mode 100644
index 0000000..482c4f3
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 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. ``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.
+ */
+
+#import "DumpRenderTree.h"
+#import "AccessibilityController.h"
+
+#import "AccessibilityUIElement.h"
+#import <Foundation/Foundation.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebHTMLView.h>
+
+AccessibilityController::AccessibilityController()
+{
+}
+
+AccessibilityController::~AccessibilityController()
+{
+}
+
+AccessibilityUIElement AccessibilityController::focusedElement()
+{
+ // FIXME: we could do some caching here.
+ id accessibilityObject = [[[mainFrame frameView] documentView] accessibilityFocusedUIElement];
+ return AccessibilityUIElement(accessibilityObject);
+}
+
+AccessibilityUIElement AccessibilityController::rootElement()
+{
+ // FIXME: we could do some caching here.
+ id accessibilityObject = [[mainFrame frameView] documentView];
+ return AccessibilityUIElement(accessibilityObject);
+}
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
new file mode 100644
index 0000000..81edd99
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2008 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. ``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.
+ */
+
+#import "DumpRenderTree.h"
+#import "AccessibilityUIElement.h"
+
+#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JSStringRef.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebHTMLView.h>
+#import <WebKit/WebTypesInternal.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/Vector.h>
+
+AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
+ : m_element(element)
+{
+ [m_element retain];
+}
+
+AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
+ : m_element(other.m_element)
+{
+ [m_element retain];
+}
+
+AccessibilityUIElement::~AccessibilityUIElement()
+{
+ [m_element release];
+}
+
+@interface NSString (JSStringRefAdditions)
+- (JSStringRef)createJSStringRef;
+@end
+
+@implementation NSString (JSStringRefAdditions)
+
+- (JSStringRef)createJSStringRef
+{
+ return JSStringCreateWithCFString((CFStringRef)self);
+}
+
+@end
+
+static NSString* descriptionOfValue(id valueObject, id focusedAccessibilityObject)
+{
+ if (!valueObject)
+ return NULL;
+
+ if ([valueObject isKindOfClass:[NSArray class]])
+ return [NSString stringWithFormat:@"<array of size %d>", [(NSArray*)valueObject count]];
+
+ if ([valueObject isKindOfClass:[NSNumber class]])
+ return [(NSNumber*)valueObject stringValue];
+
+ if ([valueObject isKindOfClass:[NSValue class]]) {
+ NSString* type = [NSString stringWithCString:[valueObject objCType] encoding:NSASCIIStringEncoding];
+ NSValue* value = (NSValue*)valueObject;
+ if ([type rangeOfString:@"NSRect"].length > 0)
+ return [NSString stringWithFormat:@"NSRect: %@", NSStringFromRect([value rectValue])];
+ if ([type rangeOfString:@"NSPoint"].length > 0)
+ return [NSString stringWithFormat:@"NSPoint: %@", NSStringFromPoint([value pointValue])];
+ if ([type rangeOfString:@"NSSize"].length > 0)
+ return [NSString stringWithFormat:@"NSSize: %@", NSStringFromSize([value sizeValue])];
+ if ([type rangeOfString:@"NSRange"].length > 0)
+ return [NSString stringWithFormat:@"NSRange: %@", NSStringFromRange([value rangeValue])];
+ }
+
+ // Strip absolute URL paths
+ NSString* description = [valueObject description];
+ NSRange range = [description rangeOfString:@"LayoutTests"];
+ if (range.length)
+ return [description substringFromIndex:range.location];
+
+ // Strip pointer locations
+ if ([description rangeOfString:@"0x"].length) {
+ NSString* role = [focusedAccessibilityObject accessibilityAttributeValue:@"AXRole"];
+ NSString* title = [focusedAccessibilityObject accessibilityAttributeValue:@"AXTitle"];
+ if ([title length])
+ return [NSString stringWithFormat:@"<%@: '%@'>", role, title];
+ return [NSString stringWithFormat:@"<%@>", role];
+ }
+
+ return [valueObject description];
+}
+
+static NSString* attributesOfElement(id accessibilityObject)
+{
+ NSArray* supportedAttributes = [accessibilityObject accessibilityAttributeNames];
+
+ NSMutableString* attributesString = [NSMutableString string];
+ for (NSUInteger i = 0; i < [supportedAttributes count]; ++i) {
+ NSString* attribute = [supportedAttributes objectAtIndex:i];
+
+ // Right now, position provides useless and screen-specific information, so we do not
+ // want to include it for the sake of universally passing tests.
+ if ([attribute isEqualToString:@"AXPosition"])
+ continue;
+
+ id valueObject = [accessibilityObject accessibilityAttributeValue:attribute];
+ NSString* value = descriptionOfValue(valueObject, accessibilityObject);
+ [attributesString appendFormat:@"%@: %@\n", attribute, value];
+ }
+
+ return attributesString;
+}
+
+static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value)
+{
+ Vector<UniChar> buffer([attribute length]);
+ [attribute getCharacters:buffer.data()];
+ buffer.append(':');
+ buffer.append(' ');
+
+ Vector<UniChar> valueBuffer([value length]);
+ [value getCharacters:valueBuffer.data()];
+ buffer.append(valueBuffer);
+
+ return JSStringCreateWithCharacters(buffer.data(), buffer.size());
+}
+
+static void convertNSArrayToVector(NSArray* array, Vector<AccessibilityUIElement>& elementVector)
+{
+ NSUInteger count = [array count];
+ for (NSUInteger i = 0; i < count; ++i)
+ elementVector.append(AccessibilityUIElement([array objectAtIndex:i]));
+}
+
+static JSStringRef descriptionOfElements(Vector<AccessibilityUIElement>& elementVector)
+{
+ NSMutableString* allElementString = [NSMutableString string];
+ size_t size = elementVector.size();
+ for (size_t i = 0; i < size; ++i) {
+ NSString* attributes = attributesOfElement(elementVector[i].platformUIElement());
+ [allElementString appendFormat:@"%@\n------------\n", attributes];
+ }
+
+ return [allElementString createJSStringRef];
+}
+
+void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector)
+{
+ NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute];
+ convertNSArrayToVector(linkedElements, elementVector);
+}
+
+void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>& elementVector)
+{
+ NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"];
+ convertNSArrayToVector(linkElements, elementVector);
+}
+
+void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& elementVector)
+{
+ NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
+ convertNSArrayToVector(children, elementVector);
+}
+
+AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
+{
+ Vector<AccessibilityUIElement> children;
+ getChildren(children);
+
+ if (index < children.size())
+ return children[index];
+ return nil;
+}
+
+AccessibilityUIElement AccessibilityUIElement::titleUIElement()
+{
+ id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityTitleUIElementAttribute];
+ if (accessibilityObject)
+ return AccessibilityUIElement(accessibilityObject);
+
+ return nil;
+}
+
+JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
+{
+ Vector<AccessibilityUIElement> linkedElements;
+ getLinkedUIElements(linkedElements);
+ return descriptionOfElements(linkedElements);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
+{
+ Vector<AccessibilityUIElement> linkElements;
+ getDocumentLinks(linkElements);
+ return descriptionOfElements(linkElements);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfChildren()
+{
+ Vector<AccessibilityUIElement> children;
+ getChildren(children);
+ return descriptionOfElements(children);
+}
+
+JSStringRef AccessibilityUIElement::allAttributes()
+{
+ NSString* attributes = attributesOfElement(m_element);
+ return [attributes createJSStringRef];
+}
+
+JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
+{
+ NSArray* supportedParameterizedAttributes = [m_element accessibilityParameterizedAttributeNames];
+
+ NSMutableString* attributesString = [NSMutableString string];
+ for (NSUInteger i = 0; i < [supportedParameterizedAttributes count]; ++i) {
+ [attributesString appendFormat:@"%@\n", [supportedParameterizedAttributes objectAtIndex:i]];
+ }
+
+ return [attributesString createJSStringRef];
+}
+
+JSStringRef AccessibilityUIElement::role()
+{
+ NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:@"AXRole"], m_element);
+ return concatenateAttributeAndValue(@"AXRole", role);
+}
+
+JSStringRef AccessibilityUIElement::title()
+{
+ NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:@"AXTitle"], m_element);
+ return concatenateAttributeAndValue(@"AXTitle", title);
+}
+
+JSStringRef AccessibilityUIElement::description()
+{
+ id description = descriptionOfValue([m_element accessibilityAttributeValue:@"AXDescription"], m_element);
+ return concatenateAttributeAndValue(@"AXDescription", description);
+}
+
+double AccessibilityUIElement::width()
+{
+ NSValue* sizeValue = [m_element accessibilityAttributeValue:@"AXSize"];
+ return static_cast<double>([sizeValue sizeValue].width);
+}
+
+double AccessibilityUIElement::height()
+{
+ NSValue* sizeValue = [m_element accessibilityAttributeValue:@"AXSize"];
+ return static_cast<double>([sizeValue sizeValue].height);
+}
+
+double AccessibilityUIElement::intValue()
+{
+ id value = [m_element accessibilityAttributeValue:@"AXValue"];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber*)value doubleValue];
+ return 0.0f;
+}
+
+double AccessibilityUIElement::minValue()
+{
+ id value = [m_element accessibilityAttributeValue:@"AXMinValue"];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber*)value doubleValue];
+ return 0.0f;
+}
+
+double AccessibilityUIElement::maxValue()
+{
+ id value = [m_element accessibilityAttributeValue:@"AXMaxValue"];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber*)value doubleValue];
+ return 0.0;
+}
+
+int AccessibilityUIElement::insertionPointLineNumber()
+{
+ id value = [m_element accessibilityAttributeValue:@"AXInsertionPointLineNumber"];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber *)value intValue];
+ return -1;
+}
+
+bool AccessibilityUIElement::supportsPressAction()
+{
+ NSArray* actions = [m_element accessibilityActionNames];
+ return [actions containsObject:@"AXPress"];
+}
+
+// parameterized attributes
+int AccessibilityUIElement::lineForIndex(int index)
+{
+ id value = [m_element accessibilityAttributeValue:@"AXLineForIndex" forParameter:[NSNumber numberWithInt:index]];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [(NSNumber *)value intValue];
+ return -1;
+}
+
+JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
+{
+ NSRange range = NSMakeRange(location, length);
+ id value = [m_element accessibilityAttributeValue:NSAccessibilityBoundsForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
+ NSRect rect = NSMakeRect(0,0,0,0);
+ if ([value isKindOfClass:[NSValue class]])
+ rect = [value rectValue];
+
+ // don't return position information because it is platform dependent
+ NSMutableString* boundsDescription = [NSMutableString stringWithFormat:@"{{%f, %f}, {%f, %f}}",-1.0f,-1.0f,rect.size.width,rect.size.height];
+ return [boundsDescription createJSStringRef];
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
+{
+ // not yet defined in AppKit... odd
+ NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"];
+ Vector<AccessibilityUIElement> columnHeadersVector;
+ convertNSArrayToVector(columnHeadersArray, columnHeadersVector);
+ return descriptionOfElements(columnHeadersVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
+{
+ NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"];
+ Vector<AccessibilityUIElement> rowHeadersVector;
+ convertNSArrayToVector(rowHeadersArray, rowHeadersVector);
+ return descriptionOfElements(rowHeadersVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumns()
+{
+ NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute];
+ Vector<AccessibilityUIElement> columnsVector;
+ convertNSArrayToVector(columnsArray, columnsVector);
+ return descriptionOfElements(columnsVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRows()
+{
+ NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute];
+ Vector<AccessibilityUIElement> rowsVector;
+ convertNSArrayToVector(rowsArray, rowsVector);
+ return descriptionOfElements(rowsVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
+{
+ NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"];
+ Vector<AccessibilityUIElement> cellsVector;
+ convertNSArrayToVector(cellsArray, cellsVector);
+ return descriptionOfElements(cellsVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfHeader()
+{
+ id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute];
+ if (!headerObject)
+ return [@"" createJSStringRef];
+
+ Vector<AccessibilityUIElement> headerVector;
+ headerVector.append(headerObject);
+ return descriptionOfElements(headerVector);
+}
+
+int AccessibilityUIElement::indexInTable()
+{
+ NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute];
+ if (!indexNumber)
+ return -1;
+ return [indexNumber intValue];
+}
+
+JSStringRef AccessibilityUIElement::rowIndexRange()
+{
+ NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"];
+ NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0);
+ NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
+ return [rangeDescription createJSStringRef];
+}
+
+JSStringRef AccessibilityUIElement::columnIndexRange()
+{
+ NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"];
+ NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0);
+ NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
+ return [rangeDescription createJSStringRef];
+}
+
+AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
+{
+ NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil];
+ return [m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray];
+}
+
+JSStringRef AccessibilityUIElement::selectedTextRange()
+{
+ NSNumber *indexRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextRangeAttribute];
+ NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0);
+ NSMutableString *rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
+ return [rangeDescription createJSStringRef];
+}
+
+void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
+{
+ NSRange textRange = NSMakeRange(location, length);
+ NSValue *textRangeValue = [NSValue valueWithRange:textRange];
+ [m_element accessibilitySetValue:textRangeValue forAttribute:NSAccessibilitySelectedTextRangeAttribute];
+}
diff --git a/WebKitTools/DumpRenderTree/mac/AppleScriptController.h b/WebKitTools/DumpRenderTree/mac/AppleScriptController.h
new file mode 100644
index 0000000..c29789c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/AppleScriptController.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.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.
+ */
+
+#import <Foundation/Foundation.h>
+
+@class WebView;
+
+@interface AppleScriptController : NSObject
+{
+ WebView *webView;
+}
+- (id)initWithWebView:(WebView *)view;
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/AppleScriptController.m b/WebKitTools/DumpRenderTree/mac/AppleScriptController.m
new file mode 100644
index 0000000..86d2881
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/AppleScriptController.m
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.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.
+ */
+
+#import "AppleScriptController.h"
+
+#import <WebKit/WebView.h>
+#import <WebKit/WebViewPrivate.h> // for aeDescByEvaluatingJavaScriptFromString, which is pending API review
+
+@implementation AppleScriptController
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(doJavaScript:))
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(doJavaScript:))
+ return @"doJavaScript";
+
+ return nil;
+}
+
+- (id)initWithWebView:(WebView *)wv
+{
+ self = [super init];
+ webView = wv;
+ return self;
+}
+
+static id convertAEDescToObject(NSAppleEventDescriptor *aeDesc)
+{
+ id value = nil;
+
+ DescType descType = [aeDesc descriptorType];
+ switch (descType) {
+ case typeUnicodeText:
+ value = [NSString stringWithFormat:@"\"%@\"", [aeDesc stringValue]];
+ break;
+ case typeLongDateTime:
+ if ([[aeDesc data] length] == sizeof(LongDateTime)) {
+ LongDateTime d;
+ [[aeDesc data] getBytes:&d];
+ value = [NSString stringWithFormat:@"%016llX", (unsigned long long)d];
+ }
+ break;
+ case typeAEList:
+ value = [NSMutableString stringWithString:@"("];
+ int numItems = [aeDesc numberOfItems];
+ for (int i = 0; i < numItems; ++i) {
+ if (i != 0)
+ [(NSMutableString*)value appendString:@", "];
+ id obj = convertAEDescToObject([aeDesc descriptorAtIndex:(i + 1)]);
+ [(NSMutableString*)value appendString:[obj description]];
+ }
+ [(NSMutableString*)value appendString:@")"];
+ break;
+ case typeType: {
+ OSType type = [aeDesc typeCodeValue];
+
+ char typeStr[5];
+ typeStr[0] = type >> 24;
+ typeStr[1] = type >> 16;
+ typeStr[2] = type >> 8;
+ typeStr[3] = type;
+ typeStr[4] = 0;
+
+ value = [NSString stringWithFormat:@"'%s'", typeStr];
+ break;
+ }
+ }
+
+ if (!value)
+ value = [aeDesc stringValue];
+ if (!value)
+ value = [aeDesc data];
+
+ return value;
+}
+
+- (NSString *)doJavaScript:(NSString *)aString
+{
+ NSAppleEventDescriptor *aeDesc = [webView aeDescByEvaluatingJavaScriptFromString:aString];
+ if (!aeDesc)
+ return @"(null)";
+
+ DescType descType = [aeDesc descriptorType];
+ char descTypeStr[5];
+ descTypeStr[0] = descType >> 24;
+ descTypeStr[1] = descType >> 16;
+ descTypeStr[2] = descType >> 8;
+ descTypeStr[3] = descType;
+ descTypeStr[4] = 0;
+
+ return [NSString stringWithFormat:@"%@ ('%s')", convertAEDescToObject(aeDesc), descTypeStr];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/CheckedMalloc.cpp b/WebKitTools/DumpRenderTree/mac/CheckedMalloc.cpp
new file mode 100644
index 0000000..467f1bb
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/CheckedMalloc.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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>
+ *
+ * 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.
+ */
+
+#import "CheckedMalloc.h"
+
+#import <malloc/malloc.h>
+
+static void* (*savedMalloc)(malloc_zone_t*, size_t);
+static void* (*savedRealloc)(malloc_zone_t*, void*, size_t);
+
+static void* checkedMalloc(malloc_zone_t* zone, size_t size)
+{
+ if (size >= 0x10000000)
+ return 0;
+ return savedMalloc(zone, size);
+}
+
+static void* checkedRealloc(malloc_zone_t* zone, void* ptr, size_t size)
+{
+ if (size >= 0x10000000)
+ return 0;
+ return savedRealloc(zone, ptr, size);
+}
+
+void makeLargeMallocFailSilently()
+{
+ malloc_zone_t* zone = malloc_default_zone();
+ savedMalloc = zone->malloc;
+ savedRealloc = zone->realloc;
+ zone->malloc = checkedMalloc;
+ zone->realloc = checkedRealloc;
+}
diff --git a/WebKitTools/DumpRenderTree/mac/CheckedMalloc.h b/WebKitTools/DumpRenderTree/mac/CheckedMalloc.h
new file mode 100644
index 0000000..c03bd20
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/CheckedMalloc.h
@@ -0,0 +1,31 @@
+/*
+ * 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>
+ *
+ * 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.
+ */
+
+void makeLargeMallocFailSilently();
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
new file mode 100644
index 0000000..de9d67f
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
@@ -0,0 +1,17 @@
+HEADER_SEARCH_PATHS = ForwardingHeaders
+FRAMEWORK_SEARCH_PATHS = $(FRAMEWORK_SEARCH_PATHS_$(MAC_OS_X_VERSION_MAJOR));
+FRAMEWORK_SEARCH_PATHS_ = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks
+FRAMEWORK_SEARCH_PATHS_1040 = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks
+FRAMEWORK_SEARCH_PATHS_1050 = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks
+FRAMEWORK_SEARCH_PATHS_1060 = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks
+GCC_PREPROCESSOR_DEFINITIONS = ENABLE_DASHBOARD_SUPPORT;
+DEBUG_INFORMATION_FORMAT = dwarf
+PREBINDING = NO
+GCC_C_LANGUAGE_STANDARD = gnu99
+GCC_PRECOMPILE_PREFIX_HEADER = YES
+GCC_TREAT_WARNINGS_AS_ERRORS = YES
+GCC_WARN_UNUSED_FUNCTION = YES
+GCC_WARN_UNUSED_VARIABLE = YES
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
+WARNING_CFLAGS = -Wall -W -Wno-unused-parameter
+LINKER_DISPLAYS_MANGLED_NAMES = YES;
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
new file mode 100644
index 0000000..e272da2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
@@ -0,0 +1,7 @@
+#include "Base.xcconfig"
+ARCHS = $(NATIVE_ARCH);
+
+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(MAC_OS_X_VERSION_MAJOR))
+MACOSX_DEPLOYMENT_TARGET_ = 10.4
+MACOSX_DEPLOYMENT_TARGET_1040 = 10.4
+MACOSX_DEPLOYMENT_TARGET_1050 = 10.5
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig
new file mode 100644
index 0000000..b977225
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/DumpRenderTree.xcconfig
@@ -0,0 +1,4 @@
+OTHER_LDFLAGS = -sectcreate __DATA Ahem qt/fonts/AHEM____.TTF -sectcreate __DATA WeightWatcher100 fonts/WebKitWeightWatcher100.ttf -sectcreate __DATA WeightWatcher200 fonts/WebKitWeightWatcher200.ttf -sectcreate __DATA WeightWatcher300 fonts/WebKitWeightWatcher300.ttf -sectcreate __DATA WeightWatcher400 fonts/WebKitWeightWatcher400.ttf -sectcreate __DATA WeightWatcher500 fonts/WebKitWeightWatcher500.ttf -sectcreate __DATA WeightWatcher600 fonts/WebKitWeightWatcher600.ttf -sectcreate __DATA WeightWatcher700 fonts/WebKitWeightWatcher700.ttf -sectcreate __DATA WeightWatcher800 fonts/WebKitWeightWatcher800.ttf -sectcreate __DATA WeightWatcher900 fonts/WebKitWeightWatcher900.ttf
+PRODUCT_NAME = DumpRenderTree
+GCC_ENABLE_OBJC_EXCEPTIONS = YES
+GCC_PREFIX_HEADER = DumpRenderTreePrefix.h
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/ImageDiff.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/ImageDiff.xcconfig
new file mode 100644
index 0000000..fcd64c5
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/ImageDiff.xcconfig
@@ -0,0 +1 @@
+PRODUCT_NAME = ImageDiff
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/TestNetscapePlugIn.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/TestNetscapePlugIn.xcconfig
new file mode 100644
index 0000000..ea17629
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/TestNetscapePlugIn.xcconfig
@@ -0,0 +1,6 @@
+PRODUCT_NAME = TestNetscapePlugIn
+WRAPPER_EXTENSION = plugin
+INFOPLIST_FILE = TestNetscapePlugIn.subproj/Info.plist
+INSTALL_PATH = "$(USER_LIBRARY_DIR)/Plugins"
+WARNING_CFLAGS = -Wmost -Wno-four-char-constants -Wno-unknown-pragmas
+LIBRARY_STYLE = BUNDLE
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
new file mode 100644
index 0000000..203c6b2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
@@ -0,0 +1,1093 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@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.
+ */
+
+#import "DumpRenderTree.h"
+
+#import "AccessibilityController.h"
+#import "CheckedMalloc.h"
+#import "DumpRenderTreePasteboard.h"
+#import "DumpRenderTreeWindow.h"
+#import "EditingDelegate.h"
+#import "EventSendingController.h"
+#import "FrameLoadDelegate.h"
+#import "JavaScriptThreading.h"
+#import "LayoutTestController.h"
+#import "NavigationController.h"
+#import "ObjCPlugin.h"
+#import "ObjCPluginFunction.h"
+#import "PixelDumpSupport.h"
+#import "PolicyDelegate.h"
+#import "ResourceLoadDelegate.h"
+#import "UIDelegate.h"
+#import "WorkQueue.h"
+#import "WorkQueueItem.h"
+#import <Carbon/Carbon.h>
+#import <CoreFoundation/CoreFoundation.h>
+#import <WebKit/DOMElementPrivate.h>
+#import <WebKit/DOMExtensions.h>
+#import <WebKit/DOMRange.h>
+#import <WebKit/WebBackForwardList.h>
+#import <WebKit/WebCache.h>
+#import <WebKit/WebCoreStatistics.h>
+#import <WebKit/WebDataSourcePrivate.h>
+#import <WebKit/WebDatabaseManagerPrivate.h>
+#import <WebKit/WebDocumentPrivate.h>
+#import <WebKit/WebEditingDelegate.h>
+#import <WebKit/WebFrameView.h>
+#import <WebKit/WebHTMLRepresentationInternal.h>
+#import <WebKit/WebHistory.h>
+#import <WebKit/WebHistoryItemPrivate.h>
+#import <WebKit/WebInspector.h>
+#import <WebKit/WebPluginDatabase.h>
+#import <WebKit/WebPreferences.h>
+#import <WebKit/WebPreferencesPrivate.h>
+#import <WebKit/WebResourceLoadDelegate.h>
+#import <WebKit/WebTypesInternal.h>
+#import <WebKit/WebViewPrivate.h>
+#import <getopt.h>
+#import <mach-o/getsect.h>
+#import <objc/objc-runtime.h>
+#import <wtf/Assertions.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/OwnPtr.h>
+
+using namespace std;
+
+@interface DumpRenderTreeEvent : NSEvent
+@end
+
+static void runTest(const string& testPathOrURL);
+
+// Deciding when it's OK to dump out the state is a bit tricky. All these must be true:
+// - There is no load in progress
+// - There is no work queued up (see workQueue var, below)
+// - waitToDump==NO. This means either waitUntilDone was never called, or it was called
+// and notifyDone was called subsequently.
+// Note that the call to notifyDone and the end of the load can happen in either order.
+
+volatile bool done;
+
+NavigationController* gNavigationController = 0;
+LayoutTestController* gLayoutTestController = 0;
+
+WebFrame *mainFrame = 0;
+// This is the topmost frame that is loading, during a given load, or nil when no load is
+// in progress. Usually this is the same as the main frame, but not always. In the case
+// where a frameset is loaded, and then new content is loaded into one of the child frames,
+// that child frame is the "topmost frame that is loading".
+WebFrame *topLoadingFrame = nil; // !nil iff a load is in progress
+
+
+CFMutableSetRef disallowedURLs = 0;
+CFRunLoopTimerRef waitToDumpWatchdog = 0;
+
+// Delegates
+static FrameLoadDelegate *frameLoadDelegate;
+static UIDelegate *uiDelegate;
+static EditingDelegate *editingDelegate;
+static ResourceLoadDelegate *resourceLoadDelegate;
+PolicyDelegate *policyDelegate;
+
+static int dumpPixels;
+static int threaded;
+static int dumpTree = YES;
+static int forceComplexText;
+static BOOL printSeparators;
+static RetainPtr<CFStringRef> persistentUserStyleSheetLocation;
+
+static WebHistoryItem *prevTestBFItem = nil; // current b/f item at the end of the previous test
+
+const unsigned maxViewHeight = 600;
+const unsigned maxViewWidth = 800;
+
+#if __OBJC2__
+static void swizzleAllMethods(Class imposter, Class original)
+{
+ unsigned int imposterMethodCount;
+ Method* imposterMethods = class_copyMethodList(imposter, &imposterMethodCount);
+
+ unsigned int originalMethodCount;
+ Method* originalMethods = class_copyMethodList(original, &originalMethodCount);
+
+ for (unsigned int i = 0; i < imposterMethodCount; i++) {
+ SEL imposterMethodName = method_getName(imposterMethods[i]);
+
+ // Attempt to add the method to the original class. If it fails, the method already exists and we should
+ // instead exchange the implementations.
+ if (class_addMethod(original, imposterMethodName, method_getImplementation(originalMethods[i]), method_getTypeEncoding(originalMethods[i])))
+ continue;
+
+ unsigned int j = 0;
+ for (; j < originalMethodCount; j++) {
+ SEL originalMethodName = method_getName(originalMethods[j]);
+ if (sel_isEqual(imposterMethodName, originalMethodName))
+ break;
+ }
+
+ // If class_addMethod failed above then the method must exist on the original class.
+ ASSERT(j < originalMethodCount);
+ method_exchangeImplementations(imposterMethods[i], originalMethods[j]);
+ }
+
+ free(imposterMethods);
+ free(originalMethods);
+}
+#endif
+
+static void poseAsClass(const char* imposter, const char* original)
+{
+ Class imposterClass = objc_getClass(imposter);
+ Class originalClass = objc_getClass(original);
+
+#if !__OBJC2__
+ class_poseAs(imposterClass, originalClass);
+#else
+
+ // Swizzle instance methods
+ swizzleAllMethods(imposterClass, originalClass);
+ // and then class methods
+ swizzleAllMethods(object_getClass(imposterClass), object_getClass(originalClass));
+#endif
+}
+
+void setPersistentUserStyleSheetLocation(CFStringRef url)
+{
+ persistentUserStyleSheetLocation = url;
+}
+
+static bool shouldIgnoreWebCoreNodeLeaks(const string& URLString)
+{
+ static char* const ignoreSet[] = {
+ // Keeping this infrastructure around in case we ever need it again.
+ };
+ static const int ignoreSetCount = sizeof(ignoreSet) / sizeof(char*);
+
+ for (int i = 0; i < ignoreSetCount; i++) {
+ // FIXME: ignore case
+ string curIgnore(ignoreSet[i]);
+ // Match at the end of the URLString
+ if (!URLString.compare(URLString.length() - curIgnore.length(), curIgnore.length(), curIgnore))
+ return true;
+ }
+ return false;
+}
+
+static void activateFonts()
+{
+ static const char* fontSectionNames[] = {
+ "Ahem",
+ "WeightWatcher100",
+ "WeightWatcher200",
+ "WeightWatcher300",
+ "WeightWatcher400",
+ "WeightWatcher500",
+ "WeightWatcher600",
+ "WeightWatcher700",
+ "WeightWatcher800",
+ "WeightWatcher900",
+ 0
+ };
+
+ for (unsigned i = 0; fontSectionNames[i]; ++i) {
+ unsigned long fontDataLength;
+ char* fontData = getsectdata("__DATA", fontSectionNames[i], &fontDataLength);
+ if (!fontData) {
+ fprintf(stderr, "Failed to locate the %s font.\n", fontSectionNames[i]);
+ exit(1);
+ }
+
+ ATSFontContainerRef fontContainer;
+ OSStatus status = ATSFontActivateFromMemory(fontData, fontDataLength, kATSFontContextLocal, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &fontContainer);
+
+ if (status != noErr) {
+ fprintf(stderr, "Failed to activate the %s font.\n", fontSectionNames[i]);
+ exit(1);
+ }
+ }
+}
+
+WebView *createWebViewAndOffscreenWindow()
+{
+ NSRect rect = NSMakeRect(0, 0, maxViewWidth, maxViewHeight);
+ WebView *webView = [[WebView alloc] initWithFrame:rect frameName:nil groupName:@"org.webkit.DumpRenderTree"];
+
+ [webView setUIDelegate:uiDelegate];
+ [webView setFrameLoadDelegate:frameLoadDelegate];
+ [webView setEditingDelegate:editingDelegate];
+ [webView setResourceLoadDelegate:resourceLoadDelegate];
+
+ // Register the same schemes that Safari does
+ [WebView registerURLSchemeAsLocal:@"feed"];
+ [WebView registerURLSchemeAsLocal:@"feeds"];
+ [WebView registerURLSchemeAsLocal:@"feedsearch"];
+
+ [webView setContinuousSpellCheckingEnabled:YES];
+
+ // To make things like certain NSViews, dragging, and plug-ins work, put the WebView a window, but put it off-screen so you don't see it.
+ // Put it at -10000, -10000 in "flipped coordinates", since WebCore and the DOM use flipped coordinates.
+ NSRect windowRect = NSOffsetRect(rect, -10000, [[[NSScreen screens] objectAtIndex:0] frame].size.height - rect.size.height + 10000);
+ DumpRenderTreeWindow *window = [[DumpRenderTreeWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
+ [[window contentView] addSubview:webView];
+ [window orderBack:nil];
+ [window setAutodisplay:NO];
+
+ // For reasons that are not entirely clear, the following pair of calls makes WebView handle its
+ // dynamic scrollbars properly. Without it, every frame will always have scrollbars.
+ NSBitmapImageRep *imageRep = [webView bitmapImageRepForCachingDisplayInRect:[webView bounds]];
+ [webView cacheDisplayInRect:[webView bounds] toBitmapImageRep:imageRep];
+
+ return webView;
+}
+
+void testStringByEvaluatingJavaScriptFromString()
+{
+ // maps expected result <= JavaScript expression
+ NSDictionary *expressions = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"0", @"0",
+ @"0", @"'0'",
+ @"", @"",
+ @"", @"''",
+ @"", @"new String()",
+ @"", @"new String('0')",
+ @"", @"throw 1",
+ @"", @"{ }",
+ @"", @"[ ]",
+ @"", @"//",
+ @"", @"a.b.c",
+ @"", @"(function() { throw 'error'; })()",
+ @"", @"null",
+ @"", @"undefined",
+ @"true", @"true",
+ @"false", @"false",
+ nil
+ ];
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ WebView *webView = [[WebView alloc] initWithFrame:NSZeroRect frameName:@"" groupName:@""];
+
+ NSEnumerator *enumerator = [expressions keyEnumerator];
+ id expression;
+ while ((expression = [enumerator nextObject])) {
+ NSString *expectedResult = [expressions objectForKey:expression];
+ NSString *result = [webView stringByEvaluatingJavaScriptFromString:expression];
+ assert([result isEqualToString:expectedResult]);
+ }
+
+ [webView close];
+ [webView release];
+ [pool release];
+}
+
+static void setDefaultsToConsistentValuesForTesting()
+{
+ // Give some clear to undocumented defaults values
+ static const int NoFontSmoothing = 0;
+ static const int BlueTintedAppearance = 1;
+
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ [defaults setInteger:4 forKey:@"AppleAntiAliasingThreshold"]; // smallest font size to CG should perform antialiasing on
+ [defaults setInteger:NoFontSmoothing forKey:@"AppleFontSmoothing"];
+ [defaults setInteger:BlueTintedAppearance forKey:@"AppleAquaColorVariant"];
+ [defaults setObject:@"0.709800 0.835300 1.000000" forKey:@"AppleHighlightColor"];
+ [defaults setObject:@"0.500000 0.500000 0.500000" forKey:@"AppleOtherHighlightColor"];
+ [defaults setObject:[NSArray arrayWithObject:@"en"] forKey:@"AppleLanguages"];
+
+ // Scrollbars are drawn either using AppKit (which uses NSUserDefaults) or using HIToolbox (which uses CFPreferences / kCFPreferencesAnyApplication / kCFPreferencesCurrentUser / kCFPreferencesAnyHost)
+ [defaults setObject:@"DoubleMax" forKey:@"AppleScrollBarVariant"];
+ RetainPtr<CFTypeRef> initialValue = CFPreferencesCopyValue(CFSTR("AppleScrollBarVariant"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+ CFPreferencesSetValue(CFSTR("AppleScrollBarVariant"), CFSTR("DoubleMax"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+ ThemeScrollBarArrowStyle style;
+ GetThemeScrollBarArrowStyle(&style); // Force HIToolbox to read from CFPreferences
+ if (initialValue)
+ CFPreferencesSetValue(CFSTR("AppleScrollBarVariant"), initialValue.get(), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+
+ NSString *libraryPath = [@"~/Library/Application Support/DumpRenderTree" stringByExpandingTildeInPath];
+ [defaults setObject:[libraryPath stringByAppendingPathComponent:@"Databases"] forKey:WebDatabaseDirectoryDefaultsKey];
+
+ WebPreferences *preferences = [WebPreferences standardPreferences];
+
+ [preferences setStandardFontFamily:@"Times"];
+ [preferences setFixedFontFamily:@"Courier"];
+ [preferences setSerifFontFamily:@"Times"];
+ [preferences setSansSerifFontFamily:@"Helvetica"];
+ [preferences setCursiveFontFamily:@"Apple Chancery"];
+ [preferences setFantasyFontFamily:@"Papyrus"];
+ [preferences setDefaultFontSize:16];
+ [preferences setDefaultFixedFontSize:13];
+ [preferences setMinimumFontSize:1];
+ [preferences setJavaEnabled:NO];
+ [preferences setEditableLinkBehavior:WebKitEditableLinkOnlyLiveWithShiftKey];
+ [preferences setTabsToLinks:NO];
+ [preferences setDOMPasteAllowed:YES];
+ [preferences setFullDocumentTeardownEnabled:YES];
+ [preferences setShouldPrintBackgrounds:YES];
+
+ // The back/forward cache is causing problems due to layouts during transition from one page to another.
+ // So, turn it off for now, but we might want to turn it back on some day.
+ [preferences setUsesPageCache:NO];
+}
+
+static void crashHandler(int sig)
+{
+ char *signalName = strsignal(sig);
+ write(STDERR_FILENO, signalName, strlen(signalName));
+ write(STDERR_FILENO, "\n", 1);
+ restoreMainDisplayColorProfile(0);
+ exit(128 + sig);
+}
+
+static void installSignalHandlers()
+{
+ signal(SIGILL, crashHandler); /* 4: illegal instruction (not reset when caught) */
+ signal(SIGTRAP, crashHandler); /* 5: trace trap (not reset when caught) */
+ signal(SIGEMT, crashHandler); /* 7: EMT instruction */
+ signal(SIGFPE, crashHandler); /* 8: floating point exception */
+ signal(SIGBUS, crashHandler); /* 10: bus error */
+ signal(SIGSEGV, crashHandler); /* 11: segmentation violation */
+ signal(SIGSYS, crashHandler); /* 12: bad argument to system call */
+ signal(SIGPIPE, crashHandler); /* 13: write on a pipe with no reader */
+ signal(SIGXCPU, crashHandler); /* 24: exceeded CPU time limit */
+ signal(SIGXFSZ, crashHandler); /* 25: exceeded file size limit */
+}
+
+static void allocateGlobalControllers()
+{
+ // FIXME: We should remove these and move to the ObjC standard [Foo sharedInstance] model
+ gNavigationController = [[NavigationController alloc] init];
+ frameLoadDelegate = [[FrameLoadDelegate alloc] init];
+ uiDelegate = [[UIDelegate alloc] init];
+ editingDelegate = [[EditingDelegate alloc] init];
+ resourceLoadDelegate = [[ResourceLoadDelegate alloc] init];
+ policyDelegate = [[PolicyDelegate alloc] init];
+}
+
+// ObjC++ doens't seem to let me pass NSObject*& sadly.
+static inline void releaseAndZero(NSObject** object)
+{
+ [*object release];
+ *object = nil;
+}
+
+static void releaseGlobalControllers()
+{
+ releaseAndZero(&gNavigationController);
+ releaseAndZero(&frameLoadDelegate);
+ releaseAndZero(&editingDelegate);
+ releaseAndZero(&resourceLoadDelegate);
+ releaseAndZero(&uiDelegate);
+ releaseAndZero(&policyDelegate);
+}
+
+static void initializeGlobalsFromCommandLineOptions(int argc, const char *argv[])
+{
+ struct option options[] = {
+ {"notree", no_argument, &dumpTree, NO},
+ {"pixel-tests", no_argument, &dumpPixels, YES},
+ {"tree", no_argument, &dumpTree, YES},
+ {"threaded", no_argument, &threaded, YES},
+ {"complex-text", no_argument, &forceComplexText, YES},
+ {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;
+ }
+ }
+}
+
+static void addTestPluginsToPluginSearchPath(const char* executablePath)
+{
+ NSString *pwd = [[NSString stringWithUTF8String:executablePath] stringByDeletingLastPathComponent];
+ [WebPluginDatabase setAdditionalWebPlugInPaths:[NSArray arrayWithObject:pwd]];
+ [[WebPluginDatabase sharedDatabase] refresh];
+}
+
+static bool useLongRunningServerMode(int argc, const char *argv[])
+{
+ // This assumes you've already called getopt_long
+ return (argc == optind+1 && strcmp(argv[optind], "-") == 0);
+}
+
+static void runTestingServerLoop()
+{
+ // When DumpRenderTree run 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) == 0)
+ continue;
+
+ runTest(filenameBuffer);
+ }
+}
+
+static void prepareConsistentTestingEnvironment()
+{
+ poseAsClass("DumpRenderTreePasteboard", "NSPasteboard");
+ poseAsClass("DumpRenderTreeEvent", "NSEvent");
+
+ setDefaultsToConsistentValuesForTesting();
+ activateFonts();
+
+ if (dumpPixels)
+ setupMainDisplayColorProfile();
+ allocateGlobalControllers();
+
+ makeLargeMallocFailSilently();
+}
+
+void dumpRenderTree(int argc, const char *argv[])
+{
+ initializeGlobalsFromCommandLineOptions(argc, argv);
+ prepareConsistentTestingEnvironment();
+ addTestPluginsToPluginSearchPath(argv[0]);
+ if (dumpPixels)
+ installSignalHandlers();
+
+ if (forceComplexText)
+ [WebView _setAlwaysUsesComplexTextCodePath:YES];
+
+ WebView *webView = createWebViewAndOffscreenWindow();
+ mainFrame = [webView mainFrame];
+
+ [[NSURLCache sharedURLCache] removeAllCachedResponses];
+
+ [WebCache empty];
+
+ // <rdar://problem/5222911>
+ testStringByEvaluatingJavaScriptFromString();
+
+ if (threaded)
+ startJavaScriptThreads();
+
+ if (useLongRunningServerMode(argc, argv)) {
+ printSeparators = YES;
+ runTestingServerLoop();
+ } else {
+ printSeparators = (optind < argc-1 || (dumpPixels && dumpTree));
+ for (int i = optind; i != argc; ++i)
+ runTest(argv[i]);
+ }
+
+ if (threaded)
+ stopJavaScriptThreads();
+
+ [webView close];
+ mainFrame = nil;
+
+ // Work around problem where registering drag types leaves an outstanding
+ // "perform selector" on the window, which retains the window. It's a bit
+ // inelegant and perhaps dangerous to just blow them all away, but in practice
+ // it probably won't cause any trouble (and this is just a test tool, after all).
+ NSWindow *window = [webView window];
+ [NSObject cancelPreviousPerformRequestsWithTarget:window];
+
+ [window close]; // releases when closed
+ [webView release];
+
+ releaseGlobalControllers();
+
+ [DumpRenderTreePasteboard releaseLocalPasteboards];
+
+ // FIXME: This should be moved onto LayoutTestController and made into a HashSet
+ if (disallowedURLs) {
+ CFRelease(disallowedURLs);
+ disallowedURLs = 0;
+ }
+
+ if (dumpPixels)
+ restoreMainDisplayColorProfile(0);
+}
+
+int main(int argc, const char *argv[])
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [NSApplication sharedApplication]; // Force AppKit to init itself
+ dumpRenderTree(argc, argv);
+ [WebCoreStatistics garbageCollectJavaScriptObjects];
+ [WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts
+ [pool release];
+ return 0;
+}
+
+static NSInteger compareHistoryItems(id item1, id item2, void *context)
+{
+ return [[item1 target] caseInsensitiveCompare:[item2 target]];
+}
+
+static void dumpHistoryItem(WebHistoryItem *item, int indent, BOOL current)
+{
+ int start = 0;
+ if (current) {
+ printf("curr->");
+ start = 6;
+ }
+ for (int i = start; i < indent; i++)
+ putchar(' ');
+ printf("%s", [[item URLString] UTF8String]);
+ NSString *target = [item target];
+ if (target && [target length] > 0)
+ printf(" (in frame \"%s\")", [target UTF8String]);
+ if ([item isTargetItem])
+ printf(" **nav target**");
+ putchar('\n');
+ NSArray *kids = [item children];
+ if (kids) {
+ // must sort to eliminate arbitrary result ordering which defeats reproducible testing
+ kids = [kids sortedArrayUsingFunction:&compareHistoryItems context:nil];
+ for (unsigned i = 0; i < [kids count]; i++)
+ dumpHistoryItem([kids objectAtIndex:i], indent+4, NO);
+ }
+}
+
+static void dumpFrameScrollPosition(WebFrame *f)
+{
+ NSPoint scrollPosition = [[[[f frameView] documentView] superview] bounds].origin;
+ if (ABS(scrollPosition.x) > 0.00000001 || ABS(scrollPosition.y) > 0.00000001) {
+ if ([f parentFrame] != nil)
+ printf("frame '%s' ", [[f name] UTF8String]);
+ printf("scrolled to %.f,%.f\n", scrollPosition.x, scrollPosition.y);
+ }
+
+ if (gLayoutTestController->dumpChildFrameScrollPositions()) {
+ NSArray *kids = [f childFrames];
+ if (kids)
+ for (unsigned i = 0; i < [kids count]; i++)
+ dumpFrameScrollPosition([kids objectAtIndex:i]);
+ }
+}
+
+static NSString *dumpFramesAsText(WebFrame *frame)
+{
+ DOMDocument *document = [frame DOMDocument];
+ DOMElement *documentElement = [document documentElement];
+
+ if (!documentElement)
+ return @"";
+
+ NSMutableString *result = [[[NSMutableString alloc] init] autorelease];
+
+ // Add header for all but the main frame.
+ if ([frame parentFrame])
+ result = [NSMutableString stringWithFormat:@"\n--------\nFrame: '%@'\n--------\n", [frame name]];
+
+ [result appendFormat:@"%@\n", [documentElement innerText]];
+
+ if (gLayoutTestController->dumpChildFramesAsText()) {
+ NSArray *kids = [frame childFrames];
+ if (kids) {
+ for (unsigned i = 0; i < [kids count]; i++)
+ [result appendString:dumpFramesAsText([kids objectAtIndex:i])];
+ }
+ }
+
+ return result;
+}
+
+static NSData *dumpFrameAsPDF(WebFrame *frame)
+{
+ if (!frame)
+ return nil;
+
+ // Sadly we have to dump to a file and then read from that file again
+ // +[NSPrintOperation PDFOperationWithView:insideRect:] requires a rect and prints to a single page
+ // likewise +[NSView dataWithPDFInsideRect:] also prints to a single continuous page
+ // The goal of this function is to test "real" printing across multiple pages.
+ // FIXME: It's possible there might be printing SPI to let us print a multi-page PDF to an NSData object
+ NSString *path = @"/tmp/test.pdf";
+
+ NSMutableDictionary *printInfoDict = [NSMutableDictionary dictionaryWithDictionary:[[NSPrintInfo sharedPrintInfo] dictionary]];
+ [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
+ [printInfoDict setObject:path forKey:NSPrintSavePath];
+
+ NSPrintInfo *printInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict];
+ [printInfo setHorizontalPagination:NSAutoPagination];
+ [printInfo setVerticalPagination:NSAutoPagination];
+ [printInfo setVerticallyCentered:NO];
+
+ NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:[frame frameView] printInfo:printInfo];
+ [printOperation setShowPanels:NO];
+ [printOperation runOperation];
+
+ [printInfo release];
+
+ NSData *pdfData = [NSData dataWithContentsOfFile:path];
+ [[NSFileManager defaultManager] removeFileAtPath:path handler:nil];
+
+ return pdfData;
+}
+
+static void convertMIMEType(NSMutableString *mimeType)
+{
+#ifdef BUILDING_ON_LEOPARD
+ // Workaround for <rdar://problem/5539824> on Leopard
+ if ([mimeType isEqualToString:@"text/xml"])
+ [mimeType setString:@"application/xml"];
+#endif
+ // Workaround for <rdar://problem/6234318> with Dashcode 2.0
+ if ([mimeType isEqualToString:@"application/x-javascript"])
+ [mimeType setString:@"text/javascript"];
+}
+
+static void convertWebResourceDataToString(NSMutableDictionary *resource)
+{
+ NSMutableString *mimeType = [resource objectForKey:@"WebResourceMIMEType"];
+ convertMIMEType(mimeType);
+
+ if ([mimeType hasPrefix:@"text/"] || [[WebHTMLRepresentation supportedNonImageMIMETypes] containsObject:mimeType]) {
+ NSData *data = [resource objectForKey:@"WebResourceData"];
+ NSString *dataAsString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
+ [resource setObject:dataAsString forKey:@"WebResourceData"];
+ }
+}
+
+static void normalizeWebResourceURL(NSMutableString *webResourceURL)
+{
+ static int fileUrlLength = [(NSString *)@"file://" length];
+ NSRange layoutTestsWebArchivePathRange = [webResourceURL rangeOfString:@"/LayoutTests/" options:NSBackwardsSearch];
+ if (layoutTestsWebArchivePathRange.location == NSNotFound)
+ return;
+ NSRange currentWorkingDirectoryRange = NSMakeRange(fileUrlLength, layoutTestsWebArchivePathRange.location - fileUrlLength);
+ [webResourceURL replaceCharactersInRange:currentWorkingDirectoryRange withString:@""];
+}
+
+static void convertWebResourceResponseToDictionary(NSMutableDictionary *propertyList)
+{
+ NSURLResponse *response = nil;
+ NSData *responseData = [propertyList objectForKey:@"WebResourceResponse"]; // WebResourceResponseKey in WebResource.m
+ if ([responseData isKindOfClass:[NSData class]]) {
+ // Decode NSURLResponse
+ NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData];
+ response = [unarchiver decodeObjectForKey:@"WebResourceResponse"]; // WebResourceResponseKey in WebResource.m
+ [unarchiver finishDecoding];
+ [unarchiver release];
+ }
+
+ NSMutableDictionary *responseDictionary = [[NSMutableDictionary alloc] init];
+
+ NSMutableString *urlString = [[[response URL] description] mutableCopy];
+ normalizeWebResourceURL(urlString);
+ [responseDictionary setObject:urlString forKey:@"URL"];
+ [urlString release];
+
+ NSMutableString *mimeTypeString = [[response MIMEType] mutableCopy];
+ convertMIMEType(mimeTypeString);
+ [responseDictionary setObject:mimeTypeString forKey:@"MIMEType"];
+ [mimeTypeString release];
+
+ NSString *textEncodingName = [response textEncodingName];
+ if (textEncodingName)
+ [responseDictionary setObject:textEncodingName forKey:@"textEncodingName"];
+ [responseDictionary setObject:[NSNumber numberWithLongLong:[response expectedContentLength]] forKey:@"expectedContentLength"];
+
+ if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
+
+ [responseDictionary setObject:[httpResponse allHeaderFields] forKey:@"allHeaderFields"];
+ [responseDictionary setObject:[NSNumber numberWithInt:[httpResponse statusCode]] forKey:@"statusCode"];
+ }
+
+ [propertyList setObject:responseDictionary forKey:@"WebResourceResponse"];
+ [responseDictionary release];
+}
+
+static NSInteger compareResourceURLs(id resource1, id resource2, void *context)
+{
+ NSString *url1 = [resource1 objectForKey:@"WebResourceURL"];
+ NSString *url2 = [resource2 objectForKey:@"WebResourceURL"];
+
+ return [url1 compare:url2];
+}
+
+static NSString *serializeWebArchiveToXML(WebArchive *webArchive)
+{
+ NSString *errorString;
+ NSMutableDictionary *propertyList = [NSPropertyListSerialization propertyListFromData:[webArchive data]
+ mutabilityOption:NSPropertyListMutableContainersAndLeaves
+ format:NULL
+ errorDescription:&errorString];
+ if (!propertyList)
+ return errorString;
+
+ NSMutableArray *resources = [NSMutableArray arrayWithCapacity:1];
+ [resources addObject:propertyList];
+
+ while ([resources count]) {
+ NSMutableDictionary *resourcePropertyList = [resources objectAtIndex:0];
+ [resources removeObjectAtIndex:0];
+
+ NSMutableDictionary *mainResource = [resourcePropertyList objectForKey:@"WebMainResource"];
+ normalizeWebResourceURL([mainResource objectForKey:@"WebResourceURL"]);
+ convertWebResourceDataToString(mainResource);
+
+ // Add subframeArchives to list for processing
+ NSMutableArray *subframeArchives = [resourcePropertyList objectForKey:@"WebSubframeArchives"]; // WebSubframeArchivesKey in WebArchive.m
+ if (subframeArchives)
+ [resources addObjectsFromArray:subframeArchives];
+
+ NSMutableArray *subresources = [resourcePropertyList objectForKey:@"WebSubresources"]; // WebSubresourcesKey in WebArchive.m
+ NSEnumerator *enumerator = [subresources objectEnumerator];
+ NSMutableDictionary *subresourcePropertyList;
+ while ((subresourcePropertyList = [enumerator nextObject])) {
+ normalizeWebResourceURL([subresourcePropertyList objectForKey:@"WebResourceURL"]);
+ convertWebResourceResponseToDictionary(subresourcePropertyList);
+ convertWebResourceDataToString(subresourcePropertyList);
+ }
+
+ // Sort the subresources so they're always in a predictable order for the dump
+ if (NSArray *sortedSubresources = [subresources sortedArrayUsingFunction:compareResourceURLs context:nil])
+ [resourcePropertyList setObject:sortedSubresources forKey:@"WebSubresources"];
+ }
+
+ NSData *xmlData = [NSPropertyListSerialization dataFromPropertyList:propertyList
+ format:NSPropertyListXMLFormat_v1_0
+ errorDescription:&errorString];
+ if (!xmlData)
+ return errorString;
+
+ NSMutableString *string = [[[NSMutableString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding] autorelease];
+
+ // Replace "Apple Computer" with "Apple" in the DTD declaration.
+ NSRange range = [string rangeOfString:@"-//Apple Computer//"];
+ if (range.location != NSNotFound)
+ [string replaceCharactersInRange:range withString:@"-//Apple//"];
+
+ return string;
+}
+
+static void dumpBackForwardListForWebView(WebView *view)
+{
+ printf("\n============== Back Forward List ==============\n");
+ WebBackForwardList *bfList = [view backForwardList];
+
+ // 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
+ NSMutableArray *itemsToPrint = [[NSMutableArray alloc] init];
+ for (int i = [bfList forwardListCount]; i > 0; i--) {
+ WebHistoryItem *item = [bfList itemAtIndex:i];
+ // something is wrong if the item from the last test is in the forward part of the b/f list
+ assert(item != prevTestBFItem);
+ [itemsToPrint addObject:item];
+ }
+
+ assert([bfList currentItem] != prevTestBFItem);
+ [itemsToPrint addObject:[bfList currentItem]];
+ int currentItemIndex = [itemsToPrint count] - 1;
+
+ for (int i = -1; i >= -[bfList backListCount]; i--) {
+ WebHistoryItem *item = [bfList itemAtIndex:i];
+ if (item == prevTestBFItem)
+ break;
+ [itemsToPrint addObject:item];
+ }
+
+ for (int i = [itemsToPrint count]-1; i >= 0; i--)
+ dumpHistoryItem([itemsToPrint objectAtIndex:i], 8, i == currentItemIndex);
+
+ [itemsToPrint release];
+ printf("===============================================\n");
+}
+
+static void sizeWebViewForCurrentTest()
+{
+ // W3C SVG tests expect to be 480x360
+ bool isSVGW3CTest = (gLayoutTestController->testPathOrURL().find("svg/W3C-SVG-1.1") != string::npos);
+ if (isSVGW3CTest)
+ [[mainFrame webView] setFrameSize:NSMakeSize(480, 360)];
+ else
+ [[mainFrame webView] setFrameSize:NSMakeSize(maxViewWidth, maxViewHeight)];
+}
+
+static const char *methodNameStringForFailedTest()
+{
+ const char *errorMessage;
+ if (gLayoutTestController->dumpAsText())
+ errorMessage = "[documentElement innerText]";
+ else if (gLayoutTestController->dumpDOMAsWebArchive())
+ errorMessage = "[[mainFrame DOMDocument] webArchive]";
+ else if (gLayoutTestController->dumpSourceAsWebArchive())
+ errorMessage = "[[mainFrame dataSource] webArchive]";
+ else
+ errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";
+
+ return errorMessage;
+}
+
+static void dumpBackForwardListForAllWindows()
+{
+ CFArrayRef openWindows = (CFArrayRef)[DumpRenderTreeWindow openWindows];
+ unsigned count = CFArrayGetCount(openWindows);
+ for (unsigned i = 0; i < count; i++) {
+ NSWindow *window = (NSWindow *)CFArrayGetValueAtIndex(openWindows, i);
+ WebView *webView = [[[window contentView] subviews] objectAtIndex:0];
+ dumpBackForwardListForWebView(webView);
+ }
+}
+
+static void invalidateAnyPreviousWaitToDumpWatchdog()
+{
+ if (waitToDumpWatchdog) {
+ CFRunLoopTimerInvalidate(waitToDumpWatchdog);
+ CFRelease(waitToDumpWatchdog);
+ waitToDumpWatchdog = 0;
+ }
+}
+
+void dump()
+{
+ invalidateAnyPreviousWaitToDumpWatchdog();
+
+ bool dumpAsText = gLayoutTestController->dumpAsText();
+ if (dumpTree) {
+ NSString *resultString = nil;
+ NSData *resultData = nil;
+ NSString *resultMimeType = @"text/plain";
+
+ dumpAsText |= [[[mainFrame dataSource] _responseMIMEType] isEqualToString:@"text/plain"];
+ gLayoutTestController->setDumpAsText(dumpAsText);
+ if (gLayoutTestController->dumpAsText()) {
+ resultString = dumpFramesAsText(mainFrame);
+ } else if (gLayoutTestController->dumpAsPDF()) {
+ resultData = dumpFrameAsPDF(mainFrame);
+ resultMimeType = @"application/pdf";
+ } else if (gLayoutTestController->dumpDOMAsWebArchive()) {
+ WebArchive *webArchive = [[mainFrame DOMDocument] webArchive];
+ resultString = serializeWebArchiveToXML(webArchive);
+ resultMimeType = @"application/x-webarchive";
+ } else if (gLayoutTestController->dumpSourceAsWebArchive()) {
+ WebArchive *webArchive = [[mainFrame dataSource] webArchive];
+ resultString = serializeWebArchiveToXML(webArchive);
+ resultMimeType = @"application/x-webarchive";
+ } else {
+ sizeWebViewForCurrentTest();
+ resultString = [mainFrame renderTreeAsExternalRepresentation];
+ }
+
+ if (resultString && !resultData)
+ resultData = [resultString dataUsingEncoding:NSUTF8StringEncoding];
+
+ printf("Content-Type: %s\n", [resultMimeType UTF8String]);
+
+ if (resultData) {
+ fwrite([resultData bytes], 1, [resultData length], stdout);
+
+ if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive())
+ dumpFrameScrollPosition(mainFrame);
+
+ if (gLayoutTestController->dumpBackForwardList())
+ dumpBackForwardListForAllWindows();
+ } else
+ printf("ERROR: nil result from %s", methodNameStringForFailedTest());
+
+ if (printSeparators) {
+ puts("#EOF"); // terminate the content block
+ fputs("#EOF\n", stderr);
+ }
+ }
+
+ if (dumpPixels && !dumpAsText)
+ dumpWebViewAsPixelsAndCompareWithExpected(gLayoutTestController->expectedPixelHash());
+
+ puts("#EOF"); // terminate the (possibly empty) pixels block
+
+ fflush(stdout);
+ fflush(stderr);
+
+ done = YES;
+}
+
+static bool shouldLogFrameLoadDelegates(const char *pathOrURL)
+{
+ return strstr(pathOrURL, "loading/");
+}
+
+static void resetWebViewToConsistentStateBeforeTesting()
+{
+ WebView *webView = [mainFrame webView];
+ [(EditingDelegate *)[webView editingDelegate] setAcceptsEditing:YES];
+ [webView makeTextStandardSize:nil];
+ [webView resetPageZoom:nil];
+ [webView setTabKeyCyclesThroughElements:YES];
+ [webView setPolicyDelegate:nil];
+ [webView _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:NO];
+ [webView _clearMainFrameName];
+
+ WebPreferences *preferences = [webView preferences];
+ [preferences setPrivateBrowsingEnabled:NO];
+ [preferences setAuthorAndUserStylesEnabled:YES];
+ [preferences setJavaScriptCanOpenWindowsAutomatically:YES];
+ [preferences setOfflineWebApplicationCacheEnabled:YES];
+ [preferences setFullDocumentTeardownEnabled:YES];
+ [preferences setDeveloperExtrasEnabled:NO];
+
+ if (persistentUserStyleSheetLocation) {
+ [preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]];
+ [preferences setUserStyleSheetEnabled:YES];
+ } else
+ [preferences setUserStyleSheetEnabled:NO];
+
+ [[mainFrame webView] setSmartInsertDeleteEnabled:YES];
+ [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:NO];
+
+ [WebView _setUsesTestModeFocusRingColor:YES];
+}
+
+static void runTest(const string& testPathOrURL)
+{
+ ASSERT(!testPathOrURL.empty());
+
+ // Look for "'" as a separator between the path or URL, and the pixel dump hash that follows.
+ string pathOrURL(testPathOrURL);
+ string expectedPixelHash;
+
+ size_t separatorPos = pathOrURL.find("'");
+ if (separatorPos != string::npos) {
+ pathOrURL = string(testPathOrURL, 0, separatorPos);
+ expectedPixelHash = string(testPathOrURL, separatorPos + 1);
+ }
+
+ NSString *pathOrURLString = [NSString stringWithUTF8String:pathOrURL.c_str()];
+ if (!pathOrURLString) {
+ fprintf(stderr, "Failed to parse \"%s\" as UTF-8\n", pathOrURL.c_str());
+ return;
+ }
+
+ NSURL *url;
+ if ([pathOrURLString hasPrefix:@"http://"] || [pathOrURLString hasPrefix:@"https://"])
+ url = [NSURL URLWithString:pathOrURLString];
+ else
+ url = [NSURL fileURLWithPath:pathOrURLString];
+ if (!url) {
+ fprintf(stderr, "Failed to parse \"%s\" as a URL\n", pathOrURL.c_str());
+ return;
+ }
+
+ const string testURL([[url absoluteString] UTF8String]);
+
+ resetWebViewToConsistentStateBeforeTesting();
+
+ gLayoutTestController = new LayoutTestController(testURL, expectedPixelHash);
+ topLoadingFrame = nil;
+ done = NO;
+
+ if (disallowedURLs)
+ CFSetRemoveAllValues(disallowedURLs);
+ if (shouldLogFrameLoadDelegates(pathOrURL.c_str()))
+ gLayoutTestController->setDumpFrameLoadCallbacks(true);
+
+ if ([WebHistory optionalSharedHistory])
+ [WebHistory setOptionalSharedHistory:nil];
+ lastMousePosition = NSZeroPoint;
+ lastClickPosition = NSZeroPoint;
+
+ [prevTestBFItem release];
+ prevTestBFItem = [[[[mainFrame webView] backForwardList] currentItem] retain];
+
+ WorkQueue::shared()->clear();
+ WorkQueue::shared()->setFrozen(false);
+
+ bool ignoreWebCoreNodeLeaks = shouldIgnoreWebCoreNodeLeaks(testURL);
+ if (ignoreWebCoreNodeLeaks)
+ [WebCoreStatistics startIgnoringWebCoreNodeLeaks];
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [mainFrame loadRequest:[NSURLRequest requestWithURL:url]];
+ [pool release];
+ while (!done) {
+ pool = [[NSAutoreleasePool alloc] init];
+ [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
+ [pool release];
+ }
+ pool = [[NSAutoreleasePool alloc] init];
+ [EventSendingController clearSavedEvents];
+ [[mainFrame webView] setSelectedDOMRange:nil affinity:NSSelectionAffinityDownstream];
+
+ WorkQueue::shared()->clear();
+
+ if (gLayoutTestController->closeRemainingWindowsWhenComplete()) {
+ NSArray* array = [DumpRenderTreeWindow openWindows];
+
+ unsigned count = [array count];
+ for (unsigned i = 0; i < count; i++) {
+ NSWindow *window = [array objectAtIndex:i];
+
+ // Don't try to close the main window
+ if (window == [[mainFrame webView] window])
+ continue;
+
+ WebView *webView = [[[window contentView] subviews] objectAtIndex:0];
+
+ [webView close];
+ [window close];
+ }
+ }
+
+ [mainFrame loadHTMLString:@"<html></html>" baseURL:[NSURL URLWithString:@"about:blank"]];
+ [mainFrame stopLoading];
+
+ [pool release];
+
+ // We should only have our main window left open when we're done
+ ASSERT(CFArrayGetCount(openWindowsRef) == 1);
+ ASSERT(CFArrayGetValueAtIndex(openWindowsRef, 0) == [[mainFrame webView] window]);
+
+ gLayoutTestController->deref();
+ gLayoutTestController = 0;
+
+ if (ignoreWebCoreNodeLeaks)
+ [WebCoreStatistics stopIgnoringWebCoreNodeLeaks];
+}
+
+void displayWebView()
+{
+ NSView *webView = [mainFrame webView];
+ [webView display];
+ [webView lockFocus];
+ [[[NSColor blackColor] colorWithAlphaComponent:0.66] set];
+ NSRectFillUsingOperation([webView frame], NSCompositeSourceOver);
+ [webView unlockFocus];
+}
+
+@implementation DumpRenderTreeEvent
+
++ (NSPoint)mouseLocation
+{
+ return [[[mainFrame webView] window] convertBaseToScreen:lastMousePosition];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.h
new file mode 100644
index 0000000..249809c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005, 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
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface DumpRenderTreeDraggingInfo : NSObject <NSDraggingInfo> {
+@private
+ NSSize offset;
+ NSImage *draggedImage;
+ NSPasteboard *draggingPasteboard;
+ id draggingSource;
+}
+
+- (id)initWithImage:(NSImage *)image offset:(NSSize)offset pasteboard:(NSPasteboard *)pasteboard source:(id)source;
+
+- (NSWindow *)draggingDestinationWindow;
+- (NSDragOperation)draggingSourceOperationMask;
+- (NSPoint)draggingLocation;
+- (NSPoint)draggedImageLocation;
+- (NSImage *)draggedImage;
+- (NSPasteboard *)draggingPasteboard;
+- (id)draggingSource;
+- (int)draggingSequenceNumber;
+
+- (void)slideDraggedImageTo:(NSPoint)screenPoint;
+- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination;
+@end
+
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm
new file mode 100644
index 0000000..41aa639
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2005, 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
+ * 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.
+ */
+
+#import "DumpRenderTreeDraggingInfo.h"
+
+#import "DumpRenderTree.h"
+#import "EventSendingController.h"
+#import <WebKit/WebKit.h>
+
+@implementation DumpRenderTreeDraggingInfo
+
+- (id)initWithImage:(NSImage *)anImage offset:(NSSize)o pasteboard:(NSPasteboard *)pboard source:(id)source
+{
+ draggedImage = [anImage retain];
+ draggingPasteboard = [pboard retain];
+ draggingSource = [source retain];
+ offset = o;
+
+ return [super init];
+}
+
+- (void)dealloc
+{
+ [draggedImage release];
+ [draggingPasteboard release];
+ [draggingSource release];
+ [super dealloc];
+}
+
+- (NSWindow *)draggingDestinationWindow
+{
+ return [[mainFrame webView] window];
+}
+
+- (NSDragOperation)draggingSourceOperationMask
+{
+ return [draggingSource draggingSourceOperationMaskForLocal:YES];
+}
+
+- (NSPoint)draggingLocation
+{
+ return lastMousePosition;
+}
+
+- (NSPoint)draggedImageLocation
+{
+ return NSMakePoint(lastMousePosition.x + offset.width, lastMousePosition.y + offset.height);
+}
+
+- (NSImage *)draggedImage
+{
+ return draggedImage;
+}
+
+- (NSPasteboard *)draggingPasteboard
+{
+ return draggingPasteboard;
+}
+
+- (id)draggingSource
+{
+ return draggingSource;
+}
+
+- (int)draggingSequenceNumber
+{
+ NSLog(@"DumpRenderTree doesn't support draggingSequenceNumber");
+ return 0;
+}
+
+- (void)slideDraggedImageTo:(NSPoint)screenPoint
+{
+ NSLog(@"DumpRenderTree doesn't support slideDraggedImageTo:");
+}
+
+- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
+{
+ NSLog(@"DumpRenderTree doesn't support namesOfPromisedFilesDroppedAtDestination:");
+ return nil;
+}
+
+@end
+
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h
new file mode 100644
index 0000000..03d354d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 DumpRenderTreeMac_h
+#define DumpRenderTreeMac_h
+
+// FIXME: we should add a config.h file for DumpRenderTree.
+#define WTF_PLATFORM_CF 1
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
+#define BUILDING_ON_TIGER 1
+#elif MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
+#define BUILDING_ON_LEOPARD 1
+#endif
+
+@class DumpRenderTreeDraggingInfo;
+@class NavigationController;
+@class PolicyDelegate;
+@class WebFrame;
+@class WebView;
+
+typedef const struct __CFString* CFStringRef;
+
+extern CFMutableArrayRef openWindowsRef;
+extern CFMutableSetRef disallowedURLs;
+extern WebFrame* mainFrame;
+extern WebFrame* topLoadingFrame;
+extern DumpRenderTreeDraggingInfo *draggingInfo;
+extern NavigationController* gNavigationController;
+extern PolicyDelegate* policyDelegate;
+
+extern const unsigned maxViewHeight;
+extern const unsigned maxViewWidth;
+
+WebView* createWebViewAndOffscreenWindow();
+void setPersistentUserStyleSheetLocation(CFStringRef);
+
+#endif // DumpRenderTreeMac_h
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h
new file mode 100644
index 0000000..ba2754b
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.h
@@ -0,0 +1,38 @@
+/*
+ * 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>
+ *
+ * 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.
+ */
+
+#import <AppKit/AppKit.h>
+#import <WebKit/WebTypesInternal.h>
+
+@interface DumpRenderTreePasteboard : NSPasteboard
+- (NSInteger)declareType:(NSString *)type owner:(id)newOwner;
++ (void)releaseLocalPasteboards;
+@end
+
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m
new file mode 100644
index 0000000..a797b5c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreePasteboard.m
@@ -0,0 +1,205 @@
+/*
+ * 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>
+ *
+ * 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.
+ */
+
+#import "DumpRenderTreeMac.h"
+#import "DumpRenderTreePasteboard.h"
+
+#import <WebKit/WebTypesInternal.h>
+
+@interface LocalPasteboard : NSPasteboard
+{
+ NSMutableArray *typesArray;
+ NSMutableSet *typesSet;
+ NSMutableDictionary *dataByType;
+ NSInteger changeCount;
+}
+@end
+
+static NSMutableDictionary *localPasteboards;
+
+@implementation DumpRenderTreePasteboard
+
+// Return a local pasteboard so we don't disturb the real pasteboards when running tests.
++ (NSPasteboard *)_pasteboardWithName:(NSString *)name
+{
+ static int number = 0;
+ if (!name)
+ name = [NSString stringWithFormat:@"LocalPasteboard%d", ++number];
+ if (!localPasteboards)
+ localPasteboards = [[NSMutableDictionary alloc] init];
+ LocalPasteboard *pasteboard = [localPasteboards objectForKey:name];
+ if (pasteboard)
+ return pasteboard;
+ pasteboard = [[LocalPasteboard alloc] init];
+ [localPasteboards setObject:pasteboard forKey:name];
+ [pasteboard release];
+ return pasteboard;
+}
+
++ (void)releaseLocalPasteboards
+{
+ [localPasteboards release];
+ localPasteboards = nil;
+}
+
+// Convenience method for JS so that it doesn't have to try and create a NSArray on the objc side instead
+// of the usual WebScriptObject that is passed around
+- (NSInteger)declareType:(NSString *)type owner:(id)newOwner
+{
+ return [self declareTypes:[NSArray arrayWithObject:type] owner:newOwner];
+}
+
+@end
+
+@implementation LocalPasteboard
+
++ (id)alloc
+{
+ return NSAllocateObject(self, 0, 0);
+}
+
+- (id)init
+{
+ typesArray = [[NSMutableArray alloc] init];
+ typesSet = [[NSMutableSet alloc] init];
+ dataByType = [[NSMutableDictionary alloc] init];
+ return self;
+}
+
+- (void)dealloc
+{
+ [typesArray release];
+ [typesSet release];
+ [dataByType release];
+ [super dealloc];
+}
+
+- (NSString *)name
+{
+ return nil;
+}
+
+- (void)releaseGlobally
+{
+}
+
+- (NSInteger)declareTypes:(NSArray *)newTypes owner:(id)newOwner
+{
+ [typesArray removeAllObjects];
+ [typesSet removeAllObjects];
+ [dataByType removeAllObjects];
+ return [self addTypes:newTypes owner:newOwner];
+}
+
+- (NSInteger)addTypes:(NSArray *)newTypes owner:(id)newOwner
+{
+ unsigned count = [newTypes count];
+ unsigned i;
+ for (i = 0; i < count; ++i) {
+ NSString *type = [newTypes objectAtIndex:i];
+ NSString *setType = [typesSet member:type];
+ if (!setType) {
+ setType = [type copy];
+ [typesArray addObject:setType];
+ [typesSet addObject:setType];
+ [setType release];
+ }
+ if (newOwner && [newOwner respondsToSelector:@selector(pasteboard:provideDataForType:)])
+ [newOwner pasteboard:self provideDataForType:setType];
+ }
+ return ++changeCount;
+}
+
+- (NSInteger)changeCount
+{
+ return changeCount;
+}
+
+- (NSArray *)types
+{
+ return typesArray;
+}
+
+- (NSString *)availableTypeFromArray:(NSArray *)types
+{
+ unsigned count = [types count];
+ unsigned i;
+ for (i = 0; i < count; ++i) {
+ NSString *type = [types objectAtIndex:i];
+ NSString *setType = [typesSet member:type];
+ if (setType)
+ return setType;
+ }
+ return nil;
+}
+
+- (BOOL)setData:(NSData *)data forType:(NSString *)dataType
+{
+ if (data == nil)
+ data = [NSData data];
+ if (![typesSet containsObject:dataType])
+ return NO;
+ [dataByType setObject:data forKey:dataType];
+ ++changeCount;
+ return YES;
+}
+
+- (NSData *)dataForType:(NSString *)dataType
+{
+ return [dataByType objectForKey:dataType];
+}
+
+- (BOOL)setPropertyList:(id)propertyList forType:(NSString *)dataType;
+{
+ CFDataRef data = NULL;
+ if (propertyList)
+ data = CFPropertyListCreateXMLData(NULL, propertyList);
+ BOOL result = [self setData:(NSData *)data forType:dataType];
+ if (data)
+ CFRelease(data);
+ return result;
+}
+
+- (BOOL)setString:(NSString *)string forType:(NSString *)dataType
+{
+ CFDataRef data = NULL;
+ if (string) {
+ if ([string length] == 0)
+ data = CFDataCreate(NULL, NULL, 0);
+ else
+ data = CFStringCreateExternalRepresentation(NULL, (CFStringRef)string, kCFStringEncodingUTF8, 0);
+ }
+ BOOL result = [self setData:(NSData *)data forType:dataType];
+ if (data)
+ CFRelease(data);
+ return result;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.h
new file mode 100644
index 0000000..3ac3223
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.h
@@ -0,0 +1,36 @@
+/*
+ * 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>
+ *
+ * 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.
+ */
+
+#import <AppKit/AppKit.h>
+
+@interface DumpRenderTreeWindow : NSWindow
+// I'm not sure why we can't just use [NSApp windows]
++ (NSArray *)openWindows;
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm
new file mode 100644
index 0000000..b3fc5a7
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeWindow.mm
@@ -0,0 +1,86 @@
+/*
+ * 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>
+ *
+ * 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.
+ */
+
+#import "DumpRenderTreeWindow.h"
+
+#import "DumpRenderTree.h"
+
+// FIXME: This file is ObjC++ only because of this include. :(
+#import "LayoutTestController.h"
+#import <WebKit/WebTypesInternal.h>
+
+CFMutableArrayRef openWindowsRef = 0;
+
+static CFArrayCallBacks NonRetainingArrayCallbacks = {
+ 0,
+ NULL,
+ NULL,
+ CFCopyDescription,
+ CFEqual
+};
+
+@implementation DumpRenderTreeWindow
+
++ (NSArray *)openWindows
+{
+ return [[(NSArray *)openWindowsRef copy] autorelease];
+}
+
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
+{
+ if (!openWindowsRef)
+ openWindowsRef = CFArrayCreateMutable(NULL, 0, &NonRetainingArrayCallbacks);
+
+ CFArrayAppendValue(openWindowsRef, self);
+
+ return [super initWithContentRect:contentRect styleMask:styleMask backing:bufferingType defer:deferCreation];
+}
+
+- (void)close
+{
+ CFRange arrayRange = CFRangeMake(0, CFArrayGetCount(openWindowsRef));
+ CFIndex i = CFArrayGetFirstIndexOfValue(openWindowsRef, arrayRange, self);
+ assert(i != -1);
+ CFArrayRemoveValueAtIndex(openWindowsRef, i);
+ [super close];
+}
+
+- (BOOL)isKeyWindow
+{
+ return gLayoutTestController ? gLayoutTestController->windowIsKey() : YES;
+}
+
+- (void)keyDown:(id)sender
+{
+ // Do nothing, avoiding the beep we'd otherwise get from NSResponder,
+ // once we get to the end of the responder chain.
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/EditingDelegate.h b/WebKitTools/DumpRenderTree/mac/EditingDelegate.h
new file mode 100644
index 0000000..b5563c8
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/EditingDelegate.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2005, 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
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface EditingDelegate : NSObject
+{
+ BOOL acceptsEditing;
+}
+
+- (void)setAcceptsEditing:(BOOL)newAcceptsEditing;
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm b/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm
new file mode 100644
index 0000000..cf4026b
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/EditingDelegate.mm
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2005, 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
+ * 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.
+ */
+
+#import "EditingDelegate.h"
+
+#import "DumpRenderTree.h"
+#import "LayoutTestController.h"
+#import <WebKit/WebKit.h>
+
+@interface DOMNode (dumpPath)
+- (NSString *)dumpPath;
+@end
+
+@implementation DOMNode (dumpPath)
+- (NSString *)dumpPath
+{
+ DOMNode *parent = [self parentNode];
+ NSString *str = [NSString stringWithFormat:@"%@", [self nodeName]];
+ if (parent != nil) {
+ str = [str stringByAppendingString:@" > "];
+ str = [str stringByAppendingString:[parent dumpPath]];
+ }
+ return str;
+}
+@end
+
+@interface DOMRange (dump)
+- (NSString *)dump;
+@end
+
+@implementation DOMRange (dump)
+- (NSString *)dump
+{
+ return [NSString stringWithFormat:@"range from %ld of %@ to %ld of %@", [self startOffset], [[self startContainer] dumpPath], [self endOffset], [[self endContainer] dumpPath]];
+}
+@end
+
+@implementation EditingDelegate
+
+- (id)init
+{
+ self = [super init];
+ if (!self)
+ return nil;
+ acceptsEditing = YES;
+ return self;
+}
+
+- (BOOL)webView:(WebView *)webView shouldBeginEditingInDOMRange:(DOMRange *)range
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n", [[range dump] UTF8String]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldEndEditingInDOMRange:(DOMRange *)range
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n", [[range dump] UTF8String]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldInsertNode:(DOMNode *)node replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action
+{
+ static const char *insertactionstring[] = {
+ "WebViewInsertActionTyped",
+ "WebViewInsertActionPasted",
+ "WebViewInsertActionDropped",
+ };
+
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n", [[node dumpPath] UTF8String], [[range dump] UTF8String], insertactionstring[action]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldInsertText:(NSString *)text replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action
+{
+ static const char *insertactionstring[] = {
+ "WebViewInsertActionTyped",
+ "WebViewInsertActionPasted",
+ "WebViewInsertActionDropped",
+ };
+
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n", [[text description] UTF8String], [[range dump] UTF8String], insertactionstring[action]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldDeleteDOMRange:(DOMRange *)range
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldDeleteDOMRange:%s\n", [[range dump] UTF8String]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldShowDeleteInterfaceForElement:(DOMHTMLElement *)element
+{
+ return [[element className] isEqualToString:@"needsDeletionUI"];
+}
+
+- (BOOL)webView:(WebView *)webView shouldChangeSelectedDOMRange:(DOMRange *)currentRange toDOMRange:(DOMRange *)proposedRange affinity:(NSSelectionAffinity)selectionAffinity stillSelecting:(BOOL)flag
+{
+ static const char *affinitystring[] = {
+ "NSSelectionAffinityUpstream",
+ "NSSelectionAffinityDownstream"
+ };
+ static const char *boolstring[] = {
+ "FALSE",
+ "TRUE"
+ };
+
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n", [[currentRange dump] UTF8String], [[proposedRange dump] UTF8String], affinitystring[selectionAffinity], boolstring[flag]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldApplyStyle:(DOMCSSStyleDeclaration *)style toElementsInDOMRange:(DOMRange *)range
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n", [[style description] UTF8String], [[range dump] UTF8String]);
+ return acceptsEditing;
+}
+
+- (BOOL)webView:(WebView *)webView shouldChangeTypingStyle:(DOMCSSStyleDeclaration *)currentStyle toStyle:(DOMCSSStyleDeclaration *)proposedStyle
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: shouldChangeTypingStyle:%s toStyle:%s\n", [[currentStyle description] UTF8String], [[proposedStyle description] UTF8String]);
+ return acceptsEditing;
+}
+
+- (void)webViewDidBeginEditing:(NSNotification *)notification
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidBeginEditing:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)webViewDidChange:(NSNotification *)notification
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidChange:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)webViewDidEndEditing:(NSNotification *)notification
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidEndEditing:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)webViewDidChangeTypingStyle:(NSNotification *)notification
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidChangeTypingStyle:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)webViewDidChangeSelection:(NSNotification *)notification
+{
+ if (!done && gLayoutTestController->dumpEditingCallbacks())
+ printf("EDITING DELEGATE: webViewDidChangeSelection:%s\n", [[notification name] UTF8String]);
+}
+
+- (void)setAcceptsEditing:(BOOL)newAcceptsEditing
+{
+ acceptsEditing = newAcceptsEditing;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/EventSendingController.h b/WebKitTools/DumpRenderTree/mac/EventSendingController.h
new file mode 100644
index 0000000..deee848
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/EventSendingController.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 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.
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <WebKit/WebKit.h>
+
+@interface EventSendingController : NSObject <DOMEventListener>
+{
+ BOOL leftMouseButtonDown;
+ BOOL dragMode;
+ int clickCount;
+ NSTimeInterval lastClick;
+ int eventNumber;
+ double timeOffset;
+}
+
++ (void)saveEvent:(NSInvocation *)event;
++ (void)replaySavedEvents;
++ (void)clearSavedEvents;
+
+- (void)enableDOMUIEventLogging:(WebScriptObject *)node;
+
+- (void)handleEvent:(DOMEvent *)event;
+
+@end
+
+extern NSPoint lastMousePosition;
+extern NSPoint lastClickPosition; \ No newline at end of file
diff --git a/WebKitTools/DumpRenderTree/mac/EventSendingController.mm b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
new file mode 100644
index 0000000..8be05e7
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
@@ -0,0 +1,667 @@
+/*
+ * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Jonas Witt <jonas.witt@gmail.com>
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.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.
+ */
+
+#import "EventSendingController.h"
+
+#import "DumpRenderTree.h"
+#import "DumpRenderTreeDraggingInfo.h"
+
+#import <Carbon/Carbon.h> // for GetCurrentEventTime()
+#import <WebKit/DOMPrivate.h>
+#import <WebKit/WebKit.h>
+#import <WebKit/WebViewPrivate.h>
+
+extern "C" void _NSNewKillRingSequence();
+
+enum MouseAction {
+ MouseDown,
+ MouseUp,
+ MouseDragged
+};
+
+// Match the DOM spec (sadly the DOM spec does not provide an enum)
+enum MouseButton {
+ LeftMouseButton = 0,
+ MiddleMouseButton = 1,
+ RightMouseButton = 2,
+ NoMouseButton = -1
+};
+
+NSPoint lastMousePosition;
+NSPoint lastClickPosition;
+int lastClickButton = NoMouseButton;
+NSArray *webkitDomEventNames;
+NSMutableArray *savedMouseEvents; // mouse events sent between mouseDown and mouseUp are stored here, and then executed at once.
+BOOL replayingSavedEvents;
+
+@implementation EventSendingController
+
++ (void)initialize
+{
+ webkitDomEventNames = [[NSArray alloc] initWithObjects:
+ @"abort",
+ @"beforecopy",
+ @"beforecut",
+ @"beforepaste",
+ @"blur",
+ @"change",
+ @"click",
+ @"contextmenu",
+ @"copy",
+ @"cut",
+ @"dblclick",
+ @"drag",
+ @"dragend",
+ @"dragenter",
+ @"dragleave",
+ @"dragover",
+ @"dragstart",
+ @"drop",
+ @"error",
+ @"focus",
+ @"input",
+ @"keydown",
+ @"keypress",
+ @"keyup",
+ @"load",
+ @"mousedown",
+ @"mousemove",
+ @"mouseout",
+ @"mouseover",
+ @"mouseup",
+ @"mousewheel",
+ @"beforeunload",
+ @"paste",
+ @"readystatechange",
+ @"reset",
+ @"resize",
+ @"scroll",
+ @"search",
+ @"select",
+ @"selectstart",
+ @"submit",
+ @"textInput",
+ @"textzoomin",
+ @"textzoomout",
+ @"unload",
+ @"zoom",
+ nil];
+}
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(mouseDown:)
+ || aSelector == @selector(mouseUp:)
+ || aSelector == @selector(contextClick)
+ || aSelector == @selector(mouseMoveToX:Y:)
+ || aSelector == @selector(leapForward:)
+ || aSelector == @selector(keyDown:withModifiers:)
+ || aSelector == @selector(enableDOMUIEventLogging:)
+ || aSelector == @selector(fireKeyboardEventsToElement:)
+ || aSelector == @selector(clearKillRing)
+ || aSelector == @selector(textZoomIn)
+ || aSelector == @selector(textZoomOut)
+ || aSelector == @selector(zoomPageIn)
+ || aSelector == @selector(zoomPageOut))
+ return NO;
+ return YES;
+}
+
++ (BOOL)isKeyExcludedFromWebScript:(const char*)name
+{
+ if (strcmp(name, "dragMode") == 0)
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(mouseDown:))
+ return @"mouseDown";
+ if (aSelector == @selector(mouseUp:))
+ return @"mouseUp";
+ if (aSelector == @selector(mouseMoveToX:Y:))
+ return @"mouseMoveTo";
+ if (aSelector == @selector(leapForward:))
+ return @"leapForward";
+ if (aSelector == @selector(keyDown:withModifiers:))
+ return @"keyDown";
+ if (aSelector == @selector(enableDOMUIEventLogging:))
+ return @"enableDOMUIEventLogging";
+ if (aSelector == @selector(fireKeyboardEventsToElement:))
+ return @"fireKeyboardEventsToElement";
+ if (aSelector == @selector(setDragMode:))
+ return @"setDragMode";
+ return nil;
+}
+
+- (id)init
+{
+ self = [super init];
+ if (self)
+ dragMode = YES;
+ return self;
+}
+
+- (void)dealloc
+{
+ [super dealloc];
+}
+
+- (double)currentEventTime
+{
+ return GetCurrentEventTime() + timeOffset;
+}
+
+- (void)leapForward:(int)milliseconds
+{
+ if (dragMode && leftMouseButtonDown && !replayingSavedEvents) {
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(leapForward:)]];
+ [invocation setTarget:self];
+ [invocation setSelector:@selector(leapForward:)];
+ [invocation setArgument:&milliseconds atIndex:2];
+
+ [EventSendingController saveEvent:invocation];
+
+ return;
+ }
+
+ timeOffset += milliseconds / 1000.0;
+}
+
+- (void)clearKillRing
+{
+ _NSNewKillRingSequence();
+}
+
+static NSEventType eventTypeForMouseButtonAndAction(int button, MouseAction action)
+{
+ switch (button) {
+ case LeftMouseButton:
+ switch (action) {
+ case MouseDown:
+ return NSLeftMouseDown;
+ case MouseUp:
+ return NSLeftMouseUp;
+ case MouseDragged:
+ return NSLeftMouseDragged;
+ }
+ case RightMouseButton:
+ switch (action) {
+ case MouseDown:
+ return NSRightMouseDown;
+ case MouseUp:
+ return NSRightMouseUp;
+ case MouseDragged:
+ return NSRightMouseDragged;
+ }
+ default:
+ switch (action) {
+ case MouseDown:
+ return NSOtherMouseDown;
+ case MouseUp:
+ return NSOtherMouseUp;
+ case MouseDragged:
+ return NSOtherMouseDragged;
+ }
+ }
+ assert(0);
+ return static_cast<NSEventType>(0);
+}
+
+- (void)updateClickCountForButton:(int)buttonNumber
+{
+ if (([self currentEventTime] - lastClick >= 1) ||
+ !NSEqualPoints(lastMousePosition, lastClickPosition) ||
+ lastClickButton != buttonNumber) {
+ clickCount = 1;
+ lastClickButton = buttonNumber;
+ } else
+ clickCount++;
+}
+
+- (void)mouseDown:(int)buttonNumber
+{
+ [[[mainFrame frameView] documentView] layout];
+ [self updateClickCountForButton:buttonNumber];
+
+ NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseDown);
+ NSEvent *event = [NSEvent mouseEventWithType:eventType
+ location:lastMousePosition
+ modifierFlags:0
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ eventNumber:++eventNumber
+ clickCount:clickCount
+ pressure:0.0];
+
+ NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
+ if (subView) {
+ [subView mouseDown:event];
+ if (buttonNumber == LeftMouseButton)
+ leftMouseButtonDown = YES;
+ }
+}
+
+- (void)textZoomIn
+{
+ [[mainFrame webView] makeTextLarger:self];
+}
+
+- (void)textZoomOut
+{
+ [[mainFrame webView] makeTextSmaller:self];
+}
+
+- (void)zoomPageIn
+{
+ [[mainFrame webView] zoomPageIn:self];
+}
+
+- (void)zoomPageOut
+{
+ [[mainFrame webView] zoomPageOut:self];
+}
+
+- (void)mouseUp:(int)buttonNumber
+{
+ if (dragMode && !replayingSavedEvents) {
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseUp:)]];
+ [invocation setTarget:self];
+ [invocation setSelector:@selector(mouseUp:)];
+ [invocation setArgument:&buttonNumber atIndex:2];
+
+ [EventSendingController saveEvent:invocation];
+ [EventSendingController replaySavedEvents];
+
+ return;
+ }
+
+ [[[mainFrame frameView] documentView] layout];
+ NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseUp);
+ NSEvent *event = [NSEvent mouseEventWithType:eventType
+ location:lastMousePosition
+ modifierFlags:0
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ eventNumber:++eventNumber
+ clickCount:clickCount
+ pressure:0.0];
+
+ NSView *targetView = [[mainFrame webView] hitTest:[event locationInWindow]];
+ // FIXME: Silly hack to teach DRT to respect capturing mouse events outside the WebView.
+ // The right solution is just to use NSApplication's built-in event sending methods,
+ // instead of rolling our own algorithm for selecting an event target.
+ targetView = targetView ? targetView : [[mainFrame frameView] documentView];
+ assert(targetView);
+ [targetView mouseUp:event];
+ if (buttonNumber == LeftMouseButton)
+ leftMouseButtonDown = NO;
+ lastClick = [event timestamp];
+ lastClickPosition = lastMousePosition;
+ if (draggingInfo) {
+ WebView *webView = [mainFrame webView];
+
+ NSDragOperation dragOperation = [webView draggingUpdated:draggingInfo];
+
+ if (dragOperation != NSDragOperationNone)
+ [webView performDragOperation:draggingInfo];
+ else
+ [webView draggingExited:draggingInfo];
+ [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] endedAt:lastMousePosition operation:dragOperation];
+ [draggingInfo release];
+ draggingInfo = nil;
+ }
+}
+
+- (void)mouseMoveToX:(int)x Y:(int)y
+{
+ if (dragMode && leftMouseButtonDown && !replayingSavedEvents) {
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseMoveToX:Y:)]];
+ [invocation setTarget:self];
+ [invocation setSelector:@selector(mouseMoveToX:Y:)];
+ [invocation setArgument:&x atIndex:2];
+ [invocation setArgument:&y atIndex:3];
+
+ [EventSendingController saveEvent:invocation];
+
+ return;
+ }
+
+ NSView *view = [mainFrame webView];
+ lastMousePosition = [view convertPoint:NSMakePoint(x, [view frame].size.height - y) toView:nil];
+ NSEvent *event = [NSEvent mouseEventWithType:(leftMouseButtonDown ? NSLeftMouseDragged : NSMouseMoved)
+ location:lastMousePosition
+ modifierFlags:0
+ timestamp:[self currentEventTime]
+ windowNumber:[[view window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ eventNumber:++eventNumber
+ clickCount:(leftMouseButtonDown ? clickCount : 0)
+ pressure:0.0];
+
+ NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
+ if (subView) {
+ if (leftMouseButtonDown) {
+ [subView mouseDragged:event];
+ if (draggingInfo) {
+ [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] movedTo:lastMousePosition];
+ [[mainFrame webView] draggingUpdated:draggingInfo];
+ }
+ } else
+ [subView mouseMoved:event];
+ }
+}
+
+- (void)contextClick
+{
+ [[[mainFrame frameView] documentView] layout];
+ [self updateClickCountForButton:RightMouseButton];
+
+ NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown
+ location:lastMousePosition
+ modifierFlags:0
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ eventNumber:++eventNumber
+ clickCount:clickCount
+ pressure:0.0];
+
+ NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
+ if (subView)
+ [subView menuForEvent:event];
+}
+
++ (void)saveEvent:(NSInvocation *)event
+{
+ if (!savedMouseEvents)
+ savedMouseEvents = [[NSMutableArray alloc] init];
+ [savedMouseEvents addObject:event];
+}
+
++ (void)replaySavedEvents
+{
+ replayingSavedEvents = YES;
+ while ([savedMouseEvents count]) {
+ // if a drag is initiated, the remaining saved events will be dispatched from our dragging delegate
+ NSInvocation *invocation = [[[savedMouseEvents objectAtIndex:0] retain] autorelease];
+ [savedMouseEvents removeObjectAtIndex:0];
+ [invocation invoke];
+ }
+ replayingSavedEvents = NO;
+}
+
++ (void)clearSavedEvents
+{
+ [savedMouseEvents release];
+ savedMouseEvents = nil;
+}
+
+- (void)keyDown:(NSString *)character withModifiers:(WebScriptObject *)modifiers
+{
+ NSString *eventCharacter = character;
+ if ([character isEqualToString:@"leftArrow"]) {
+ const unichar ch = NSLeftArrowFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"rightArrow"]) {
+ const unichar ch = NSRightArrowFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"upArrow"]) {
+ const unichar ch = NSUpArrowFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"downArrow"]) {
+ const unichar ch = NSDownArrowFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"pageUp"]) {
+ const unichar ch = NSPageUpFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"pageDown"]) {
+ const unichar ch = NSPageDownFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"home"]) {
+ const unichar ch = NSHomeFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"end"]) {
+ const unichar ch = NSEndFunctionKey;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ } else if ([character isEqualToString:@"delete"]) {
+ const unichar ch = 0x7f;
+ eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ }
+
+ NSString *charactersIgnoringModifiers = eventCharacter;
+
+ int modifierFlags = 0;
+
+ if ([character length] == 1 && [character characterAtIndex:0] >= 'A' && [character characterAtIndex:0] <= 'Z') {
+ modifierFlags |= NSShiftKeyMask;
+ charactersIgnoringModifiers = [character lowercaseString];
+ }
+
+ if ([modifiers isKindOfClass:[WebScriptObject class]])
+ for (unsigned i = 0; [[modifiers webScriptValueAtIndex:i] isKindOfClass:[NSString class]]; i++) {
+ NSString *modifier = (NSString *)[modifiers webScriptValueAtIndex:i];
+ if ([modifier isEqual:@"ctrlKey"])
+ modifierFlags |= NSControlKeyMask;
+ else if ([modifier isEqual:@"shiftKey"])
+ modifierFlags |= NSShiftKeyMask;
+ else if ([modifier isEqual:@"altKey"])
+ modifierFlags |= NSAlternateKeyMask;
+ else if ([modifier isEqual:@"metaKey"])
+ modifierFlags |= NSCommandKeyMask;
+ }
+
+ [[[mainFrame frameView] documentView] layout];
+
+ NSEvent *event = [NSEvent keyEventWithType:NSKeyDown
+ location:NSMakePoint(5, 5)
+ modifierFlags:modifierFlags
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ characters:eventCharacter
+ charactersIgnoringModifiers:charactersIgnoringModifiers
+ isARepeat:NO
+ keyCode:0];
+
+ [[[[mainFrame webView] window] firstResponder] keyDown:event];
+
+ event = [NSEvent keyEventWithType:NSKeyUp
+ location:NSMakePoint(5, 5)
+ modifierFlags:modifierFlags
+ timestamp:[self currentEventTime]
+ windowNumber:[[[mainFrame webView] window] windowNumber]
+ context:[NSGraphicsContext currentContext]
+ characters:eventCharacter
+ charactersIgnoringModifiers:charactersIgnoringModifiers
+ isARepeat:NO
+ keyCode:0];
+
+ [[[[mainFrame webView] window] firstResponder] keyUp:event];
+}
+
+- (void)enableDOMUIEventLogging:(WebScriptObject *)node
+{
+ NSEnumerator *eventEnumerator = [webkitDomEventNames objectEnumerator];
+ id eventName;
+ while ((eventName = [eventEnumerator nextObject])) {
+ [(id<DOMEventTarget>)node addEventListener:eventName listener:self useCapture:NO];
+ }
+}
+
+- (void)handleEvent:(DOMEvent *)event
+{
+ DOMNode *target = [event target];
+
+ printf("event type: %s\n", [[event type] UTF8String]);
+ printf(" target: <%s>\n", [[[target nodeName] lowercaseString] UTF8String]);
+
+ if ([event isKindOfClass:[DOMEvent class]]) {
+ printf(" eventPhase: %d\n", [event eventPhase]);
+ printf(" bubbles: %d\n", [event bubbles] ? 1 : 0);
+ printf(" cancelable: %d\n", [event cancelable] ? 1 : 0);
+ }
+
+ if ([event isKindOfClass:[DOMUIEvent class]]) {
+ printf(" detail: %d\n", [(DOMUIEvent*)event detail]);
+
+ DOMAbstractView *view = [(DOMUIEvent*)event view];
+ if (view) {
+ printf(" view: OK");
+ if ([view document])
+ printf(" (document: OK)");
+ printf("\n");
+ }
+ }
+
+ if ([event isKindOfClass:[DOMKeyboardEvent class]]) {
+ printf(" keyIdentifier: %s\n", [[(DOMKeyboardEvent*)event keyIdentifier] UTF8String]);
+ printf(" keyLocation: %d\n", [(DOMKeyboardEvent*)event keyLocation]);
+ printf(" modifier keys: c:%d s:%d a:%d m:%d\n",
+ [(DOMKeyboardEvent*)event ctrlKey] ? 1 : 0,
+ [(DOMKeyboardEvent*)event shiftKey] ? 1 : 0,
+ [(DOMKeyboardEvent*)event altKey] ? 1 : 0,
+ [(DOMKeyboardEvent*)event metaKey] ? 1 : 0);
+ printf(" keyCode: %d\n", [(DOMKeyboardEvent*)event keyCode]);
+ printf(" charCode: %d\n", [(DOMKeyboardEvent*)event charCode]);
+ }
+
+ if ([event isKindOfClass:[DOMMouseEvent class]]) {
+ printf(" button: %d\n", [(DOMMouseEvent*)event button]);
+ printf(" clientX: %d\n", [(DOMMouseEvent*)event clientX]);
+ printf(" clientY: %d\n", [(DOMMouseEvent*)event clientY]);
+ printf(" screenX: %d\n", [(DOMMouseEvent*)event screenX]);
+ printf(" screenY: %d\n", [(DOMMouseEvent*)event screenY]);
+ printf(" modifier keys: c:%d s:%d a:%d m:%d\n",
+ [(DOMMouseEvent*)event ctrlKey] ? 1 : 0,
+ [(DOMMouseEvent*)event shiftKey] ? 1 : 0,
+ [(DOMMouseEvent*)event altKey] ? 1 : 0,
+ [(DOMMouseEvent*)event metaKey] ? 1 : 0);
+ id relatedTarget = [(DOMMouseEvent*)event relatedTarget];
+ if (relatedTarget) {
+ printf(" relatedTarget: %s", [[[relatedTarget class] description] UTF8String]);
+ if ([relatedTarget isKindOfClass:[DOMNode class]])
+ printf(" (nodeName: %s)", [[(DOMNode*)relatedTarget nodeName] UTF8String]);
+ printf("\n");
+ }
+ }
+
+ if ([event isKindOfClass:[DOMMutationEvent class]]) {
+ printf(" prevValue: %s\n", [[(DOMMutationEvent*)event prevValue] UTF8String]);
+ printf(" newValue: %s\n", [[(DOMMutationEvent*)event newValue] UTF8String]);
+ printf(" attrName: %s\n", [[(DOMMutationEvent*)event attrName] UTF8String]);
+ printf(" attrChange: %d\n", [(DOMMutationEvent*)event attrChange]);
+ DOMNode *relatedNode = [(DOMMutationEvent*)event relatedNode];
+ if (relatedNode) {
+ printf(" relatedNode: %s (nodeName: %s)\n",
+ [[[relatedNode class] description] UTF8String],
+ [[relatedNode nodeName] UTF8String]);
+ }
+ }
+
+ if ([event isKindOfClass:[DOMWheelEvent class]]) {
+ printf(" clientX: %d\n", [(DOMWheelEvent*)event clientX]);
+ printf(" clientY: %d\n", [(DOMWheelEvent*)event clientY]);
+ printf(" screenX: %d\n", [(DOMWheelEvent*)event screenX]);
+ printf(" screenY: %d\n", [(DOMWheelEvent*)event screenY]);
+ printf(" modifier keys: c:%d s:%d a:%d m:%d\n",
+ [(DOMWheelEvent*)event ctrlKey] ? 1 : 0,
+ [(DOMWheelEvent*)event shiftKey] ? 1 : 0,
+ [(DOMWheelEvent*)event altKey] ? 1 : 0,
+ [(DOMWheelEvent*)event metaKey] ? 1 : 0);
+ printf(" isHorizontal: %d\n", [(DOMWheelEvent*)event isHorizontal] ? 1 : 0);
+ printf(" wheelDelta: %d\n", [(DOMWheelEvent*)event wheelDelta]);
+ }
+}
+
+// FIXME: It's not good to have a test hard-wired into this controller like this.
+// Instead we need to get testing framework based on the Objective-C bindings
+// to work well enough that we can test that way instead.
+- (void)fireKeyboardEventsToElement:(WebScriptObject *)element {
+
+ if (![element isKindOfClass:[DOMHTMLElement class]]) {
+ return;
+ }
+
+ DOMHTMLElement *target = (DOMHTMLElement*)element;
+ DOMDocument *document = [target ownerDocument];
+
+ // Keyboard Event 1
+
+ DOMEvent *domEvent = [document createEvent:@"KeyboardEvent"];
+ [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keydown"
+ canBubble:YES
+ cancelable:YES
+ view:[document defaultView]
+ keyIdentifier:@"U+000041"
+ keyLocation:0
+ ctrlKey:YES
+ altKey:NO
+ shiftKey:NO
+ metaKey:NO];
+ [target dispatchEvent:domEvent];
+
+ // Keyboard Event 2
+
+ domEvent = [document createEvent:@"KeyboardEvent"];
+ [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keypress"
+ canBubble:YES
+ cancelable:YES
+ view:[document defaultView]
+ keyIdentifier:@"U+000045"
+ keyLocation:1
+ ctrlKey:NO
+ altKey:YES
+ shiftKey:NO
+ metaKey:NO];
+ [target dispatchEvent:domEvent];
+
+ // Keyboard Event 3
+
+ domEvent = [document createEvent:@"KeyboardEvent"];
+ [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keyup"
+ canBubble:YES
+ cancelable:YES
+ view:[document defaultView]
+ keyIdentifier:@"U+000056"
+ keyLocation:0
+ ctrlKey:NO
+ altKey:NO
+ shiftKey:NO
+ metaKey:NO];
+ [target dispatchEvent:domEvent];
+
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h
new file mode 100644
index 0000000..6c3cbdb
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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.
+ */
+
+#import <Foundation/Foundation.h>
+
+class AccessibilityController;
+class GCController;
+
+@interface FrameLoadDelegate : NSObject
+{
+ AccessibilityController* accessibilityController;
+ GCController* gcController;
+}
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm
new file mode 100644
index 0000000..3d7f8b4
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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.
+ */
+
+#import "DumpRenderTree.h"
+#import "FrameLoadDelegate.h"
+
+#import "AccessibilityController.h"
+#import "AppleScriptController.h"
+#import "EventSendingController.h"
+#import "GCController.h"
+#import "LayoutTestController.h"
+#import "NavigationController.h"
+#import "ObjCController.h"
+#import "ObjCPlugin.h"
+#import "ObjCPluginFunction.h"
+#import "TextInputController.h"
+#import "WorkQueue.h"
+#import "WorkQueueItem.h"
+#import <JavaScriptCore/JavaScriptCore.h>
+#import <WebKit/WebFramePrivate.h>
+#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebKit.h>
+#import <WebKit/WebNSURLExtras.h>
+#import <wtf/Assertions.h>
+
+@interface NSURLRequest (PrivateThingsWeShouldntReallyUse)
++(void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString *)host;
+@end
+
+@interface NSURL (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSError (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSURLResponse (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSURLRequest (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface WebFrame (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@implementation WebFrame (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ BOOL isMainFrame = (self == [[self webView] mainFrame]);
+ NSString *name = [self name];
+ if (isMainFrame) {
+ if ([name length])
+ return [NSString stringWithFormat:@"main frame \"%@\"", name];
+ else
+ return @"main frame";
+ } else {
+ if (name)
+ return [NSString stringWithFormat:@"frame \"%@\"", name];
+ else
+ return @"frame (anonymous)";
+ }
+}
+@end
+
+@implementation FrameLoadDelegate
+
+- (id)init
+{
+ if ((self = [super init])) {
+ gcController = new GCController;
+ accessibilityController = new AccessibilityController;
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ delete gcController;
+ [super dealloc];
+}
+
+// Exec messages in the work queue until they're all done, or one of them starts a new load
+- (void)processWork:(id)dummy
+{
+ // quit doing work once a load is in progress
+ while (WorkQueue::shared()->count() > 0 && !topLoadingFrame) {
+ WorkQueueItem* item = WorkQueue::shared()->dequeue();
+ ASSERT(item);
+ item->invoke();
+ delete item;
+ }
+
+ // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
+ if (!topLoadingFrame && !gLayoutTestController->waitToDump())
+ dump();
+}
+
+- (void)webView:(WebView *)c locationChangeDone:(NSError *)error forDataSource:(WebDataSource *)dataSource
+{
+ if ([dataSource webFrame] == topLoadingFrame) {
+ topLoadingFrame = nil;
+ WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
+ if (!gLayoutTestController->waitToDump()) {
+ if (WorkQueue::shared()->count())
+ [self performSelector:@selector(processWork:) withObject:nil afterDelay:0];
+ else
+ dump();
+ }
+ }
+}
+
+- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didStartProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ ASSERT([frame provisionalDataSource]);
+ // 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;
+
+ if (!done && gLayoutTestController->stopProvisionalFrameLoads()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - stopping load in didStartProvisionalLoadForFrame callback", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ [frame stopLoading];
+ }
+}
+
+- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didCommitLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ ASSERT(![frame provisionalDataSource]);
+ ASSERT([frame dataSource]);
+
+ gLayoutTestController->setWindowIsKey(true);
+ NSView *documentView = [[mainFrame frameView] documentView];
+ [[[mainFrame webView] window] makeFirstResponder:documentView];
+ if ([documentView isKindOfClass:[WebHTMLView class]])
+ [(WebHTMLView *)documentView _updateFocusedAndActiveState];
+}
+
+- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFailProvisionalLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ if ([error domain] == NSURLErrorDomain && [error code] == NSURLErrorServerCertificateHasUnknownRoot) {
+ NSURL *failedURL = [[error userInfo] objectForKey:@"NSErrorFailingURLKey"];
+ [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[failedURL _web_hostString]];
+ [frame loadRequest:[[[[frame provisionalDataSource] request] mutableCopy] autorelease]];
+ return;
+ }
+
+ ASSERT([frame provisionalDataSource]);
+ [self webView:sender locationChangeDone:error forDataSource:[frame provisionalDataSource]];
+}
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+ ASSERT([frame dataSource]);
+ ASSERT(frame == [[frame dataSource] webFrame]);
+
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ // FIXME: This call to displayIfNeeded can be removed when <rdar://problem/5092361> is fixed.
+ // After that is fixed, we will reenable painting after WebCore is done loading the document,
+ // and this call will no longer be needed.
+ if ([[sender mainFrame] isEqual:frame])
+ [sender displayIfNeeded];
+ [self webView:sender locationChangeDone:nil forDataSource:[frame dataSource]];
+ [gNavigationController webView:sender didFinishLoadForFrame:frame];
+}
+
+- (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame;
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ ASSERT(![frame provisionalDataSource]);
+ ASSERT([frame dataSource]);
+
+ [self webView:sender locationChangeDone:error forDataSource:[frame dataSource]];
+}
+
+- (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject;
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"?? - windowScriptObjectAvailable"];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ ASSERT_NOT_REACHED();
+}
+
+- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)obj forFrame:(WebFrame *)frame
+{
+ ASSERT(obj == [frame windowObject]);
+ ASSERT([obj JSObject] == JSContextGetGlobalObject([frame globalContext]));
+
+ // Make New-Style LayoutTestController
+ JSContextRef context = [frame globalContext];
+ JSObjectRef globalObject = JSContextGetGlobalObject(context);
+ JSValueRef exception = 0;
+
+ ASSERT(gLayoutTestController);
+ gLayoutTestController->makeWindowObject(context, globalObject, &exception);
+ ASSERT(!exception);
+
+ gcController->makeWindowObject(context, globalObject, &exception);
+ ASSERT(!exception);
+
+ accessibilityController->makeWindowObject(context, globalObject, &exception);
+ ASSERT(!exception);
+
+ // Make Old-Style controllers
+ EventSendingController *esc = [[EventSendingController alloc] init];
+ [obj setValue:esc forKey:@"eventSender"];
+ [esc release];
+
+ TextInputController *tic = [[TextInputController alloc] initWithWebView:sender];
+ [obj setValue:tic forKey:@"textInputController"];
+ [tic release];
+
+ AppleScriptController *asc = [[AppleScriptController alloc] initWithWebView:sender];
+ [obj setValue:asc forKey:@"appleScriptController"];
+ [asc release];
+
+ ObjCController *occ = [[ObjCController alloc] init];
+ [obj setValue:occ forKey:@"objCController"];
+ [occ release];
+
+ [obj setValue:gNavigationController forKey:@"navigationController"];
+
+ ObjCPlugin *plugin = [[ObjCPlugin alloc] init];
+ [obj setValue:plugin forKey:@"objCPlugin"];
+ [plugin release];
+
+ ObjCPluginFunction *pluginFunction = [[ObjCPluginFunction alloc] init];
+ [obj setValue:pluginFunction forKey:@"objCPluginFunction"];
+ [pluginFunction release];
+}
+
+- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didReceiveTitle: %@", [frame _drt_descriptionSuitableForTestResult], title];
+ printf ("%s\n", [string UTF8String]);
+ }
+
+ if (gLayoutTestController->dumpTitleChanges())
+ printf("TITLE CHANGED: %s\n", [title UTF8String]);
+}
+
+- (void)webView:(WebView *)sender didReceiveServerRedirectForProvisionalLoadForFrame:(WebFrame *)frame
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didReceiveServerRedirectForProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didChangeLocationWithinPageForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView:(WebView *)sender willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date forFrame:(WebFrame *)frame
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - willPerformClientRedirectToURL: %@ ", [frame _drt_descriptionSuitableForTestResult], [URL _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView:(WebView *)sender didCancelClientRedirectForFrame:(WebFrame *)frame
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didCancelClientRedirectForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView:(WebView *)sender didFinishDocumentLoadForFrame:(WebFrame *)frame;
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFinishDocumentLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ } else if (!done) {
+ unsigned pendingFrameUnloadEvents = [frame _pendingFrameUnloadEventCount];
+ if (pendingFrameUnloadEvents) {
+ NSString *string = [NSString stringWithFormat:@"%@ - has %u onunload handler(s)", [frame _drt_descriptionSuitableForTestResult], pendingFrameUnloadEvents];
+ printf ("%s\n", [string UTF8String]);
+ }
+ }
+}
+
+- (void)webView:(WebView *)sender didHandleOnloadEventsForFrame:(WebFrame *)frame;
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didHandleOnloadEventsForFrame", [frame _drt_descriptionSuitableForTestResult]];
+ printf ("%s\n", [string UTF8String]);
+ }
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/GCControllerMac.mm b/WebKitTools/DumpRenderTree/mac/GCControllerMac.mm
new file mode 100644
index 0000000..4b845ba
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/GCControllerMac.mm
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.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.
+ */
+
+#import "GCController.h"
+#import <WebKit/WebCoreStatistics.h>
+
+
+void GCController::collect() const
+{
+ [WebCoreStatistics garbageCollectJavaScriptObjects];
+}
+
+void GCController::collectOnAlternateThread(bool waitUntilDone) const
+{
+ [WebCoreStatistics garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging:waitUntilDone];
+}
+
+size_t GCController::getJSObjectCount() const
+{
+ return [WebCoreStatistics javaScriptObjectsCount];
+}
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
new file mode 100644
index 0000000..2200c27
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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.
+ */
+
+#import "DumpRenderTree.h"
+#import "LayoutTestController.h"
+
+#import "EditingDelegate.h"
+#import "WorkQueue.h"
+#import "WorkQueueItem.h"
+#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JSRetainPtr.h>
+#import <JavaScriptCore/JSStringRef.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <WebKit/DOMDocument.h>
+#import <WebKit/WebBackForwardList.h>
+#import <WebKit/WebDatabaseManagerPrivate.h>
+#import <WebKit/WebDataSource.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebHTMLRepresentation.h>
+#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebHistory.h>
+#import <WebKit/WebInspector.h>
+#import <WebKit/WebNSURLExtras.h>
+#import <WebKit/WebPreferences.h>
+#import <WebKit/WebPreferencesPrivate.h>
+#import <WebKit/WebSecurityOriginPrivate.h>
+#import <WebKit/WebView.h>
+#import <WebKit/WebViewPrivate.h>
+#import <wtf/RetainPtr.h>
+
+LayoutTestController::~LayoutTestController()
+{
+}
+
+void LayoutTestController::addDisallowedURL(JSStringRef url)
+{
+ RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
+
+ if (!disallowedURLs)
+ disallowedURLs = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
+
+ // Canonicalize the URL
+ NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
+ request = [NSURLProtocol canonicalRequestForRequest:request];
+
+ CFSetAddValue(disallowedURLs, [request URL]);
+}
+
+void LayoutTestController::clearAllDatabases()
+{
+ [[WebDatabaseManager sharedWebDatabaseManager] deleteAllDatabases];
+}
+
+void LayoutTestController::clearBackForwardList()
+{
+ WebBackForwardList *backForwardList = [[mainFrame webView] backForwardList];
+ WebHistoryItem *item = [[backForwardList currentItem] retain];
+
+ // We clear the history by setting the back/forward list's capacity to 0
+ // then restoring it back and adding back the current item.
+ int capacity = [backForwardList capacity];
+ [backForwardList setCapacity:0];
+ [backForwardList setCapacity:capacity];
+ [backForwardList addItem:item];
+ [backForwardList goToItem:item];
+ [item release];
+}
+
+JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
+{
+ RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
+ NSString *nameNS = (NSString *)nameCF.get();
+ return JSStringCreateWithCFString((CFStringRef)[nameNS _web_decodeHostName]);
+}
+
+JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
+{
+ RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
+ NSString *nameNS = (NSString *)nameCF.get();
+ return JSStringCreateWithCFString((CFStringRef)[nameNS _web_encodeHostName]);
+}
+
+void LayoutTestController::display()
+{
+ displayWebView();
+}
+
+void LayoutTestController::keepWebHistory()
+{
+ if (![WebHistory optionalSharedHistory]) {
+ WebHistory *history = [[WebHistory alloc] init];
+ [WebHistory setOptionalSharedHistory:history];
+ [history release];
+ }
+}
+
+void LayoutTestController::notifyDone()
+{
+ if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
+ dump();
+ m_waitToDump = false;
+}
+
+JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
+{
+ return JSStringRetain(url); // Do nothing on mac.
+}
+
+void LayoutTestController::queueBackNavigation(int howFarBack)
+{
+ WorkQueue::shared()->queue(new BackItem(howFarBack));
+}
+
+void LayoutTestController::queueForwardNavigation(int howFarForward)
+{
+ WorkQueue::shared()->queue(new ForwardItem(howFarForward));
+}
+
+void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
+{
+ RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
+ NSString *urlNS = (NSString *)urlCF.get();
+
+ NSURL *nsurl = [NSURL URLWithString:urlNS relativeToURL:[[[mainFrame dataSource] response] URL]];
+ NSString* nsurlString = [nsurl absoluteString];
+
+ JSRetainPtr<JSStringRef> absoluteURL(Adopt, JSStringCreateWithUTF8CString([nsurlString UTF8String]));
+ WorkQueue::shared()->queue(new LoadItem(absoluteURL.get(), target));
+}
+
+void LayoutTestController::queueReload()
+{
+ WorkQueue::shared()->queue(new ReloadItem);
+}
+
+void LayoutTestController::queueScript(JSStringRef script)
+{
+ WorkQueue::shared()->queue(new ScriptItem(script));
+}
+
+void LayoutTestController::setAcceptsEditing(bool newAcceptsEditing)
+{
+ [(EditingDelegate *)[[mainFrame webView] editingDelegate] setAcceptsEditing:newAcceptsEditing];
+}
+
+void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
+{
+ [[[mainFrame webView] preferences] setAuthorAndUserStylesEnabled:flag];
+}
+
+void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
+{
+ if (setDelegate)
+ [[mainFrame webView] setPolicyDelegate:policyDelegate];
+ else
+ [[mainFrame webView] setPolicyDelegate:nil];
+}
+
+void LayoutTestController::setDatabaseQuota(unsigned long long quota)
+{
+ WebSecurityOrigin *origin = [[WebSecurityOrigin alloc] initWithURL:[NSURL URLWithString:@"file:///"]];
+ [origin setQuota:quota];
+ [origin release];
+}
+
+void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
+{
+ NSView *documentView = [[mainFrame frameView] documentView];
+
+ NSResponder *firstResponder = flag ? documentView : nil;
+ [[[mainFrame webView] window] makeFirstResponder:firstResponder];
+
+ if ([documentView isKindOfClass:[WebHTMLView class]])
+ [(WebHTMLView *)documentView _updateFocusedAndActiveState];
+}
+
+void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
+{
+ [[[mainFrame webView] preferences] setPrivateBrowsingEnabled:privateBrowsingEnabled];
+}
+
+void LayoutTestController::setPopupBlockingEnabled(bool popupBlockingEnabled)
+{
+ [[[mainFrame webView] preferences] setJavaScriptCanOpenWindowsAutomatically:!popupBlockingEnabled];
+}
+
+void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles)
+{
+ [[mainFrame webView] setTabKeyCyclesThroughElements:cycles];
+}
+
+void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
+{
+ [[mainFrame webView] _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:flag];
+}
+
+void LayoutTestController::setUserStyleSheetEnabled(bool flag)
+{
+ [[WebPreferences standardPreferences] setUserStyleSheetEnabled:flag];
+}
+
+void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
+{
+ RetainPtr<CFStringRef> pathCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, path));
+ NSURL *url = [NSURL URLWithString:(NSString *)pathCF.get()];
+ [[WebPreferences standardPreferences] setUserStyleSheetLocation:url];
+}
+
+void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
+{
+ RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
+ ::setPersistentUserStyleSheetLocation(urlString.get());
+}
+
+void LayoutTestController::clearPersistentUserStyleSheet()
+{
+ ::setPersistentUserStyleSheetLocation(0);
+}
+
+void LayoutTestController::setWindowIsKey(bool windowIsKey)
+{
+ m_windowIsKey = windowIsKey;
+ NSView *documentView = [[mainFrame frameView] documentView];
+ if ([documentView isKindOfClass:[WebHTMLView class]])
+ [(WebHTMLView *)documentView _updateFocusedAndActiveState];
+}
+
+void LayoutTestController::setSmartInsertDeleteEnabled(bool flag)
+{
+ [[mainFrame webView] setSmartInsertDeleteEnabled:flag];
+}
+
+void LayoutTestController::setJavaScriptProfilingEnabled(bool profilingEnabled)
+{
+ [[[mainFrame webView] preferences] setDeveloperExtrasEnabled:profilingEnabled];
+ [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:profilingEnabled];
+}
+
+static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
+
+static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
+{
+ const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
+ fprintf(stderr, "%s", message);
+ fprintf(stdout, "%s", message);
+ dump();
+}
+
+void LayoutTestController::setWaitToDump(bool waitUntilDone)
+{
+ m_waitToDump = waitUntilDone;
+ if (m_waitToDump && !waitToDumpWatchdog) {
+ waitToDumpWatchdog = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + waitToDumpWatchdogInterval, 0, 0, 0, waitUntilDoneWatchdogFired, NULL);
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), waitToDumpWatchdog, kCFRunLoopCommonModes);
+ }
+}
+
+int LayoutTestController::windowCount()
+{
+ return CFArrayGetCount(openWindowsRef);
+}
+
+bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id)
+{
+ RetainPtr<CFStringRef> idCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, id));
+ NSString *idNS = (NSString *)idCF.get();
+
+ DOMElement *element = [[mainFrame DOMDocument] getElementById:idNS];
+ id rep = [[mainFrame dataSource] representation];
+
+ if ([rep class] == [WebHTMLRepresentation class])
+ return [(WebHTMLRepresentation *)rep elementDoesAutoComplete:element];
+
+ return false;
+}
+
+void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
+{
+ RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
+ NSString *nameNS = (NSString *)nameCF.get();
+
+ RetainPtr<CFStringRef> valueCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, value));
+ NSString *valueNS = (NSString *)valueCF.get();
+
+ [[mainFrame webView] _executeCoreCommandByName:nameNS value:valueNS];
+}
diff --git a/WebKitTools/DumpRenderTree/mac/NavigationController.h b/WebKitTools/DumpRenderTree/mac/NavigationController.h
new file mode 100644
index 0000000..8ee3432
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/NavigationController.h
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <WebKit/WebView.h>
+
+@interface NavigationController : NSObject
+{
+ enum { None, Load, GoBack, ExecuteScript } pendingAction;
+ NSString *pendingScript;
+ NSURLRequest *pendingRequest;
+}
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame;
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/NavigationController.m b/WebKitTools/DumpRenderTree/mac/NavigationController.m
new file mode 100644
index 0000000..44aed8a
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/NavigationController.m
@@ -0,0 +1,109 @@
+/*
+ * 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
+ * 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.
+ */
+
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebScriptObject.h>
+#import "NavigationController.h"
+
+@implementation NavigationController
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
+{
+ if (selector == @selector(evaluateWebScript:afterBackForwardNavigation:))
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)selector
+{
+ if (selector == @selector(evaluateWebScript:afterBackForwardNavigation:))
+ return @"evalAfterBackForwardNavigation";
+ return nil;
+}
+
+- (void)setPendingScript:(NSString *)script
+{
+ if (script != pendingScript) {
+ [pendingScript release];
+ pendingScript = [script copy];
+ }
+}
+
+- (void)setPendingRequest:(NSURLRequest *)request
+{
+ if (request != pendingRequest) {
+ [pendingRequest release];
+ pendingRequest = [request copy];
+ }
+}
+
+- (void)evaluateWebScript:(NSString *)script afterBackForwardNavigation:(NSString *)navigation
+{
+ // Allow both arguments to be optional
+ if (![script isKindOfClass:[NSString class]])
+ script = @"";
+ if (![navigation isKindOfClass:[NSString class]])
+ navigation = @"about:blank";
+
+ [self setPendingScript:script];
+ [self setPendingRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:navigation]]];
+ pendingAction = Load;
+}
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+ if (frame == [[frame webView] mainFrame]) {
+ switch (pendingAction) {
+ case Load:
+ pendingAction = GoBack;
+ [frame loadRequest:pendingRequest];
+ [self setPendingRequest:nil];
+ break;
+ case GoBack:
+ pendingAction = ExecuteScript;
+ [[frame webView] goBack];
+ break;
+ case ExecuteScript:
+ pendingAction = None;
+ [[[frame webView] windowScriptObject] evaluateWebScript:pendingScript];
+ [self setPendingScript:nil];
+ break;
+ case None:
+ default:
+ break;
+ }
+ }
+}
+
+- (void)dealloc
+{
+ [self setPendingScript:nil];
+ [self setPendingRequest:nil];
+ [super dealloc];
+}
+@end
+
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCController.h b/WebKitTools/DumpRenderTree/mac/ObjCController.h
new file mode 100644
index 0000000..d1d001c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCController.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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.
+ */
+
+#import <Foundation/Foundation.h>
+
+@class WebScriptObject;
+
+// This controller should be used to test Objective-C language features and the WebScriptObject.
+@interface ObjCController : NSObject
+{
+ WebScriptObject *storedWebScriptObject;
+}
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCController.m b/WebKitTools/DumpRenderTree/mac/ObjCController.m
new file mode 100644
index 0000000..ec1ed38
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCController.m
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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.
+ */
+
+#import "ObjCController.h"
+
+#import <JavaScriptCore/JavaScriptCore.h>
+#import <WebKit/DOMAbstractView.h>
+#import <WebKit/WebScriptObject.h>
+#import <WebKit/WebView.h>
+#import <pthread.h>
+#import <wtf/Assertions.h>
+
+static void* runJavaScriptThread(void* arg)
+{
+ JSGlobalContextRef ctx = JSGlobalContextCreate(0);
+ JSStringRef scriptRef = JSStringCreateWithUTF8CString("'Hello World!'");
+
+ JSValueRef exception = 0;
+ JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception);
+ ASSERT(!exception);
+
+ JSGlobalContextRelease(ctx);
+ JSStringRelease(scriptRef);
+
+ return 0;
+}
+
+@implementation ObjCController
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (0
+ || aSelector == @selector(classNameOf:)
+ || aSelector == @selector(objectOfClass:)
+ || aSelector == @selector(identityIsEqual::)
+ || aSelector == @selector(longLongRoundTrip:)
+ || aSelector == @selector(unsignedLongLongRoundTrip:)
+ || aSelector == @selector(testWrapperRoundTripping:)
+ || aSelector == @selector(accessStoredWebScriptObject)
+ || aSelector == @selector(storeWebScriptObject:)
+ || aSelector == @selector(testValueForKey)
+ || aSelector == @selector(testArray)
+ )
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(classNameOf:))
+ return @"className";
+ if (aSelector == @selector(objectOfClass:))
+ return @"objectOfClass";
+ if (aSelector == @selector(identityIsEqual::))
+ return @"identityIsEqual";
+ if (aSelector == @selector(longLongRoundTrip:))
+ return @"longLongRoundTrip";
+ if (aSelector == @selector(unsignedLongLongRoundTrip:))
+ return @"unsignedLongLongRoundTrip";
+ if (aSelector == @selector(testWrapperRoundTripping:))
+ return @"testWrapperRoundTripping";
+ if (aSelector == @selector(storeWebScriptObject:))
+ return @"storeWebScriptObject";
+ if (aSelector == @selector(testValueForKey))
+ return @"testValueForKey";
+ if (aSelector == @selector(testArray))
+ return @"testArray";
+
+ return nil;
+}
+
+- (NSString *)classNameOf:(id)object
+{
+ if (!object)
+ return @"nil";
+ return NSStringFromClass([object class]);
+}
+
+- (id)objectOfClass:(NSString *)aClass
+{
+ if ([aClass isEqualToString:@"NSNull"])
+ return [NSNull null];
+ if ([aClass isEqualToString:@"WebUndefined"])
+ return [WebUndefined undefined];
+ if ([aClass isEqualToString:@"NSCFBoolean"])
+ return [NSNumber numberWithBool:true];
+ if ([aClass isEqualToString:@"NSCFNumber"])
+ return [NSNumber numberWithInt:1];
+ if ([aClass isEqualToString:@"NSCFString"])
+ return @"";
+ if ([aClass isEqualToString:@"WebScriptObject"])
+ return self;
+ if ([aClass isEqualToString:@"NSArray"])
+ return [NSArray array];
+
+ return nil;
+}
+
+- (BOOL)identityIsEqual:(WebScriptObject *)a :(WebScriptObject *)b
+{
+ if ([a isKindOfClass:[NSString class]] && [b isKindOfClass:[NSString class]])
+ return [(NSString *)a isEqualToString:(NSString *)b];
+ return a == b;
+}
+
+- (long long)longLongRoundTrip:(long long)num
+{
+ return num;
+}
+
+- (unsigned long long)unsignedLongLongRoundTrip:(unsigned long long)num
+{
+ return num;
+}
+
+- (void)testValueForKey
+{
+ ASSERT(storedWebScriptObject);
+
+ @try {
+ [storedWebScriptObject valueForKey:@"ThisKeyDoesNotExist"];
+ } @catch (NSException *e) {
+ }
+
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_join(pthread, 0);
+}
+
+- (BOOL)testWrapperRoundTripping:(WebScriptObject *)webScriptObject
+{
+ JSObjectRef jsObject = [webScriptObject JSObject];
+
+ if (!jsObject)
+ return false;
+
+ if (!webScriptObject)
+ return false;
+
+ if ([[webScriptObject evaluateWebScript:@"({ })"] class] != [webScriptObject class])
+ return false;
+
+ [webScriptObject setValue:[NSNumber numberWithInt:666] forKey:@"key"];
+ if (![[webScriptObject valueForKey:@"key"] isKindOfClass:[NSNumber class]] ||
+ ![[webScriptObject valueForKey:@"key"] isEqualToNumber:[NSNumber numberWithInt:666]])
+ return false;
+
+ [webScriptObject removeWebScriptKey:@"key"];
+ @try {
+ if ([webScriptObject valueForKey:@"key"])
+ return false;
+ } @catch(NSException *exception) {
+ // NSObject throws an exception if the key doesn't exist.
+ }
+
+ [webScriptObject setWebScriptValueAtIndex:0 value:webScriptObject];
+ if ([webScriptObject webScriptValueAtIndex:0] != webScriptObject)
+ return false;
+
+ if ([[webScriptObject stringRepresentation] isEqualToString:@"[Object object]"])
+ return false;
+
+ if ([webScriptObject callWebScriptMethod:@"returnThis" withArguments:nil] != webScriptObject)
+ return false;
+
+ return true;
+}
+
+- (void)accessStoredWebScriptObject
+{
+#if !ASSERT_DISABLED
+ BOOL isWindowObject = [storedWebScriptObject isKindOfClass:[DOMAbstractView class]];
+#endif
+ JSObjectRef jsObject = [storedWebScriptObject JSObject];
+ ASSERT((jsObject && isWindowObject) || (!jsObject && !isWindowObject));
+
+ [storedWebScriptObject callWebScriptMethod:@"" withArguments:nil];
+ [storedWebScriptObject evaluateWebScript:@""];
+ [storedWebScriptObject setValue:[WebUndefined undefined] forKey:@"key"];
+ [storedWebScriptObject valueForKey:@"key"];
+ [storedWebScriptObject removeWebScriptKey:@"key"];
+ [storedWebScriptObject stringRepresentation];
+ [storedWebScriptObject webScriptValueAtIndex:0];
+ [storedWebScriptObject setWebScriptValueAtIndex:0 value:[WebUndefined undefined]];
+ [storedWebScriptObject setException:@"exception"];
+}
+
+- (void)storeWebScriptObject:(WebScriptObject *)webScriptObject
+{
+ if (webScriptObject == storedWebScriptObject)
+ return;
+
+ [storedWebScriptObject release];
+ storedWebScriptObject = [webScriptObject retain];
+}
+
+- (NSArray *)testArray
+{
+ return [NSArray array];
+}
+
+- (void)dealloc
+{
+ [storedWebScriptObject release];
+ [super dealloc];
+}
+
+- (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args
+{
+ // FIXME: Perhaps we should log that this has been called.
+ return nil;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCPlugin.h b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.h
new file mode 100644
index 0000000..a6d3e50
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.h
@@ -0,0 +1,36 @@
+/*
+ * 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
+ * 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 THE AUTHOR ``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 AUTHOR 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.
+*/
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface ObjCPlugin : NSObject
+{
+ BOOL throwOnDealloc;
+}
+
+- (void)removeBridgeRestrictions:(id)container;
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m
new file mode 100644
index 0000000..3ec3e74
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCPlugin.m
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 James G. Speth (speth@end.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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+#import "ObjCPlugin.h"
+#import <objc/objc-runtime.h>
+#import <WebKit/WebKit.h>
+
+
+// === NSObject category to expose almost everything to JavaScript ===
+
+// Warning: this class introduces huge security weaknesses, and should only be used
+// for testing inside of DumpRenderTree, and only with trusted code. By default, it has
+// the same restrictive behavior as the standard WebKit setup. However, scripts can use the
+// plugin's removeBridgeRestrictions: method to open up almost total access to the Cocoa
+// frameworks.
+
+static BOOL _allowsScriptsFullAccess = NO;
+
+@interface NSObject (ObjCScriptAccess)
+
++ (void)setAllowsScriptsFullAccess:(BOOL)value;
++ (BOOL)allowsScriptsFullAccess;
+
+@end
+
+@implementation NSObject (ObjCScriptAccess)
+
++ (void)setAllowsScriptsFullAccess:(BOOL)value
+{
+ _allowsScriptsFullAccess = value;
+}
+
++ (BOOL)allowsScriptsFullAccess
+{
+ return _allowsScriptsFullAccess;
+}
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
+{
+ return !_allowsScriptsFullAccess;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)selector
+{
+ return nil;
+}
+
+@end
+
+@interface JSObjC : NSObject {
+}
+
+// expose some useful objc functions to the scripting environment
+- (id)lookUpClass:(NSString *)name;
+- (void)log:(NSString *)message;
+- (id)retainObject:(id)obj;
+- (id)classOfObject:(id)obj;
+- (NSString *)classNameOfObject:(id)obj;
+
+@end
+
+@implementation JSObjC
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
+{
+ return NO;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)selector
+{
+ return nil;
+}
+
+- (id)invokeDefaultMethodWithArguments:(NSArray *)args
+{
+ // this is a useful shortcut for accessing objective-c classes from the scripting
+ // environment, e.g. 'var myObject = objc("NSObject").alloc().init();'
+ if ([args count] == 1)
+ return [self lookUpClass:[args objectAtIndex:0]];
+ return nil;
+}
+
+- (id)lookUpClass:(NSString *)name
+{
+ return NSClassFromString(name);
+}
+
+- (void)log:(NSString *)message
+{
+ NSLog(@"%@", message);
+}
+
+- (id)retainObject:(id)obj
+{
+ return [obj retain];
+}
+
+- (id)classOfObject:(id)obj
+{
+ return (id)[obj class];
+}
+
+- (NSString *)classNameOfObject:(id)obj
+{
+ return [obj className];
+}
+
+@end
+
+@implementation ObjCPlugin
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(removeBridgeRestrictions:))
+ return NO;
+
+ if (aSelector == @selector(echo:))
+ return NO;
+
+ if (aSelector == @selector(throwIfArgumentIsNotHello:))
+ return NO;
+
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(echo:))
+ return @"echo";
+
+ if (aSelector == @selector(throwIfArgumentIsNotHello:))
+ return @"throwIfArgumentIsNotHello";
+
+ return nil;
+}
+
++ (NSString *)webScriptNameForKey:(const char *)key
+{
+ if (strcmp(key, "throwOnDealloc") == 0)
+ return @"throwOnDealloc";
+
+ return nil;
+}
+
++ (BOOL)isKeyExcludedFromWebScript:(const char *)key
+{
+ if (strcmp(key, "throwOnDealloc") == 0)
+ return NO;
+
+ return YES;
+}
+
+- (void)removeBridgeRestrictions:(id)container
+{
+ // let scripts invoke any selector
+ [NSObject setAllowsScriptsFullAccess:YES];
+
+ // store a JSObjC instance into the provided container
+ JSObjC *objc = [[JSObjC alloc] init];
+ [container setValue:objc forKey:@"objc"];
+ [objc release];
+}
+
+- (id)echo:(id)obj
+{
+ return obj;
+}
+
+- (void)throwIfArgumentIsNotHello:(NSString *)str
+{
+ if (![str isEqualToString:@"Hello"])
+ [WebScriptObject throwException:[NSString stringWithFormat:@"%@ != Hello", str]];
+}
+
+- (void)dealloc
+{
+ if (throwOnDealloc)
+ [WebScriptObject throwException:@"Throwing exception on dealloc of ObjCPlugin"];
+
+ [super dealloc];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.h b/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.h
new file mode 100644
index 0000000..1e81b21
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.h
@@ -0,0 +1,34 @@
+/*
+ * 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
+ * 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 THE AUTHOR ``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 AUTHOR 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.
+*/
+
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface ObjCPluginFunction : NSObject
+{
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.m b/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.m
new file mode 100644
index 0000000..5cd16f8
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ObjCPluginFunction.m
@@ -0,0 +1,37 @@
+/*
+ * 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
+ * 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 THE AUTHOR ``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 AUTHOR 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.
+*/
+
+
+#import "ObjCPluginFunction.h"
+
+
+@implementation ObjCPluginFunction
+
+- (id)invokeDefaultMethodWithArguments:(NSArray *)args
+{
+ return @"test";
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm b/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm
new file mode 100644
index 0000000..f4191e5
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/PixelDumpSupportMac.mm
@@ -0,0 +1,241 @@
+/*
+ * 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>
+ *
+ * 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 "DumpRenderTree.h"
+#include "PixelDumpSupport.h"
+#include "PixelDumpSupportCG.h"
+
+#include "LayoutTestController.h"
+#include <CoreGraphics/CGBitmapContext.h>
+#ifndef BUILDING_ON_LEOPARD
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/CGLMacro.h>
+#endif
+#include <wtf/Assertions.h>
+#include <wtf/RefPtr.h>
+
+#import <WebKit/WebDocumentPrivate.h>
+#import <WebKit/WebKit.h>
+
+// To ensure pixel tests consistency, we need to always render in the same colorspace.
+// Unfortunately, because of AppKit / WebKit constraints, we can't render directly in the colorspace of our choice.
+// This implies we have to temporarily change the profile of the main display to the colorspace we want to render into.
+// We also need to make sure the CGBitmapContext we return is in that same colorspace.
+
+#define PROFILE_PATH "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc" // FIXME: This cannot be more than CS_MAX_PATH (256 characters)
+
+static CMProfileLocation sInitialProfileLocation; // The locType field is initialized to 0 which is the same as cmNoProfileBase
+
+void restoreMainDisplayColorProfile(int ignored)
+{
+ // This is used as a signal handler, and thus the calls into ColorSync are unsafe
+ // But we might as well try to restore the user's color profile, we're going down anyway...
+ if (sInitialProfileLocation.locType != cmNoProfileBase) {
+ const CMDeviceScope scope = { kCFPreferencesCurrentUser, kCFPreferencesCurrentHost };
+ int error = CMSetDeviceProfile(cmDisplayDeviceClass, (CMDeviceID)kCGDirectMainDisplay, &scope, cmDefaultProfileID, &sInitialProfileLocation);
+ if (error)
+ fprintf(stderr, "Failed to restore initial color profile for main display! Open System Preferences > Displays > Color and manually re-select the profile. (Error: %i)", error);
+ sInitialProfileLocation.locType = cmNoProfileBase;
+ }
+}
+
+void setupMainDisplayColorProfile()
+{
+ const CMDeviceScope scope = { kCFPreferencesCurrentUser, kCFPreferencesCurrentHost };
+ int error;
+
+ CMProfileRef profile = 0;
+ error = CMGetProfileByAVID((CMDisplayIDType)kCGDirectMainDisplay, &profile);
+ if (!error) {
+ UInt32 size = sizeof(CMProfileLocation);
+ error = NCMGetProfileLocation(profile, &sInitialProfileLocation, &size);
+ CMCloseProfile(profile);
+ }
+ if (error) {
+ fprintf(stderr, "Failed to retrieve current color profile for main display, thus it won't be changed. Many pixel tests may fail as a result. (Error: %i)", error);
+ sInitialProfileLocation.locType = cmNoProfileBase;
+ return;
+ }
+
+ CMProfileLocation location;
+ location.locType = cmPathBasedProfile;
+ strcpy(location.u.pathLoc.path, PROFILE_PATH);
+ error = CMSetDeviceProfile(cmDisplayDeviceClass, (CMDeviceID)kCGDirectMainDisplay, &scope, cmDefaultProfileID, &location);
+ if (error) {
+ fprintf(stderr, "Failed to set color profile for main display! Many pixel tests may fail as a result. (Error: %i)", error);
+ sInitialProfileLocation.locType = cmNoProfileBase;
+ return;
+ }
+
+ // Other signals are handled in installSignalHandlers() which also calls restoreMainDisplayColorProfile()
+ signal(SIGINT, restoreMainDisplayColorProfile);
+ signal(SIGHUP, restoreMainDisplayColorProfile);
+ signal(SIGTERM, restoreMainDisplayColorProfile);
+
+ fprintf(stderr, "\n\nWARNING: Temporarily changing the main display color profile to \"%s\": the colors on your screen will change for the duration of the testing.\n", PROFILE_PATH);
+ fprintf(stderr, "This allows the WebKit pixel-based regression tests to have consistent color values across all machines.\n");
+}
+
+PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool onscreen, bool incrementalRepaint, bool sweepHorizontally, bool drawSelectionRect)
+{
+ WebView* view = [mainFrame webView];
+ NSSize webViewSize = [view frame].size;
+ size_t pixelsWide = static_cast<size_t>(webViewSize.width);
+ size_t pixelsHigh = static_cast<size_t>(webViewSize.height);
+ size_t rowBytes = (4 * pixelsWide + 63) & ~63; // Use a multiple of 64 bytes to improve CG performance
+
+ void *buffer = calloc(pixelsHigh, rowBytes);
+ if (!buffer)
+ return 0;
+
+ static CGColorSpaceRef colorSpace = 0;
+ if (!colorSpace) {
+ CMProfileLocation location;
+ location.locType = cmPathBasedProfile;
+ strcpy(location.u.pathLoc.path, PROFILE_PATH);
+ CMProfileRef profile;
+ if (CMOpenProfile(&profile, &location) == noErr) {
+ colorSpace = CGColorSpaceCreateWithPlatformColorSpace(profile);
+ CMCloseProfile(profile);
+ }
+ }
+
+ CGContextRef context = CGBitmapContextCreate(buffer, pixelsWide, pixelsHigh, 8, rowBytes, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); // Use ARGB8 on PPC or BGRA8 on X86 to improve CG performance
+ if (!context) {
+ free(buffer);
+ return 0;
+ }
+
+ // The BitmapContext keeps the CGContextRef and the pixel buffer alive
+ RefPtr<BitmapContext> bitmapContext = BitmapContext::createByAdoptingBitmapAndContext(buffer, context);
+
+ NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
+ ASSERT(nsContext);
+
+ if (incrementalRepaint) {
+ if (sweepHorizontally) {
+ for (NSRect column = NSMakeRect(0, 0, 1, webViewSize.height); column.origin.x < webViewSize.width; column.origin.x++)
+ [view displayRectIgnoringOpacity:column inContext:nsContext];
+ } else {
+ for (NSRect line = NSMakeRect(0, 0, webViewSize.width, 1); line.origin.y < webViewSize.height; line.origin.y++)
+ [view displayRectIgnoringOpacity:line inContext:nsContext];
+ }
+ } else {
+ if (onscreen) {
+#ifdef BUILDING_ON_LEOPARD
+ // Ask the window server to provide us a composited version of the *real* window content including surfaces (i.e. OpenGL content)
+ // Note that the returned image might differ very slightly from the window backing because of dithering artifacts in the window server compositor
+
+ CGImageRef image = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, [[view window] windowNumber], kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque);
+ CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
+ CGImageRelease(image);
+#else
+ // On 10.4 and earlier, we have to move the window temporarily "onscreen" and read directly from the display framebuffer using OpenGL
+ // In this code path, we need to ensure the window is above any other window or captured result will be corrupted
+
+ NSWindow *window = [view window];
+ int oldLevel = [window level];
+ NSRect oldFrame = [window frame];
+
+ NSRect newFrame = [[[NSScreen screens] objectAtIndex:0] frame];
+ newFrame = NSMakeRect(newFrame.origin.x + (newFrame.size.width - oldFrame.size.width) / 2, newFrame.origin.y + (newFrame.size.height - oldFrame.size.height) / 2, oldFrame.size.width, oldFrame.size.height);
+ [window setLevel:NSScreenSaverWindowLevel];
+ [window setFrame:newFrame display:NO animate:NO];
+
+ CGRect rect = CGRectMake(newFrame.origin.x, newFrame.origin.y, webViewSize.width, webViewSize.height);
+ CGDirectDisplayID displayID;
+ CGDisplayCount count;
+ if (CGGetDisplaysWithRect(rect, 1, &displayID, &count) == kCGErrorSuccess) {
+ CGRect bounds = CGDisplayBounds(displayID);
+ rect.origin.x -= bounds.origin.x;
+ rect.origin.y -= bounds.origin.y;
+
+ CGLPixelFormatAttribute attributes[] = {kCGLPFAAccelerated, kCGLPFANoRecovery, kCGLPFAFullScreen, kCGLPFADisplayMask, (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(displayID), (CGLPixelFormatAttribute)0};
+ CGLPixelFormatObj pixelFormat;
+ GLint num;
+ if (CGLChoosePixelFormat(attributes, &pixelFormat, &num) == kCGLNoError) {
+ CGLContextObj cgl_ctx;
+ if (CGLCreateContext(pixelFormat, 0, &cgl_ctx) == kCGLNoError) {
+ if (CGLSetFullScreen(cgl_ctx) == kCGLNoError) {
+ void *flipBuffer = calloc(pixelsHigh, rowBytes);
+ if (flipBuffer) {
+ glPixelStorei(GL_PACK_ROW_LENGTH, rowBytes / 4);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+#if __BIG_ENDIAN__
+ glReadPixels(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, flipBuffer);
+#else
+ glReadPixels(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, flipBuffer);
+#endif
+ if (!glGetError()) {
+ for(size_t i = 0; i < pixelsHigh; ++i)
+ bcopy((char*)flipBuffer + rowBytes * i, (char*)buffer + rowBytes * (pixelsHigh - i - 1), pixelsWide * 4);
+ }
+
+ free(flipBuffer);
+ }
+ }
+ CGLDestroyContext(cgl_ctx);
+ }
+ CGLDestroyPixelFormat(pixelFormat);
+ }
+ }
+
+ [window setFrame:oldFrame display:NO animate:NO];
+ [window setLevel:oldLevel];
+#endif
+ } else {
+ // Grab directly the contents of the window backing buffer (this ignores any surfaces on the window)
+ // FIXME: This path is suboptimal: data is read from window backing store, converted to RGB8 then drawn again into an RGBA8 bitmap
+
+ [view displayIfNeeded];
+ [view lockFocus];
+ NSBitmapImageRep *imageRep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:[view frame]] autorelease];
+ [view unlockFocus];
+
+ RetainPtr<NSGraphicsContext> savedContext = [NSGraphicsContext currentContext];
+ [NSGraphicsContext setCurrentContext:nsContext];
+ [imageRep draw];
+ [NSGraphicsContext setCurrentContext:savedContext.get()];
+ }
+ }
+
+ if (drawSelectionRect) {
+ NSView *documentView = [[mainFrame frameView] documentView];
+ ASSERT([documentView conformsToProtocol:@protocol(WebDocumentSelection)]);
+ NSRect rect = [documentView convertRect:[(id <WebDocumentSelection>)documentView selectionRect] fromView:nil];
+ CGContextSaveGState(context);
+ CGContextSetLineWidth(context, 1.0);
+ CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
+ CGContextStrokeRect(context, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));
+ CGContextRestoreGState(context);
+ }
+
+ return bitmapContext.release();
+}
diff --git a/WebKitTools/DumpRenderTree/mac/PolicyDelegate.h b/WebKitTools/DumpRenderTree/mac/PolicyDelegate.h
new file mode 100644
index 0000000..f8bce68
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/PolicyDelegate.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface PolicyDelegate : NSObject {
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/PolicyDelegate.mm b/WebKitTools/DumpRenderTree/mac/PolicyDelegate.mm
new file mode 100644
index 0000000..fc4ac74
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/PolicyDelegate.mm
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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.
+ */
+
+#import "PolicyDelegate.h"
+
+#import "DumpRenderTree.h"
+#import "DumpRenderTreeDraggingInfo.h"
+#import <WebKit/WebPolicyDelegate.h>
+
+@implementation PolicyDelegate
+- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation
+ request:(NSURLRequest *)request
+ frame:(WebFrame *)frame
+ decisionListener:(id<WebPolicyDecisionListener>)listener
+{
+ printf("Policy delegate: attempt to load %s\n", [[[request URL] absoluteString] UTF8String]);
+ [listener ignore];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.h b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.h
new file mode 100644
index 0000000..0c4618e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface ResourceLoadDelegate : NSObject {
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
new file mode 100644
index 0000000..5d2e2b4
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2007, 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.
+ * 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.
+ */
+
+#import "ResourceLoadDelegate.h"
+
+#import "DumpRenderTree.h"
+#import "LayoutTestController.h"
+#import <WebKit/WebKit.h>
+#import <WebKit/WebTypesInternal.h>
+#import <wtf/Assertions.h>
+
+@interface NSURL (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSError (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSURLResponse (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@interface NSURLRequest (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult;
+@end
+
+@implementation NSError (DRTExtras)
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ NSString *str = [NSString stringWithFormat:@"<NSError domain %@, code %d", [self domain], [self code]];
+ NSURL *failingURL;
+
+ if ((failingURL = [[self userInfo] objectForKey:@"NSErrorFailingURLKey"]))
+ str = [str stringByAppendingFormat:@", failing URL \"%@\"", [failingURL _drt_descriptionSuitableForTestResult]];
+
+ str = [str stringByAppendingFormat:@">"];
+
+ return str;
+}
+
+@end
+
+@implementation NSURL (DRTExtras)
+
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ if (![self isFileURL])
+ return [self absoluteString];
+
+ WebDataSource *dataSource = [mainFrame dataSource];
+ if (!dataSource)
+ dataSource = [mainFrame provisionalDataSource];
+
+ NSString *basePath = [[[[dataSource request] URL] path] stringByDeletingLastPathComponent];
+
+ return [[self path] substringFromIndex:[basePath length] + 1];
+}
+
+@end
+
+@implementation NSURLResponse (DRTExtras)
+
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ return [NSString stringWithFormat:@"<NSURLResponse %@>", [[self URL] _drt_descriptionSuitableForTestResult]];
+}
+
+@end
+
+@implementation NSURLRequest (DRTExtras)
+
+- (NSString *)_drt_descriptionSuitableForTestResult
+{
+ return [NSString stringWithFormat:@"<NSURLRequest %@>", [[self URL] _drt_descriptionSuitableForTestResult]];
+}
+
+@end
+
+@implementation ResourceLoadDelegate
+
+- webView: (WebView *)wv identifierForInitialRequest: (NSURLRequest *)request fromDataSource: (WebDataSource *)dataSource
+{
+ ASSERT([[dataSource webFrame] dataSource] || [[dataSource webFrame] provisionalDataSource]);
+
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks())
+ return [[request URL] _drt_descriptionSuitableForTestResult];
+
+ return @"<unknown>";
+}
+
+-(NSURLRequest *)webView: (WebView *)wv resource:identifier willSendRequest: (NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - willSendRequest %@ redirectResponse %@", identifier, [newRequest _drt_descriptionSuitableForTestResult],
+ [redirectResponse _drt_descriptionSuitableForTestResult]];
+ printf("%s\n", [string UTF8String]);
+ }
+
+ NSURL *url = [newRequest URL];
+ NSString *host = [url host];
+ if (host
+ && (NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"http"] || NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"https"])
+ && NSOrderedSame != [host compare:@"127.0.0.1"]
+ && NSOrderedSame != [host compare:@"255.255.255.255"] // used in some tests that expect to get back an error
+ && NSOrderedSame != [host caseInsensitiveCompare:@"localhost"]) {
+ printf("Blocked access to external URL %s\n", [[url absoluteString] cStringUsingEncoding:NSUTF8StringEncoding]);
+ return nil;
+ }
+
+ if (disallowedURLs && CFSetContainsValue(disallowedURLs, url))
+ return nil;
+
+ return newRequest;
+}
+
+- (void)webView:(WebView *)wv resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource
+{
+}
+
+- (void)webView:(WebView *)wv resource:(id)identifier didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource
+{
+}
+
+-(void)webView: (WebView *)wv resource:identifier didReceiveResponse: (NSURLResponse *)response fromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didReceiveResponse %@", identifier, [response _drt_descriptionSuitableForTestResult]];
+ printf("%s\n", [string UTF8String]);
+ }
+}
+
+-(void)webView: (WebView *)wv resource:identifier didReceiveContentLength: (NSInteger)length fromDataSource:(WebDataSource *)dataSource
+{
+}
+
+-(void)webView: (WebView *)wv resource:identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoading", identifier];
+ printf("%s\n", [string UTF8String]);
+ }
+}
+
+-(void)webView: (WebView *)wv resource:identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadingWithError: %@", identifier, [error _drt_descriptionSuitableForTestResult]];
+ printf("%s\n", [string UTF8String]);
+ }
+}
+
+- (void)webView: (WebView *)wv plugInFailedWithError:(NSError *)error dataSource:(WebDataSource *)dataSource
+{
+ // The call to -display here simulates the "Plug-in not found" sheet that Safari shows.
+ // It is used for platform/mac/plugins/update-widget-from-style-recalc.html
+ [wv display];
+}
+
+-(NSCachedURLResponse *) webView: (WebView *)wv resource:(id)identifier willCacheResponse:(NSCachedURLResponse *)response fromDataSource:(WebDataSource *)dataSource
+{
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
+ NSString *string = [NSString stringWithFormat:@"%@ - willCacheResponse: called", identifier];
+ printf("%s\n", [string UTF8String]);
+ }
+ return response;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/TextInputController.h b/WebKitTools/DumpRenderTree/mac/TextInputController.h
new file mode 100644
index 0000000..767e72f
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/TextInputController.h
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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.
+ */
+
+#import <Foundation/Foundation.h>
+
+@class WebView;
+@class WebHTMLView;
+@class WebScriptObject;
+
+@interface TextInputController : NSObject
+{
+ WebView *webView;
+ WebHTMLView *inputMethodView;
+ WebScriptObject *inputMethodHandler;
+}
+- (id)initWithWebView:(WebView *)view;
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/TextInputController.m b/WebKitTools/DumpRenderTree/mac/TextInputController.m
new file mode 100644
index 0000000..88b480b
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/TextInputController.m
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2005, 2007 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.
+ * 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.
+ */
+
+#import "TextInputController.h"
+
+#import <AppKit/NSInputManager.h>
+#import <WebKit/WebDocument.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebFrameView.h>
+#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebScriptObject.h>
+#import <WebKit/WebView.h>
+
+@interface TextInputController (DumpRenderTreeInputMethodHandler)
+- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender;
+@end
+
+@interface WebHTMLView (DumpRenderTreeInputMethodHandler)
+- (void)interpretKeyEvents:(NSArray *)eventArray;
+@end
+
+@interface WebHTMLView (WebKitSecretsTextInputControllerIsAwareOf)
+- (WebFrame *)_frame;
+@end
+
+@implementation WebHTMLView (DumpRenderTreeInputMethodHandler)
+- (void)interpretKeyEvents:(NSArray *)eventArray
+{
+ WebScriptObject *obj = [[self _frame] windowObject];
+ TextInputController *tic = [obj valueForKey:@"textInputController"];
+ if (![tic interpretKeyEvents:eventArray withSender:self])
+ [super interpretKeyEvents:eventArray];
+}
+@end
+
+@implementation NSMutableAttributedString (TextInputController)
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(string)
+ || aSelector == @selector(getLength)
+ || aSelector == @selector(attributeNamesAtIndex:)
+ || aSelector == @selector(valueOfAttribute:atIndex:)
+ || aSelector == @selector(addAttribute:value:)
+ || aSelector == @selector(addAttribute:value:from:length:)
+ || aSelector == @selector(addColorAttribute:red:green:blue:alpha:)
+ || aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:)
+ || aSelector == @selector(addFontAttribute:fontName:size:)
+ || aSelector == @selector(addFontAttribute:fontName:size:from:length:))
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(getLength))
+ return @"length";
+ if (aSelector == @selector(attributeNamesAtIndex:))
+ return @"getAttributeNamesAtIndex";
+ if (aSelector == @selector(valueOfAttribute:atIndex:))
+ return @"getAttributeValueAtIndex";
+ if (aSelector == @selector(addAttribute:value:))
+ return @"addAttribute";
+ if (aSelector == @selector(addAttribute:value:from:length:))
+ return @"addAttributeForRange";
+ if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:))
+ return @"addColorAttribute";
+ if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:))
+ return @"addColorAttributeForRange";
+ if (aSelector == @selector(addFontAttribute:fontName:size:))
+ return @"addFontAttribute";
+ if (aSelector == @selector(addFontAttribute:fontName:size:from:length:))
+ return @"addFontAttributeForRange";
+
+ return nil;
+}
+
+- (int)getLength
+{
+ return (int)[self length];
+}
+
+- (NSArray *)attributeNamesAtIndex:(int)index
+{
+ NSDictionary *attributes = [self attributesAtIndex:(unsigned)index effectiveRange:nil];
+ return [attributes allKeys];
+}
+
+- (id)valueOfAttribute:(NSString *)attrName atIndex:(int)index
+{
+ return [self attribute:attrName atIndex:(unsigned)index effectiveRange:nil];
+}
+
+- (void)addAttribute:(NSString *)attrName value:(id)value
+{
+ [self addAttribute:attrName value:value range:NSMakeRange(0, [self length])];
+}
+
+- (void)addAttribute:(NSString *)attrName value:(id)value from:(int)from length:(int)length
+{
+ [self addAttribute:attrName value:value range:NSMakeRange((unsigned)from, (unsigned)length)];
+}
+
+- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
+{
+ [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange(0, [self length])];
+}
+
+- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha from:(int)from length:(int)length
+{
+ [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange((unsigned)from, (unsigned)length)];
+}
+
+- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize
+{
+ [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange(0, [self length])];
+}
+
+- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize from:(int)from length:(int)length
+{
+ [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange((unsigned)from, (unsigned)length)];
+}
+
+@end
+
+@implementation TextInputController
+
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
+{
+ if (aSelector == @selector(insertText:)
+ || aSelector == @selector(doCommand:)
+ || aSelector == @selector(setMarkedText:selectedFrom:length:)
+ || aSelector == @selector(unmarkText)
+ || aSelector == @selector(hasMarkedText)
+ || aSelector == @selector(conversationIdentifier)
+ || aSelector == @selector(substringFrom:length:)
+ || aSelector == @selector(attributedSubstringFrom:length:)
+ || aSelector == @selector(markedRange)
+ || aSelector == @selector(selectedRange)
+ || aSelector == @selector(firstRectForCharactersFrom:length:)
+ || aSelector == @selector(characterIndexForPointX:Y:)
+ || aSelector == @selector(validAttributesForMarkedText)
+ || aSelector == @selector(attributedStringWithString:)
+ || aSelector == @selector(setInputMethodHandler:))
+ return NO;
+ return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)aSelector
+{
+ if (aSelector == @selector(insertText:))
+ return @"insertText";
+ else if (aSelector == @selector(doCommand:))
+ return @"doCommand";
+ else if (aSelector == @selector(setMarkedText:selectedFrom:length:))
+ return @"setMarkedText";
+ else if (aSelector == @selector(substringFrom:length:))
+ return @"substringFromRange";
+ else if (aSelector == @selector(attributedSubstringFrom:length:))
+ return @"attributedSubstringFromRange";
+ else if (aSelector == @selector(firstRectForCharactersFrom:length:))
+ return @"firstRectForCharacterRange";
+ else if (aSelector == @selector(characterIndexForPointX:Y:))
+ return @"characterIndexForPoint";
+ else if (aSelector == @selector(attributedStringWithString:))
+ return @"makeAttributedString"; // just a factory method, doesn't call into NSTextInput
+ else if (aSelector == @selector(setInputMethodHandler:))
+ return @"setInputMethodHandler";
+
+ return nil;
+}
+
+- (id)initWithWebView:(WebView *)wv
+{
+ self = [super init];
+ webView = wv;
+ inputMethodView = nil;
+ inputMethodHandler = nil;
+ return self;
+}
+
+- (void)dealloc
+{
+ [inputMethodHandler release];
+ inputMethodHandler = nil;
+
+ [super dealloc];
+}
+
+- (NSObject <NSTextInput> *)textInput
+{
+ NSView <NSTextInput> *view = inputMethodView ? inputMethodView : (id)[[[webView mainFrame] frameView] documentView];
+ return [view conformsToProtocol:@protocol(NSTextInput)] ? view : nil;
+}
+
+- (void)insertText:(id)aString
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ [textInput insertText:aString];
+}
+
+- (void)doCommand:(NSString *)aCommand
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ [textInput doCommandBySelector:NSSelectorFromString(aCommand)];
+}
+
+- (void)setMarkedText:(NSString *)aString selectedFrom:(int)from length:(int)length
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ [textInput setMarkedText:aString selectedRange:NSMakeRange(from, length)];
+}
+
+- (void)unmarkText
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ [textInput unmarkText];
+}
+
+- (BOOL)hasMarkedText
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ return [textInput hasMarkedText];
+
+ return FALSE;
+}
+
+- (long)conversationIdentifier
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ return [textInput conversationIdentifier];
+
+ return 0;
+}
+
+- (NSString *)substringFrom:(int)from length:(int)length
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ return [[textInput attributedSubstringFromRange:NSMakeRange(from, length)] string];
+
+ return @"";
+}
+
+- (NSMutableAttributedString *)attributedSubstringFrom:(int)from length:(int)length
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ NSMutableAttributedString *ret = [[[NSMutableAttributedString alloc] init] autorelease];
+
+ if (textInput)
+ [ret setAttributedString:[textInput attributedSubstringFromRange:NSMakeRange(from, length)]];
+
+ return ret;
+}
+
+- (NSArray *)markedRange
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput) {
+ NSRange range = [textInput markedRange];
+ return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
+ }
+
+ return nil;
+}
+
+- (NSArray *)selectedRange
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput) {
+ NSRange range = [textInput selectedRange];
+ return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
+ }
+
+ return nil;
+}
+
+
+- (NSArray *)firstRectForCharactersFrom:(int)from length:(int)length
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput) {
+ NSRect rect = [textInput firstRectForCharacterRange:NSMakeRange(from, length)];
+ if (rect.origin.x || rect.origin.y || rect.size.width || rect.size.height) {
+ rect.origin = [[webView window] convertScreenToBase:rect.origin];
+ rect = [webView convertRect:rect fromView:nil];
+ }
+ return [NSArray arrayWithObjects:
+ [NSNumber numberWithFloat:rect.origin.x],
+ [NSNumber numberWithFloat:rect.origin.y],
+ [NSNumber numberWithFloat:rect.size.width],
+ [NSNumber numberWithFloat:rect.size.height],
+ nil];
+ }
+
+ return nil;
+}
+
+- (int)characterIndexForPointX:(float)x Y:(float)y
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput) {
+ NSPoint point = NSMakePoint(x, y);
+ point = [webView convertPoint:point toView:nil];
+ point = [[webView window] convertBaseToScreen:point];
+ return [textInput characterIndexForPoint:point];
+ }
+
+ return 0;
+}
+
+- (NSArray *)validAttributesForMarkedText
+{
+ NSObject <NSTextInput> *textInput = [self textInput];
+
+ if (textInput)
+ return [textInput validAttributesForMarkedText];
+
+ return nil;
+}
+
+- (NSMutableAttributedString *)attributedStringWithString:(NSString *)aString
+{
+ return [[[NSMutableAttributedString alloc] initWithString:aString] autorelease];
+}
+
+- (void)setInputMethodHandler:(WebScriptObject *)handler
+{
+ if (inputMethodHandler == handler)
+ return;
+ [handler retain];
+ [inputMethodHandler release];
+ inputMethodHandler = handler;
+}
+
+- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender
+{
+ if (!inputMethodHandler)
+ return NO;
+
+ inputMethodView = sender;
+
+ NSEvent *event = [eventArray objectAtIndex:0];
+ unsigned modifierFlags = [event modifierFlags];
+ NSMutableArray *modifiers = [[NSMutableArray alloc] init];
+ if (modifierFlags & NSAlphaShiftKeyMask)
+ [modifiers addObject:@"NSAlphaShiftKeyMask"];
+ if (modifierFlags & NSShiftKeyMask)
+ [modifiers addObject:@"NSShiftKeyMask"];
+ if (modifierFlags & NSControlKeyMask)
+ [modifiers addObject:@"NSControlKeyMask"];
+ if (modifierFlags & NSAlternateKeyMask)
+ [modifiers addObject:@"NSAlternateKeyMask"];
+ if (modifierFlags & NSCommandKeyMask)
+ [modifiers addObject:@"NSCommandKeyMask"];
+ if (modifierFlags & NSNumericPadKeyMask)
+ [modifiers addObject:@"NSNumericPadKeyMask"];
+ if (modifierFlags & NSHelpKeyMask)
+ [modifiers addObject:@"NSHelpKeyMask"];
+ if (modifierFlags & NSFunctionKeyMask)
+ [modifiers addObject:@"NSFunctionKeyMask"];
+
+ WebScriptObject* eventParam = [inputMethodHandler evaluateWebScript:@"new Object();"];
+ [eventParam setValue:[event characters] forKey:@"characters"];
+ [eventParam setValue:[event charactersIgnoringModifiers] forKey:@"charactersIgnoringModifiers"];
+ [eventParam setValue:[NSNumber numberWithBool:[event isARepeat]] forKey:@"isARepeat"];
+ [eventParam setValue:[NSNumber numberWithUnsignedShort:[event keyCode]] forKey:@"keyCode"];
+ [eventParam setValue:modifiers forKey:@"modifierFlags"];
+
+ [modifiers release];
+
+ id result = [inputMethodHandler callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:inputMethodHandler, eventParam, nil]];
+ if (![result respondsToSelector:@selector(boolValue)] || ![result boolValue])
+ [sender doCommandBySelector:@selector(noop:)]; // AppKit sends noop: if the ime does not handle an event
+
+ inputMethodView = nil;
+ return YES;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/UIDelegate.h b/WebKitTools/DumpRenderTree/mac/UIDelegate.h
new file mode 100644
index 0000000..da472d6
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/UIDelegate.h
@@ -0,0 +1,37 @@
+/*
+ * 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
+ * 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface UIDelegate : NSObject {
+
+@private
+ NSRect m_frame;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/UIDelegate.mm b/WebKitTools/DumpRenderTree/mac/UIDelegate.mm
new file mode 100644
index 0000000..0c5a93c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/UIDelegate.mm
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2006. 2007 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.
+ * 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.
+ */
+
+#import "DumpRenderTree.h"
+#import "UIDelegate.h"
+
+#import "DumpRenderTreeDraggingInfo.h"
+#import "EventSendingController.h"
+#import "LayoutTestController.h"
+#import <WebKit/WebFramePrivate.h>
+#import <WebKit/WebHTMLViewPrivate.h>
+#import <WebKit/WebView.h>
+#import <WebKit/WebSecurityOriginPrivate.h>
+#import <wtf/Assertions.h>
+
+DumpRenderTreeDraggingInfo *draggingInfo = nil;
+
+@implementation UIDelegate
+
+- (void)webView:(WebView *)sender setFrame:(NSRect)frame
+{
+ m_frame = frame;
+}
+
+- (NSRect)webViewFrame:(WebView *)sender;
+{
+ return m_frame;
+}
+
+- (void)webView:(WebView *)sender addMessageToConsole:(NSDictionary *)dictionary
+{
+ NSString *message = [dictionary objectForKey:@"message"];
+ NSNumber *lineNumber = [dictionary objectForKey:@"lineNumber"];
+
+ NSRange range = [message rangeOfString:@"file://"];
+ if (range.location != NSNotFound)
+ message = [[message substringToIndex:range.location] stringByAppendingString:[[message substringFromIndex:NSMaxRange(range)] lastPathComponent]];
+
+ printf ("CONSOLE MESSAGE: line %d: %s\n", [lineNumber intValue], [message UTF8String]);
+}
+
+- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
+{
+ if (!done)
+ printf("ALERT: %s\n", [message UTF8String]);
+}
+
+- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
+{
+ if (!done)
+ printf("CONFIRM: %s\n", [message UTF8String]);
+ return YES;
+}
+
+- (NSString *)webView:(WebView *)sender runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WebFrame *)frame
+{
+ if (!done)
+ printf("PROMPT: %s, default text: %s\n", [prompt UTF8String], [defaultText UTF8String]);
+ return defaultText;
+}
+
+- (BOOL)webView:(WebView *)c runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
+{
+ if (!done)
+ printf("CONFIRM NAVIGATION: %s\n", [message UTF8String]);
+ return YES;
+}
+
+
+- (void)webView:(WebView *)sender dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag forView:(NSView *)view
+{
+ assert(!draggingInfo);
+ if (gLayoutTestController->addFileToPasteboardOnDrag()) {
+ [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];
+ [pboard setPropertyList:[NSArray arrayWithObject:@"DRTFakeFile"] forType:NSFilenamesPboardType];
+ }
+ draggingInfo = [[DumpRenderTreeDraggingInfo alloc] initWithImage:anImage offset:initialOffset pasteboard:pboard source:sourceObj];
+ [EventSendingController replaySavedEvents];
+}
+
+- (void)webViewFocus:(WebView *)webView
+{
+ gLayoutTestController->setWindowIsKey(true);
+}
+
+- (void)webViewUnfocus:(WebView *)webView
+{
+ gLayoutTestController->setWindowIsKey(false);
+}
+
+- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
+{
+ if (!gLayoutTestController->canOpenWindows())
+ return nil;
+
+ // Make sure that waitUntilDone has been called.
+ ASSERT(gLayoutTestController->waitToDump());
+
+ WebView *webView = createWebViewAndOffscreenWindow();
+
+ return [webView autorelease];
+}
+
+- (void)webViewClose:(WebView *)sender
+{
+ NSWindow* window = [sender window];
+
+ if (gLayoutTestController->callCloseOnWebViews())
+ [sender close];
+
+ [window close];
+}
+
+- (void)webView:(WebView *)sender frame:(WebFrame *)frame exceededDatabaseQuotaForSecurityOrigin:(WebSecurityOrigin *)origin database:(NSString *)databaseIdentifier
+{
+ if (!done && gLayoutTestController->dumpDatabaseCallbacks())
+ printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n", [[origin protocol] UTF8String], [[origin host] UTF8String],
+ [origin port], [databaseIdentifier UTF8String]);
+
+ static const unsigned long long defaultQuota = 5 * 1024 * 1024;
+ [origin setQuota:defaultQuota];
+}
+
+- (void)webView:(WebView *)sender setStatusText:(NSString *)text
+{
+ if (gLayoutTestController->dumpStatusCallbacks())
+ printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", [text UTF8String]);
+}
+
+- (void)dealloc
+{
+ [draggingInfo release];
+ draggingInfo = nil;
+
+ [super dealloc];
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/WorkQueueItemMac.mm b/WebKitTools/DumpRenderTree/mac/WorkQueueItemMac.mm
new file mode 100644
index 0000000..3a7b0e2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/WorkQueueItemMac.mm
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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.
+ */
+
+#import "DumpRenderTree.h"
+#import "WorkQueueItem.h"
+
+#import <JavaScriptCore/JSStringRef.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <WebKit/WebBackForwardList.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebScriptObject.h>
+#import <WebKit/WebView.h>
+#import <wtf/RetainPtr.h>
+
+void LoadItem::invoke() const
+{
+ RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, m_url.get()));
+ NSString *urlNS = (NSString *)urlCF.get();
+ RetainPtr<CFStringRef> targetCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, m_target.get()));
+ NSString *targetNS = (NSString *)targetCF.get();
+
+ WebFrame *targetFrame;
+ if (targetNS && [targetNS length])
+ targetFrame = [mainFrame findFrameNamed:targetNS];
+ else
+ targetFrame = mainFrame;
+ [targetFrame loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlNS]]];
+}
+
+void ReloadItem::invoke() const
+{
+ [[mainFrame webView] reload:nil];
+}
+
+void ScriptItem::invoke() const
+{
+ RetainPtr<CFStringRef> scriptCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, m_script.get()));
+ NSString *scriptNS = (NSString *)scriptCF.get();
+ [[mainFrame webView] stringByEvaluatingJavaScriptFromString:scriptNS];
+}
+
+void BackForwardItem::invoke() const
+{
+ if (m_howFar == 1)
+ [[mainFrame webView] goForward];
+ else if (m_howFar == -1)
+ [[mainFrame webView] goBack];
+ else {
+ WebBackForwardList *bfList = [[mainFrame webView] backForwardList];
+ [[mainFrame webView] goToBackForwardItem:[bfList itemAtIndex:m_howFar]];
+ }
+}
diff --git a/WebKitTools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp b/WebKitTools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp
new file mode 100644
index 0000000..3ac257d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp
@@ -0,0 +1,137 @@
+/*
+ * 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>
+ *
+ * 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 "JavaScriptThreading.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <pthread.h>
+#include <wtf/Assertions.h>
+#include <wtf/HashSet.h>
+
+static pthread_mutex_t javaScriptThreadsMutex = PTHREAD_MUTEX_INITIALIZER;
+static bool javaScriptThreadsShouldTerminate;
+
+static const int javaScriptThreadsCount = 4;
+
+typedef HashSet<pthread_t> ThreadSet;
+
+static ThreadSet* javaScriptThreads()
+{
+ ASSERT(pthread_mutex_trylock(&javaScriptThreadsMutex) == EBUSY);
+ static ThreadSet staticJavaScriptThreads;
+ return &staticJavaScriptThreads;
+}
+
+// Loops forever, running a script and randomly respawning, until
+// javaScriptThreadsShouldTerminate becomes true.
+void* runJavaScriptThread(void* arg)
+{
+ const char* const script =
+ "var array = [];"
+ "for (var i = 0; i < 10; i++) {"
+ " array.push(String(i));"
+ "}";
+
+ while (1) {
+ JSGlobalContextRef ctx = JSGlobalContextCreate(0);
+ JSStringRef scriptRef = JSStringCreateWithUTF8CString(script);
+
+ JSValueRef exception = 0;
+ JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception);
+ ASSERT(!exception);
+
+ JSGarbageCollect(ctx);
+ JSGlobalContextRelease(ctx);
+ JSStringRelease(scriptRef);
+
+ JSGarbageCollect(0);
+
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ // Check for cancellation.
+ if (javaScriptThreadsShouldTerminate) {
+ javaScriptThreads()->remove(pthread_self());
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ return 0;
+ }
+
+ // Respawn probabilistically.
+ if (random() % 5 == 0) {
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_detach(pthread);
+
+ javaScriptThreads()->remove(pthread_self());
+ javaScriptThreads()->add(pthread);
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ return 0;
+ }
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ }
+}
+
+void startJavaScriptThreads()
+{
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ for (int i = 0; i < javaScriptThreadsCount; i++) {
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_detach(pthread);
+ javaScriptThreads()->add(pthread);
+ }
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+}
+
+void stopJavaScriptThreads()
+{
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ javaScriptThreadsShouldTerminate = true;
+
+ ASSERT(javaScriptThreads()->size() == javaScriptThreadsCount);
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+
+ while (true) {
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+ int threadCount = javaScriptThreads()->size();
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+
+ if (!threadCount)
+ break;
+
+ usleep(1000);
+ }
+}
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp
new file mode 100644
index 0000000..07075ba
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 "DumpRenderTree.h"
+#include "jsobjects.h"
+#include "testplugin.h"
+
+#include <QDir>
+#include <QFile>
+#include <QTimer>
+#include <QBoxLayout>
+#include <QScrollArea>
+#include <QApplication>
+#include <QUrl>
+#include <QFocusEvent>
+
+#include <qwebpage.h>
+#include <qwebframe.h>
+#include <qwebview.h>
+#include <qwebsettings.h>
+
+#include <unistd.h>
+#include <qdebug.h>
+
+extern void qt_drt_run(bool b);
+extern void qt_dump_set_accepts_editing(bool b);
+extern void qt_dump_frame_loader(bool b);
+
+
+namespace WebCore {
+
+// Choose some default values.
+const unsigned int maxViewWidth = 800;
+const unsigned int maxViewHeight = 600;
+
+class WebPage : public QWebPage {
+ Q_OBJECT
+public:
+ WebPage(QWidget *parent, DumpRenderTree *drt);
+
+ QWebPage *createWindow(QWebPage::WebWindowType);
+
+ void javaScriptAlert(QWebFrame *frame, const QString& message);
+ void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID);
+ bool javaScriptConfirm(QWebFrame *frame, const QString& msg);
+ bool javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result);
+
+private slots:
+ void setViewGeometry(const QRect &r)
+ {
+ QWidget *v = view();
+ if (v)
+ v->setGeometry(r);
+ }
+private:
+ DumpRenderTree *m_drt;
+};
+
+WebPage::WebPage(QWidget *parent, DumpRenderTree *drt)
+ : QWebPage(parent), m_drt(drt)
+{
+ settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
+ settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true);
+ settings()->setAttribute(QWebSettings::LinksIncludedInFocusChain, false);
+ connect(this, SIGNAL(geometryChangeRequested(const QRect &)),
+ this, SLOT(setViewGeometry(const QRect & )));
+
+ setPluginFactory(new TestPlugin(this));
+}
+
+QWebPage *WebPage::createWindow(QWebPage::WebWindowType)
+{
+ return m_drt->createWindow();
+}
+
+void WebPage::javaScriptAlert(QWebFrame *frame, const QString& message)
+{
+ fprintf(stdout, "ALERT: %s\n", message.toUtf8().constData());
+}
+
+void WebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString&)
+{
+ fprintf (stdout, "CONSOLE MESSAGE: line %d: %s\n", lineNumber, message.toUtf8().constData());
+}
+
+bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
+{
+ fprintf(stdout, "CONFIRM: %s\n", msg.toUtf8().constData());
+ return true;
+}
+
+bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
+{
+ fprintf(stdout, "PROMPT: %s, default text: %s\n", msg.toUtf8().constData(), defaultValue.toUtf8().constData());
+ *result = defaultValue;
+ return true;
+}
+
+DumpRenderTree::DumpRenderTree()
+ : m_stdin(0)
+ , m_notifier(0)
+{
+ m_controller = new LayoutTestController(this);
+ connect(m_controller, SIGNAL(done()), this, SLOT(dump()), Qt::QueuedConnection);
+
+ QWebView *view = new QWebView(0);
+ view->resize(QSize(maxViewWidth, maxViewHeight));
+ m_page = new WebPage(view, this);
+ view->setPage(m_page);
+ connect(m_page, SIGNAL(frameCreated(QWebFrame *)), this, SLOT(connectFrame(QWebFrame *)));
+ connectFrame(m_page->mainFrame());
+
+ connect(m_page, SIGNAL(loadFinished(bool)), m_controller, SLOT(maybeDump(bool)));
+
+ m_page->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
+ m_page->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
+ connect(m_page->mainFrame(), SIGNAL(titleChanged(const QString&)),
+ SLOT(titleChanged(const QString&)));
+
+ m_eventSender = new EventSender(m_page);
+ m_textInputController = new TextInputController(m_page);
+
+ QObject::connect(this, SIGNAL(quit()), qApp, SLOT(quit()), Qt::QueuedConnection);
+ qt_drt_run(true);
+ QFocusEvent event(QEvent::FocusIn, Qt::ActiveWindowFocusReason);
+ QApplication::sendEvent(view, &event);
+}
+
+DumpRenderTree::~DumpRenderTree()
+{
+ delete m_page;
+
+ delete m_stdin;
+ delete m_notifier;
+}
+
+void DumpRenderTree::open()
+{
+ if (!m_stdin) {
+ m_stdin = new QFile;
+ m_stdin->open(stdin, QFile::ReadOnly);
+ }
+
+ if (!m_notifier) {
+ m_notifier = new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read);
+ connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readStdin(int)));
+ }
+}
+
+void DumpRenderTree::open(const QUrl& url)
+{
+ // W3C SVG tests expect to be 480x360
+ bool isW3CTest = url.toString().contains("svg/W3C-SVG-1.1");
+ int width = isW3CTest ? 480 : maxViewWidth;
+ int height = isW3CTest ? 360 : maxViewHeight;
+ m_page->view()->resize(QSize(width, height));
+ m_page->setViewportSize(QSize(width, height));
+
+ resetJSObjects();
+
+ qt_dump_frame_loader(url.toString().contains("loading/"));
+ m_page->mainFrame()->load(url);
+}
+
+void DumpRenderTree::readStdin(int /* socket */)
+{
+ // Read incoming data from stdin...
+ QByteArray line = m_stdin->readLine();
+ if (line.endsWith('\n'))
+ line.truncate(line.size()-1);
+ //fprintf(stderr, "\n opening %s\n", line.constData());
+ if (line.isEmpty())
+ quit();
+
+ if (line.startsWith("http:") || line.startsWith("https:"))
+ open(QUrl(line));
+ else {
+ QFileInfo fi(line);
+ open(QUrl::fromLocalFile(fi.absoluteFilePath()));
+ }
+
+ fflush(stdout);
+}
+
+void DumpRenderTree::resetJSObjects()
+{
+ m_controller->reset();
+ foreach(QWidget *widget, windows)
+ delete widget;
+ windows.clear();
+}
+
+void DumpRenderTree::initJSObjects()
+{
+ QWebFrame *frame = qobject_cast<QWebFrame*>(sender());
+ Q_ASSERT(frame);
+ frame->addToJavaScriptWindowObject(QLatin1String("layoutTestController"), m_controller);
+ frame->addToJavaScriptWindowObject(QLatin1String("eventSender"), m_eventSender);
+ frame->addToJavaScriptWindowObject(QLatin1String("textInputController"), m_textInputController);
+}
+
+
+QString DumpRenderTree::dumpFramesAsText(QWebFrame* frame)
+{
+ if (!frame)
+ return QString();
+
+ QString result;
+ QWebFrame *parent = qobject_cast<QWebFrame *>(frame->parent());
+ if (parent) {
+ result.append(QLatin1String("\n--------\nFrame: '"));
+ result.append(frame->frameName());
+ result.append(QLatin1String("'\n--------\n"));
+ }
+
+ result.append(frame->toPlainText());
+ result.append(QLatin1String("\n"));
+
+ if (m_controller->shouldDumpChildrenAsText()) {
+ QList<QWebFrame *> children = frame->childFrames();
+ for (int i = 0; i < children.size(); ++i)
+ result += dumpFramesAsText(children.at(i));
+ }
+
+ return result;
+}
+
+void DumpRenderTree::dump()
+{
+ QWebFrame *frame = m_page->mainFrame();
+
+ //fprintf(stderr, " Dumping\n");
+ if (!m_notifier) {
+ // Dump markup in single file mode...
+ QString markup = frame->toHtml();
+ fprintf(stdout, "Source:\n\n%s\n", markup.toUtf8().constData());
+ }
+
+ // Dump render text...
+ QString renderDump;
+ if (m_controller->shouldDumpAsText()) {
+ renderDump = dumpFramesAsText(frame);
+ } else {
+ renderDump = frame->renderTreeDump();
+ }
+ if (renderDump.isEmpty()) {
+ printf("ERROR: nil result from %s", m_controller->shouldDumpAsText() ? "[documentElement innerText]" : "[frame renderTreeAsExternalRepresentation]");
+ } else {
+ fprintf(stdout, "%s", renderDump.toUtf8().constData());
+ }
+
+ fprintf(stdout, "#EOF\n");
+
+ fflush(stdout);
+
+ fprintf(stderr, "#EOF\n");
+
+ fflush(stderr);
+
+ if (!m_notifier) {
+ // Exit now in single file mode...
+ quit();
+ }
+}
+
+void DumpRenderTree::titleChanged(const QString &s)
+{
+ if (m_controller->shouldDumpTitleChanges())
+ printf("TITLE CHANGED: %s\n", s.toUtf8().data());
+}
+
+void DumpRenderTree::connectFrame(QWebFrame *frame)
+{
+ connect(frame, SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(initJSObjects()));
+ connect(frame, SIGNAL(provisionalLoad()),
+ layoutTestController(), SLOT(provisionalLoad()));
+}
+
+QWebPage *DumpRenderTree::createWindow()
+{
+ if (!m_controller->canOpenWindows())
+ return 0;
+ QWidget *container = new QWidget(0);
+ container->resize(0, 0);
+ container->move(-1, -1);
+ container->hide();
+ QWebPage *page = new WebPage(container, this);
+ connect(m_page, SIGNAL(frameCreated(QWebFrame *)), this, SLOT(connectFrame(QWebFrame *)));
+ windows.append(container);
+ return page;
+}
+
+int DumpRenderTree::windowCount() const
+{
+ int count = 0;
+ foreach(QWidget *w, windows) {
+ if (w->children().count())
+ ++count;
+ }
+ return count + 1;
+}
+
+}
+
+#include "DumpRenderTree.moc"
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h
new file mode 100644
index 0000000..a46cccb
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.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 DUMPRENDERTREE_H
+#define DUMPRENDERTREE_H
+
+#include <QList>
+#include <QObject>
+#include <QTextStream>
+#include <QSocketNotifier>
+
+QT_BEGIN_NAMESPACE
+class QUrl;
+class QFile;
+QT_END_NAMESPACE
+class QWebPage;
+class QWebFrame;
+
+class LayoutTestController;
+class EventSender;
+class TextInputController;
+
+namespace WebCore {
+
+class DumpRenderTree : public QObject {
+Q_OBJECT
+
+public:
+ DumpRenderTree();
+ virtual ~DumpRenderTree();
+
+ // Initialize in multi-file mode, used by run-webkit-tests.
+ void open();
+
+ // Initialize in single-file mode.
+ void open(const QUrl& url);
+
+ void resetJSObjects();
+
+ LayoutTestController *layoutTestController() const { return m_controller; }
+ EventSender *eventSender() const { return m_eventSender; }
+ TextInputController *textInputController() const { return m_textInputController; }
+
+ QWebPage *createWindow();
+ int windowCount() const;
+
+ QWebPage *webPage() const { return m_page; }
+
+public Q_SLOTS:
+ void initJSObjects();
+ void readStdin(int);
+ void dump();
+ void titleChanged(const QString &s);
+ void connectFrame(QWebFrame *frame);
+
+Q_SIGNALS:
+ void quit();
+
+private:
+ QString dumpFramesAsText(QWebFrame* frame);
+ LayoutTestController *m_controller;
+
+ QWebPage *m_page;
+
+ EventSender *m_eventSender;
+ TextInputController *m_textInputController;
+
+ QFile *m_stdin;
+ QSocketNotifier* m_notifier;
+
+ QList<QWidget *> windows;
+};
+
+}
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
new file mode 100644
index 0000000..08f1ab7
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
@@ -0,0 +1,22 @@
+TARGET = DumpRenderTree
+CONFIG -= app_bundle
+
+include(../../../WebKit.pri)
+INCLUDEPATH += /usr/include/freetype2
+INCLUDEPATH += ../../../JavaScriptCore/kjs
+DESTDIR = ../../../bin
+
+
+QT = core gui
+macx: QT += xml network
+
+HEADERS = DumpRenderTree.h jsobjects.h testplugin.h
+SOURCES = DumpRenderTree.cpp main.cpp jsobjects.cpp testplugin.cpp
+
+unix:!mac {
+ QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR
+}
+
+qt-port:lessThan(QT_MINOR_VERSION, 4) {
+ DEFINES += QT_BEGIN_NAMESPACE="" QT_END_NAMESPACE=""
+}
diff --git a/WebKitTools/DumpRenderTree/qt/fonts.conf b/WebKitTools/DumpRenderTree/qt/fonts.conf
new file mode 100644
index 0000000..3540c47
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/fonts.conf
@@ -0,0 +1,258 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+
+<!--
+ Accept deprecated 'mono' alias, replacing it with 'monospace'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>mono</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>monospace</string>
+ </edit>
+ </match>
+
+<!--
+ Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans serif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+<!--
+ Accept deprecated 'sans' alias, replacing it with 'sans-serif'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+
+ <config>
+<!--
+ These are the default Unicode chars that are expected to be blank
+ in fonts. All other blank chars are assumed to be broken and
+ won't appear in the resulting charsets
+ -->
+ <blank>
+ <int>0x0020</int> <!-- SPACE -->
+ <int>0x00A0</int> <!-- NO-BREAK SPACE -->
+ <int>0x00AD</int> <!-- SOFT HYPHEN -->
+ <int>0x034F</int> <!-- COMBINING GRAPHEME JOINER -->
+ <int>0x0600</int> <!-- ARABIC NUMBER SIGN -->
+ <int>0x0601</int> <!-- ARABIC SIGN SANAH -->
+ <int>0x0602</int> <!-- ARABIC FOOTNOTE MARKER -->
+ <int>0x0603</int> <!-- ARABIC SIGN SAFHA -->
+ <int>0x06DD</int> <!-- ARABIC END OF AYAH -->
+ <int>0x070F</int> <!-- SYRIAC ABBREVIATION MARK -->
+ <int>0x115F</int> <!-- HANGUL CHOSEONG FILLER -->
+ <int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER -->
+ <int>0x1680</int> <!-- OGHAM SPACE MARK -->
+ <int>0x17B4</int> <!-- KHMER VOWEL INHERENT AQ -->
+ <int>0x17B5</int> <!-- KHMER VOWEL INHERENT AA -->
+ <int>0x180E</int> <!-- MONGOLIAN VOWEL SEPARATOR -->
+ <int>0x2000</int> <!-- EN QUAD -->
+ <int>0x2001</int> <!-- EM QUAD -->
+ <int>0x2002</int> <!-- EN SPACE -->
+ <int>0x2003</int> <!-- EM SPACE -->
+ <int>0x2004</int> <!-- THREE-PER-EM SPACE -->
+ <int>0x2005</int> <!-- FOUR-PER-EM SPACE -->
+ <int>0x2006</int> <!-- SIX-PER-EM SPACE -->
+ <int>0x2007</int> <!-- FIGURE SPACE -->
+ <int>0x2008</int> <!-- PUNCTUATION SPACE -->
+ <int>0x2009</int> <!-- THIN SPACE -->
+ <int>0x200A</int> <!-- HAIR SPACE -->
+ <int>0x200B</int> <!-- ZERO WIDTH SPACE -->
+ <int>0x200C</int> <!-- ZERO WIDTH NON-JOINER -->
+ <int>0x200D</int> <!-- ZERO WIDTH JOINER -->
+ <int>0x200E</int> <!-- LEFT-TO-RIGHT MARK -->
+ <int>0x200F</int> <!-- RIGHT-TO-LEFT MARK -->
+ <int>0x2028</int> <!-- LINE SEPARATOR -->
+ <int>0x2029</int> <!-- PARAGRAPH SEPARATOR -->
+ <int>0x202A</int> <!-- LEFT-TO-RIGHT EMBEDDING -->
+ <int>0x202B</int> <!-- RIGHT-TO-LEFT EMBEDDING -->
+ <int>0x202C</int> <!-- POP DIRECTIONAL FORMATTING -->
+ <int>0x202D</int> <!-- LEFT-TO-RIGHT OVERRIDE -->
+ <int>0x202E</int> <!-- RIGHT-TO-LEFT OVERRIDE -->
+ <int>0x202F</int> <!-- NARROW NO-BREAK SPACE -->
+ <int>0x205F</int> <!-- MEDIUM MATHEMATICAL SPACE -->
+ <int>0x2060</int> <!-- WORD JOINER -->
+ <int>0x2061</int> <!-- FUNCTION APPLICATION -->
+ <int>0x2062</int> <!-- INVISIBLE TIMES -->
+ <int>0x2063</int> <!-- INVISIBLE SEPARATOR -->
+ <int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING -->
+ <int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING -->
+ <int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING -->
+ <int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING -->
+ <int>0x206E</int> <!-- NATIONAL DIGIT SHAPES -->
+ <int>0x206F</int> <!-- NOMINAL DIGIT SHAPES -->
+ <int>0x3000</int> <!-- IDEOGRAPHIC SPACE -->
+ <int>0x3164</int> <!-- HANGUL FILLER -->
+ <int>0xFEFF</int> <!-- ZERO WIDTH NO-BREAK SPACE -->
+ <int>0xFFA0</int> <!-- HALFWIDTH HANGUL FILLER -->
+ <int>0xFFF9</int> <!-- INTERLINEAR ANNOTATION ANCHOR -->
+ <int>0xFFFA</int> <!-- INTERLINEAR ANNOTATION SEPARATOR -->
+ <int>0xFFFB</int> <!-- INTERLINEAR ANNOTATION TERMINATOR -->
+ </blank>
+<!--
+ Rescan configuration every 30 seconds when FcFontSetList is called
+ -->
+ <rescan>
+ <int>30</int>
+ </rescan>
+ </config>
+
+<!--
+ URW provides metric and shape compatible fonts for these 10 Adobe families.
+
+ However, these fonts are quite ugly and do not render well on-screen,
+ so we avoid matching them if the application said `anymetrics'; in that
+ case, a more generic font with different metrics but better appearance
+ will be used.
+ -->
+ <match target="pattern">
+ <test name="family">
+ <string>Avant Garde</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>URW Gothic L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Bookman</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>URW Bookman L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Courier</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Nimbus Mono L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Helvetica</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Nimbus Sans L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>New Century Schoolbook</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Century Schoolbook L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Palatino</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>URW Palladio L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Times</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Nimbus Roman No9 L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Zapf Chancery</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>URW Chancery L</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Zapf Dingbats</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append">
+ <string>Dingbats</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test name="family">
+ <string>Symbol</string>
+ </test>
+ <test name="anymetrics" qual="all" compare="not_eq">
+ <bool>true</bool>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Standard Symbols L</string>
+ </edit>
+ </match>
+
+<!--
+ Serif faces
+ -->
+ <alias>
+ <family>Nimbus Roman No9 L</family>
+ <default><family>serif</family></default>
+ </alias>
+<!--
+ Sans-serif faces
+ -->
+ <alias>
+ <family>Nimbus Sans L</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+<!--
+ Monospace faces
+ -->
+ <alias>
+ <family>Nimbus Mono L</family>
+ <default><family>monospace</family></default>
+ </alias>
+
+
+</fontconfig>
diff --git a/WebKitTools/DumpRenderTree/qt/fonts/AHEM____.TTF b/WebKitTools/DumpRenderTree/qt/fonts/AHEM____.TTF
new file mode 100644
index 0000000..ac81cb0
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/fonts/AHEM____.TTF
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/qt/jsobjects.cpp b/WebKitTools/DumpRenderTree/qt/jsobjects.cpp
new file mode 100644
index 0000000..98603ad
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/jsobjects.cpp
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 <jsobjects.h>
+#include <qwebpage.h>
+#include <qwebhistory.h>
+#include <qwebframe.h>
+#include <qevent.h>
+#include <qapplication.h>
+#include <qevent.h>
+
+#include "DumpRenderTree.h"
+extern void qt_dump_editing_callbacks(bool b);
+extern void qt_dump_resource_load_callbacks(bool b);
+
+LayoutTestController::LayoutTestController(WebCore::DumpRenderTree *drt)
+ : QObject()
+ , m_drt(drt)
+{
+ m_timeoutTimer = 0;
+ reset();
+}
+
+void LayoutTestController::reset()
+{
+ m_isLoading = true;
+ m_textDump = false;
+ m_dumpChildrenAsText = false;
+ m_canOpenWindows = false;
+ m_waitForDone = false;
+ m_dumpTitleChanges = false;
+ if (m_timeoutTimer) {
+ killTimer(m_timeoutTimer);
+ m_timeoutTimer = 0;
+ }
+ m_topLoadingFrame = 0;
+ qt_dump_editing_callbacks(false);
+ qt_dump_resource_load_callbacks(false);
+}
+
+void LayoutTestController::maybeDump(bool ok)
+{
+ m_topLoadingFrame = 0;
+
+ if (!shouldWaitUntilDone()) {
+ emit done();
+ m_isLoading = false;
+ }
+}
+
+void LayoutTestController::waitUntilDone()
+{
+ //qDebug() << ">>>>waitForDone";
+ m_waitForDone = true;
+ m_timeoutTimer = startTimer(11000);
+}
+
+void LayoutTestController::notifyDone()
+{
+ //qDebug() << ">>>>notifyDone";
+ if (!m_timeoutTimer)
+ return;
+ killTimer(m_timeoutTimer);
+ m_timeoutTimer = 0;
+ emit done();
+ m_isLoading = false;
+}
+
+int LayoutTestController::windowCount()
+{
+ return m_drt->windowCount();
+}
+
+void LayoutTestController::clearBackForwardList()
+{
+ m_drt->webPage()->history()->clear();
+}
+
+
+void LayoutTestController::dumpEditingCallbacks()
+{
+ qDebug() << ">>>dumpEditingCallbacks";
+ qt_dump_editing_callbacks(true);
+}
+
+void LayoutTestController::dumpResourceLoadCallbacks()
+{
+ qt_dump_resource_load_callbacks(true);
+}
+
+void LayoutTestController::queueReload()
+{
+ //qDebug() << ">>>queueReload";
+}
+
+void LayoutTestController::provisionalLoad()
+{
+ QWebFrame *frame = qobject_cast<QWebFrame*>(sender());
+ if (!m_topLoadingFrame && m_isLoading)
+ m_topLoadingFrame = frame;
+}
+
+void LayoutTestController::timerEvent(QTimerEvent *)
+{
+ qDebug() << ">>>>>>>>>>>>> timeout";
+ notifyDone();
+}
+
+QString LayoutTestController::encodeHostName(const QString &host)
+{
+ QString encoded = QString::fromLatin1(QUrl::toAce(host + QLatin1String(".no")));
+ encoded.truncate(encoded.length() - 3); // strip .no
+ return encoded;
+}
+
+QString LayoutTestController::decodeHostName(const QString &host)
+{
+ QString decoded = QUrl::fromAce(host.toLatin1() + QByteArray(".no"));
+ decoded.truncate(decoded.length() - 3);
+ return decoded;
+}
+
+
+EventSender::EventSender(QWebPage *parent)
+ : QObject(parent)
+{
+ m_page = parent;
+}
+
+void EventSender::mouseDown()
+{
+// qDebug() << "EventSender::mouseDown" << frame;
+ QMouseEvent event(QEvent::MouseButtonPress, m_mousePos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(m_page, &event);
+}
+
+void EventSender::mouseUp()
+{
+// qDebug() << "EventSender::mouseUp" << frame;
+ QMouseEvent event(QEvent::MouseButtonRelease, m_mousePos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(m_page, &event);
+}
+
+void EventSender::mouseMoveTo(int x, int y)
+{
+// qDebug() << "EventSender::mouseMoveTo" << x << y;
+ m_mousePos = QPoint(x, y);
+ QMouseEvent event(QEvent::MouseMove, m_mousePos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ QApplication::sendEvent(m_page, &event);
+}
+
+void EventSender::leapForward(int ms)
+{
+ m_timeLeap += ms;
+ qDebug() << "EventSender::leapForward" << ms;
+}
+
+void EventSender::keyDown(const QString &string, const QStringList &modifiers)
+{
+ QString s = string;
+ Qt::KeyboardModifiers modifs = 0;
+ for (int i = 0; i < modifiers.size(); ++i) {
+ const QString &m = modifiers.at(i);
+ if (m == "ctrlKey")
+ modifs |= Qt::ControlModifier;
+ else if (m == "shiftKey")
+ modifs |= Qt::ShiftModifier;
+ else if (m == "altKey")
+ modifs |= Qt::AltModifier;
+ else if (m == "metaKey")
+ modifs |= Qt::MetaModifier;
+ }
+ int code = 0;
+ if (string.length() == 1) {
+ code = string.unicode()->unicode();
+ qDebug() << ">>>>>>>>> keyDown" << code << (char)code;
+ // map special keycodes used by the tests to something that works for Qt/X11
+ if (code == '\t') {
+ code = Qt::Key_Tab;
+ if (modifs == Qt::ShiftModifier)
+ code = Qt::Key_Backtab;
+ s = QString();
+ } else if (code == 127) {
+ code = Qt::Key_Backspace;
+ if (modifs == Qt::AltModifier)
+ modifs = Qt::ControlModifier;
+ s = QString();
+ } else if (code == 'o' && modifs == Qt::ControlModifier) {
+ s = QLatin1String("\n");
+ code = '\n';
+ modifs = 0;
+ } else if (code == 'y' && modifs == Qt::ControlModifier) {
+ s = QLatin1String("c");
+ code = 'c';
+ } else if (code == 'k' && modifs == Qt::ControlModifier) {
+ s = QLatin1String("x");
+ code = 'x';
+ } else if (code == 'a' && modifs == Qt::ControlModifier) {
+ s = QString();
+ code = Qt::Key_Home;
+ modifs = 0;
+ } else if (code == 0xf702) {
+ s = QString();
+ code = Qt::Key_Left;
+ if (modifs & Qt::MetaModifier) {
+ code = Qt::Key_Home;
+ modifs &= ~Qt::MetaModifier;
+ }
+ } else if (code == 0xf703) {
+ s = QString();
+ code = Qt::Key_Right;
+ if (modifs & Qt::MetaModifier) {
+ code = Qt::Key_End;
+ modifs &= ~Qt::MetaModifier;
+ }
+ } else if (code == 'a' && modifs == Qt::ControlModifier) {
+ s = QString();
+ code = Qt::Key_Home;
+ modifs = 0;
+ } else {
+ code = string.unicode()->toUpper().unicode();
+ }
+ }
+ QKeyEvent event(QEvent::KeyPress, code, modifs, s);
+ QApplication::sendEvent(m_page, &event);
+}
+
+QWebFrame *EventSender::frameUnderMouse() const
+{
+ QWebFrame *frame = m_page->mainFrame();
+
+redo:
+ QList<QWebFrame*> children = frame->childFrames();
+ for (int i = 0; i < children.size(); ++i) {
+ if (children.at(i)->geometry().contains(m_mousePos)) {
+ frame = children.at(i);
+ goto redo;
+ }
+ }
+ if (frame->geometry().contains(m_mousePos))
+ return frame;
+ return 0;
+}
+
+
+TextInputController::TextInputController(QWebPage *parent)
+ : QObject(parent)
+{
+}
+
+void TextInputController::doCommand(const QString &command)
+{
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+ int keycode = 0;
+ if (command == "moveBackwardAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveDown:") {
+ keycode = Qt::Key_Down;
+ } else if(command =="moveDownAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Down;
+ } else if(command =="moveForward:") {
+ keycode = Qt::Key_Right;
+ } else if(command =="moveForwardAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveLeft:") {
+ keycode = Qt::Key_Left;
+ } else if(command =="moveLeftAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveRight:") {
+ keycode = Qt::Key_Right;
+ } else if(command =="moveRightAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveToBeginningOfDocument:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Home;
+ } else if(command =="moveToBeginningOfLine:") {
+ keycode = Qt::Key_Home;
+// } else if(command =="moveToBeginningOfParagraph:") {
+ } else if(command =="moveToEndOfDocument:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_End;
+ } else if(command =="moveToEndOfLine:") {
+ keycode = Qt::Key_End;
+// } else if(command =="moveToEndOfParagraph:") {
+ } else if(command =="moveUp:") {
+ keycode = Qt::Key_Up;
+ } else if(command =="moveUpAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Up;
+ } else if(command =="moveWordBackward:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Up;
+ } else if(command =="moveWordBackwardAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveWordForward:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveWordForwardAndModifySelection:") {
+ modifiers |= Qt::ControlModifier;
+ modifiers |= Qt::ShiftModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveWordLeft:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveWordRight:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="moveWordRightAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Right;
+ } else if(command =="moveWordLeftAndModifySelection:") {
+ modifiers |= Qt::ShiftModifier;
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Left;
+ } else if(command =="pageDown:") {
+ keycode = Qt::Key_PageDown;
+ } else if(command =="pageUp:") {
+ keycode = Qt::Key_PageUp;
+ } else if(command == "deleteWordBackward:") {
+ modifiers |= Qt::ControlModifier;
+ keycode = Qt::Key_Backspace;
+ } else if(command == "deleteBackward:") {
+ keycode = Qt::Key_Backspace;
+ } else if(command == "deleteForward:") {
+ keycode = Qt::Key_Delete;
+ }
+ QKeyEvent event(QEvent::KeyPress, keycode, modifiers);
+ QApplication::sendEvent(parent(), &event);
+ QKeyEvent event2(QEvent::KeyRelease, keycode, modifiers);
+ QApplication::sendEvent(parent(), &event2);
+}
diff --git a/WebKitTools/DumpRenderTree/qt/jsobjects.h b/WebKitTools/DumpRenderTree/qt/jsobjects.h
new file mode 100644
index 0000000..4ee6439
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/jsobjects.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 JSOBJECTS_H
+#define JSOBJECTS_H
+
+#include <qobject.h>
+#include <qdebug.h>
+#include <qpoint.h>
+#include <qstringlist.h>
+
+class QWebFrame;
+namespace WebCore {
+ class DumpRenderTree;
+}
+class LayoutTestController : public QObject
+{
+ Q_OBJECT
+public:
+ LayoutTestController(WebCore::DumpRenderTree *drt);
+
+ bool isLoading() const { return m_isLoading; }
+ void setLoading(bool loading) { m_isLoading = loading; }
+
+ bool shouldDumpAsText() const { return m_textDump; }
+ bool shouldDumpChildrenAsText() const { return m_dumpChildrenAsText; }
+ bool shouldWaitUntilDone() const { return m_waitForDone; }
+ bool canOpenWindows() const { return m_canOpenWindows; }
+ bool shouldDumpTitleChanges() const { return m_dumpTitleChanges; }
+
+ void reset();
+
+protected:
+ void timerEvent(QTimerEvent *);
+
+signals:
+ void done();
+
+public slots:
+ void maybeDump(bool ok);
+ void dumpAsText() { m_textDump = true; }
+ void dumpChildFramesAsText() { m_dumpChildrenAsText = true; }
+ void setCanOpenWindows() { m_canOpenWindows = true; }
+ void waitUntilDone();
+ void notifyDone();
+ void dumpEditingCallbacks();
+ void dumpResourceLoadCallbacks();
+ void queueReload();
+ void provisionalLoad();
+ void setCloseRemainingWindowsWhenComplete(bool=false) {}
+ int windowCount();
+ void display() {}
+ void clearBackForwardList();
+ void dumpTitleChanges() { m_dumpTitleChanges = true; }
+ QString encodeHostName(const QString &host);
+ QString decodeHostName(const QString &host);
+ void dumpSelectionRect() const {}
+
+private:
+ bool m_isLoading;
+ bool m_textDump;
+ bool m_dumpChildrenAsText;
+ bool m_canOpenWindows;
+ bool m_waitForDone;
+ bool m_dumpTitleChanges;
+ int m_timeoutTimer;
+ QWebFrame *m_topLoadingFrame;
+ WebCore::DumpRenderTree *m_drt;
+};
+
+class QWebPage;
+class QWebFrame;
+
+class EventSender : public QObject
+{
+ Q_OBJECT
+public:
+ EventSender(QWebPage *parent);
+
+public slots:
+ void mouseDown();
+ void mouseUp();
+ void mouseMoveTo(int x, int y);
+ void leapForward(int ms);
+ void keyDown(const QString &string, const QStringList &modifiers=QStringList());
+ void clearKillRing() {}
+
+private:
+ QPoint m_mousePos;
+ QWebPage *m_page;
+ int m_timeLeap;
+ QWebFrame *frameUnderMouse() const;
+};
+
+class TextInputController : public QObject
+{
+ Q_OBJECT
+public:
+ TextInputController(QWebPage *parent);
+
+public slots:
+ void doCommand(const QString &command);
+// void setMarkedText(const QString &str, int from, int length);
+// bool hasMarkedText();
+// void unmarkText();
+// QList<int> markedRange();
+// QList<int> selectedRange();
+// void validAttributesForMarkedText();
+// void inserText(const QString &);
+// void firstRectForCharacterRange();
+// void characterIndexForPoint(int, int);
+// void substringFromRange(int, int);
+// void conversationIdentifier();
+};
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/qt/main.cpp b/WebKitTools/DumpRenderTree/qt/main.cpp
new file mode 100644
index 0000000..8c4bc9c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/main.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 "DumpRenderTree.h"
+
+#include <qstringlist.h>
+#include <qapplication.h>
+#include <qurl.h>
+#include <qdir.h>
+#include <qdebug.h>
+#include <qfont.h>
+
+#ifdef Q_WS_X11
+#include <qx11info_x11.h>
+#include <fontconfig/fontconfig.h>
+#endif
+
+#include <limits.h>
+#include <signal.h>
+
+#if defined(__GLIBC__)
+#include <execinfo.h>
+#endif
+
+void messageHandler(QtMsgType type, const char *message)
+{
+ if (type == QtCriticalMsg) {
+ fprintf(stderr, "%s\n", message);
+ return;
+ }
+ // do nothing
+}
+
+QString get_backtrace() {
+ QString s;
+
+#if defined(__GLIBC__)
+ void* array[256];
+ size_t size; /* number of stack frames */
+
+ size = backtrace(array, 256);
+
+ if (!size)
+ return s;
+
+ char** strings = backtrace_symbols(array, size);
+ for (int i = 0; i < size; ++i) {
+ s += QString::number(i) +
+ QLatin1String(": ") +
+ QLatin1String(strings[i]) + QLatin1String("\n");
+ }
+
+ if (strings)
+ free (strings);
+#endif
+
+ return s;
+}
+
+static void crashHandler(int sig)
+{
+ fprintf(stderr, "%s\n", strsignal(sig));
+ fprintf(stderr, "%s\n", get_backtrace().toLatin1().constData());
+ exit(128 + sig);
+}
+
+int main(int argc, char* argv[])
+{
+#ifdef Q_WS_X11
+ FcInit();
+ FcConfig *config = FcConfigCreate();
+ QByteArray fontDir = getenv("WEBKIT_TESTFONTS");
+ if (fontDir.isEmpty() || !QDir(fontDir).exists()) {
+ fprintf(stderr,
+ "\n\n"
+ "--------------------------------------------------------------------\n"
+ "WEBKIT_TESTFONTS environment variable is not set correctly.\n"
+ "This variable has to point to the directory containing the fonts\n"
+ "you can checkout from svn://labs.trolltech.com/svn/webkit/testfonts\n"
+ "--------------------------------------------------------------------\n"
+);
+ exit(1);
+ }
+ char currentPath[PATH_MAX+1];
+ getcwd(currentPath, PATH_MAX);
+ QByteArray configFile = currentPath;
+ configFile += "/WebKitTools/DumpRenderTree/qt/fonts.conf";
+ if (!FcConfigParseAndLoad (config, (FcChar8*) configFile.data(), true))
+ qFatal("Couldn't load font configuration file");
+ if (!FcConfigAppFontAddDir (config, (FcChar8*) fontDir.data()))
+ qFatal("Couldn't add font dir!");
+ FcConfigSetCurrent(config);
+#endif
+ QApplication app(argc, argv);
+#ifdef Q_WS_X11
+ QX11Info::setAppDpiY(0, 96);
+ QX11Info::setAppDpiX(0, 96);
+#endif
+
+ QFont f("Sans Serif");
+ f.setPointSize(9);
+ f.setWeight(QFont::Normal);
+ f.setStyle(QFont::StyleNormal);
+ app.setFont(f);
+ app.setStyle(QLatin1String("Plastique"));
+
+
+ signal(SIGILL, crashHandler); /* 4: illegal instruction (not reset when caught) */
+ signal(SIGTRAP, crashHandler); /* 5: trace trap (not reset when caught) */
+ signal(SIGFPE, crashHandler); /* 8: floating point exception */
+ signal(SIGBUS, crashHandler); /* 10: bus error */
+ signal(SIGSEGV, crashHandler); /* 11: segmentation violation */
+ signal(SIGSYS, crashHandler); /* 12: bad argument to system call */
+ signal(SIGPIPE, crashHandler); /* 13: write on a pipe with no reader */
+ signal(SIGXCPU, crashHandler); /* 24: exceeded CPU time limit */
+ signal(SIGXFSZ, crashHandler); /* 25: exceeded file size limit */
+
+ QStringList args = app.arguments();
+ if (args.count() < 2) {
+ qDebug() << "Usage: DumpRenderTree [-v] filename";
+ exit(0);
+ }
+
+ // supress debug output from Qt if not started with -v
+ if (!args.contains(QLatin1String("-v")))
+ qInstallMsgHandler(messageHandler);
+
+ WebCore::DumpRenderTree dumper;
+
+ if (args.last() == QLatin1String("-")) {
+ dumper.open();
+ } else {
+ if (!args.last().startsWith("/")
+ && !args.last().startsWith("file:")
+ && !args.last().startsWith("http:")
+ && !args.last().startsWith("https:")) {
+ QString path = QDir::currentPath();
+ if (!path.endsWith('/'))
+ path.append('/');
+ args.last().prepend(path);
+ }
+ dumper.open(QUrl(args.last()));
+ }
+ return app.exec();
+#ifdef Q_WS_X11
+ FcConfigSetCurrent(0);
+#endif
+}
diff --git a/WebKitTools/DumpRenderTree/qt/testplugin.cpp b/WebKitTools/DumpRenderTree/qt/testplugin.cpp
new file mode 100644
index 0000000..54431e9
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/testplugin.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 "testplugin.h"
+
+TestPlugin::TestPlugin(QObject *parent)
+ : QWebPluginFactory(parent)
+{
+}
+
+TestPlugin::~TestPlugin()
+{
+}
+
+QList<QWebPluginFactory::Plugin> TestPlugin::plugins() const
+{
+ QWebPluginFactory::Plugin plugin;
+
+ plugin.name = "testplugin";
+ plugin.description = "testdescription";
+ MimeType mimeType;
+ mimeType.name = "testtype";
+ mimeType.fileExtensions.append("testsuffixes");
+ plugin.mimeTypes.append(mimeType);
+
+ plugin.name = "testplugin2";
+ plugin.description = "testdescription2";
+ mimeType.name = "testtype2";
+ mimeType.fileExtensions.append("testsuffixes2");
+ mimeType.fileExtensions.append("testsuffixes3");
+ plugin.mimeTypes.append(mimeType);
+
+ return QList<QWebPluginFactory::Plugin>() << plugin;
+}
+
+QObject *TestPlugin::create(const QString &mimeType,
+ const QUrl &url,
+ const QStringList &argumentNames,
+ const QStringList &argumentValues) const
+{
+ return 0;
+}
+
diff --git a/WebKitTools/DumpRenderTree/qt/testplugin.h b/WebKitTools/DumpRenderTree/qt/testplugin.h
new file mode 100644
index 0000000..3d8a28c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/qt/testplugin.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 <qwebpluginfactory.h>
+
+
+class TestPlugin : public QWebPluginFactory
+{
+public:
+ explicit TestPlugin(QObject *parent = 0);
+ virtual ~TestPlugin();
+
+ virtual QList<Plugin> plugins() const;
+
+ virtual QObject *create(const QString &mimeType,
+ const QUrl &url,
+ const QStringList &argumentNames,
+ const QStringList &argumentValues) const;
+
+};
+
diff --git a/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp b/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp
new file mode 100644
index 0000000..b6e45f2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 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. ``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"
+
+#include "AccessibilityUIElement.h"
+#include "DumpRenderTree.h"
+#include <JavaScriptCore/Assertions.h>
+#include <WebCore/COMPtr.h>
+#include <WebKit/WebKit.h>
+#include <oleacc.h>
+
+AccessibilityController::AccessibilityController()
+{
+}
+
+AccessibilityController::~AccessibilityController()
+{
+}
+
+AccessibilityUIElement AccessibilityController::focusedElement()
+{
+ COMPtr<IAccessible> rootAccessible = rootElement().platformUIElement();
+
+ VARIANT vFocus;
+ if (FAILED(rootAccessible->get_accFocus(&vFocus)))
+ return 0;
+
+ if (V_VT(&vFocus) == VT_I4) {
+ ASSERT(V_I4(&vFocus) == CHILDID_SELF);
+ // The root accessible object is the focused object.
+ return rootAccessible;
+ }
+
+ ASSERT(V_VT(&vFocus) == VT_DISPATCH);
+ // We have an IDispatch; query for IAccessible.
+ return COMPtr<IAccessible>(Query, V_DISPATCH(&vFocus));
+}
+
+AccessibilityUIElement AccessibilityController::rootElement()
+{
+ COMPtr<IWebView> view;
+ if (FAILED(frame->webView(&view)))
+ return 0;
+
+ COMPtr<IWebViewPrivate> viewPrivate(Query, view);
+ if (!viewPrivate)
+ return 0;
+
+ HWND webViewWindow;
+ if (FAILED(viewPrivate->viewWindow((OLE_HANDLE*)&webViewWindow)))
+ return 0;
+
+ // Get the root accessible object by querying for the accessible object for the
+ // WebView's window.
+ COMPtr<IAccessible> rootAccessible;
+ if (FAILED(AccessibleObjectFromWindow(webViewWindow, static_cast<DWORD>(OBJID_CLIENT), __uuidof(IAccessible), reinterpret_cast<void**>(&rootAccessible))))
+ return 0;
+
+ return rootAccessible;
+}
diff --git a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
new file mode 100644
index 0000000..d835bb3
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2008 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. ``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"
+
+#include <JavaScriptCore/JSStringRef.h>
+#include <tchar.h>
+#include <string>
+
+using std::wstring;
+
+AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
+ : m_element(element)
+{
+}
+
+AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
+ : m_element(other.m_element)
+{
+}
+
+AccessibilityUIElement::~AccessibilityUIElement()
+{
+}
+
+void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>&)
+{
+}
+
+void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>&)
+{
+}
+
+void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& children)
+{
+ long childCount;
+ if (FAILED(m_element->get_accChildCount(&childCount)))
+ return;
+ for (long i = 0; i < childCount; ++i)
+ children.append(getChildAtIndex(i));
+}
+
+AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
+{
+ COMPtr<IDispatch> child;
+ VARIANT vChild;
+ ::VariantInit(&vChild);
+ V_VT(&vChild) = VT_I4;
+ // In MSAA, index 0 is the object itself.
+ V_I4(&vChild) = index + 1;
+ if (FAILED(m_element->get_accChild(vChild, &child)))
+ return 0;
+ return COMPtr<IAccessible>(Query, child);
+}
+
+JSStringRef AccessibilityUIElement::allAttributes()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+AccessibilityUIElement AccessibilityUIElement::titleUIElement()
+{
+ return 0;
+}
+
+JSStringRef AccessibilityUIElement::attributesOfChildren()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+static VARIANT& self()
+{
+ static VARIANT vSelf;
+ static bool haveInitialized;
+
+ if (!haveInitialized) {
+ ::VariantInit(&vSelf);
+ V_VT(&vSelf) = VT_I4;
+ V_I4(&vSelf) = CHILDID_SELF;
+ }
+ return vSelf;
+}
+
+JSStringRef AccessibilityUIElement::role()
+{
+ VARIANT vRole;
+ if (FAILED(m_element->get_accRole(self(), &vRole)))
+ return JSStringCreateWithCharacters(0, 0);
+ ASSERT(V_VT(&vRole) == VT_I4);
+ TCHAR roleText[64] = {0};
+ ::GetRoleText(V_I4(&vRole), roleText, ARRAYSIZE(roleText));
+ return JSStringCreateWithCharacters(roleText, _tcslen(roleText));
+}
+
+JSStringRef AccessibilityUIElement::title()
+{
+ BSTR titleBSTR;
+ if (FAILED(m_element->get_accName(self(), &titleBSTR)) || !titleBSTR)
+ return JSStringCreateWithCharacters(0, 0);
+ wstring title(titleBSTR, SysStringLen(titleBSTR));
+ ::SysFreeString(titleBSTR);
+ return JSStringCreateWithCharacters(title.data(), title.length());
+}
+
+JSStringRef AccessibilityUIElement::description()
+{
+ BSTR descriptionBSTR;
+ if (FAILED(m_element->get_accName(self(), &descriptionBSTR)) || !descriptionBSTR)
+ return JSStringCreateWithCharacters(0, 0);
+ wstring description(descriptionBSTR, SysStringLen(descriptionBSTR));
+ ::SysFreeString(descriptionBSTR);
+ return JSStringCreateWithCharacters(description.data(), description.length());
+}
+
+double AccessibilityUIElement::width()
+{
+ long x, y, width, height;
+ if (FAILED(m_element->accLocation(&x, &y, &width, &height, self())))
+ return 0;
+ return width;
+}
+
+double AccessibilityUIElement::height()
+{
+ long x, y, width, height;
+ if (FAILED(m_element->accLocation(&x, &y, &width, &height, self())))
+ return 0;
+ return height;
+}
+
+double AccessibilityUIElement::intValue()
+{
+ BSTR valueBSTR;
+ if (FAILED(m_element->get_accValue(self(), &valueBSTR)) || !valueBSTR)
+ return 0;
+ wstring value(valueBSTR, SysStringLen(valueBSTR));
+ ::SysFreeString(valueBSTR);
+ TCHAR* ignored;
+ return _tcstod(value.data(), &ignored);
+}
+
+double AccessibilityUIElement::minValue()
+{
+ return 0;
+}
+
+double AccessibilityUIElement::maxValue()
+{
+ return 0;
+}
+
+bool AccessibilityUIElement::supportsPressAction()
+{
+ return false;
+}
+
+int AccessibilityUIElement::insertionPointLineNumber()
+{
+ return 0;
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumns()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRows()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfHeader()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+int AccessibilityUIElement::indexInTable()
+{
+ return 0;
+}
+
+JSStringRef AccessibilityUIElement::rowIndexRange()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+JSStringRef AccessibilityUIElement::columnIndexRange()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+int AccessibilityUIElement::lineForIndex(int)
+{
+ return 0;
+}
+
+JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row)
+{
+ return 0;
+}
+
+JSStringRef AccessibilityUIElement::selectedTextRange()
+{
+ return JSStringCreateWithCharacters(0, 0);
+}
+
+void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
+{
+}
diff --git a/WebKitTools/DumpRenderTree/win/DraggingInfo.h b/WebKitTools/DumpRenderTree/win/DraggingInfo.h
new file mode 100644
index 0000000..2ead457
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/DraggingInfo.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 DraggingInfo_h
+#define DraggingInfo_h
+
+#include <objidl.h>
+
+class DraggingInfo {
+public:
+ DraggingInfo(IDataObject* object, IDropSource* source)
+ : m_object(object)
+ , m_source(source)
+ {
+ m_object->AddRef();
+ m_source->AddRef();
+ }
+
+ ~DraggingInfo()
+ {
+ if (m_object)
+ m_object->Release();
+ m_object = 0;
+ if (m_source)
+ m_source->Release();
+ m_source = 0;
+ }
+
+ IDataObject* dataObject() const { return m_object; }
+ IDropSource* dropSource() const { return m_source; }
+
+private:
+ IDataObject* m_object;
+ IDropSource* m_source;
+};
+
+#endif // !defined(DraggingInfo_h)
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
new file mode 100644
index 0000000..b3b73a9
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
@@ -0,0 +1,1127 @@
+/*
+ * Copyright (C) 2005, 2006, 2007, 2008 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.
+ * 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 "EditingDelegate.h"
+#include "FrameLoadDelegate.h"
+#include "LayoutTestController.h"
+#include "PixelDumpSupport.h"
+#include "PolicyDelegate.h"
+#include "ResourceLoadDelegate.h"
+#include "UIDelegate.h"
+#include "WorkQueueItem.h"
+#include "WorkQueue.h"
+
+#include <fcntl.h>
+#include <io.h>
+#include <math.h>
+#include <pthread.h>
+#include <shlwapi.h>
+#include <stdio.h>
+#include <string.h>
+#include <tchar.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <windows.h>
+#include <CFNetwork/CFURLCachePriv.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <WebCore/COMPtr.h>
+#include <WebKit/ForEachCoClass.h>
+#include <WebKit/WebKit.h>
+
+using namespace std;
+
+#ifndef NDEBUG
+const LPWSTR TestPluginDir = L"TestNetscapePlugin_Debug";
+#else
+const LPWSTR TestPluginDir = L"TestNetscapePlugin";
+#endif
+
+static LPCWSTR fontsEnvironmentVariable = L"WEBKIT_TESTFONTS";
+#define USE_MAC_FONTS
+
+const LPCWSTR kDumpRenderTreeClassName = L"DumpRenderTreeWindow";
+
+static bool dumpTree = true;
+static bool dumpPixels;
+static bool dumpAllPixels;
+static bool printSeparators;
+static bool leakChecking = false;
+static bool threaded = false;
+static bool forceComplexText = false;
+static RetainPtr<CFStringRef> persistentUserStyleSheetLocation;
+
+volatile bool done;
+// This is the topmost frame that is loading, during a given load, or nil when no load is
+// in progress. Usually this is the same as the main frame, but not always. In the case
+// where a frameset is loaded, and then new content is loaded into one of the child frames,
+// that child frame is the "topmost frame that is loading".
+IWebFrame* topLoadingFrame; // !nil iff a load is in progress
+static COMPtr<IWebHistoryItem> prevTestBFItem; // current b/f item at the end of the previous test
+IWebPolicyDelegate* policyDelegate;
+COMPtr<FrameLoadDelegate> sharedFrameLoadDelegate;
+COMPtr<UIDelegate> sharedUIDelegate;
+COMPtr<EditingDelegate> sharedEditingDelegate;
+COMPtr<ResourceLoadDelegate> sharedResourceLoadDelegate;
+
+IWebFrame* frame;
+HWND webViewWindow;
+
+LayoutTestController* gLayoutTestController = 0;
+CFRunLoopTimerRef waitToDumpWatchdog = 0;
+
+const unsigned maxViewWidth = 800;
+const unsigned maxViewHeight = 600;
+
+void setPersistentUserStyleSheetLocation(CFStringRef url)
+{
+ persistentUserStyleSheetLocation = url;
+}
+
+wstring urlSuitableForTestResult(const wstring& url)
+{
+ if (!url.c_str() || url.find(L"file://") == wstring::npos)
+ return url;
+
+ return PathFindFileNameW(url.c_str());
+}
+
+static LRESULT CALLBACK DumpRenderTreeWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_DESTROY:
+ for (unsigned i = openWindows().size() - 1; i >= 0; --i) {
+ if (openWindows()[i] == hWnd) {
+ openWindows().remove(i);
+ windowToWebViewMap().remove(hWnd);
+ break;
+ }
+ }
+ return 0;
+ break;
+ default:
+ return DefWindowProc(hWnd, msg, wParam, lParam);
+ }
+}
+
+static const wstring& exePath()
+{
+ static wstring path;
+ static bool initialized;
+
+ if (initialized)
+ return path;
+ initialized = true;
+
+ TCHAR buffer[MAX_PATH];
+ GetModuleFileName(GetModuleHandle(0), buffer, ARRAYSIZE(buffer));
+ path = buffer;
+ int lastSlash = path.rfind('\\');
+ if (lastSlash != -1 && lastSlash + 1 < path.length())
+ path = path.substr(0, lastSlash + 1);
+
+ return path;
+}
+
+static const wstring& fontsPath()
+{
+ static wstring path;
+ static bool initialized;
+
+ if (initialized)
+ return path;
+ initialized = true;
+
+ DWORD size = GetEnvironmentVariable(fontsEnvironmentVariable, 0, 0);
+ Vector<TCHAR> buffer(size);
+ if (GetEnvironmentVariable(fontsEnvironmentVariable, buffer.data(), buffer.size())) {
+ path = buffer.data();
+ if (path[path.length() - 1] != '\\')
+ path.append(L"\\");
+ return path;
+ }
+
+ path = exePath() + TEXT("DumpRenderTree.resources\\");
+ return path;
+}
+
+#ifdef DEBUG_WEBKIT_HAS_SUFFIX
+#define WEBKITDLL TEXT("WebKit_debug.dll")
+#else
+#define WEBKITDLL TEXT("WebKit.dll")
+#endif
+
+static void initialize()
+{
+ if (HMODULE webKitModule = LoadLibrary(WEBKITDLL))
+ if (FARPROC dllRegisterServer = GetProcAddress(webKitModule, "DllRegisterServer"))
+ dllRegisterServer();
+
+ // Init COM
+ OleInitialize(0);
+
+ static LPCTSTR fontsToInstall[] = {
+ TEXT("AHEM____.ttf"),
+ TEXT("Apple Chancery.ttf"),
+ TEXT("Courier Bold.ttf"),
+ TEXT("Courier.ttf"),
+ TEXT("Helvetica Bold Oblique.ttf"),
+ TEXT("Helvetica Bold.ttf"),
+ TEXT("Helvetica Oblique.ttf"),
+ TEXT("Helvetica.ttf"),
+ TEXT("Helvetica Neue Bold Italic.ttf"),
+ TEXT("Helvetica Neue Bold.ttf"),
+ TEXT("Helvetica Neue Condensed Black.ttf"),
+ TEXT("Helvetica Neue Condensed Bold.ttf"),
+ TEXT("Helvetica Neue Italic.ttf"),
+ TEXT("Helvetica Neue Light Italic.ttf"),
+ TEXT("Helvetica Neue Light.ttf"),
+ TEXT("Helvetica Neue UltraLight Italic.ttf"),
+ TEXT("Helvetica Neue UltraLight.ttf"),
+ TEXT("Helvetica Neue.ttf"),
+ TEXT("Lucida Grande.ttf"),
+ TEXT("Lucida Grande Bold.ttf"),
+ TEXT("Monaco.ttf"),
+ TEXT("Papyrus.ttf"),
+ TEXT("Times Bold Italic.ttf"),
+ TEXT("Times Bold.ttf"),
+ TEXT("Times Italic.ttf"),
+ TEXT("Times Roman.ttf"),
+ TEXT("WebKit Layout Tests.ttf"),
+ TEXT("WebKitWeightWatcher100.ttf"),
+ TEXT("WebKitWeightWatcher200.ttf"),
+ TEXT("WebKitWeightWatcher300.ttf"),
+ TEXT("WebKitWeightWatcher400.ttf"),
+ TEXT("WebKitWeightWatcher500.ttf"),
+ TEXT("WebKitWeightWatcher600.ttf"),
+ TEXT("WebKitWeightWatcher700.ttf"),
+ TEXT("WebKitWeightWatcher800.ttf"),
+ TEXT("WebKitWeightWatcher900.ttf")
+ };
+
+ wstring resourcesPath = fontsPath();
+
+ COMPtr<IWebTextRenderer> textRenderer;
+ if (SUCCEEDED(CoCreateInstance(CLSID_WebTextRenderer, 0, CLSCTX_ALL, IID_IWebTextRenderer, (void**)&textRenderer)))
+ for (int i = 0; i < ARRAYSIZE(fontsToInstall); ++i)
+ textRenderer->registerPrivateFont(wstring(resourcesPath + fontsToInstall[i]).c_str());
+
+ // Register a host window
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = DumpRenderTreeWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = GetModuleHandle(0);
+ wcex.hIcon = 0;
+ wcex.hCursor = LoadCursor(0, IDC_ARROW);
+ wcex.hbrBackground = 0;
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = kDumpRenderTreeClassName;
+ wcex.hIconSm = 0;
+
+ RegisterClassEx(&wcex);
+}
+
+void displayWebView()
+{
+ ::InvalidateRect(webViewWindow, 0, TRUE);
+ ::UpdateWindow(webViewWindow);
+}
+
+void dumpFrameScrollPosition(IWebFrame* frame)
+{
+ if (!frame)
+ return;
+
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (FAILED(frame->QueryInterface(&framePrivate)))
+ return;
+
+ SIZE scrollPosition;
+ if (FAILED(framePrivate->scrollOffset(&scrollPosition)))
+ return;
+
+ if (abs(scrollPosition.cx) > 0.00000001 || abs(scrollPosition.cy) > 0.00000001) {
+ COMPtr<IWebFrame> parent;
+ if (FAILED(frame->parentFrame(&parent)))
+ return;
+ if (parent) {
+ BSTR name;
+ if (FAILED(frame->name(&name)))
+ return;
+ printf("frame '%S' ", name ? name : L"");
+ SysFreeString(name);
+ }
+ printf("scrolled to %.f,%.f\n", (double)scrollPosition.cx, (double)scrollPosition.cy);
+ }
+
+ if (::gLayoutTestController->dumpChildFrameScrollPositions()) {
+ COMPtr<IEnumVARIANT> enumKids;
+ if (FAILED(frame->childFrames(&enumKids)))
+ return;
+ VARIANT var;
+ VariantInit(&var);
+ while (enumKids->Next(1, &var, 0) == S_OK) {
+ ASSERT(V_VT(&var) == VT_UNKNOWN);
+ COMPtr<IWebFrame> framePtr;
+ V_UNKNOWN(&var)->QueryInterface(IID_IWebFrame, (void**)&framePtr);
+ dumpFrameScrollPosition(framePtr.get());
+ VariantClear(&var);
+ }
+ }
+}
+
+static wstring dumpFramesAsText(IWebFrame* frame)
+{
+ if (!frame)
+ return L"";
+
+ COMPtr<IDOMDocument> document;
+ if (FAILED(frame->DOMDocument(&document)))
+ return L"";
+
+ COMPtr<IDOMElement> documentElement;
+ if (FAILED(document->documentElement(&documentElement)))
+ return L"";
+
+ wstring result;
+
+ // Add header for all but the main frame.
+ COMPtr<IWebFrame> parent;
+ if (FAILED(frame->parentFrame(&parent)))
+ return L"";
+ if (parent) {
+ BSTR name = L"";
+ if (FAILED(frame->name(&name)))
+ return L"";
+
+ result.append(L"\n--------\nFrame: '");
+ result.append(name ? name : L"", SysStringLen(name));
+ result.append(L"'\n--------\n");
+
+ SysFreeString(name);
+ }
+
+ BSTR innerText = 0;
+ COMPtr<IDOMElementPrivate> docPrivate;
+ if (SUCCEEDED(documentElement->QueryInterface(&docPrivate)))
+ docPrivate->innerText(&innerText);
+
+ result.append(innerText ? innerText : L"", SysStringLen(innerText));
+ result.append(L"\n");
+
+ SysFreeString(innerText);
+
+ if (::gLayoutTestController->dumpChildFramesAsText()) {
+ COMPtr<IEnumVARIANT> enumKids;
+ if (FAILED(frame->childFrames(&enumKids)))
+ return L"";
+ VARIANT var;
+ VariantInit(&var);
+ while (enumKids->Next(1, &var, 0) == S_OK) {
+ ASSERT(V_VT(&var) == VT_UNKNOWN);
+ COMPtr<IWebFrame> framePtr;
+ V_UNKNOWN(&var)->QueryInterface(IID_IWebFrame, (void**)&framePtr);
+ result.append(dumpFramesAsText(framePtr.get()));
+ VariantClear(&var);
+ }
+ }
+
+ return result;
+}
+
+static int compareHistoryItems(const void* item1, const void* item2)
+{
+ COMPtr<IWebHistoryItemPrivate> itemA;
+ if (FAILED((*(COMPtr<IUnknown>*)item1)->QueryInterface(&itemA)))
+ return 0;
+
+ COMPtr<IWebHistoryItemPrivate> itemB;
+ if (FAILED((*(COMPtr<IUnknown>*)item2)->QueryInterface(&itemB)))
+ return 0;
+
+ BSTR targetA;
+ if (FAILED(itemA->target(&targetA)))
+ return 0;
+
+ BSTR targetB;
+ if (FAILED(itemB->target(&targetB))) {
+ SysFreeString(targetA);
+ return 0;
+ }
+
+ int result = wcsicmp(wstring(targetA, SysStringLen(targetA)).c_str(), wstring(targetB, SysStringLen(targetB)).c_str());
+ SysFreeString(targetA);
+ SysFreeString(targetB);
+ return result;
+}
+
+static void dumpHistoryItem(IWebHistoryItem* item, int indent, bool current)
+{
+ assert(item);
+
+ int start = 0;
+ if (current) {
+ printf("curr->");
+ start = 6;
+ }
+ for (int i = start; i < indent; i++)
+ putchar(' ');
+
+ BSTR url;
+ if (FAILED(item->URLString(&url)))
+ return;
+ printf("%S", url ? url : L"");
+ SysFreeString(url);
+
+ COMPtr<IWebHistoryItemPrivate> itemPrivate;
+ if (FAILED(item->QueryInterface(&itemPrivate)))
+ return;
+
+ BSTR target;
+ if (FAILED(itemPrivate->target(&target)))
+ return;
+ if (SysStringLen(target))
+ printf(" (in frame \"%S\")", target);
+ SysFreeString(target);
+ BOOL isTargetItem = FALSE;
+ if (FAILED(itemPrivate->isTargetItem(&isTargetItem)))
+ return;
+ if (isTargetItem)
+ printf(" **nav target**");
+ putchar('\n');
+
+ unsigned kidsCount;
+ SAFEARRAY* arrPtr;
+ if (FAILED(itemPrivate->children(&kidsCount, &arrPtr)) || !kidsCount)
+ return;
+
+ Vector<COMPtr<IUnknown> > kidsVector;
+
+ LONG lowerBound;
+ if (FAILED(::SafeArrayGetLBound(arrPtr, 1, &lowerBound)))
+ goto exit;
+
+ LONG upperBound;
+ if (FAILED(::SafeArrayGetUBound(arrPtr, 1, &upperBound)))
+ goto exit;
+
+ LONG length = upperBound - lowerBound + 1;
+ if (!length)
+ goto exit;
+ ASSERT(length == kidsCount);
+
+ IUnknown** safeArrayData;
+ if (FAILED(::SafeArrayAccessData(arrPtr, (void**)&safeArrayData)))
+ goto exit;
+
+ for (int i = 0; i < length; ++i)
+ kidsVector.append(safeArrayData[i]);
+ ::SafeArrayUnaccessData(arrPtr);
+
+ // must sort to eliminate arbitrary result ordering which defeats reproducible testing
+ qsort(kidsVector.data(), kidsCount, sizeof(kidsVector[0]), compareHistoryItems);
+
+ for (unsigned i = 0; i < kidsCount; ++i) {
+ COMPtr<IWebHistoryItem> item;
+ kidsVector[i]->QueryInterface(&item);
+ dumpHistoryItem(item.get(), indent + 4, false);
+ }
+
+exit:
+ if (arrPtr && SUCCEEDED(::SafeArrayUnlock(arrPtr)))
+ ::SafeArrayDestroy(arrPtr);
+}
+
+static void dumpBackForwardList(IWebView* webView)
+{
+ ASSERT(webView);
+
+ printf("\n============== Back Forward List ==============\n");
+
+ COMPtr<IWebBackForwardList> bfList;
+ if (FAILED(webView->backForwardList(&bfList)))
+ return;
+
+ // 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
+
+ Vector<COMPtr<IUnknown> > itemsToPrint;
+
+ int forwardListCount;
+ if (FAILED(bfList->forwardListCount(&forwardListCount)))
+ return;
+
+ for (int i = forwardListCount; i > 0; --i) {
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(bfList->itemAtIndex(i, &item)))
+ return;
+ // something is wrong if the item from the last test is in the forward part of the b/f list
+ assert(item != prevTestBFItem);
+ COMPtr<IUnknown> itemUnknown;
+ item->QueryInterface(&itemUnknown);
+ itemsToPrint.append(itemUnknown);
+ }
+
+ COMPtr<IWebHistoryItem> currentItem;
+ if (FAILED(bfList->currentItem(&currentItem)))
+ return;
+
+ assert(currentItem != prevTestBFItem);
+ COMPtr<IUnknown> currentItemUnknown;
+ currentItem->QueryInterface(&currentItemUnknown);
+ itemsToPrint.append(currentItemUnknown);
+ int currentItemIndex = itemsToPrint.size() - 1;
+
+ int backListCount;
+ if (FAILED(bfList->backListCount(&backListCount)))
+ return;
+
+ for (int i = -1; i >= -backListCount; --i) {
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(bfList->itemAtIndex(i, &item)))
+ return;
+ if (item == prevTestBFItem)
+ break;
+ COMPtr<IUnknown> itemUnknown;
+ item->QueryInterface(&itemUnknown);
+ itemsToPrint.append(itemUnknown);
+ }
+
+ for (int i = itemsToPrint.size() - 1; i >= 0; --i) {
+ COMPtr<IWebHistoryItem> historyItemToPrint;
+ itemsToPrint[i]->QueryInterface(&historyItemToPrint);
+ dumpHistoryItem(historyItemToPrint.get(), 8, i == currentItemIndex);
+ }
+
+ printf("===============================================\n");
+}
+
+static void dumpBackForwardListForAllWindows()
+{
+ unsigned count = openWindows().size();
+ for (unsigned i = 0; i < count; i++) {
+ HWND window = openWindows()[i];
+ IWebView* webView = windowToWebViewMap().get(window);
+ dumpBackForwardList(webView);
+ }
+}
+
+void dump()
+{
+ COMPtr<IWebDataSource> dataSource;
+ if (SUCCEEDED(frame->dataSource(&dataSource))) {
+ COMPtr<IWebURLResponse> response;
+ if (SUCCEEDED(dataSource->response(&response)) && response) {
+ BSTR mimeType;
+ if (SUCCEEDED(response->MIMEType(&mimeType)))
+ ::gLayoutTestController->setDumpAsText(::gLayoutTestController->dumpAsText() | !_tcscmp(mimeType, TEXT("text/plain")));
+ SysFreeString(mimeType);
+ }
+ }
+
+ BSTR resultString = 0;
+
+ if (dumpTree) {
+ if (::gLayoutTestController->dumpAsText()) {
+ ::InvalidateRect(webViewWindow, 0, TRUE);
+ ::SendMessage(webViewWindow, WM_PAINT, 0, 0);
+ wstring result = dumpFramesAsText(frame);
+ resultString = SysAllocStringLen(result.data(), result.size());
+ } else {
+ bool isSVGW3CTest = (gLayoutTestController->testPathOrURL().find("svg\\W3C-SVG-1.1") != string::npos);
+ unsigned width;
+ unsigned height;
+ if (isSVGW3CTest) {
+ width = 480;
+ height = 360;
+ } else {
+ width = maxViewWidth;
+ height = maxViewHeight;
+ }
+
+ ::SetWindowPos(webViewWindow, 0, 0, 0, width, height, SWP_NOMOVE);
+ ::InvalidateRect(webViewWindow, 0, TRUE);
+ ::SendMessage(webViewWindow, WM_PAINT, 0, 0);
+
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (FAILED(frame->QueryInterface(&framePrivate)))
+ goto fail;
+ framePrivate->renderTreeAsExternalRepresentation(&resultString);
+ }
+
+ if (!resultString)
+ printf("ERROR: nil result from %s", ::gLayoutTestController->dumpAsText() ? "IDOMElement::innerText" : "IFrameViewPrivate::renderTreeAsExternalRepresentation");
+ else {
+ unsigned stringLength = SysStringLen(resultString);
+ int bufferSize = ::WideCharToMultiByte(CP_UTF8, 0, resultString, stringLength, 0, 0, 0, 0);
+ char* buffer = (char*)malloc(bufferSize + 1);
+ ::WideCharToMultiByte(CP_UTF8, 0, resultString, stringLength, buffer, bufferSize + 1, 0, 0);
+ fwrite(buffer, 1, bufferSize, stdout);
+ free(buffer);
+ if (!::gLayoutTestController->dumpAsText())
+ dumpFrameScrollPosition(frame);
+ }
+ if (::gLayoutTestController->dumpBackForwardList())
+ dumpBackForwardListForAllWindows();
+ }
+
+ if (printSeparators) {
+ puts("#EOF"); // terminate the content block
+ fputs("#EOF\n", stderr);
+ fflush(stdout);
+ fflush(stderr);
+ }
+
+ if (dumpPixels) {
+ if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive())
+ dumpWebViewAsPixelsAndCompareWithExpected(gLayoutTestController->expectedPixelHash());
+ }
+
+ printf("#EOF\n"); // terminate the (possibly empty) pixels block
+ fflush(stdout);
+
+fail:
+ SysFreeString(resultString);
+ // This will exit from our message loop
+ PostQuitMessage(0);
+ done = true;
+}
+
+static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
+{
+ return strstr(pathOrURL, "loading/");
+}
+
+static void resetWebViewToConsistentStateBeforeTesting()
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ webView->setPolicyDelegate(0);
+
+ COMPtr<IWebIBActions> webIBActions(Query, webView);
+ if (webIBActions) {
+ webIBActions->makeTextStandardSize(0);
+ webIBActions->resetPageZoom(0);
+ }
+
+ COMPtr<IWebPreferences> preferences;
+ if (SUCCEEDED(webView->preferences(&preferences))) {
+ preferences->setPrivateBrowsingEnabled(FALSE);
+ preferences->setJavaScriptCanOpenWindowsAutomatically(TRUE);
+
+ if (persistentUserStyleSheetLocation) {
+ Vector<wchar_t> urlCharacters(CFStringGetLength(persistentUserStyleSheetLocation.get()));
+ CFStringGetCharacters(persistentUserStyleSheetLocation.get(), CFRangeMake(0, CFStringGetLength(persistentUserStyleSheetLocation.get())), (UniChar *)urlCharacters.data());
+ BSTR url = SysAllocStringLen(urlCharacters.data(), urlCharacters.size());
+ preferences->setUserStyleSheetLocation(url);
+ SysFreeString(url);
+ preferences->setUserStyleSheetEnabled(TRUE);
+ } else
+ preferences->setUserStyleSheetEnabled(FALSE);
+
+ COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
+ if (prefsPrivate) {
+ prefsPrivate->setAuthorAndUserStylesEnabled(TRUE);
+ prefsPrivate->setDeveloperExtrasEnabled(FALSE);
+ }
+ }
+
+ COMPtr<IWebViewEditing> viewEditing;
+ if (SUCCEEDED(webView->QueryInterface(&viewEditing)))
+ viewEditing->setSmartInsertDeleteEnabled(TRUE);
+
+ COMPtr<IWebViewPrivate> webViewPrivate(Query, webView);
+ if (!webViewPrivate)
+ return;
+
+ COMPtr<IWebInspector> inspector;
+ if (SUCCEEDED(webViewPrivate->inspector(&inspector)))
+ inspector->setJavaScriptProfilingEnabled(FALSE);
+
+ HWND viewWindow;
+ if (SUCCEEDED(webViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))) && viewWindow)
+ SetFocus(viewWindow);
+
+ webViewPrivate->clearMainFrameName();
+}
+
+static void runTest(const string& testPathOrURL)
+{
+ static BSTR methodBStr = SysAllocString(TEXT("GET"));
+
+ // Look for "'" as a separator between the path or URL, and the pixel dump hash that follows.
+ string pathOrURL(testPathOrURL);
+ string expectedPixelHash;
+
+ size_t separatorPos = pathOrURL.find("'");
+ if (separatorPos != string::npos) {
+ pathOrURL = string(testPathOrURL, 0, separatorPos);
+ expectedPixelHash = string(testPathOrURL, separatorPos + 1);
+ }
+
+ BSTR urlBStr;
+
+ CFStringRef str = CFStringCreateWithCString(0, pathOrURL.c_str(), kCFStringEncodingWindowsLatin1);
+ CFURLRef url = CFURLCreateWithString(0, str, 0);
+
+ if (!url)
+ url = CFURLCreateWithFileSystemPath(0, str, kCFURLWindowsPathStyle, false);
+
+ CFRelease(str);
+
+ str = CFURLGetString(url);
+
+ CFIndex length = CFStringGetLength(str);
+ UniChar* buffer = new UniChar[length];
+
+ CFStringGetCharacters(str, CFRangeMake(0, length), buffer);
+ urlBStr = SysAllocStringLen((OLECHAR*)buffer, length);
+ delete[] buffer;
+
+ CFRelease(url);
+
+ ::gLayoutTestController = new LayoutTestController(pathOrURL, expectedPixelHash);
+ done = false;
+ topLoadingFrame = 0;
+
+ if (shouldLogFrameLoadDelegates(pathOrURL.c_str()))
+ gLayoutTestController->setDumpFrameLoadCallbacks(true);
+
+ COMPtr<IWebHistory> history(Create, CLSID_WebHistory);
+ if (history)
+ history->setOptionalSharedHistory(0);
+
+ resetWebViewToConsistentStateBeforeTesting();
+ sharedUIDelegate->resetUndoManager();
+
+ prevTestBFItem = 0;
+ COMPtr<IWebView> webView;
+ if (SUCCEEDED(frame->webView(&webView))) {
+ COMPtr<IWebBackForwardList> bfList;
+ if (SUCCEEDED(webView->backForwardList(&bfList)))
+ bfList->currentItem(&prevTestBFItem);
+ }
+
+ WorkQueue::shared()->clear();
+ WorkQueue::shared()->setFrozen(false);
+
+ HWND hostWindow;
+ webView->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
+
+ COMPtr<IWebMutableURLRequest> request;
+ HRESULT hr = CoCreateInstance(CLSID_WebMutableURLRequest, 0, CLSCTX_ALL, IID_IWebMutableURLRequest, (void**)&request);
+ if (FAILED(hr))
+ goto exit;
+
+ request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 60);
+
+ request->setHTTPMethod(methodBStr);
+ frame->loadRequest(request.get());
+
+ MSG msg;
+ while (GetMessage(&msg, 0, 0, 0)) {
+ // We get spurious WM_MOUSELEAVE events which make event handling machinery think that mouse button
+ // is released during dragging (see e.g. fast\dynamic\layer-hit-test-crash.html).
+ // Mouse can never leave WebView during normal DumpRenderTree operation, so we just ignore all such events.
+ if (msg.message == WM_MOUSELEAVE)
+ continue;
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ frame->stopLoading();
+
+ if (::gLayoutTestController->closeRemainingWindowsWhenComplete()) {
+ Vector<HWND> windows = openWindows();
+ unsigned size = windows.size();
+ for (unsigned i = 0; i < size; i++) {
+ HWND window = windows[i];
+
+ // Don't try to close the main window
+ if (window == hostWindow)
+ continue;
+
+ DestroyWindow(window);
+ }
+ }
+
+exit:
+ SysFreeString(urlBStr);
+ ::gLayoutTestController->deref();
+ ::gLayoutTestController = 0;
+
+ return;
+}
+
+static void initializePreferences(IWebPreferences* preferences)
+{
+#ifdef USE_MAC_FONTS
+ BSTR standardFamily = SysAllocString(TEXT("Times"));
+ BSTR fixedFamily = SysAllocString(TEXT("Courier"));
+ BSTR sansSerifFamily = SysAllocString(TEXT("Helvetica"));
+ BSTR cursiveFamily = SysAllocString(TEXT("Apple Chancery"));
+ BSTR fantasyFamily = SysAllocString(TEXT("Papyrus"));
+#else
+ BSTR standardFamily = SysAllocString(TEXT("Times New Roman"));
+ BSTR fixedFamily = SysAllocString(TEXT("Courier New"));
+ BSTR sansSerifFamily = SysAllocString(TEXT("Arial"));
+ BSTR cursiveFamily = SysAllocString(TEXT("Comic Sans MS")); // Not actually cursive, but it's what IE and Firefox use.
+ BSTR fantasyFamily = SysAllocString(TEXT("Times New Roman"));
+#endif
+
+ preferences->setStandardFontFamily(standardFamily);
+ preferences->setFixedFontFamily(fixedFamily);
+ preferences->setSerifFontFamily(standardFamily);
+ preferences->setSansSerifFontFamily(sansSerifFamily);
+ preferences->setCursiveFontFamily(cursiveFamily);
+ preferences->setFantasyFontFamily(fantasyFamily);
+
+ preferences->setAutosaves(FALSE);
+ preferences->setJavaEnabled(FALSE);
+ preferences->setPlugInsEnabled(TRUE);
+ preferences->setDOMPasteAllowed(TRUE);
+ preferences->setEditableLinkBehavior(WebKitEditableLinkOnlyLiveWithShiftKey);
+ preferences->setFontSmoothing(FontSmoothingTypeStandard);
+ preferences->setUsesPageCache(FALSE);
+
+ SysFreeString(standardFamily);
+ SysFreeString(fixedFamily);
+ SysFreeString(sansSerifFamily);
+ SysFreeString(cursiveFamily);
+ SysFreeString(fantasyFamily);
+}
+
+static Boolean pthreadEqualCallback(const void* value1, const void* value2)
+{
+ return (Boolean)pthread_equal(*(pthread_t*)value1, *(pthread_t*)value2);
+}
+
+static CFDictionaryKeyCallBacks pthreadKeyCallbacks = { 0, 0, 0, 0, pthreadEqualCallback, 0 };
+
+static pthread_mutex_t javaScriptThreadsMutex = PTHREAD_MUTEX_INITIALIZER;
+static bool javaScriptThreadsShouldTerminate;
+
+static const int javaScriptThreadsCount = 4;
+static CFMutableDictionaryRef javaScriptThreads()
+{
+ assert(pthread_mutex_trylock(&javaScriptThreadsMutex) == EBUSY);
+ static CFMutableDictionaryRef staticJavaScriptThreads;
+ if (!staticJavaScriptThreads)
+ staticJavaScriptThreads = CFDictionaryCreateMutable(0, 0, &pthreadKeyCallbacks, 0);
+ return staticJavaScriptThreads;
+}
+
+// Loops forever, running a script and randomly respawning, until
+// javaScriptThreadsShouldTerminate becomes true.
+void* runJavaScriptThread(void* arg)
+{
+ const char* const script =
+ " \
+ var array = []; \
+ for (var i = 0; i < 10; i++) { \
+ array.push(String(i)); \
+ } \
+ ";
+
+ while (true) {
+ JSGlobalContextRef ctx = JSGlobalContextCreate(0);
+ JSStringRef scriptRef = JSStringCreateWithUTF8CString(script);
+
+ JSValueRef exception = 0;
+ JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception);
+ assert(!exception);
+
+ JSGlobalContextRelease(ctx);
+ JSStringRelease(scriptRef);
+
+ JSGarbageCollect(ctx);
+
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ // Check for cancellation.
+ if (javaScriptThreadsShouldTerminate) {
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ return 0;
+ }
+
+ // Respawn probabilistically.
+ if (rand() % 5 == 0) {
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_detach(pthread);
+
+ pthread_t self = pthread_self();
+ CFDictionaryRemoveValue(javaScriptThreads(), self.p);
+ CFDictionaryAddValue(javaScriptThreads(), pthread.p, 0);
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ return 0;
+ }
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+ }
+}
+
+static void startJavaScriptThreads(void)
+{
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ for (int i = 0; i < javaScriptThreadsCount; i++) {
+ pthread_t pthread;
+ pthread_create(&pthread, 0, &runJavaScriptThread, 0);
+ pthread_detach(pthread);
+ CFDictionaryAddValue(javaScriptThreads(), pthread.p, 0);
+ }
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+}
+
+static void stopJavaScriptThreads(void)
+{
+ pthread_mutex_lock(&javaScriptThreadsMutex);
+
+ javaScriptThreadsShouldTerminate = true;
+
+ pthread_t* pthreads[javaScriptThreadsCount] = {0};
+ int threadDictCount = CFDictionaryGetCount(javaScriptThreads());
+ assert(threadDictCount == javaScriptThreadsCount);
+ CFDictionaryGetKeysAndValues(javaScriptThreads(), (const void**)pthreads, 0);
+
+ pthread_mutex_unlock(&javaScriptThreadsMutex);
+
+ for (int i = 0; i < javaScriptThreadsCount; i++) {
+ pthread_t* pthread = pthreads[i];
+ pthread_join(*pthread, 0);
+ free(pthread);
+ }
+}
+
+Vector<HWND>& openWindows()
+{
+ static Vector<HWND> vector;
+ return vector;
+}
+
+HashMap<HWND, IWebView*>& windowToWebViewMap()
+{
+ static HashMap<HWND, IWebView*> map;
+ return map;
+}
+
+IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow)
+{
+ HWND hostWindow = CreateWindowEx(WS_EX_TOOLWINDOW, kDumpRenderTreeClassName, TEXT("DumpRenderTree"), WS_POPUP,
+ -maxViewWidth, -maxViewHeight, maxViewWidth, maxViewHeight, 0, 0, GetModuleHandle(0), 0);
+
+ IWebView* webView;
+
+ HRESULT hr = CoCreateInstance(CLSID_WebView, 0, CLSCTX_ALL, IID_IWebView, (void**)&webView);
+ if (FAILED(hr)) {
+ fprintf(stderr, "Failed to create CLSID_WebView instance, error 0x%x\n", hr);
+ return 0;
+ }
+
+ if (FAILED(webView->setHostWindow((OLE_HANDLE)(ULONG64)hostWindow)))
+ return 0;
+
+ RECT clientRect;
+ clientRect.bottom = clientRect.left = clientRect.top = clientRect.right = 0;
+ BSTR groupName = SysAllocString(L"org.webkit.DumpRenderTree");
+ bool failed = FAILED(webView->initWithFrame(clientRect, 0, groupName));
+ SysFreeString(groupName);
+ if (failed)
+ return 0;
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (FAILED(webView->QueryInterface(&viewPrivate)))
+ return 0;
+
+ viewPrivate->setShouldApplyMacFontAscentHack(TRUE);
+ viewPrivate->setAlwaysUsesComplexTextCodePath(forceComplexText);
+
+ BSTR pluginPath = SysAllocStringLen(0, exePath().length() + _tcslen(TestPluginDir));
+ _tcscpy(pluginPath, exePath().c_str());
+ _tcscat(pluginPath, TestPluginDir);
+ failed = FAILED(viewPrivate->addAdditionalPluginDirectory(pluginPath));
+ SysFreeString(pluginPath);
+ if (failed)
+ return 0;
+
+ HWND viewWindow;
+ if (FAILED(viewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ return 0;
+ if (webViewWindow)
+ *webViewWindow = viewWindow;
+
+ SetWindowPos(viewWindow, 0, 0, 0, maxViewWidth, maxViewHeight, 0);
+ ShowWindow(hostWindow, SW_SHOW);
+
+ if (FAILED(webView->setFrameLoadDelegate(sharedFrameLoadDelegate.get())))
+ return 0;
+
+ if (FAILED(viewPrivate->setFrameLoadDelegatePrivate(sharedFrameLoadDelegate.get())))
+ return 0;
+
+ if (FAILED(webView->setUIDelegate(sharedUIDelegate.get())))
+ return 0;
+
+ COMPtr<IWebViewEditing> viewEditing;
+ if (FAILED(webView->QueryInterface(&viewEditing)))
+ return 0;
+
+ if (FAILED(viewEditing->setEditingDelegate(sharedEditingDelegate.get())))
+ return 0;
+
+ if (FAILED(webView->setResourceLoadDelegate(sharedResourceLoadDelegate.get())))
+ return 0;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return 0;
+
+ initializePreferences(preferences.get());
+
+ openWindows().append(hostWindow);
+ windowToWebViewMap().set(hostWindow, webView);
+ return webView;
+}
+
+int main(int argc, char* argv[])
+{
+ leakChecking = false;
+
+ _setmode(1, _O_BINARY);
+ _setmode(2, _O_BINARY);
+
+ initialize();
+
+ Vector<const char*> tests;
+
+ for (int i = 1; i < argc; ++i) {
+ if (!stricmp(argv[i], "--threaded")) {
+ threaded = true;
+ continue;
+ }
+
+ if (!stricmp(argv[i], "--dump-all-pixels")) {
+ dumpAllPixels = true;
+ continue;
+ }
+
+ if (!stricmp(argv[i], "--pixel-tests")) {
+ dumpPixels = true;
+ continue;
+ }
+
+ if (!stricmp(argv[i], "--complex-text")) {
+ forceComplexText = true;
+ continue;
+ }
+
+ tests.append(argv[i]);
+ }
+
+ policyDelegate = new PolicyDelegate();
+ sharedFrameLoadDelegate.adoptRef(new FrameLoadDelegate);
+ sharedUIDelegate.adoptRef(new UIDelegate);
+ sharedEditingDelegate.adoptRef(new EditingDelegate);
+ sharedResourceLoadDelegate.adoptRef(new ResourceLoadDelegate);
+
+ COMPtr<IWebView> webView(AdoptCOM, createWebViewAndOffscreenWindow(&webViewWindow));
+ if (!webView)
+ return -1;
+
+ COMPtr<IWebIconDatabase> iconDatabase;
+ COMPtr<IWebIconDatabase> tmpIconDatabase;
+ if (FAILED(CoCreateInstance(CLSID_WebIconDatabase, 0, CLSCTX_ALL, IID_IWebIconDatabase, (void**)&tmpIconDatabase)))
+ return -1;
+ if (FAILED(tmpIconDatabase->sharedIconDatabase(&iconDatabase)))
+ return -1;
+
+ if (FAILED(webView->mainFrame(&frame)))
+ return -1;
+
+ CFURLCacheRemoveAllCachedResponses(CFURLCacheSharedURLCache());
+
+#ifdef _DEBUG
+ _CrtMemState entryToMainMemCheckpoint;
+ if (leakChecking)
+ _CrtMemCheckpoint(&entryToMainMemCheckpoint);
+#endif
+
+ if (threaded)
+ startJavaScriptThreads();
+
+ if (tests.size() == 1 && !strcmp(tests[0], "-")) {
+ char filenameBuffer[2048];
+ printSeparators = true;
+ while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
+ char* newLineCharacter = strchr(filenameBuffer, '\n');
+ if (newLineCharacter)
+ *newLineCharacter = '\0';
+
+ if (strlen(filenameBuffer) == 0)
+ continue;
+
+ runTest(filenameBuffer);
+ }
+ } else {
+ printSeparators = tests.size() > 1;
+ for (int i = 0; i < tests.size(); i++)
+ runTest(tests[i]);
+ }
+
+ if (threaded)
+ stopJavaScriptThreads();
+
+ delete policyDelegate;
+ frame->Release();
+
+#ifdef _DEBUG
+ if (leakChecking) {
+ // dump leaks to stderr
+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+ _CrtMemDumpAllObjectsSince(&entryToMainMemCheckpoint);
+ }
+#endif
+
+ shutDownWebKit();
+
+ return 0;
+}
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
new file mode 100644
index 0000000..e094bde
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
@@ -0,0 +1,411 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="DumpRenderTree"
+ ProjectGUID="{6567DFD4-D6DE-4CD5-825D-17E353D160E1}"
+ RootNamespace="DumpRenderTree"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)\.&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)\..\cg&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\DumpRenderTree\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitOutputDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ PreprocessorDefinitions="_CONSOLE"
+ DisableSpecificWarnings="4146"
+ ForcedIncludeFiles="DumpRenderTreePrefix.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib WTF$(WebKitConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib"
+ AdditionalLibraryDirectories=""
+ DelayLoadDLLs=""
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ TypeLibraryFile="$(WebKitOutputDir)\lib\WebKit.tlb"
+ ComponentFileName="WebKit$(WebKitDLLConfigSuffix)"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;if &quot;$(ARCHIVE_BUILD)&quot;==&quot;&quot; (if not &quot;$(PRODUCTION)&quot;==&quot;&quot; exit /b)&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if not exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; exit /b&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CFNetwork.resources&quot; &quot;$(WebKitOutputDir)\bin\CFNetwork.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\dnssd.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)\.&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)\..\cg&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\DumpRenderTree\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitOutputDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ PreprocessorDefinitions="_CONSOLE"
+ DisableSpecificWarnings="4146"
+ ForcedIncludeFiles="DumpRenderTreePrefix.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib WTF$(WebKitConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib"
+ AdditionalLibraryDirectories=""
+ DelayLoadDLLs=""
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ TypeLibraryFile="$(WebKitOutputDir)\lib\WebKit.tlb"
+ ComponentFileName="WebKit$(WebKitDLLConfigSuffix)"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;if &quot;$(ARCHIVE_BUILD)&quot;==&quot;&quot; (if not &quot;$(PRODUCTION)&quot;==&quot;&quot; exit /b)&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if not exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; exit /b&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CFNetwork.resources&quot; &quot;$(WebKitOutputDir)\bin\CFNetwork.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\dnssd.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_Internal|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)\.&quot;;&quot;$(ProjectDir)\..&quot;;&quot;$(ProjectDir)\..\cg&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\DumpRenderTree\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitOutputDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ PreprocessorDefinitions="_CONSOLE;DEBUG_WEBKIT_HAS_SUFFIX"
+ DisableSpecificWarnings="4146"
+ ForcedIncludeFiles="DumpRenderTreePrefix.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WebKitGUID$(WebKitConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib WTF$(WebKitConfigSuffix).lib CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib gdi32.lib ole32.lib oleaut32.lib user32.lib shlwapi.lib oleacc.lib"
+ AdditionalLibraryDirectories=""
+ DelayLoadDLLs=""
+ SubSystem="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ TypeLibraryFile="$(WebKitOutputDir)\lib\WebKit.tlb"
+ ComponentFileName="WebKit$(WebKitDLLConfigSuffix)"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;if &quot;$(ARCHIVE_BUILD)&quot;==&quot;&quot; (if not &quot;$(PRODUCTION)&quot;==&quot;&quot; exit /b)&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if not exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; exit /b&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CFNetwork.resources&quot; &quot;$(WebKitOutputDir)\bin\CFNetwork.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\dnssd.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Controllers"
+ >
+ <File
+ RelativePath="..\AccessibilityController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\AccessibilityController.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AccessibilityControllerWin.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\EventSender.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\EventSender.h"
+ >
+ </File>
+ <File
+ RelativePath="..\GCController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\GCController.h"
+ >
+ </File>
+ <File
+ RelativePath=".\GCControllerWin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\LayoutTestController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\LayoutTestController.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LayoutTestControllerWin.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Delegates"
+ >
+ <File
+ RelativePath=".\EditingDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\EditingDelegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\FrameLoadDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\FrameLoadDelegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\PolicyDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\PolicyDelegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ResourceLoadDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ResourceLoadDelegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\UIDelegate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\UIDelegate.h"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\AccessibilityUIElement.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\AccessibilityUIElement.h"
+ >
+ </File>
+ <File
+ RelativePath=".\AccessibilityUIElementWin.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\DraggingInfo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\DumpRenderTree.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\DumpRenderTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\DumpRenderTreePrefix.h"
+ >
+ </File>
+ <File
+ RelativePath=".\DumpRenderTreeWin.h"
+ >
+ </File>
+ <File
+ RelativePath=".\MD5.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\MD5.h"
+ >
+ </File>
+ <File
+ RelativePath=".\PixelDumpSupport.h"
+ >
+ </File>
+ <File
+ RelativePath="..\cg\PixelDumpSupportCG.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\cg\PixelDumpSupportCG.h"
+ >
+ </File>
+ <File
+ RelativePath=".\PixelDumpSupportWin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\WorkQueue.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\WorkQueue.h"
+ >
+ </File>
+ <File
+ RelativePath="..\WorkQueueItem.h"
+ >
+ </File>
+ <File
+ RelativePath=".\WorkQueueItemWin.cpp"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h
new file mode 100644
index 0000000..45ce0dc
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006, 2007 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.
+ * 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 DumpRenderTreeWin_h
+#define DumpRenderTreeWin_h
+
+struct IWebFrame;
+struct IWebPolicyDelegate;
+struct IWebView;
+typedef const struct __CFString* CFStringRef;
+typedef struct HWND__* HWND;
+
+extern IWebFrame* topLoadingFrame;
+extern IWebFrame* frame;
+extern IWebPolicyDelegate* policyDelegate;
+
+extern HWND webViewWindow;
+
+#include <string>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+std::wstring urlSuitableForTestResult(const std::wstring& url);
+IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow = 0);
+Vector<HWND>& openWindows();
+HashMap<HWND, IWebView*>& windowToWebViewMap();
+
+void setPersistentUserStyleSheetLocation(CFStringRef);
+
+#endif // DumpRenderTreeWin_h
diff --git a/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp b/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp
new file mode 100644
index 0000000..32c02bd
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 "EditingDelegate.h"
+
+#include "DumpRenderTree.h"
+#include "LayoutTestController.h"
+#include <WebCore/COMPtr.h>
+#include <wtf/Platform.h>
+#include <JavaScriptCore/Assertions.h>
+#include <string>
+#include <tchar.h>
+
+using std::wstring;
+
+EditingDelegate::EditingDelegate()
+ : m_refCount(1)
+ , m_acceptsEditing(true)
+{
+}
+
+// IUnknown
+HRESULT STDMETHODCALLTYPE EditingDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebEditingDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebEditingDelegate))
+ *ppvObject = static_cast<IWebEditingDelegate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE EditingDelegate::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE EditingDelegate::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete this;
+
+ return newRef;
+}
+
+static wstring dumpPath(IDOMNode* node)
+{
+ ASSERT(node);
+
+ wstring result;
+
+ BSTR name;
+ if (FAILED(node->nodeName(&name)))
+ return result;
+ result.assign(name, SysStringLen(name));
+ SysFreeString(name);
+
+ COMPtr<IDOMNode> parent;
+ if (SUCCEEDED(node->parentNode(&parent)))
+ result += TEXT(" > ") + dumpPath(parent.get());
+
+ return result;
+}
+
+static wstring dump(IDOMRange* range)
+{
+ ASSERT(range);
+
+ int startOffset;
+ if (FAILED(range->startOffset(&startOffset)))
+ return 0;
+
+ int endOffset;
+ if (FAILED(range->endOffset(&endOffset)))
+ return 0;
+
+ COMPtr<IDOMNode> startContainer;
+ if (FAILED(range->startContainer(&startContainer)))
+ return 0;
+
+ COMPtr<IDOMNode> endContainer;
+ if (FAILED(range->endContainer(&endContainer)))
+ return 0;
+
+ wchar_t buffer[1024];
+ _snwprintf(buffer, ARRAYSIZE(buffer), L"range from %ld of %s to %ld of %s", startOffset, dumpPath(startContainer.get()), endOffset, dumpPath(endContainer.get()));
+ return buffer;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldBeginEditingInDOMRange(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMRange* range,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n"), dump(range));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldEndEditingInDOMRange(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMRange* range,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n"), dump(range));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertNode(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMNode* node,
+ /* [in] */ IDOMRange* range,
+ /* [in] */ WebViewInsertAction action)
+{
+ static LPCTSTR insertactionstring[] = {
+ TEXT("WebViewInsertActionTyped"),
+ TEXT("WebViewInsertActionPasted"),
+ TEXT("WebViewInsertActionDropped"),
+ };
+
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n"), dumpPath(node), dump(range), insertactionstring[action]);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertText(
+ /* [in] */ IWebView* webView,
+ /* [in] */ BSTR text,
+ /* [in] */ IDOMRange* range,
+ /* [in] */ WebViewInsertAction action,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ static LPCTSTR insertactionstring[] = {
+ TEXT("WebViewInsertActionTyped"),
+ TEXT("WebViewInsertActionPasted"),
+ TEXT("WebViewInsertActionDropped"),
+ };
+
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n"), text ? text : TEXT(""), dump(range), insertactionstring[action]);
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldDeleteDOMRange(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMRange* range,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldDeleteDOMRange:%s\n"), dump(range));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeSelectedDOMRange(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMRange* currentRange,
+ /* [in] */ IDOMRange* proposedRange,
+ /* [in] */ WebSelectionAffinity selectionAffinity,
+ /* [in] */ BOOL stillSelecting,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ static LPCTSTR affinitystring[] = {
+ TEXT("NSSelectionAffinityUpstream"),
+ TEXT("NSSelectionAffinityDownstream")
+ };
+ static LPCTSTR boolstring[] = {
+ TEXT("FALSE"),
+ TEXT("TRUE")
+ };
+
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n"), dump(currentRange), dump(proposedRange), affinitystring[selectionAffinity], boolstring[stillSelecting]);
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldApplyStyle(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMCSSStyleDeclaration* style,
+ /* [in] */ IDOMRange* range,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n"), TEXT("'style description'")/*[[style description] UTF8String]*/, dump(range));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeTypingStyle(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IDOMCSSStyleDeclaration* currentStyle,
+ /* [in] */ IDOMCSSStyleDeclaration* proposedStyle,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: shouldChangeTypingStyle:%s toStyle:%s\n"), TEXT("'currentStyle description'"), TEXT("'proposedStyle description'"));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::doPlatformCommand(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR command,
+ /* [retval][out] */ BOOL *result)
+{
+ if (!result) {
+ ASSERT_NOT_REACHED();
+ return E_POINTER;
+ }
+
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done)
+ _tprintf(TEXT("EDITING DELEGATE: doPlatformCommand:%s\n"), command ? command : TEXT(""));
+
+ *result = m_acceptsEditing;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidBeginEditing(
+ /* [in] */ IWebNotification* notification)
+{
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChange(
+ /* [in] */ IWebNotification *notification)
+{
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidEndEditing(
+ /* [in] */ IWebNotification *notification)
+{
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidEndEditing:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeTypingStyle(
+ /* [in] */ IWebNotification *notification)
+{
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeTypingStyle:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeSelection(
+ /* [in] */ IWebNotification *notification)
+{
+ if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
+ BSTR name;
+ notification->name(&name);
+ _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeSelection:%s\n"), name ? name : TEXT(""));
+ SysFreeString(name);
+ }
+ return S_OK;
+}
diff --git a/WebKitTools/DumpRenderTree/win/EditingDelegate.h b/WebKitTools/DumpRenderTree/win/EditingDelegate.h
new file mode 100644
index 0000000..6dba675
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/EditingDelegate.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 EditingDelegate_h
+#define EditingDelegate_h
+
+#include <WebKit/WebKit.h>
+
+class __declspec(uuid("265DCD4B-79C3-44a2-84BC-511C3EDABD6F")) EditingDelegate : public IWebEditingDelegate {
+public:
+ EditingDelegate();
+
+ void setAcceptsEditing(bool b) { m_acceptsEditing = b; }
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebEditingDelegate
+ virtual HRESULT STDMETHODCALLTYPE shouldBeginEditingInDOMRange(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMRange *range,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldEndEditingInDOMRange(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMRange *range,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldInsertNode(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMNode *node,
+ /* [in] */ IDOMRange *range,
+ /* [in] */ WebViewInsertAction action);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldInsertText(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR text,
+ /* [in] */ IDOMRange *range,
+ /* [in] */ WebViewInsertAction action,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldDeleteDOMRange(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMRange *range,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldChangeSelectedDOMRange(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMRange *currentRange,
+ /* [in] */ IDOMRange *proposedRange,
+ /* [in] */ WebSelectionAffinity selectionAffinity,
+ /* [in] */ BOOL stillSelecting,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldApplyStyle(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMCSSStyleDeclaration *style,
+ /* [in] */ IDOMRange *range,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE shouldChangeTypingStyle(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDOMCSSStyleDeclaration *currentStyle,
+ /* [in] */ IDOMCSSStyleDeclaration *proposedStyle,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE doPlatformCommand(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR command,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidBeginEditing(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidChange(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidEndEditing(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidChangeTypingStyle(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDidChangeSelection(
+ /* [in] */ IWebNotification *notification);
+
+ virtual HRESULT STDMETHODCALLTYPE undoManagerForWebView(
+ /* [in] */ IWebView *webView,
+ /* [retval][out] */ IWebUndoManager **undoManager) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE ignoreWordInSpellDocument(
+ /* [in] */ IWebView *view,
+ /* [in] */ BSTR word) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE learnWord(
+ /* [in] */ BSTR word) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE checkSpellingOfString(
+ /* [in] */ IWebView *view,
+ /* [in] */ LPCTSTR text,
+ /* [in] */ int length,
+ /* [out] */ int *misspellingLocation,
+ /* [out] */ int *misspellingLength) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE checkGrammarOfString(
+ /* [in] */ IWebView *view,
+ /* [in] */ LPCTSTR text,
+ /* [in] */ int length,
+ /* [out] */ IEnumWebGrammarDetails **grammarDetails,
+ /* [out] */ int *badGrammarLocation,
+ /* [out] */ int *badGrammarLength) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE updateSpellingUIWithGrammarString(
+ /* [in] */ BSTR string,
+ /* [in] */ int location,
+ /* [in] */ int length,
+ /* [in] */ BSTR userDescription,
+ /* [in] */ BSTR *guesses,
+ /* [in] */ int guessesCount) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE updateSpellingUIWithMisspelledWord(
+ /* [in] */ BSTR word) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE showSpellingUI(
+ /* [in] */ BOOL show) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE spellingUIIsShowing(
+ /* [retval][out] */ BOOL *result) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE guessesForWord(
+ /* [in] */ BSTR word,
+ /* [retval][out] */ IEnumSpellingGuesses **guesses) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE closeSpellDocument(
+ /* [in] */ IWebView *view) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE sharedSpellCheckerExists(
+ /* [retval][out] */ BOOL *exists) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE preflightChosenSpellServer( void) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE updateGrammar( void) { return E_NOTIMPL; }
+
+private:
+ bool m_acceptsEditing;
+ ULONG m_refCount;
+};
+
+#endif // !defined(EditingDelegate_h)
diff --git a/WebKitTools/DumpRenderTree/win/EventSender.cpp b/WebKitTools/DumpRenderTree/win/EventSender.cpp
new file mode 100644
index 0000000..efecc03
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/EventSender.cpp
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2007, 2008 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.
+ * 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 "DraggingInfo.h"
+#include "DumpRenderTree.h"
+
+#include <WebCore/COMPtr.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/Platform.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <JavaScriptCore/Assertions.h>
+#include <WebKit/WebKit.h>
+#include <windows.h>
+
+#define WM_DRT_SEND_QUEUED_EVENT (WM_APP+1)
+
+static bool down;
+static bool dragMode = true;
+static bool replayingSavedEvents;
+static int timeOffset;
+static POINT lastMousePosition;
+
+struct DelayedMessage {
+ MSG msg;
+ unsigned delay;
+};
+
+static DelayedMessage msgQueue[1024];
+static unsigned endOfQueue;
+static unsigned startOfQueue;
+
+static bool didDragEnter;
+DraggingInfo* draggingInfo = 0;
+
+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 getConstantCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_KEYDOWN"))
+ return JSValueMakeNumber(context, WM_KEYDOWN);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_KEYUP"))
+ return JSValueMakeNumber(context, WM_KEYUP);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_CHAR"))
+ return JSValueMakeNumber(context, WM_CHAR);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_DEADCHAR"))
+ return JSValueMakeNumber(context, WM_DEADCHAR);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSKEYDOWN"))
+ return JSValueMakeNumber(context, WM_SYSKEYDOWN);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSKEYUP"))
+ return JSValueMakeNumber(context, WM_SYSKEYUP);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSCHAR"))
+ return JSValueMakeNumber(context, WM_SYSCHAR);
+ if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSDEADCHAR"))
+ return JSValueMakeNumber(context, WM_SYSDEADCHAR);
+ ASSERT_NOT_REACHED();
+ return JSValueMakeUndefined(context);
+}
+
+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);
+ ASSERT(!exception || !*exception);
+ }
+
+ return JSValueMakeUndefined(context);
+}
+
+static DWORD currentEventTime()
+{
+ return ::GetTickCount() + timeOffset;
+}
+
+static MSG makeMsg(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ MSG result = {0};
+ result.hwnd = hwnd;
+ result.message = message;
+ result.wParam = wParam;
+ result.lParam = lParam;
+ result.time = currentEventTime();
+ result.pt = lastMousePosition;
+
+ return result;
+}
+
+static LRESULT dispatchMessage(const MSG* msg)
+{
+ ASSERT(msg);
+ ::TranslateMessage(msg);
+ return ::DispatchMessage(msg);
+}
+
+static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ down = true;
+ MSG msg = makeMsg(webViewWindow, WM_RBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+ dispatchMessage(&msg);
+ down = false;
+ msg = makeMsg(webViewWindow, WM_RBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+ dispatchMessage(&msg);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ down = true;
+ MSG msg = makeMsg(webViewWindow, WM_LBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+ if (!msgQueue[endOfQueue].delay)
+ dispatchMessage(&msg);
+ else {
+ // replaySavedEvents has the required logic to make leapForward delays work
+ msgQueue[endOfQueue++].msg = msg;
+ replaySavedEvents();
+ }
+
+ return JSValueMakeUndefined(context);
+}
+
+static inline POINTL pointl(const POINT& point)
+{
+ POINTL result;
+ result.x = point.x;
+ result.y = point.y;
+ return result;
+}
+
+static void doMouseUp(MSG msg)
+{
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ dispatchMessage(&msg);
+ down = false;
+
+ if (draggingInfo) {
+ COMPtr<IWebView> webView;
+ COMPtr<IDropTarget> webViewDropTarget;
+ if (SUCCEEDED(frame->webView(&webView)) && SUCCEEDED(webView->QueryInterface(IID_IDropTarget, (void**)&webViewDropTarget))) {
+ POINT screenPoint = msg.pt;
+ DWORD effect = 0;
+ ::ClientToScreen(webViewWindow, &screenPoint);
+ if (!didDragEnter) {
+ webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
+ didDragEnter = true;
+ }
+ HRESULT hr = draggingInfo->dropSource()->QueryContinueDrag(0, 0);
+ webViewDropTarget->DragOver(0, pointl(screenPoint), &effect);
+ if (hr == DRAGDROP_S_DROP && effect != DROPEFFECT_NONE) {
+ DWORD effect = 0;
+ webViewDropTarget->Drop(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
+ } else
+ webViewDropTarget->DragLeave();
+
+ delete draggingInfo;
+ draggingInfo = 0;
+ }
+ }
+}
+
+static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ MSG msg = makeMsg(webViewWindow, WM_LBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+
+ if ((dragMode && !replayingSavedEvents) || msgQueue[endOfQueue].delay) {
+ msgQueue[endOfQueue++].msg = msg;
+ replaySavedEvents();
+ } else
+ doMouseUp(msg);
+
+ return JSValueMakeUndefined(context);
+}
+
+static void doMouseMove(MSG msg)
+{
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ dispatchMessage(&msg);
+
+ if (down && draggingInfo) {
+ POINT screenPoint = msg.pt;
+ ::ClientToScreen(webViewWindow, &screenPoint);
+
+ IWebView* webView;
+ COMPtr<IDropTarget> webViewDropTarget;
+ if (SUCCEEDED(frame->webView(&webView)) && SUCCEEDED(webView->QueryInterface(IID_IDropTarget, (void**)&webViewDropTarget))) {
+ DWORD effect = 0;
+ if (didDragEnter)
+ webViewDropTarget->DragOver(MK_LBUTTON, pointl(screenPoint), &effect);
+ else {
+ webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
+ didDragEnter = true;
+ }
+ draggingInfo->dropSource()->GiveFeedback(effect);
+ }
+ }
+}
+
+static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 2)
+ return JSValueMakeUndefined(context);
+
+ lastMousePosition.x = (int)JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!exception || !*exception);
+ lastMousePosition.y = (int)JSValueToNumber(context, arguments[1], exception);
+ ASSERT(!exception || !*exception);
+
+ MSG msg = makeMsg(webViewWindow, WM_MOUSEMOVE, down ? MK_LBUTTON : 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
+
+ if (dragMode && down && !replayingSavedEvents) {
+ msgQueue[endOfQueue++].msg = msg;
+ return JSValueMakeUndefined(context);
+ }
+
+ doMouseMove(msg);
+
+ return JSValueMakeUndefined(context);
+}
+
+void replaySavedEvents()
+{
+ replayingSavedEvents = true;
+
+ MSG msg = { 0 };
+
+ while (startOfQueue < endOfQueue && !msgQueue[startOfQueue].delay) {
+ msg = msgQueue[startOfQueue++].msg;
+ switch (msg.message) {
+ case WM_LBUTTONUP:
+ doMouseUp(msg);
+ break;
+ case WM_MOUSEMOVE:
+ doMouseMove(msg);
+ break;
+ case WM_LBUTTONDOWN:
+ dispatchMessage(&msg);
+ break;
+ default:
+ // Not reached
+ break;
+ }
+ }
+
+ int numQueuedMessages = endOfQueue - startOfQueue;
+ if (!numQueuedMessages) {
+ startOfQueue = 0;
+ endOfQueue = 0;
+ replayingSavedEvents = false;
+ ASSERT(!down);
+ return;
+ }
+
+ if (msgQueue[startOfQueue].delay) {
+ ::Sleep(msgQueue[startOfQueue].delay);
+ msgQueue[startOfQueue].delay = 0;
+ }
+
+ ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0);
+ while (::GetMessage(&msg, webViewWindow, 0, 0)) {
+ // FIXME: Why do we get a WM_MOUSELEAVE? it breaks tests
+ if (msg.message == WM_MOUSELEAVE)
+ continue;
+ if (msg.message != WM_DRT_SEND_QUEUED_EVENT) {
+ dispatchMessage(&msg);
+ continue;
+ }
+ msg = msgQueue[startOfQueue++].msg;
+ switch (msg.message) {
+ case WM_LBUTTONUP:
+ doMouseUp(msg);
+ break;
+ case WM_MOUSEMOVE:
+ doMouseMove(msg);
+ break;
+ case WM_LBUTTONDOWN:
+ dispatchMessage(&msg);
+ break;
+ default:
+ // Not reached
+ break;
+ }
+ if (startOfQueue >= endOfQueue)
+ break;
+ ::Sleep(msgQueue[startOfQueue].delay);
+ msgQueue[startOfQueue].delay = 0;
+ ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0);
+ }
+ startOfQueue = 0;
+ endOfQueue = 0;
+
+ replayingSavedEvents = false;
+}
+
+static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ static const JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");
+
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ JSStringRef character = JSValueToStringCopy(context, arguments[0], exception);
+ ASSERT(!*exception);
+ int virtualKeyCode;
+ int charCode = 0;
+ int keyData = 1;
+ bool needsShiftKeyModifier = false;
+ if (JSStringIsEqualToUTF8CString(character, "leftArrow")) {
+ virtualKeyCode = VK_LEFT;
+ keyData += KF_EXTENDED << 16; // In this case, extended means "not keypad".
+ } else if (JSStringIsEqualToUTF8CString(character, "rightArrow")) {
+ virtualKeyCode = VK_RIGHT;
+ keyData += KF_EXTENDED << 16;
+ } else if (JSStringIsEqualToUTF8CString(character, "upArrow")) {
+ virtualKeyCode = VK_UP;
+ keyData += KF_EXTENDED << 16;
+ } else if (JSStringIsEqualToUTF8CString(character, "downArrow")) {
+ virtualKeyCode = VK_DOWN;
+ keyData += KF_EXTENDED << 16;
+ } else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
+ virtualKeyCode = VK_PRIOR;
+ else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
+ virtualKeyCode = VK_NEXT;
+ else if (JSStringIsEqualToUTF8CString(character, "home"))
+ virtualKeyCode = VK_HOME;
+ else if (JSStringIsEqualToUTF8CString(character, "end"))
+ virtualKeyCode = VK_END;
+ else if (JSStringIsEqualToUTF8CString(character, "delete"))
+ virtualKeyCode = VK_BACK;
+ else {
+ charCode = JSStringGetCharactersPtr(character)[0];
+ virtualKeyCode = LOBYTE(VkKeyScan(charCode));
+ if (WTF::isASCIIUpper(charCode))
+ needsShiftKeyModifier = true;
+ }
+ JSStringRelease(character);
+
+ BYTE keyState[256];
+ if (argumentCount > 1 || needsShiftKeyModifier) {
+ ::GetKeyboardState(keyState);
+
+ BYTE newKeyState[256];
+ memcpy(newKeyState, keyState, sizeof(keyState));
+
+ if (needsShiftKeyModifier)
+ newKeyState[VK_SHIFT] = 0x80;
+
+ if (argumentCount > 1) {
+ JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], exception);
+ if (modifiersArray) {
+ int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0);
+ for (int i = 0; i < modifiersCount; ++i) {
+ JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
+ JSStringRef string = JSValueToStringCopy(context, value, 0);
+ if (JSStringIsEqualToUTF8CString(string, "ctrlKey"))
+ newKeyState[VK_CONTROL] = 0x80;
+ else if (JSStringIsEqualToUTF8CString(string, "shiftKey"))
+ newKeyState[VK_SHIFT] = 0x80;
+ else if (JSStringIsEqualToUTF8CString(string, "altKey"))
+ newKeyState[VK_MENU] = 0x80;
+
+ JSStringRelease(string);
+ }
+ }
+ }
+
+ ::SetKeyboardState(newKeyState);
+ }
+
+ MSG msg = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYDOWN : WM_KEYDOWN, virtualKeyCode, keyData);
+ if (virtualKeyCode != 255)
+ dispatchMessage(&msg);
+ else {
+ // For characters that do not exist in the active keyboard layout,
+ // ::Translate will not work, so we post an WM_CHAR event ourselves.
+ ::PostMessage(webViewWindow, WM_CHAR, charCode, 0);
+ }
+
+ // Tests expect that all messages are processed by the time keyDown() returns.
+ if (::PeekMessage(&msg, webViewWindow, WM_CHAR, WM_CHAR, PM_REMOVE) || ::PeekMessage(&msg, webViewWindow, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE))
+ ::DispatchMessage(&msg);
+
+ MSG msgUp = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYUP : WM_KEYUP, virtualKeyCode, keyData);
+ ::DispatchMessage(&msgUp);
+
+ if (argumentCount > 1 || needsShiftKeyModifier)
+ ::SetKeyboardState(keyState);
+
+ return JSValueMakeUndefined(context);
+}
+
+// eventSender.dispatchMessage(message, wParam, lParam, time = currentEventTime(), x = lastMousePosition.x, y = lastMousePosition.y)
+static JSValueRef dispatchMessageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount < 3)
+ return JSValueMakeUndefined(context);
+
+ COMPtr<IWebFramePrivate> framePrivate;
+ if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+ framePrivate->layout();
+
+ MSG msg = {};
+ msg.hwnd = webViewWindow;
+ msg.message = JSValueToNumber(context, arguments[0], exception);
+ ASSERT(!*exception);
+ msg.wParam = JSValueToNumber(context, arguments[1], exception);
+ ASSERT(!*exception);
+ msg.lParam = static_cast<ULONG_PTR>(JSValueToNumber(context, arguments[2], exception));
+ ASSERT(!*exception);
+ if (argumentCount >= 4) {
+ msg.time = JSValueToNumber(context, arguments[3], exception);
+ ASSERT(!*exception);
+ }
+ if (!msg.time)
+ msg.time = currentEventTime();
+ if (argumentCount >= 6) {
+ msg.pt.x = JSValueToNumber(context, arguments[4], exception);
+ ASSERT(!*exception);
+ msg.pt.y = JSValueToNumber(context, arguments[5], exception);
+ ASSERT(!*exception);
+ } else
+ msg.pt = lastMousePosition;
+
+ ::DispatchMessage(&msg);
+
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef textZoomInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return JSValueMakeUndefined(context);
+
+ COMPtr<IWebIBActions> webIBActions(Query, webView);
+ if (!webIBActions)
+ return JSValueMakeUndefined(context);
+
+ webIBActions->makeTextLarger(0);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef textZoomOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return JSValueMakeUndefined(context);
+
+ COMPtr<IWebIBActions> webIBActions(Query, webView);
+ if (!webIBActions)
+ return JSValueMakeUndefined(context);
+
+ webIBActions->makeTextSmaller(0);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef zoomPageInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return JSValueMakeUndefined(context);
+
+ COMPtr<IWebIBActions> webIBActions(Query, webView);
+ if (!webIBActions)
+ return JSValueMakeUndefined(context);
+
+ webIBActions->zoomPageIn(0);
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef zoomPageOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return JSValueMakeUndefined(context);
+
+ COMPtr<IWebIBActions> webIBActions(Query, webView);
+ if (!webIBActions)
+ return JSValueMakeUndefined(context);
+
+ webIBActions->zoomPageOut(0);
+ return JSValueMakeUndefined(context);
+}
+
+static JSStaticFunction staticFunctions[] = {
+ { "contextClick", contextClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "mouseDown", mouseDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "mouseUp", mouseUpCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "mouseMoveTo", mouseMoveToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "leapForward", leapForwardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "keyDown", keyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "dispatchMessage", dispatchMessageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "textZoomIn", textZoomInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "zoomPageIn", zoomPageInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "zoomPageOut", zoomPageOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+};
+
+static JSStaticValue staticValues[] = {
+ { "dragMode", getDragModeCallback, setDragModeCallback, kJSPropertyAttributeNone },
+ { "WM_KEYDOWN", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_KEYUP", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_CHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_DEADCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_SYSKEYDOWN", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_SYSKEYUP", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_SYSCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { "WM_SYSDEADCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+};
+
+static JSClassRef getClass(JSContextRef context)
+{
+ static JSClassRef eventSenderClass = 0;
+
+ if (!eventSenderClass) {
+ JSClassDefinition classDefinition = {0};
+ classDefinition.staticFunctions = staticFunctions;
+ classDefinition.staticValues = staticValues;
+
+ eventSenderClass = JSClassCreate(&classDefinition);
+ }
+
+ return eventSenderClass;
+}
+
+JSObjectRef makeEventSender(JSContextRef context)
+{
+ down = false;
+ dragMode = true;
+ replayingSavedEvents = false;
+ timeOffset = 0;
+ lastMousePosition.x = 0;
+ lastMousePosition.y = 0;
+
+ endOfQueue = 0;
+ startOfQueue = 0;
+
+ didDragEnter = false;
+ draggingInfo = 0;
+
+ return JSObjectMake(context, getClass(context), 0);
+}
diff --git a/WebKitTools/DumpRenderTree/win/EventSender.h b/WebKitTools/DumpRenderTree/win/EventSender.h
new file mode 100644
index 0000000..9ae0aec
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/EventSender.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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
+
+class DraggingInfo;
+
+typedef const struct OpaqueJSContext* JSContextRef;
+typedef struct OpaqueJSValue* JSObjectRef;
+
+JSObjectRef makeEventSender(JSContextRef context);
+void replaySavedEvents();
+
+extern DraggingInfo* draggingInfo;
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp
new file mode 100644
index 0000000..b18b961
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 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.
+ * 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 "FrameLoadDelegate.h"
+
+#include "AccessibilityController.h"
+#include "DumpRenderTree.h"
+#include "EventSender.h"
+#include "GCController.h"
+#include "LayoutTestController.h"
+#include "WorkQueueItem.h"
+#include "WorkQueue.h"
+#include <WebCore/COMPtr.h>
+#include <JavaScriptCore/Assertions.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <WebKit/WebKit.h>
+#include <wtf/Vector.h>
+#include <stdio.h>
+#include <string>
+
+using std::string;
+
+static FrameLoadDelegate* g_delegateWaitingOnTimer;
+
+string BSTRtoString(BSTR bstr)
+{
+ int result = WideCharToMultiByte(CP_UTF8, 0, bstr, SysStringLen(bstr) + 1, 0, 0, 0, 0);
+ Vector<char> utf8Vector(result);
+ result = WideCharToMultiByte(CP_UTF8, 0, bstr, SysStringLen(bstr) + 1, utf8Vector.data(), result, 0, 0);
+ if (!result)
+ return string();
+
+ return string(utf8Vector.data(), utf8Vector.size() - 1);
+}
+
+string descriptionSuitableForTestResult(IWebFrame* webFrame)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(webFrame->webView(&webView)))
+ return string();
+
+ COMPtr<IWebFrame> mainFrame;
+ if (FAILED(webView->mainFrame(&mainFrame)))
+ return string();
+
+ BSTR frameNameBSTR;
+ if (FAILED(webFrame->name(&frameNameBSTR)) || BSTRtoString(frameNameBSTR).empty() )
+ return (webFrame == mainFrame) ? "main frame" : string();
+
+ string frameName = (webFrame == mainFrame) ? "main frame" : "frame";
+ frameName += " \"" + BSTRtoString(frameNameBSTR) + "\"";
+
+ SysFreeString(frameNameBSTR);
+
+ return frameName;
+}
+
+FrameLoadDelegate::FrameLoadDelegate()
+ : m_refCount(1)
+ , m_gcController(new GCController)
+ , m_accessibilityController(new AccessibilityController)
+{
+}
+
+FrameLoadDelegate::~FrameLoadDelegate()
+{
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate2))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegatePrivate))
+ *ppvObject = static_cast<IWebFrameLoadDelegatePrivate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE FrameLoadDelegate::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE FrameLoadDelegate::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didStartProvisionalLoadForFrame(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebFrame* frame)
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didStartProvisionalLoadForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+ // 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;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFailProvisionalLoadWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *frame)
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didFailProvisionalLoadWithError\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didCommitLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame)
+{
+ COMPtr<IWebViewPrivate> webViewPrivate;
+ HRESULT hr = webView->QueryInterface(&webViewPrivate);
+ if (FAILED(hr))
+ return hr;
+ webViewPrivate->updateFocusedAndActiveState();
+
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didCommitLoadForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didReceiveTitle(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR title,
+ /* [in] */ IWebFrame *frame)
+{
+ if (::gLayoutTestController->dumpTitleChanges() && !done)
+ printf("TITLE CHANGED: %S\n", title ? title : L"");
+ return S_OK;
+}
+
+void FrameLoadDelegate::processWork()
+{
+ // quit doing work once a load is in progress
+ while (!topLoadingFrame && WorkQueue::shared()->count()) {
+ WorkQueueItem* item = WorkQueue::shared()->dequeue();
+ ASSERT(item);
+ item->invoke();
+ }
+
+ // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
+ if (!topLoadingFrame && !::gLayoutTestController->waitToDump())
+ dump();
+}
+
+static void CALLBACK processWorkTimer(HWND, UINT, UINT_PTR id, DWORD)
+{
+ ::KillTimer(0, id);
+ FrameLoadDelegate* d = g_delegateWaitingOnTimer;
+ g_delegateWaitingOnTimer = 0;
+ d->processWork();
+}
+
+void FrameLoadDelegate::locationChangeDone(IWebError*, IWebFrame* frame)
+{
+ if (frame != topLoadingFrame)
+ return;
+
+ topLoadingFrame = 0;
+ WorkQueue::shared()->setFrozen(true);
+
+ if (::gLayoutTestController->waitToDump())
+ return;
+
+ if (WorkQueue::shared()->count()) {
+ ASSERT(!g_delegateWaitingOnTimer);
+ g_delegateWaitingOnTimer = this;
+ ::SetTimer(0, 0, 0, processWorkTimer);
+ return;
+ }
+
+ dump();
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFinishLoadForFrame(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebFrame* frame)
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didFinishLoadForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+ locationChangeDone(0, frame);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFailLoadWithError(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebError* error,
+ /* [in] */ IWebFrame* forFrame)
+{
+ locationChangeDone(error, forFrame);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::willCloseFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didClearWindowObject(
+ /* [in] */ IWebView*webView,
+ /* [in] */ JSContextRef context,
+ /* [in] */ JSObjectRef windowObject,
+ /* [in] */ IWebFrame* frame)
+{
+ JSValueRef exception = 0;
+
+ ::gLayoutTestController->makeWindowObject(context, windowObject, &exception);
+ ASSERT(!exception);
+
+ m_gcController->makeWindowObject(context, windowObject, &exception);
+ ASSERT(!exception);
+
+ m_accessibilityController->makeWindowObject(context, windowObject, &exception);
+ ASSERT(!exception);
+
+ JSStringRef eventSenderStr = JSStringCreateWithUTF8CString("eventSender");
+ JSValueRef eventSender = makeEventSender(context);
+ JSObjectSetProperty(context, windowObject, eventSenderStr, eventSender, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0);
+ JSStringRelease(eventSenderStr);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFinishDocumentLoadForFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame)
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didFinishDocumentLoadForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+ if (!done) {
+ COMPtr<IWebFramePrivate> webFramePrivate;
+ HRESULT hr = frame->QueryInterface(&webFramePrivate);
+ if (FAILED(hr))
+ return hr;
+ unsigned pendingFrameUnloadEvents;
+ hr = webFramePrivate->pendingFrameUnloadEventCount(&pendingFrameUnloadEvents);
+ if (FAILED(hr))
+ return hr;
+ if (pendingFrameUnloadEvents)
+ printf("%s - has %u onunload handler(s)\n",
+ descriptionSuitableForTestResult(frame).c_str(), pendingFrameUnloadEvents);
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didHandleOnloadEventsForFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame)
+{
+ if (!done && gLayoutTestController->dumpFrameLoadCallbacks())
+ printf("%s - didHandleOnloadEventsForFrame\n",
+ descriptionSuitableForTestResult(frame).c_str());
+
+ return S_OK;
+}
+
diff --git a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h
new file mode 100644
index 0000000..1a134fc
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 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.
+ * 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 FrameLoadDelegate_h
+#define FrameLoadDelegate_h
+
+#include <WebKit/WebKit.h>
+#include <wtf/OwnPtr.h>
+
+class AccessibilityController;
+class GCController;
+
+class FrameLoadDelegate : public IWebFrameLoadDelegate2, public IWebFrameLoadDelegatePrivate {
+public:
+ FrameLoadDelegate();
+ virtual ~FrameLoadDelegate();
+
+ void processWork();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebFrameLoadDelegate
+ virtual HRESULT STDMETHODCALLTYPE didStartProvisionalLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveServerRedirectForProvisionalLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFailProvisionalLoadWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didCommitLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveTitle(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR title,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveIcon(
+ /* [in] */ IWebView *webView,
+ /* [in] */ OLE_HANDLE image,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFinishLoadForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didFailLoadWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *forFrame);
+
+ virtual HRESULT STDMETHODCALLTYPE didChangeLocationWithinPageForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformClientRedirectToURL(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR url,
+ /* [in] */ double delaySeconds,
+ /* [in] */ DATE fireDate,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didCancelClientRedirectForFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willCloseFrame(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE windowScriptObjectAvailable(
+ /* [in] */ IWebView *sender,
+ /* [in] */ JSContextRef context,
+ /* [in] */ JSObjectRef windowObject) { return E_NOTIMPL; }
+
+ // IWebFrameLoadDelegatePrivate
+ virtual HRESULT STDMETHODCALLTYPE didFinishDocumentLoadForFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE didFirstLayoutInFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didHandleOnloadEventsForFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame);
+
+ // IWebFrameLoadDelegate2
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE didClearWindowObject(
+ /* [in] */ IWebView* webView,
+ /* [in] */ JSContextRef context,
+ /* [in] */ JSObjectRef windowObject,
+ /* [in] */ IWebFrame* frame);
+
+protected:
+ void locationChangeDone(IWebError*, IWebFrame*);
+
+ ULONG m_refCount;
+ OwnPtr<GCController> m_gcController;
+ OwnPtr<AccessibilityController> m_accessibilityController;
+};
+
+#endif // FrameLoadDelegate_h
diff --git a/WebKitTools/DumpRenderTree/win/GCControllerWin.cpp b/WebKitTools/DumpRenderTree/win/GCControllerWin.cpp
new file mode 100644
index 0000000..547aabc
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/GCControllerWin.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 "DumpRenderTree.h"
+#include <WebCore/COMPtr.h>
+#include <WebKit/WebKit.h>
+
+void GCController::collect() const
+{
+ COMPtr<IWebJavaScriptCollector> collector;
+ if (FAILED(::CoCreateInstance(CLSID_WebJavaScriptCollector, 0, CLSCTX_ALL, IID_IWebJavaScriptCollector, (void**)&collector)))
+ return;
+ collector->collect();
+}
+
+void GCController::collectOnAlternateThread(bool waitUntilDone) const
+{
+ COMPtr<IWebJavaScriptCollector> collector;
+ if (FAILED(::CoCreateInstance(CLSID_WebJavaScriptCollector, 0, CLSCTX_ALL, IID_IWebJavaScriptCollector, (void**)&collector)))
+ return;
+ collector->collectOnAlternateThread(waitUntilDone ? TRUE : FALSE);
+}
+
+size_t GCController::getJSObjectCount() const
+{
+ COMPtr<IWebJavaScriptCollector> collector;
+ if (FAILED(::CoCreateInstance(CLSID_WebJavaScriptCollector, 0, CLSCTX_ALL, IID_IWebJavaScriptCollector, (void**)&collector)))
+ return 0;
+ UINT objects = 0;
+ collector->objectCount(&objects);
+ return objects;
+}
diff --git a/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj b/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj
new file mode 100644
index 0000000..9da1a56
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/ImageDiff.vcproj
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="ImageDiff"
+ ProjectGUID="{59CC0547-70AC-499C-9B19-EC01C6F61137}"
+ RootNamespace="ImageDiff"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib"
+ AdditionalLibraryDirectories=""
+ SubSystem="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if &quot;$(ARCHIVE_BUILD)&quot;==&quot;&quot; (if not &quot;$(PRODUCTION)&quot;==&quot;&quot; exit /b)&#x0D;&#x0A;&#x0D;&#x0A;if not exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; exit /b&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt38.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt38$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="CoreGraphics$(LibraryConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib"
+ AdditionalLibraryDirectories=""
+ SubSystem="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if &quot;$(ARCHIVE_BUILD)&quot;==&quot;&quot; (if not &quot;$(PRODUCTION)&quot;==&quot;&quot; exit /b)&#x0D;&#x0A;&#x0D;&#x0A;if not exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; exit /b&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt38.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt38$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin38$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc38$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="..\cg\ImageDiffCG.cpp"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
new file mode 100644
index 0000000..275fcd3
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
@@ -0,0 +1,630 @@
+/*
+ * Copyright (C) 2006, 2007 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.
+ * 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 "LayoutTestController.h"
+
+#include "DumpRenderTree.h"
+#include "EditingDelegate.h"
+#include "PolicyDelegate.h"
+#include "WorkQueue.h"
+#include "WorkQueueItem.h"
+#include <WebCore/COMPtr.h>
+#include <wtf/Platform.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <JavaScriptCore/Assertions.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <WebKit/WebKit.h>
+#include <string>
+#include <CoreFoundation/CoreFoundation.h>
+#include <shlwapi.h>
+#include <shlguid.h>
+#include <shobjidl.h>
+
+using std::string;
+using std::wstring;
+
+static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath);
+
+LayoutTestController::~LayoutTestController()
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ // reset webview-related states back to default values in preparation for next test
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (SUCCEEDED(webView->QueryInterface(&viewPrivate)))
+ viewPrivate->setTabKeyCyclesThroughElements(TRUE);
+
+ COMPtr<IWebViewEditing> viewEditing;
+ if (FAILED(webView->QueryInterface(&viewEditing)))
+ return;
+ COMPtr<IWebEditingDelegate> delegate;
+ if (FAILED(viewEditing->editingDelegate(&delegate)))
+ return;
+ COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get());
+ if (editingDelegate)
+ editingDelegate->setAcceptsEditing(TRUE);
+}
+
+void LayoutTestController::addDisallowedURL(JSStringRef url)
+{
+ // FIXME: Implement!
+}
+
+void LayoutTestController::clearBackForwardList()
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebBackForwardList> backForwardList;
+ if (FAILED(webView->backForwardList(&backForwardList)))
+ return;
+
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(backForwardList->currentItem(&item)))
+ return;
+
+ // We clear the history by setting the back/forward list's capacity to 0
+ // then restoring it back and adding back the current item.
+ int capacity;
+ if (FAILED(backForwardList->capacity(&capacity)))
+ return;
+
+ backForwardList->setCapacity(0);
+ backForwardList->setCapacity(capacity);
+ backForwardList->addItem(item.get());
+ backForwardList->goToItem(item.get());
+}
+
+JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
+{
+ // FIXME: Implement!
+ return 0;
+}
+
+JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
+{
+ // FIXME: Implement!
+ return 0;
+}
+
+void LayoutTestController::display()
+{
+ displayWebView();
+}
+
+void LayoutTestController::keepWebHistory()
+{
+ COMPtr<IWebHistory> history(Create, CLSID_WebHistory);
+ if (!history)
+ return;
+
+ COMPtr<IWebHistory> sharedHistory(Create, CLSID_WebHistory);
+ if (!sharedHistory)
+ return;
+
+ history->setOptionalSharedHistory(sharedHistory.get());
+}
+
+void LayoutTestController::notifyDone()
+{
+ // Same as on mac. This can be shared.
+ if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
+ dump();
+ m_waitToDump = false;
+}
+
+JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
+{
+ wstring input(JSStringGetCharactersPtr(url), JSStringGetLength(url));
+
+ wstring localPath;
+ if (!resolveCygwinPath(input, localPath)) {
+ printf("ERROR: Failed to resolve Cygwin path %S\n", input.c_str());
+ return 0;
+ }
+
+ return JSStringCreateWithCharacters(localPath.c_str(), localPath.length());
+}
+
+void LayoutTestController::queueBackNavigation(int howFarBack)
+{
+ // Same as on mac. This can be shared.
+ WorkQueue::shared()->queue(new BackItem(howFarBack));
+}
+
+void LayoutTestController::queueForwardNavigation(int howFarForward)
+{
+ // Same as on mac. This can be shared.
+ WorkQueue::shared()->queue(new ForwardItem(howFarForward));
+}
+
+static wstring jsStringRefToWString(JSStringRef jsStr)
+{
+ size_t length = JSStringGetLength(jsStr);
+ Vector<WCHAR> buffer(length + 1);
+ memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
+ buffer[length] = '\0';
+
+ return buffer.data();
+}
+
+void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
+{
+ COMPtr<IWebDataSource> dataSource;
+ if (FAILED(frame->dataSource(&dataSource)))
+ return;
+
+ COMPtr<IWebURLResponse> response;
+ if (FAILED(dataSource->response(&response)) || !response)
+ return;
+
+ BSTR responseURLBSTR;
+ if (FAILED(response->URL(&responseURLBSTR)))
+ return;
+ wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR));
+ SysFreeString(responseURLBSTR);
+
+ // FIXME: We should do real relative URL resolution here.
+ int lastSlash = responseURL.rfind('/');
+ if (lastSlash != -1)
+ responseURL = responseURL.substr(0, lastSlash);
+
+ wstring wURL = jsStringRefToWString(url);
+ wstring wAbsoluteURL = responseURL + TEXT("/") + wURL;
+ JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbsoluteURL.data(), wAbsoluteURL.length()));
+
+ WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target));
+}
+
+void LayoutTestController::queueReload()
+{
+ WorkQueue::shared()->queue(new ReloadItem);
+}
+
+void LayoutTestController::queueScript(JSStringRef script)
+{
+ WorkQueue::shared()->queue(new ScriptItem(script));
+}
+
+void LayoutTestController::setAcceptsEditing(bool acceptsEditing)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewEditing> viewEditing;
+ if (FAILED(webView->QueryInterface(&viewEditing)))
+ return;
+
+ COMPtr<IWebEditingDelegate> delegate;
+ if (FAILED(viewEditing->editingDelegate(&delegate)))
+ return;
+
+ EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get();
+ editingDelegate->setAcceptsEditing(acceptsEditing);
+}
+
+void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
+ if (!prefsPrivate)
+ return;
+
+ prefsPrivate->setAuthorAndUserStylesEnabled(flag);
+}
+
+void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ if (setDelegate)
+ webView->setPolicyDelegate(policyDelegate);
+ else
+ webView->setPolicyDelegate(NULL);
+}
+
+void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
+{
+ // FIXME: Implement!
+}
+
+void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ preferences->setPrivateBrowsingEnabled(privateBrowsingEnabled);
+}
+
+void LayoutTestController::setPopupBlockingEnabled(bool privateBrowsingEnabled)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ preferences->setJavaScriptCanOpenWindowsAutomatically(!privateBrowsingEnabled);
+}
+
+void LayoutTestController::setTabKeyCyclesThroughElements(bool shouldCycle)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (FAILED(webView->QueryInterface(&viewPrivate)))
+ return;
+
+ viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE);
+}
+
+void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
+{
+ // FIXME: Implement!
+}
+
+void LayoutTestController::setUserStyleSheetEnabled(bool flag)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ preferences->setUserStyleSheetEnabled(flag);
+}
+
+bool appendComponentToPath(wstring& path, const wstring& component)
+{
+ WCHAR buffer[MAX_PATH];
+
+ if (path.size() + 1 > MAX_PATH)
+ return false;
+
+ memcpy(buffer, path.data(), path.size() * sizeof(WCHAR));
+ buffer[path.size()] = '\0';
+
+ if (!PathAppendW(buffer, component.c_str()))
+ return false;
+
+ path = wstring(buffer);
+ return true;
+}
+
+static bool followShortcuts(wstring& path)
+{
+ if (PathFileExists(path.c_str()))
+ return true;
+
+ // Do we have a shortcut?
+ wstring linkPath = path;
+ linkPath.append(TEXT(".lnk"));
+ if (!PathFileExists(linkPath.c_str()))
+ return true;
+
+ // We have a shortcut, find its target.
+ COMPtr<IShellLink> shortcut(Create, CLSID_ShellLink);
+ if (!shortcut)
+ return false;
+ COMPtr<IPersistFile> persistFile(Query, shortcut);
+ if (!shortcut)
+ return false;
+ if (FAILED(persistFile->Load(linkPath.c_str(), STGM_READ)))
+ return false;
+ if (FAILED(shortcut->Resolve(0, 0)))
+ return false;
+ WCHAR targetPath[MAX_PATH];
+ DWORD targetPathLen = _countof(targetPath);
+ if (FAILED(shortcut->GetPath(targetPath, targetPathLen, 0, 0)))
+ return false;
+ if (!PathFileExists(targetPath))
+ return false;
+ // Use the target path as the result path instead.
+ path = wstring(targetPath);
+
+ return true;
+}
+
+static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath)
+{
+ wstring fileProtocol = L"file://";
+ bool isFileProtocol = cygwinPath.find(fileProtocol) != string::npos;
+ if (cygwinPath[isFileProtocol ? 7 : 0] != '/') // ensure path is absolute
+ return false;
+
+ // Get the Root path.
+ WCHAR rootPath[MAX_PATH];
+ DWORD rootPathSize = _countof(rootPath);
+ DWORD keyType;
+ DWORD result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/"), TEXT("native"), &keyType, &rootPath, &rootPathSize);
+
+ if (result != ERROR_SUCCESS || keyType != REG_SZ)
+ return false;
+
+ windowsPath = wstring(rootPath, rootPathSize);
+
+ int oldPos = isFileProtocol ? 8 : 1;
+ while (1) {
+ int newPos = cygwinPath.find('/', oldPos);
+
+ if (newPos == -1) {
+ wstring pathComponent = cygwinPath.substr(oldPos);
+
+ if (!appendComponentToPath(windowsPath, pathComponent))
+ return false;
+
+ if (!followShortcuts(windowsPath))
+ return false;
+
+ break;
+ }
+
+ wstring pathComponent = cygwinPath.substr(oldPos, newPos - oldPos);
+ if (!appendComponentToPath(windowsPath, pathComponent))
+ return false;
+
+ if (!followShortcuts(windowsPath))
+ return false;
+
+ oldPos = newPos + 1;
+ }
+
+ if (isFileProtocol)
+ windowsPath = fileProtocol + windowsPath;
+
+ return true;
+}
+
+static wstring cfStringRefToWString(CFStringRef cfStr)
+{
+ Vector<wchar_t> v(CFStringGetLength(cfStr));
+ CFStringGetCharacters(cfStr, CFRangeMake(0, CFStringGetLength(cfStr)), (UniChar *)v.data());
+
+ return wstring(v.data(), v.size());
+}
+
+void LayoutTestController::setUserStyleSheetLocation(JSStringRef jsURL)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
+ RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateWithString(0, urlString.get(), 0));
+ if (!url)
+ return;
+
+ // Now copy the file system path, POSIX style.
+ RetainPtr<CFStringRef> pathCF(AdoptCF, CFURLCopyFileSystemPath(url.get(), kCFURLPOSIXPathStyle));
+ if (!pathCF)
+ return;
+
+ wstring path = cfStringRefToWString(pathCF.get());
+
+ wstring resultPath;
+ if (!resolveCygwinPath(path, resultPath))
+ return;
+
+ // The path has been resolved, now convert it back to a CFURL.
+ int result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, 0, 0, 0, 0);
+ Vector<char> utf8Vector(result);
+ result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, utf8Vector.data(), result, 0, 0);
+ if (!result)
+ return;
+
+ url = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)utf8Vector.data(), utf8Vector.size() - 1, false);
+ if (!url)
+ return;
+
+ resultPath = cfStringRefToWString(CFURLGetString(url.get()));
+
+ BSTR resultPathBSTR = SysAllocStringLen(resultPath.data(), resultPath.size());
+ preferences->setUserStyleSheetLocation(resultPathBSTR);
+ SysFreeString(resultPathBSTR);
+}
+
+void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
+{
+ RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
+ ::setPersistentUserStyleSheetLocation(urlString.get());
+}
+
+void LayoutTestController::clearPersistentUserStyleSheet()
+{
+ ::setPersistentUserStyleSheetLocation(0);
+}
+
+void LayoutTestController::setWindowIsKey(bool flag)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (FAILED(webView->QueryInterface(&viewPrivate)))
+ return;
+
+ HWND webViewWindow;
+ if (FAILED(viewPrivate->viewWindow((OLE_HANDLE*)&webViewWindow)))
+ return;
+
+ ::SendMessage(webViewWindow, flag ? WM_SETFOCUS : WM_KILLFOCUS, (WPARAM)::GetDesktopWindow(), 0);
+}
+
+void LayoutTestController::setSmartInsertDeleteEnabled(bool flag)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewEditing> viewEditing;
+ if (FAILED(webView->QueryInterface(&viewEditing)))
+ return;
+
+ viewEditing->setSmartInsertDeleteEnabled(flag ? TRUE : FALSE);
+}
+
+void LayoutTestController::setJavaScriptProfilingEnabled(bool flag)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (FAILED(webView->QueryInterface(&viewPrivate)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
+ if (!prefsPrivate)
+ return;
+
+ COMPtr<IWebInspector> inspector;
+ if (FAILED(viewPrivate->inspector(&inspector)))
+ return;
+
+ prefsPrivate->setDeveloperExtrasEnabled(flag);
+ inspector->setJavaScriptProfilingEnabled(flag);
+}
+
+static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
+
+static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
+{
+ const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
+ fprintf(stderr, message);
+ fprintf(stdout, message);
+ dump();
+}
+
+void LayoutTestController::setWaitToDump(bool waitUntilDone)
+{
+ // Same as on mac. This can be shared.
+ m_waitToDump = waitUntilDone;
+ if (m_waitToDump && !waitToDumpWatchdog) {
+ waitToDumpWatchdog = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + waitToDumpWatchdogInterval, 0, 0, 0, waitUntilDoneWatchdogFired, NULL);
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), waitToDumpWatchdog, kCFRunLoopCommonModes);
+ }
+}
+
+int LayoutTestController::windowCount()
+{
+ return openWindows().size();
+}
+
+bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id)
+{
+ COMPtr<IDOMDocument> document;
+ if (FAILED(frame->DOMDocument(&document)))
+ return false;
+
+ wstring idWstring = jsStringRefToWString(id);
+ BSTR idBSTR = SysAllocStringLen((OLECHAR*)idWstring.c_str(), idWstring.length());
+ COMPtr<IDOMElement> element;
+ HRESULT result = document->getElementById(idBSTR, &element);
+ SysFreeString(idBSTR);
+
+ if (FAILED(result))
+ return false;
+
+ COMPtr<IWebFramePrivate> framePrivate(Query, frame);
+ if (!framePrivate)
+ return false;
+
+ BOOL autoCompletes;
+ if (FAILED(framePrivate->elementDoesAutoComplete(element.get(), &autoCompletes)))
+ return false;
+
+ return autoCompletes;
+}
+
+void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
+{
+ wstring wName = jsStringRefToWString(name);
+ wstring wValue = jsStringRefToWString(value);
+
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebViewPrivate> viewPrivate;
+ if (FAILED(webView->QueryInterface(&viewPrivate)))
+ return;
+
+ BSTR nameBSTR = SysAllocStringLen((OLECHAR*)wName.c_str(), wName.length());
+ BSTR valueBSTR = SysAllocStringLen((OLECHAR*)wValue.c_str(), wValue.length());
+ viewPrivate->executeCoreCommandByName(nameBSTR, valueBSTR);
+
+ SysFreeString(nameBSTR);
+ SysFreeString(valueBSTR);
+}
+
+void LayoutTestController::clearAllDatabases()
+{
+ printf("ERROR: LayoutTestController::clearAllDatabases() not implemented\n");
+}
+
+void LayoutTestController::setDatabaseQuota(unsigned long long quota)
+{
+ printf("ERROR: LayoutTestController::setDatabaseQuota() not implemented\n");
+}
diff --git a/WebKitTools/DumpRenderTree/win/MD5.cpp b/WebKitTools/DumpRenderTree/win/MD5.cpp
new file mode 100644
index 0000000..1bfc9c7
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/MD5.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 "MD5.h"
+
+#include <windows.h>
+
+typedef void (WINAPI*initPtr)(MD5_CTX*);
+typedef void (WINAPI*updatePtr)(MD5_CTX*, unsigned char*, unsigned);
+typedef void (WINAPI*finalPtr)(MD5_CTX*);
+
+static HMODULE cryptDLL()
+{
+ static HMODULE module = LoadLibraryW(L"Cryptdll.dll");
+ return module;
+}
+
+static initPtr init()
+{
+ static initPtr ptr = reinterpret_cast<initPtr>(GetProcAddress(cryptDLL(), "MD5Init"));
+ return ptr;
+}
+
+static updatePtr update()
+{
+ static updatePtr ptr = reinterpret_cast<updatePtr>(GetProcAddress(cryptDLL(), "MD5Update"));
+ return ptr;
+}
+
+static finalPtr final()
+{
+ static finalPtr ptr = reinterpret_cast<finalPtr>(GetProcAddress(cryptDLL(), "MD5Final"));
+ return ptr;
+}
+
+void MD5_Init(MD5_CTX* context)
+{
+ init()(context);
+}
+
+void MD5_Update(MD5_CTX* context, unsigned char* input, unsigned length)
+{
+ update()(context, input, length);
+}
+
+void MD5_Final(unsigned char hash[16], MD5_CTX* context)
+{
+ final()(context);
+
+ for (int i = 0; i < 16; ++i)
+ hash[i] = context->digest[i];
+}
diff --git a/WebKitTools/DumpRenderTree/win/MD5.h b/WebKitTools/DumpRenderTree/win/MD5.h
new file mode 100644
index 0000000..326e21d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/MD5.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 MD5_h
+#define MD5_h
+
+typedef unsigned long ULONG;
+
+struct MD5_CTX {
+ ULONG i[2];
+ ULONG buf[4];
+ unsigned char in[64];
+ unsigned char digest[16];
+};
+
+void MD5_Init(MD5_CTX*);
+void MD5_Update(MD5_CTX*, unsigned char* input, unsigned length);
+void MD5_Final(unsigned char hash[16], MD5_CTX*);
+
+#endif // MD5_h
diff --git a/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp b/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp
new file mode 100644
index 0000000..d0b79e1
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 "PixelDumpSupportCG.h"
+
+#include "DumpRenderTree.h"
+#include <CoreGraphics/CGBitmapContext.h>
+#include <wtf/Assertions.h>
+#include <wtf/RetainPtr.h>
+
+PassRefPtr<BitmapContext> getBitmapContextFromWebView(bool onscreen, bool incrementalRepaint, bool sweepHorizontally, bool drawSelectionRect)
+{
+ RECT frame;
+ if (!GetWindowRect(webViewWindow, &frame))
+ return 0;
+
+ BITMAPINFO bmp = {0};
+ bmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmp.bmiHeader.biWidth = frame.right - frame.left;
+ bmp.bmiHeader.biHeight = -(frame.bottom - frame.top);
+ bmp.bmiHeader.biPlanes = 1;
+ bmp.bmiHeader.biBitCount = 32;
+ bmp.bmiHeader.biCompression = BI_RGB;
+
+ void* bits = 0;
+ HBITMAP bitmap = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, &bits, 0, 0);
+
+ HDC memoryDC = CreateCompatibleDC(0);
+ SelectObject(memoryDC, bitmap);
+ SendMessage(webViewWindow, WM_PRINTCLIENT, reinterpret_cast<WPARAM>(memoryDC), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED);
+ DeleteDC(memoryDC);
+
+ BITMAP info = {0};
+ GetObject(bitmap, sizeof(info), &info);
+ ASSERT(info.bmBitsPixel == 32);
+
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ CGContextRef context = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
+ info.bmWidthBytes, colorSpace.get(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
+
+ return BitmapContext::createByAdoptingBitmapAndContext(bitmap, context);
+}
diff --git a/WebKitTools/DumpRenderTree/win/PolicyDelegate.cpp b/WebKitTools/DumpRenderTree/win/PolicyDelegate.cpp
new file mode 100644
index 0000000..99a1fd7
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/PolicyDelegate.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 "PolicyDelegate.h"
+
+#include "DumpRenderTree.h"
+
+#include <string>
+
+using std::wstring;
+
+PolicyDelegate::PolicyDelegate()
+ : m_refCount(1)
+{
+}
+
+// IUnknown
+HRESULT STDMETHODCALLTYPE PolicyDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebPolicyDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebPolicyDelegate))
+ *ppvObject = static_cast<IWebPolicyDelegate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE PolicyDelegate::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE PolicyDelegate::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete this;
+
+ return newRef;
+}
+
+HRESULT STDMETHODCALLTYPE PolicyDelegate::decidePolicyForNavigationAction(
+ /*[in]*/ IWebView* /*webView*/,
+ /*[in]*/ IPropertyBag* /*actionInformation*/,
+ /*[in]*/ IWebURLRequest* request,
+ /*[in]*/ IWebFrame* frame,
+ /*[in]*/ IWebPolicyDecisionListener* listener)
+{
+ BSTR url;
+ request->URL(&url);
+
+ printf("Policy delegate: attempt to load %S\n", url ? url : TEXT(""));
+ SysFreeString(url);
+ listener->ignore();
+
+ return S_OK;
+}
diff --git a/WebKitTools/DumpRenderTree/win/PolicyDelegate.h b/WebKitTools/DumpRenderTree/win/PolicyDelegate.h
new file mode 100644
index 0000000..b9844f4
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/PolicyDelegate.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 PolicyDelegate_h
+#define PolicyDelegate_h
+
+#include <WebKit/WebKit.h>
+
+class PolicyDelegate : public IWebPolicyDelegate {
+public:
+ PolicyDelegate();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebPolicyDelegate
+ virtual HRESULT STDMETHODCALLTYPE decidePolicyForNavigationAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IPropertyBag *actionInformation,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ IWebFrame *frame,
+ /* [in] */ IWebPolicyDecisionListener *listener);
+
+ virtual HRESULT STDMETHODCALLTYPE decidePolicyForNewWindowAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IPropertyBag *actionInformation,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ BSTR frameName,
+ /* [in] */ IWebPolicyDecisionListener *listener){ return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE decidePolicyForMIMEType(
+ /* [in] */ IWebView *webView,
+ /* [in] */ BSTR type,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ IWebFrame *frame,
+ /* [in] */ IWebPolicyDecisionListener *listener){ return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE unableToImplementPolicyWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebFrame *frame){ return E_NOTIMPL; }
+
+private:
+ ULONG m_refCount;
+};
+
+#endif // PolicyDelegate_h
diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp
new file mode 100644
index 0000000..1e77eda
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 "ResourceLoadDelegate.h"
+
+#include "DumpRenderTree.h"
+#include "LayoutTestController.h"
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+#include <sstream>
+
+using std::wstring;
+using std::wiostream;
+
+static inline wstring wstringFromBSTR(BSTR str)
+{
+ return wstring(str, ::SysStringLen(str));
+}
+
+wstring wstringFromInt(int i)
+{
+ std::wostringstream ss;
+ ss << i;
+ return ss.str();
+}
+
+typedef HashMap<unsigned long, wstring> IdentifierMap;
+
+IdentifierMap& urlMap()
+{
+ static IdentifierMap urlMap;
+
+ return urlMap;
+}
+
+static wstring descriptionSuitableForTestResult(unsigned long identifier)
+{
+ IdentifierMap::iterator it = urlMap().find(identifier);
+
+ if (it == urlMap().end())
+ return L"<unknown>";
+
+ return urlSuitableForTestResult(it->second);
+}
+
+static wstring descriptionSuitableForTestResult(IWebURLRequest* request)
+{
+ if (!request)
+ return L"(null)";
+
+ BSTR urlBSTR;
+ if (FAILED(request->URL(&urlBSTR)))
+ return wstring();
+
+ wstring url = urlSuitableForTestResult(wstringFromBSTR(urlBSTR));
+ ::SysFreeString(urlBSTR);
+
+ return L"<NSURLRequest " + url + L">";
+}
+
+static wstring descriptionSuitableForTestResult(IWebURLResponse* response)
+{
+ if (!response)
+ return L"(null)";
+
+ BSTR urlBSTR;
+ if (FAILED(response->URL(&urlBSTR)))
+ return wstring();
+
+ wstring url = urlSuitableForTestResult(wstringFromBSTR(urlBSTR));
+ ::SysFreeString(urlBSTR);
+
+ return L"<NSURLResponse " + url + L">";
+}
+
+static wstring descriptionSuitableForTestResult(IWebError* error, unsigned long identifier)
+{
+ wstring result = L"<NSError ";
+
+ BSTR domainSTR;
+ if (FAILED(error->domain(&domainSTR)))
+ return wstring();
+
+ wstring domain = wstringFromBSTR(domainSTR);
+ ::SysFreeString(domainSTR);
+
+ int code;
+ if (FAILED(error->code(&code)))
+ return wstring();
+
+ if (domain == L"CFURLErrorDomain") {
+ domain = L"NSURLErrorDomain";
+
+ // Convert kCFURLErrorUnknown to NSURLErrorUnknown
+ if (code == -998)
+ code = -1;
+ } else if (domain == L"kCFErrorDomainWinSock") {
+ domain = L"NSURLErrorDomain";
+
+ // Convert the winsock error code to an NSURLError code.
+ if (code == WSAEADDRNOTAVAIL)
+ code = -1004; // NSURLErrorCannotConnectToHose;
+ }
+
+ result += L"domain " + domain;
+ result += L", code " + wstringFromInt(code);
+
+ BSTR failingURLSTR;
+ if (FAILED(error->failingURL(&failingURLSTR)))
+ return wstring();
+
+ wstring failingURL;
+
+ // If the error doesn't have a failing URL, we fake one by using the URL the resource had
+ // at creation time. This seems to work fine for now.
+ // See <rdar://problem/5064234> CFErrors should have failingURL key.
+ if (failingURLSTR)
+ failingURL = wstringFromBSTR(failingURLSTR);
+ else
+ failingURL = descriptionSuitableForTestResult(identifier);
+
+ ::SysFreeString(failingURLSTR);
+
+ result += L", failing URL \"" + urlSuitableForTestResult(failingURL) + L"\">";
+
+ return result;
+}
+
+ResourceLoadDelegate::ResourceLoadDelegate()
+ : m_refCount(1)
+{
+}
+
+ResourceLoadDelegate::~ResourceLoadDelegate()
+{
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebResourceLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebResourceLoadDelegate))
+ *ppvObject = static_cast<IWebResourceLoadDelegate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE ResourceLoadDelegate::AddRef(void)
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE ResourceLoadDelegate::Release(void)
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::identifierForInitialRequest(
+ /* [in] */ IWebView* webView,
+ /* [in] */ IWebURLRequest* request,
+ /* [in] */ IWebDataSource* dataSource,
+ /* [in] */ unsigned long identifier)
+{
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
+ BSTR urlStr;
+ if (FAILED(request->URL(&urlStr)))
+ return E_FAIL;
+
+ urlMap().set(identifier, wstringFromBSTR(urlStr));
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::willSendRequest(
+ /* [in] */ IWebView* webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLRequest* request,
+ /* [in] */ IWebURLResponse* redirectResponse,
+ /* [in] */ IWebDataSource* dataSource,
+ /* [retval][out] */ IWebURLRequest **newRequest)
+{
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
+ printf("%S - willSendRequest %S redirectResponse %S\n",
+ descriptionSuitableForTestResult(identifier).c_str(),
+ descriptionSuitableForTestResult(request).c_str(),
+ descriptionSuitableForTestResult(redirectResponse).c_str());
+ }
+
+ request->AddRef();
+ *newRequest = request;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFinishLoadingFromDataSource(
+ /* [in] */ IWebView* webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebDataSource* dataSource)
+{
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
+ printf("%S - didFinishLoading\n",
+ descriptionSuitableForTestResult(identifier).c_str()),
+ urlMap().remove(identifier);
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFailLoadingWithError(
+ /* [in] */ IWebView* webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebError* error,
+ /* [in] */ IWebDataSource* dataSource)
+{
+ if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
+ printf("%S - didFailLoadingWithError: %S\n",
+ descriptionSuitableForTestResult(identifier).c_str(),
+ descriptionSuitableForTestResult(error, identifier).c_str());
+ urlMap().remove(identifier);
+ }
+
+ return S_OK;
+}
diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h
new file mode 100644
index 0000000..e259adc
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 ResourceLoadDelegate_h
+#define ResourceLoadDelegate_h
+
+#include <WebKit/WebKit.h>
+
+class ResourceLoadDelegate : public IWebResourceLoadDelegate {
+public:
+ ResourceLoadDelegate();
+ virtual ~ResourceLoadDelegate();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebResourceLoadDelegate
+ virtual HRESULT STDMETHODCALLTYPE identifierForInitialRequest(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ IWebDataSource *dataSource,
+ /* [in] */ unsigned long identifier);
+
+ virtual HRESULT STDMETHODCALLTYPE willSendRequest(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLRequest *request,
+ /* [in] */ IWebURLResponse *redirectResponse,
+ /* [in] */ IWebDataSource *dataSource,
+ /* [retval][out] */ IWebURLRequest **newRequest);
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveAuthenticationChallenge(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLAuthenticationChallenge *challenge,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didCancelAuthenticationChallenge(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLAuthenticationChallenge *challenge,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveResponse(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebURLResponse *response,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didReceiveContentLength(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ UINT length,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE didFinishLoadingFromDataSource(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebDataSource *dataSource);
+
+ virtual HRESULT STDMETHODCALLTYPE didFailLoadingWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebDataSource *dataSource);
+
+ virtual HRESULT STDMETHODCALLTYPE plugInFailedWithError(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IWebError *error,
+ /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+protected:
+ ULONG m_refCount;
+};
+
+#endif // ResourceLoadDelegate_h
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.def b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.def
new file mode 100644
index 0000000..92cdb12
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.def
@@ -0,0 +1,6 @@
+LIBRARY "TestNetscapePlugin"
+
+EXPORTS
+ NP_GetEntryPoints @1
+ NP_Initialize @2
+ NP_Shutdown @3
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.rc b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.rc
new file mode 100644
index 0000000..7801de9
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.rc
@@ -0,0 +1,101 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "Apple Inc."
+ VALUE "FileDescription", "TestNetscapePlugIn"
+ VALUE "FileOpenName", "test netscape content"
+ VALUE "LegalCopyright", "Copyright Apple Inc. 2007-2008"
+ VALUE "MIMEType", "application/x-webkit-test-netscape"
+ VALUE "OriginalFilename", "npTestNetscapePlugin.dll"
+ VALUE "ProductName", "TestNetscapePlugIn"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj
new file mode 100644
index 0000000..eced57e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/TestNetscapePlugin.vcproj
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="TestNetscapePlugin"
+ ProjectGUID="{C0737398-3565-439E-A2B8-AB2BE4D5430C}"
+ RootNamespace="TestNetscapePlugin"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin.subproj&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
+ ModuleDefinitionFile="TestNetscapePlugin.def"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin.subproj&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
+ ModuleDefinitionFile="TestNetscapePlugin.def"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_Internal|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin.subproj&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
+ ModuleDefinitionFile="TestNetscapePlugin.def"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\main.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\TestNetscapePlugIn.subproj\PluginObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\TestNetscapePlugIn.subproj\PluginObject.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\TestNetscapePlugin.def"
+ >
+ </File>
+ <File
+ RelativePath=".\TestNetscapePlugin.rc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\TestNetscapePlugIn.subproj\TestObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\TestNetscapePlugIn.subproj\TestObject.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.c b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.c
new file mode 100644
index 0000000..829a32c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2007 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. ``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 "PluginObject.h"
+
+#include <stdio.h>
+
+extern "C"
+NPError __stdcall NP_Initialize(NPNetscapeFuncs* browserFuncs)
+{
+ browser = browserFuncs;
+ return NPERR_NO_ERROR;
+}
+
+extern "C"
+NPError __stdcall NP_GetEntryPoints(NPPluginFuncs* pluginFuncs)
+{
+ pluginFuncs->version = 11;
+ pluginFuncs->size = sizeof(pluginFuncs);
+ pluginFuncs->newp = NPP_New;
+ pluginFuncs->destroy = NPP_Destroy;
+ pluginFuncs->setwindow = NPP_SetWindow;
+ pluginFuncs->newstream = NPP_NewStream;
+ pluginFuncs->destroystream = NPP_DestroyStream;
+ pluginFuncs->asfile = NPP_StreamAsFile;
+ pluginFuncs->writeready = NPP_WriteReady;
+ pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
+ pluginFuncs->print = NPP_Print;
+ pluginFuncs->event = NPP_HandleEvent;
+ pluginFuncs->urlnotify = NPP_URLNotify;
+ pluginFuncs->getvalue = NPP_GetValue;
+ pluginFuncs->setvalue = NPP_SetValue;
+
+ return NPERR_NO_ERROR;
+}
+
+
+extern "C"
+NPError __stdcall NP_Shutdown()
+{
+ return NPERR_NO_ERROR;
+}
+
+
+NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved)
+{
+ if (browser->version >= 14) {
+ PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
+
+ obj->onStreamLoad = NULL;
+
+ for (int16 i = 0; i < argc; i++) {
+ if (_stricmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
+ obj->onStreamLoad = _strdup(argv[i]);
+ }
+
+ instance->pdata = obj;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_Destroy(NPP instance, NPSavedData **save)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ if (obj) {
+ if (obj->onStreamLoad)
+ free(obj->onStreamLoad);
+
+ if (obj->logDestroy)
+ printf("PLUGIN: NPP_Destroy\n");
+
+ browser->releaseobject(&obj->header);
+ }
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_SetWindow(NPP instance, NPWindow *window)
+{
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
+{
+ PluginObject* obj = (PluginObject*)instance->pdata;
+ obj->stream = stream;
+ *stype = NP_ASFILEONLY;
+
+ if (obj->onStreamLoad) {
+ NPObject *windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString script;
+ script.UTF8Characters = obj->onStreamLoad;
+ script.UTF8Length = strlen(obj->onStreamLoad);
+
+ NPVariant browserResult;
+ browser->evaluate(obj->npp, windowScriptObject, &script, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
+{
+ return NPERR_NO_ERROR;
+}
+
+int32 NPP_WriteReady(NPP instance, NPStream *stream)
+{
+ return 0;
+}
+
+int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
+{
+ return 0;
+}
+
+void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
+{
+}
+
+void NPP_Print(NPP instance, NPPrint *platformPrint)
+{
+}
+
+int16 NPP_HandleEvent(NPP instance, void *event)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ if (!obj->eventLogging)
+ return 0;
+
+ // FIXME: Implement this
+ return 0;
+}
+
+void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+
+ handleCallback(obj, url, reason, notifyData);
+}
+
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
+{
+ if (variable == NPPVpluginScriptableNPObject) {
+ void **v = (void **)value;
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ // Return value is expected to be retained
+ browser->retainobject((NPObject *)obj);
+ *v = obj;
+ return NPERR_NO_ERROR;
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
+{
+ return NPERR_GENERIC_ERROR;
+}
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
new file mode 100644
index 0000000..ab54872
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
@@ -0,0 +1,215 @@
+/*
+ IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
+ consideration of your agreement to the following terms, and your use, installation,
+ modification or redistribution of this Apple software constitutes acceptance of these
+ terms. If you do not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject to these
+ terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
+ this original Apple software (the "Apple Software"), to use, reproduce, modify and
+ redistribute the Apple Software, with or without modifications, in source and/or binary
+ forms; provided that if you redistribute the Apple Software in its entirety and without
+ modifications, you must retain this notice and the following text and disclaimers in all
+ such redistributions of the Apple Software. Neither the name, trademarks, service marks
+ or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
+ the Apple Software without specific prior written permission from Apple. Except as expressly
+ stated in this notice, no other rights or licenses, express or implied, are granted by Apple
+ herein, including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
+ EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
+ USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
+ REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
+ WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
+ OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+
+#include <stdio.h>
+
+extern "C"
+NPError __stdcall NP_Initialize(NPNetscapeFuncs* browserFuncs)
+{
+ browser = browserFuncs;
+ return NPERR_NO_ERROR;
+}
+
+extern "C"
+NPError __stdcall NP_GetEntryPoints(NPPluginFuncs* pluginFuncs)
+{
+ pluginFuncs->version = 11;
+ pluginFuncs->size = sizeof(pluginFuncs);
+ pluginFuncs->newp = NPP_New;
+ pluginFuncs->destroy = NPP_Destroy;
+ pluginFuncs->setwindow = NPP_SetWindow;
+ pluginFuncs->newstream = NPP_NewStream;
+ pluginFuncs->destroystream = NPP_DestroyStream;
+ pluginFuncs->asfile = NPP_StreamAsFile;
+ pluginFuncs->writeready = NPP_WriteReady;
+ pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
+ pluginFuncs->print = NPP_Print;
+ pluginFuncs->event = NPP_HandleEvent;
+ pluginFuncs->urlnotify = NPP_URLNotify;
+ pluginFuncs->getvalue = NPP_GetValue;
+ pluginFuncs->setvalue = NPP_SetValue;
+
+ return NPERR_NO_ERROR;
+}
+
+
+extern "C"
+NPError __stdcall NP_Shutdown()
+{
+ return NPERR_NO_ERROR;
+}
+
+
+NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved)
+{
+ if (browser->version >= 14) {
+ PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
+
+ for (int16 i = 0; i < argc; i++) {
+ if (_stricmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
+ obj->onStreamLoad = _strdup(argv[i]);
+ else if (_stricmp(argn[i], "onStreamDestroy") == 0 && !obj->onStreamDestroy)
+ obj->onStreamDestroy = _strdup(argv[i]);
+ else if (_stricmp(argn[i], "onURLNotify") == 0 && !obj->onURLNotify)
+ obj->onURLNotify = _strdup(argv[i]);
+ }
+
+ instance->pdata = obj;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_Destroy(NPP instance, NPSavedData **save)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ if (obj) {
+ if (obj->onStreamLoad)
+ free(obj->onStreamLoad);
+
+ if (obj->onURLNotify)
+ free(obj->onURLNotify);
+
+ if (obj->onStreamDestroy)
+ free(obj->onStreamDestroy);
+
+ if (obj->logDestroy)
+ printf("PLUGIN: NPP_Destroy\n");
+
+ browser->releaseobject(&obj->header);
+ }
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_SetWindow(NPP instance, NPWindow *window)
+{
+ return NPERR_NO_ERROR;
+}
+
+static void executeScript(const PluginObject* obj, const char* script)
+{
+ NPObject *windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString npScript;
+ npScript.UTF8Characters = script;
+ npScript.UTF8Length = strlen(script);
+
+ NPVariant browserResult;
+ browser->evaluate(obj->npp, windowScriptObject, &npScript, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+}
+
+NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
+{
+ PluginObject* obj = (PluginObject*)instance->pdata;
+
+ if (obj->returnErrorFromNewStream)
+ return NPERR_GENERIC_ERROR;
+
+ obj->stream = stream;
+ *stype = NP_ASFILEONLY;
+
+ if (obj->onStreamLoad)
+ executeScript(obj, obj->onStreamLoad);
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
+{
+ PluginObject* obj = (PluginObject*)instance->pdata;
+
+ if (obj->onStreamDestroy)
+ executeScript(obj, obj->onStreamDestroy);
+
+ return NPERR_NO_ERROR;
+}
+
+int32 NPP_WriteReady(NPP instance, NPStream *stream)
+{
+ return 0;
+}
+
+int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
+{
+ return 0;
+}
+
+void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
+{
+}
+
+void NPP_Print(NPP instance, NPPrint *platformPrint)
+{
+}
+
+int16 NPP_HandleEvent(NPP instance, void *event)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ if (!obj->eventLogging)
+ return 0;
+
+ // FIXME: Implement this
+ return 0;
+}
+
+void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
+{
+ PluginObject *obj = (PluginObject*)instance->pdata;
+
+ if (obj->onURLNotify)
+ executeScript(obj, obj->onURLNotify);
+
+ handleCallback(obj, url, reason, notifyData);
+}
+
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
+{
+ if (variable == NPPVpluginScriptableNPObject) {
+ void **v = (void **)value;
+ PluginObject *obj = (PluginObject*)instance->pdata;
+ // Return value is expected to be retained
+ browser->retainobject((NPObject *)obj);
+ *v = obj;
+ return NPERR_NO_ERROR;
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
+{
+ return NPERR_GENERIC_ERROR;
+}
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/resource.h b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/resource.h
new file mode 100644
index 0000000..b0ce340
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by TestNetscapePlugin.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/WebKitTools/DumpRenderTree/win/UIDelegate.cpp b/WebKitTools/DumpRenderTree/win/UIDelegate.cpp
new file mode 100755
index 0000000..a2532a5
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/UIDelegate.cpp
@@ -0,0 +1,444 @@
+/*
+ * Copyright (C) 2005, 2006, 2007, 2008 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.
+ * 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 "UIDelegate.h"
+
+#include "DumpRenderTree.h"
+#include "DraggingInfo.h"
+#include "EventSender.h"
+#include "LayoutTestController.h"
+
+#include <WebCore/COMPtr.h>
+#include <wtf/Platform.h>
+#include <wtf/Vector.h>
+#include <JavaScriptCore/Assertions.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <WebKit/WebKit.h>
+#include <stdio.h>
+
+using std::wstring;
+
+class DRTUndoObject {
+public:
+ DRTUndoObject(IWebUndoTarget* target, BSTR actionName, IUnknown* obj)
+ : m_target(target)
+ , m_actionName(SysAllocString(actionName))
+ , m_obj(obj)
+ {
+ }
+
+ ~DRTUndoObject()
+ {
+ SysFreeString(m_actionName);
+ }
+
+ void invoke()
+ {
+ m_target->invoke(m_actionName, m_obj.get());
+ }
+
+private:
+ IWebUndoTarget* m_target;
+ BSTR m_actionName;
+ COMPtr<IUnknown> m_obj;
+};
+
+class DRTUndoStack {
+public:
+ ~DRTUndoStack() { deleteAllValues(m_undoVector); }
+
+ bool isEmpty() const { return m_undoVector.isEmpty(); }
+ void clear() { deleteAllValues(m_undoVector); m_undoVector.clear(); }
+
+ void push(DRTUndoObject* undoObject) { m_undoVector.append(undoObject); }
+ DRTUndoObject* pop() { DRTUndoObject* top = m_undoVector.last(); m_undoVector.removeLast(); return top; }
+
+private:
+ Vector<DRTUndoObject*> m_undoVector;
+};
+
+class DRTUndoManager {
+public:
+ DRTUndoManager();
+
+ void removeAllActions();
+ void registerUndoWithTarget(IWebUndoTarget* target, BSTR actionName, IUnknown* obj);
+ void redo();
+ void undo();
+ bool canRedo() { return !m_redoStack->isEmpty(); }
+ bool canUndo() { return !m_undoStack->isEmpty(); }
+
+private:
+ OwnPtr<DRTUndoStack> m_redoStack;
+ OwnPtr<DRTUndoStack> m_undoStack;
+ bool m_isRedoing;
+ bool m_isUndoing;
+};
+
+DRTUndoManager::DRTUndoManager()
+ : m_redoStack(new DRTUndoStack)
+ , m_undoStack(new DRTUndoStack)
+ , m_isRedoing(false)
+ , m_isUndoing(false)
+{
+}
+
+void DRTUndoManager::removeAllActions()
+{
+ m_redoStack->clear();
+ m_undoStack->clear();
+}
+
+void DRTUndoManager::registerUndoWithTarget(IWebUndoTarget* target, BSTR actionName, IUnknown* obj)
+{
+ if (!m_isUndoing && !m_isRedoing)
+ m_redoStack->clear();
+
+ DRTUndoStack* stack = m_isUndoing ? m_redoStack.get() : m_undoStack.get();
+ stack->push(new DRTUndoObject(target, actionName, obj));
+}
+
+void DRTUndoManager::redo()
+{
+ if (!canRedo())
+ return;
+
+ m_isRedoing = true;
+
+ DRTUndoObject* redoObject = m_redoStack->pop();
+ redoObject->invoke();
+ delete redoObject;
+
+ m_isRedoing = false;
+}
+
+void DRTUndoManager::undo()
+{
+ if (!canUndo())
+ return;
+
+ m_isUndoing = true;
+
+ DRTUndoObject* undoObject = m_undoStack->pop();
+ undoObject->invoke();
+ delete undoObject;
+
+ m_isUndoing = false;
+}
+
+UIDelegate::UIDelegate()
+ : m_refCount(1)
+ , m_undoManager(new DRTUndoManager)
+{
+ m_frame.bottom = 0;
+ m_frame.top = 0;
+ m_frame.left = 0;
+ m_frame.right = 0;
+}
+
+void UIDelegate::resetUndoManager()
+{
+ m_undoManager.set(new DRTUndoManager);
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<IWebUIDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegate))
+ *ppvObject = static_cast<IWebUIDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate))
+ *ppvObject = static_cast<IWebUIDelegatePrivate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate2))
+ *ppvObject = static_cast<IWebUIDelegatePrivate2*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate3))
+ *ppvObject = static_cast<IWebUIDelegatePrivate3*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE UIDelegate::AddRef()
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE UIDelegate::Release()
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete(this);
+
+ return newRef;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::hasCustomMenuImplementation(
+ /* [retval][out] */ BOOL *hasCustomMenus)
+{
+ *hasCustomMenus = TRUE;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::trackCustomPopupMenu(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE menu,
+ /* [in] */ LPPOINT point)
+{
+ // Do nothing
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::registerUndoWithTarget(
+ /* [in] */ IWebUndoTarget* target,
+ /* [in] */ BSTR actionName,
+ /* [in] */ IUnknown* actionArg)
+{
+ m_undoManager->registerUndoWithTarget(target, actionName, actionArg);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::removeAllActionsWithTarget(
+ /* [in] */ IWebUndoTarget*)
+{
+ m_undoManager->removeAllActions();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::setActionTitle(
+ /* [in] */ BSTR actionTitle)
+{
+ // It is not neccessary to implement this for DRT because there is
+ // menu to write out the title to.
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::undo()
+{
+ m_undoManager->undo();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::redo()
+{
+ m_undoManager->redo();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::canUndo(
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result)
+ return E_POINTER;
+
+ *result = m_undoManager->canUndo();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::canRedo(
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result)
+ return E_POINTER;
+
+ *result = m_undoManager->canRedo();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::setFrame(
+ /* [in] */ IWebView* /*sender*/,
+ /* [in] */ RECT* frame)
+{
+ m_frame = *frame;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewFrame(
+ /* [in] */ IWebView* /*sender*/,
+ /* [retval][out] */ RECT* frame)
+{
+ *frame = m_frame;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptAlertPanelWithMessage(
+ /* [in] */ IWebView* /*sender*/,
+ /* [in] */ BSTR message)
+{
+ printf("ALERT: %S\n", message ? message : L"");
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptConfirmPanelWithMessage(
+ /* [in] */ IWebView* sender,
+ /* [in] */ BSTR message,
+ /* [retval][out] */ BOOL* result)
+{
+ printf("CONFIRM: %S\n", message ? message : L"");
+ *result = TRUE;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptTextInputPanelWithPrompt(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [in] */ BSTR defaultText,
+ /* [retval][out] */ BSTR *result)
+{
+ printf("PROMPT: %S, default text: %S\n", message ? message : L"", defaultText ? defaultText : L"");
+ *result = SysAllocString(defaultText);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::runBeforeUnloadConfirmPanelWithMessage(
+ /* [in] */ IWebView* /*sender*/,
+ /* [in] */ BSTR /*message*/,
+ /* [in] */ IWebFrame* /*initiatedByFrame*/,
+ /* [retval][out] */ BOOL* result)
+{
+ if (!result)
+ return E_POINTER;
+ *result = TRUE;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewAddMessageToConsole(
+ /* [in] */ IWebView* sender,
+ /* [in] */ BSTR message,
+ /* [in] */ int lineNumber,
+ /* [in] */ BSTR url,
+ /* [in] */ BOOL isError)
+{
+ wstring newMessage;
+ if (message) {
+ newMessage = message;
+ size_t fileProtocol = newMessage.find(L"file://");
+ if (fileProtocol != wstring::npos)
+ newMessage = newMessage.substr(0, fileProtocol) + urlSuitableForTestResult(newMessage.substr(fileProtocol));
+ }
+
+ printf("CONSOLE MESSAGE: line %d: %S\n", lineNumber, newMessage.c_str());
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::doDragDrop(
+ /* [in] */ IWebView* sender,
+ /* [in] */ IDataObject* object,
+ /* [in] */ IDropSource* source,
+ /* [in] */ DWORD okEffect,
+ /* [retval][out] */ DWORD* performedEffect)
+{
+ if (!performedEffect)
+ return E_POINTER;
+
+ *performedEffect = 0;
+
+ draggingInfo = new DraggingInfo(object, source);
+ replaySavedEvents();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewGetDlgCode(
+ /* [in] */ IWebView* /*sender*/,
+ /* [in] */ UINT /*keyCode*/,
+ /* [retval][out] */ LONG_PTR *code)
+{
+ if (!code)
+ return E_POINTER;
+ *code = 0;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::createWebViewWithRequest(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebURLRequest *request,
+ /* [retval][out] */ IWebView **newWebView)
+{
+ if (!::gLayoutTestController->canOpenWindows())
+ return E_FAIL;
+ *newWebView = createWebViewAndOffscreenWindow();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewClose(
+ /* [in] */ IWebView *sender)
+{
+ HWND hostWindow;
+ sender->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
+ DestroyWindow(hostWindow);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewFocus(
+ /* [in] */ IWebView *sender)
+{
+ HWND hostWindow;
+ sender->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
+ SetForegroundWindow(hostWindow);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewUnfocus(
+ /* [in] */ IWebView *sender)
+{
+ SetForegroundWindow(GetDesktopWindow());
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::webViewPainted(
+ /* [in] */ IWebView *sender)
+{
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE UIDelegate::exceededDatabaseQuota(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame,
+ /* [in] */ IWebSecurityOrigin *origin,
+ /* [in] */ BSTR databaseIdentifier)
+{
+ static const unsigned long long defaultQuota = 5 * 1024 * 1024;
+ origin->setQuota(defaultQuota);
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE UIDelegate::setStatusText(IWebView*, BSTR text)
+{
+ if (gLayoutTestController->dumpStatusCallbacks())
+ printf("UI DELEGATE STATUS CALLBACK: setStatusText:%S\n", text ? text : L"");
+ return S_OK;
+}
diff --git a/WebKitTools/DumpRenderTree/win/UIDelegate.h b/WebKitTools/DumpRenderTree/win/UIDelegate.h
new file mode 100755
index 0000000..2113957
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/UIDelegate.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 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.
+ * 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 UIDelegate_h
+#define UIDelegate_h
+
+#include <WebKit/WebKit.h>
+#include <wtf/OwnPtr.h>
+#include <windef.h>
+
+class DRTUndoManager;
+
+class UIDelegate : public IWebUIDelegate, IWebUIDelegatePrivate3 {
+public:
+ UIDelegate();
+
+ void resetUndoManager();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IWebUIDelegate
+ virtual HRESULT STDMETHODCALLTYPE createWebViewWithRequest(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebURLRequest *request,
+ /* [retval][out] */ IWebView **newWebView);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewShow(
+ /* [in] */ IWebView *sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewClose(
+ /* [in] */ IWebView *sender);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFocus(
+ /* [in] */ IWebView *sender);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewUnfocus(
+ /* [in] */ IWebView *sender);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFirstResponder(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ OLE_HANDLE *responder) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE makeFirstResponder(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE responder) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setStatusText(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR text);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewStatusText(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BSTR *text) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewAreToolbarsVisible(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BOOL *visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setToolbarsVisible(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewIsStatusBarVisible(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BOOL *visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setStatusBarVisible(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL visible) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewIsResizable(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BOOL *resizable) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setResizable(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL resizable) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE setFrame(
+ /* [in] */ IWebView *sender,
+ /* [in] */ RECT *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewFrame(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ RECT *frame);
+
+ virtual HRESULT STDMETHODCALLTYPE setContentRect(
+ /* [in] */ IWebView *sender,
+ /* [in] */ RECT *contentRect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewContentRect(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ RECT *contentRect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptAlertPanelWithMessage(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message);
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptConfirmPanelWithMessage(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE runJavaScriptTextInputPanelWithPrompt(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [in] */ BSTR defaultText,
+ /* [retval][out] */ BSTR *result);
+
+ virtual HRESULT STDMETHODCALLTYPE runBeforeUnloadConfirmPanelWithMessage(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [in] */ IWebFrame *initiatedByFrame,
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE runOpenPanelForFileButtonWithResultListener(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebOpenPanelResultListener *resultListener) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE mouseDidMoveOverElement(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IPropertyBag *elementInformation,
+ /* [in] */ UINT modifierFlags) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE contextMenuItemsForElement(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IPropertyBag *element,
+ /* [in] */ OLE_HANDLE defaultItems,
+ /* [retval][out] */ OLE_HANDLE *resultMenu) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE validateUserInterfaceItem(
+ /* [in] */ IWebView *webView,
+ /* [in] */ UINT itemCommandID,
+ /* [in] */ BOOL defaultValidation,
+ /* [retval][out] */ BOOL *isValid) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE shouldPerformAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ UINT itemCommandID,
+ /* [in] */ UINT sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE dragDestinationActionMaskForDraggingInfo(
+ /* [in] */ IWebView *webView,
+ /* [in] */ IDataObject *draggingInfo,
+ /* [retval][out] */ WebDragDestinationAction *action) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformDragDestinationAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ WebDragDestinationAction action,
+ /* [in] */ IDataObject *draggingInfo) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE dragSourceActionMaskForPoint(
+ /* [in] */ IWebView *webView,
+ /* [in] */ LPPOINT point,
+ /* [retval][out] */ WebDragSourceAction *action) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE willPerformDragSourceAction(
+ /* [in] */ IWebView *webView,
+ /* [in] */ WebDragSourceAction action,
+ /* [in] */ LPPOINT point,
+ /* [in] */ IDataObject *pasteboard) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE contextMenuItemSelected(
+ /* [in] */ IWebView *sender,
+ /* [in] */ void *item,
+ /* [in] */ IPropertyBag *element) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE hasCustomMenuImplementation(
+ /* [retval][out] */ BOOL *hasCustomMenus);
+
+ virtual HRESULT STDMETHODCALLTYPE trackCustomPopupMenu(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE menu,
+ /* [in] */ LPPOINT point);
+
+ virtual HRESULT STDMETHODCALLTYPE measureCustomMenuItem(
+ /* [in] */ IWebView *sender,
+ /* [in] */ void *measureItem) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE drawCustomMenuItem(
+ /* [in] */ IWebView *sender,
+ /* [in] */ void *drawItem) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE addCustomMenuDrawingData(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE menu) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE cleanUpCustomMenuDrawingData(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE menu) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE canTakeFocus(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL forward,
+ /* [out] */ BOOL *result) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE takeFocus(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BOOL forward) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE registerUndoWithTarget(
+ /* [in] */ IWebUndoTarget *target,
+ /* [in] */ BSTR actionName,
+ /* [in] */ IUnknown *actionArg);
+
+ virtual HRESULT STDMETHODCALLTYPE removeAllActionsWithTarget(
+ /* [in] */ IWebUndoTarget *target);
+
+ virtual HRESULT STDMETHODCALLTYPE setActionTitle(
+ /* [in] */ BSTR actionTitle);
+
+ virtual HRESULT STDMETHODCALLTYPE undo();
+
+ virtual HRESULT STDMETHODCALLTYPE redo();
+
+ virtual HRESULT STDMETHODCALLTYPE canUndo(
+ /* [retval][out] */ BOOL *result);
+
+ virtual HRESULT STDMETHODCALLTYPE canRedo(
+ /* [retval][out] */ BOOL *result);
+
+protected:
+ // IWebUIDelegatePrivate
+
+ virtual HRESULT STDMETHODCALLTYPE webViewResizerRect(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ RECT *rect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewSendResizeMessage(
+ /* [in] */ UINT uMsg,
+ /* [in] */ WPARAM wParam,
+ /* [in] */ LPARAM lParam) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewDrawResizer(
+ /* [in] */ IWebView *sender,
+ /* [in] */ HDC dc,
+ /* [in] */ BOOL overlapsContent,
+ /* [in] */ RECT *rect) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewScrolled(
+ /* [in] */ IWebView *sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewAddMessageToConsole(
+ /* [in] */ IWebView *sender,
+ /* [in] */ BSTR message,
+ /* [in] */ int lineNumber,
+ /* [in] */ BSTR url,
+ /* [in] */ BOOL isError);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewShouldInterruptJavaScript(
+ /* [in] */ IWebView *sender,
+ /* [retval][out] */ BOOL *result) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewReceivedFocus(
+ /* [in] */ IWebView *sender) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE webViewLostFocus(
+ /* [in] */ IWebView *sender,
+ /* [in] */ OLE_HANDLE loseFocusTo) { return E_NOTIMPL; }
+
+ virtual HRESULT STDMETHODCALLTYPE doDragDrop(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IDataObject *dataObject,
+ /* [in] */ IDropSource *dropSource,
+ /* [in] */ DWORD okEffect,
+ /* [retval][out] */ DWORD *performedEffect);
+
+ virtual HRESULT STDMETHODCALLTYPE webViewGetDlgCode(
+ /* [in] */ IWebView *sender,
+ /* [in] */ UINT keyCode,
+ /* [retval][out] */ LONG_PTR *code);
+
+ // IWebUIDelegatePrivate2
+
+ virtual HRESULT STDMETHODCALLTYPE webViewPainted(
+ /* [in] */ IWebView *sender);
+
+ // IWebUIDelegatePrivate3
+
+ virtual HRESULT STDMETHODCALLTYPE exceededDatabaseQuota(
+ /* [in] */ IWebView *sender,
+ /* [in] */ IWebFrame *frame,
+ /* [in] */ IWebSecurityOrigin *origin,
+ /* [in] */ BSTR databaseIdentifier);
+
+ ULONG m_refCount;
+
+private:
+ RECT m_frame;
+ OwnPtr<DRTUndoManager> m_undoManager;
+};
+
+#endif
diff --git a/WebKitTools/DumpRenderTree/win/WorkQueueItemWin.cpp b/WebKitTools/DumpRenderTree/win/WorkQueueItemWin.cpp
new file mode 100644
index 0000000..a489498
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/win/WorkQueueItemWin.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2007 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.
+ * 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 "WorkQueueItem.h"
+
+#include "DumpRenderTree.h"
+#include <WebCore/COMPtr.h>
+#include <WebKit/WebKit.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/JSStringRefCF.h>
+#include <JavaScriptCore/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <string>
+
+using std::wstring;
+
+static wstring jsStringRefToWString(JSStringRef jsStr)
+{
+ size_t length = JSStringGetLength(jsStr);
+ Vector<WCHAR> buffer(length + 1);
+ memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
+ buffer[length] = '\0';
+
+ return buffer.data();
+}
+
+void LoadItem::invoke() const
+{
+ wstring targetString = jsStringRefToWString(target());
+
+ COMPtr<IWebFrame> targetFrame;
+ if (targetString.empty())
+ targetFrame = frame;
+ else {
+ BSTR targetBSTR = SysAllocString(targetString.c_str());
+ bool failed = FAILED(frame->findFrameNamed(targetBSTR, &targetFrame));
+ SysFreeString(targetBSTR);
+ if (failed)
+ return;
+ }
+
+ COMPtr<IWebURLRequest> request;
+ if (FAILED(CoCreateInstance(CLSID_WebURLRequest, 0, CLSCTX_ALL, IID_IWebURLRequest, (void**)&request)))
+ return;
+
+ wstring urlString = jsStringRefToWString(url());
+ BSTR urlBSTR = SysAllocString(urlString.c_str());
+ bool failed = FAILED(request->initWithURL(urlBSTR, WebURLRequestUseProtocolCachePolicy, 60));
+ SysFreeString(urlBSTR);
+ if (failed)
+ return;
+
+ targetFrame->loadRequest(request.get());
+}
+
+void ReloadItem::invoke() const
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebIBActions> webActions;
+ if (SUCCEEDED(webView->QueryInterface(&webActions)))
+ webActions->reload(0);
+}
+
+void ScriptItem::invoke() const
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ wstring scriptString = jsStringRefToWString(script());
+
+ BSTR result;
+ BSTR scriptBSTR = SysAllocString(scriptString.c_str());
+ webView->stringByEvaluatingJavaScriptFromString(scriptBSTR, &result);
+ SysFreeString(result);
+ SysFreeString(scriptBSTR);
+}
+
+void BackForwardItem::invoke() const
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ BOOL result;
+ if (m_howFar == 1) {
+ webView->goForward(&result);
+ return;
+ }
+
+ if (m_howFar == -1) {
+ webView->goBack(&result);
+ return;
+ }
+
+ COMPtr<IWebBackForwardList> bfList;
+ if (FAILED(webView->backForwardList(&bfList)))
+ return;
+
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(bfList->itemAtIndex(m_howFar, &item)))
+ return;
+
+ webView->goToBackForwardItem(item.get(), &result);
+}