summaryrefslogtreecommitdiff
path: root/Tools/WebKitTestRunner
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Tools/WebKitTestRunner
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Tools/WebKitTestRunner')
-rw-r--r--Tools/WebKitTestRunner/CMakeLists.txt121
-rw-r--r--Tools/WebKitTestRunner/DerivedSources.make62
-rw-r--r--Tools/WebKitTestRunner/EventSenderProxy.h27
-rw-r--r--Tools/WebKitTestRunner/FontWithFeatures.otfbin0 -> 14452 bytes
-rw-r--r--Tools/WebKitTestRunner/FontWithFeatures.ttfbin0 -> 12324 bytes
-rw-r--r--Tools/WebKitTestRunner/GNUmakefile.am175
-rw-r--r--Tools/WebKitTestRunner/GeolocationProviderMock.cpp4
-rw-r--r--Tools/WebKitTestRunner/GeolocationProviderMock.h4
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp47
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h31
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.cpp10
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.h17
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.cpp10
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.h17
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp195
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h129
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityController.idl45
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityTextMarker.idl29
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityTextMarkerRange.idl29
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl249
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm577
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl72
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/Bindings/GCController.idl (renamed from Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrappable.h)24
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl262
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl32
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp332
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h25
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/GCController.cpp12
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/GCController.h9
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp373
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h58
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp4
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp557
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h7
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp853
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/TestRunner.h141
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/TextInputController.cpp14
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/TextInputController.h9
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityControllerAtk.cpp37
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.cpp72
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.h13
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp634
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/gtk/ActivateFontsGtk.cpp10
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.cpp6
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.h2
-rw-r--r--Tools/WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp25
-rw-r--r--Tools/WebKitTestRunner/Options.cpp43
-rw-r--r--Tools/WebKitTestRunner/Options.h9
-rw-r--r--Tools/WebKitTestRunner/PixelDumpSupport.cpp2
-rw-r--r--Tools/WebKitTestRunner/PixelDumpSupport.h2
-rw-r--r--Tools/WebKitTestRunner/PlatformGTK.cmake60
-rw-r--r--Tools/WebKitTestRunner/PlatformWebView.h74
-rw-r--r--Tools/WebKitTestRunner/StringFunctions.h10
-rw-r--r--Tools/WebKitTestRunner/TestController.cpp1648
-rw-r--r--Tools/WebKitTestRunner/TestController.h264
-rw-r--r--Tools/WebKitTestRunner/TestInvocation.cpp772
-rw-r--r--Tools/WebKitTestRunner/TestInvocation.h74
-rw-r--r--Tools/WebKitTestRunner/TestOptions.cpp (renamed from Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrapper.cpp)66
-rw-r--r--Tools/WebKitTestRunner/TestOptions.h (renamed from Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrapper.h)51
-rw-r--r--Tools/WebKitTestRunner/WebKitTestRunnerPrefix.h7
-rw-r--r--Tools/WebKitTestRunner/WebNotificationProvider.cpp116
-rw-r--r--Tools/WebKitTestRunner/WebNotificationProvider.h16
-rw-r--r--Tools/WebKitTestRunner/WorkQueueManager.cpp22
-rw-r--r--Tools/WebKitTestRunner/WorkQueueManager.h5
-rw-r--r--Tools/WebKitTestRunner/cairo/TestInvocationCairo.cpp11
-rw-r--r--Tools/WebKitTestRunner/config.h38
-rw-r--r--Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp43
-rw-r--r--Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp95
-rw-r--r--Tools/WebKitTestRunner/gtk/TestControllerGtk.cpp83
-rw-r--r--Tools/WebKitTestRunner/gtk/fonts/AHEM____.TTFbin0 -> 12480 bytes
-rw-r--r--Tools/WebKitTestRunner/gtk/fonts/FontWithNoValidEncoding.fonbin0 -> 8368 bytes
-rw-r--r--Tools/WebKitTestRunner/gtk/fonts/fonts.conf435
-rw-r--r--Tools/WebKitTestRunner/gtk/main.cpp9
73 files changed, 7241 insertions, 2075 deletions
diff --git a/Tools/WebKitTestRunner/CMakeLists.txt b/Tools/WebKitTestRunner/CMakeLists.txt
new file mode 100644
index 000000000..fb7d52339
--- /dev/null
+++ b/Tools/WebKitTestRunner/CMakeLists.txt
@@ -0,0 +1,121 @@
+set(WEBKIT_TESTRUNNER_DIR "${TOOLS_DIR}/WebKitTestRunner")
+set(WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR "${TOOLS_DIR}/WebKitTestRunner/InjectedBundle")
+set(WEBKIT_TESTRUNNER_SHARED_DIR "${TOOLS_DIR}/TestRunnerShared/")
+set(WEBKIT_TESTRUNNER_UISCRIPTCONTEXT_DIR "${WEBKIT_TESTRUNNER_SHARED_DIR}/UIScriptContext")
+set(WEBKIT_TESTRUNNER_BINDINGS_DIR "${WEBKIT_TESTRUNNER_SHARED_DIR}/Bindings")
+
+file(MAKE_DIRECTORY ${DERIVED_SOURCES_DIR}/InjectedBundle)
+file(MAKE_DIRECTORY ${DERIVED_SOURCES_DIR}/UIScriptContext)
+
+set(WebKitTestRunner_SOURCES
+ ${WEBKIT_TESTRUNNER_DIR}/CyclicRedundancyCheck.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/GeolocationProviderMock.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/Options.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/PixelDumpSupport.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/TestController.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/TestInvocation.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/TestOptions.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/WebNotificationProvider.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/WorkQueueManager.cpp
+ ${WEBKIT_TESTRUNNER_UISCRIPTCONTEXT_DIR}/UIScriptContext.cpp
+ ${WEBKIT_TESTRUNNER_UISCRIPTCONTEXT_DIR}/UIScriptController.cpp
+ ${WEBKIT_TESTRUNNER_BINDINGS_DIR}/JSWrapper.cpp
+)
+
+set(WebKitTestRunner_LIBRARIES
+ JavaScriptCore
+ WebCoreTestSupport
+ WebKit2
+)
+
+set(WebKitTestRunner_INCLUDE_DIRECTORIES
+ ${WEBKIT_TESTRUNNER_DIR}
+ ${WEBKIT_TESTRUNNER_DIR}/InjectedBundle
+ ${WEBKIT_TESTRUNNER_DIR}/InjectedBundle/Bindings
+ ${WEBKIT_TESTRUNNER_DIR}/InjectedBundle/atk
+ ${WEBKIT_TESTRUNNER_UISCRIPTCONTEXT_DIR}
+ ${WEBKIT_TESTRUNNER_BINDINGS_DIR}
+ ${WEBCORE_DIR}/testing/js
+ ${WEBKIT2_DIR}/Platform/IPC
+ ${WEBKIT2_DIR}/Shared
+ ${WEBKIT2_DIR}/Shared/API/c
+ ${WEBKIT2_DIR}/Shared/Plugins
+ ${WEBKIT2_DIR}/UIProcess
+ ${WEBKIT2_DIR}/UIProcess/API/C/soup
+ ${WEBKIT2_DIR}/WebProcess/InjectedBundle
+ ${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/c
+ ${DERIVED_SOURCES_DIR}/InjectedBundle
+ ${DERIVED_SOURCES_DIR}/UIScriptContext
+ ${CMAKE_SOURCE_DIR}/Source
+)
+
+set(WebKitTestRunner_SYSTEM_INCLUDE_DIRECTORIES
+ ${LIBSOUP_INCLUDE_DIRS}
+ ${ICU_INCLUDE_DIRS}
+)
+
+set(WebKitTestRunnerInjectedBundle_SOURCES
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/AccessibilityController.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/AccessibilityTextMarker.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/AccessibilityTextMarkerRange.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/AccessibilityUIElement.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/EventSendingController.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/GCController.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/InjectedBundle.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/InjectedBundleMain.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/InjectedBundlePage.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/TestRunner.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/TextInputController.cpp
+
+ ${WEBKIT_TESTRUNNER_BINDINGS_DIR}/JSWrapper.cpp
+)
+
+set(WebKitTestRunnerInjectedBundle_IDL_FILES
+ "${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings/AccessibilityController.idl"
+ "${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings/AccessibilityTextMarker.idl"
+ "${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings/AccessibilityTextMarkerRange.idl"
+ "${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings/AccessibilityUIElement.idl"
+ "${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings/EventSendingController.idl"
+ "${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings/GCController.idl"
+ "${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings/TestRunner.idl"
+ "${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings/TextInputController.idl"
+)
+
+set(WebKitTestRunner_IDL_FILES
+ "${WEBKIT_TESTRUNNER_UISCRIPTCONTEXT_DIR}/Bindings/UIScriptController.idl"
+)
+
+GENERATE_BINDINGS(WebKitTestRunnerInjectedBundleBindings
+ OUTPUT_SOURCE WebKitTestRunnerInjectedBundle_SOURCES
+ INPUT_FILES ${WebKitTestRunnerInjectedBundle_IDL_FILES}
+ BASE_DIR ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings
+ IDL_INCLUDES ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings
+ FEATURES ${FEATURE_DEFINES_WITH_SPACE_SEPARATOR}
+ DESTINATION ${DERIVED_SOURCES_DIR}/InjectedBundle
+ GENERATOR TestRunner)
+
+GENERATE_BINDINGS(WebKitTestRunnerBindings
+ OUTPUT_SOURCE WebKitTestRunner_SOURCES
+ INPUT_FILES ${WebKitTestRunner_IDL_FILES}
+ BASE_DIR ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings
+ IDL_INCLUDES ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/Bindings
+ FEATURES ${FEATURE_DEFINES_WITH_SPACE_SEPARATOR}
+ DESTINATION ${DERIVED_SOURCES_DIR}/UIScriptContext
+ GENERATOR TestRunner)
+
+WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS()
+
+include_directories(${WebKitTestRunner_INCLUDE_DIRECTORIES})
+include_directories(SYSTEM ${WebKitTestRunner_SYSTEM_INCLUDE_DIRECTORIES})
+
+add_library(TestRunnerInjectedBundle SHARED ${WebKitTestRunnerInjectedBundle_SOURCES})
+target_link_libraries(TestRunnerInjectedBundle ${WebKitTestRunner_LIBRARIES})
+add_dependencies(TestRunnerInjectedBundle WebKitTestRunnerInjectedBundleBindings)
+
+add_executable(WebKitTestRunner ${WebKitTestRunner_SOURCES})
+target_link_libraries(WebKitTestRunner ${WebKitTestRunner_LIBRARIES})
+add_dependencies(WebKitTestRunner WebKitTestRunnerBindings)
+
+if (NOT APPLE)
+ add_dependencies(WebKit2 ${ForwardingHeadersForWebKitTestRunner_NAME})
+endif () \ No newline at end of file
diff --git a/Tools/WebKitTestRunner/DerivedSources.make b/Tools/WebKitTestRunner/DerivedSources.make
new file mode 100644
index 000000000..4a2b1790f
--- /dev/null
+++ b/Tools/WebKitTestRunner/DerivedSources.make
@@ -0,0 +1,62 @@
+# Copyright (C) 2010 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+VPATH = \
+ $(WebKitTestRunner)/InjectedBundle/Bindings \
+ $(WebKitTestRunner)/../TestRunnerShared/UIScriptContext/Bindings \
+#
+
+INJECTED_BUNDLE_INTERFACES = \
+ AccessibilityController \
+ AccessibilityTextMarker \
+ AccessibilityTextMarkerRange \
+ AccessibilityUIElement \
+ EventSendingController \
+ GCController \
+ TestRunner \
+ TextInputController \
+#
+
+UICONTEXT_INTERFACES = \
+ UIScriptController \
+#
+
+SCRIPTS = \
+ $(WebCoreScripts)/CodeGenerator.pm \
+ $(WebKitTestRunner)/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm \
+ $(WebCoreScripts)/IDLParser.pm \
+ $(WebCoreScripts)/generate-bindings.pl \
+#
+
+.PHONY : all
+
+JS%.h JS%.cpp : %.idl $(SCRIPTS)
+ @echo Generating bindings for $*...
+ @perl -I $(WebCoreScripts) -I $(WebKitTestRunner)/InjectedBundle/Bindings -I $(WebKitTestRunner)/UIScriptContext/Bindings $(WebCoreScripts)/generate-bindings.pl --defines "" --include InjectedBundle/Bindings --include UIScriptContext/Bindings --outputDir . --generator TestRunner $<
+
+all : \
+ $(INJECTED_BUNDLE_INTERFACES:%=JS%.h) \
+ $(INJECTED_BUNDLE_INTERFACES:%=JS%.cpp) \
+ $(UICONTEXT_INTERFACES:%=JS%.h) \
+ $(UICONTEXT_INTERFACES:%=JS%.cpp) \
+#
diff --git a/Tools/WebKitTestRunner/EventSenderProxy.h b/Tools/WebKitTestRunner/EventSenderProxy.h
index db2c58b0d..70d94014c 100644
--- a/Tools/WebKitTestRunner/EventSenderProxy.h
+++ b/Tools/WebKitTestRunner/EventSenderProxy.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,7 @@
#include <wtf/Deque.h>
#include <wtf/HashMap.h>
+#include <wtf/RetainPtr.h>
#include <wtf/Vector.h>
#if PLATFORM(GTK)
@@ -36,7 +37,11 @@
#include <gdk/gdk.h>
#include <wtf/HashSet.h>
#elif PLATFORM(EFL)
-#include <WebKit2/EWebKit2.h>
+#include "EWebKit2.h"
+#endif
+
+#if PLATFORM(COCOA)
+OBJC_CLASS NSEvent;
#endif
namespace WTR {
@@ -58,8 +63,15 @@ public:
void mouseDown(unsigned button, WKEventModifiers);
void mouseUp(unsigned button, WKEventModifiers);
+ void mouseForceDown();
+ void mouseForceUp();
+ void mouseForceChanged(float);
+ void mouseForceClick();
+ void startAndCancelMouseForceClick();
void mouseMoveTo(double x, double y);
void mouseScrollBy(int x, int y);
+ void mouseScrollByWithWheelAndMomentumPhases(int x, int y, int phase, int momentum);
+ void swipeGestureWithWheelAndMomentumPhases(int x, int y, int phase, int momentum);
void continuousMouseScrollBy(int x, int y, bool paged);
void leapForward(int milliseconds);
@@ -91,8 +103,17 @@ private:
void replaySavedEvents();
#endif
+ void sendMouseDownToStartPressureEvents();
+#if PLATFORM(COCOA)
+ enum class PressureChangeDirection { Increasing, Decreasing };
+ RetainPtr<NSEvent> beginPressureEvent(int stage);
+ RetainPtr<NSEvent> pressureChangeEvent(int stage, PressureChangeDirection);
+ RetainPtr<NSEvent> pressureChangeEvent(int stage, float pressure, PressureChangeDirection);
+#endif
+
#if PLATFORM(GTK)
void sendOrQueueEvent(GdkEvent*);
+ void dispatchEvent(GdkEvent*);
GdkEvent* createMouseButtonEvent(GdkEventType, unsigned button, WKEventModifiers);
GUniquePtr<GdkEvent> createTouchEvent(GdkEventType, int id);
void sendUpdatedTouchEvents();
@@ -111,7 +132,7 @@ private:
double m_clickTime;
WKPoint m_clickPosition;
WKEventMouseButton m_clickButton;
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
int eventNumber;
#elif PLATFORM(GTK)
Deque<WTREventQueueItem> m_eventQueue;
diff --git a/Tools/WebKitTestRunner/FontWithFeatures.otf b/Tools/WebKitTestRunner/FontWithFeatures.otf
new file mode 100644
index 000000000..3e5069995
--- /dev/null
+++ b/Tools/WebKitTestRunner/FontWithFeatures.otf
Binary files differ
diff --git a/Tools/WebKitTestRunner/FontWithFeatures.ttf b/Tools/WebKitTestRunner/FontWithFeatures.ttf
new file mode 100644
index 000000000..42c332a13
--- /dev/null
+++ b/Tools/WebKitTestRunner/FontWithFeatures.ttf
Binary files differ
diff --git a/Tools/WebKitTestRunner/GNUmakefile.am b/Tools/WebKitTestRunner/GNUmakefile.am
deleted file mode 100644
index 28a2d5747..000000000
--- a/Tools/WebKitTestRunner/GNUmakefile.am
+++ /dev/null
@@ -1,175 +0,0 @@
-
-stamp-webkittestrunner-forwarding-headers: $(WebKit2)/Scripts/generate-forwarding-headers.pl $(Programs_WebKitTestRunner_SOURCES) $(Libraries_libTestRunnerInjectedBundle_la_SOURCES)
- $(AM_V_GEN)$(PERL) $< $(srcdir)/Tools/WebKitTestRunner $(GENSOURCES_WEBKIT2)/include gtk \
- && echo timestamp > $(@F)
-
-BUILT_SOURCES += $(top_builddir)/stamp-webkittestrunner-forwarding-headers
-
-if ENABLE_WEBKIT2
-noinst_PROGRAMS += \
- Programs/WebKitTestRunner
-endif
-
-Programs_WebKitTestRunner_SOURCES = \
- Tools/WebKitTestRunner/EventSenderProxy.h \
- Tools/WebKitTestRunner/gtk/main.cpp \
- Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp \
- Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp \
- Tools/WebKitTestRunner/gtk/TestControllerGtk.cpp \
- Tools/WebKitTestRunner/cairo/TestInvocationCairo.cpp \
- Tools/WebKitTestRunner/CyclicRedundancyCheck.cpp \
- Tools/WebKitTestRunner/CyclicRedundancyCheck.h \
- Tools/WebKitTestRunner/GeolocationProviderMock.cpp \
- Tools/WebKitTestRunner/GeolocationProviderMock.h \
- Tools/WebKitTestRunner/Options.cpp \
- Tools/WebKitTestRunner/Options.h \
- Tools/WebKitTestRunner/PixelDumpSupport.cpp \
- Tools/WebKitTestRunner/PixelDumpSupport.h \
- Tools/WebKitTestRunner/PlatformWebView.h \
- Tools/WebKitTestRunner/StringFunctions.h \
- Tools/WebKitTestRunner/TestController.cpp \
- Tools/WebKitTestRunner/TestController.h \
- Tools/WebKitTestRunner/TestInvocation.cpp \
- Tools/WebKitTestRunner/TestInvocation.h \
- Tools/WebKitTestRunner/WebNotificationProvider.cpp \
- Tools/WebKitTestRunner/WebNotificationProvider.h \
- Tools/WebKitTestRunner/WebKitTestRunnerPrefix.h \
- Tools/WebKitTestRunner/WorkQueueManager.cpp \
- Tools/WebKitTestRunner/WorkQueueManager.h
-
-Programs_WebKitTestRunner_CPPFLAGS = \
- -include Tools/WebKitTestRunner/WebKitTestRunnerPrefix.h \
- -I$(srcdir)/Tools/WebKitTestRunner \
- -I$(srcdir)/Source/WebCore/platform/gtk \
- -I$(top_builddir)/DerivedSources/WebKit2/include \
- $(global_cppflags) \
- $(javascriptcore_cppflags) \
- $(webcore_cppflags) \
- $(CAIRO_CFLAGS) \
- $(GTK_CFLAGS) \
- $(LIBSOUP_CFLAGS)
-Programs_WebKitTestRunner_CXXFLAGS = $(global_cxxflags)
-Programs_WebKitTestRunner_CFLAGS = $(global_cflags)
-
-Programs_WebKitTestRunner_LDADD = \
- libjavascriptcoregtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \
- libwebkit2gtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \
- $(CAIRO_LIBS) \
- $(GTK_LIBS) \
- $(GLIB_LIBS) \
- $(LIBSOUP_LIBS) \
- $(FREETYPE_LIBS) \
- $(WINMM_LIBS) \
- $(XRENDER_LIBS) \
- $(XT_LIBS)
-
-Programs_WebKitTestRunner_LDFLAGS = \
- -no-install
-
-# The InjectedBundle library allows the render process to load harness code.
-if ENABLE_WEBKIT2
-noinst_LTLIBRARIES += Libraries/libTestRunnerInjectedBundle.la
-endif
-
-webkittestrunner_built_sources += \
- DerivedSources/InjectedBundle/JSAccessibilityController.cpp \
- DerivedSources/InjectedBundle/JSAccessibilityTextMarker.cpp \
- DerivedSources/InjectedBundle/JSAccessibilityTextMarkerRange.cpp \
- DerivedSources/InjectedBundle/JSAccessibilityUIElement.cpp \
- DerivedSources/InjectedBundle/JSEventSendingController.cpp \
- DerivedSources/InjectedBundle/JSGCController.cpp \
- DerivedSources/InjectedBundle/JSTestRunner.cpp \
- DerivedSources/InjectedBundle/JSTextInputController.cpp
-nodist_Libraries_libTestRunnerInjectedBundle_la_SOURCES = $(webkittestrunner_built_sources)
-BUILT_SOURCES += $(webkittestrunner_built_sources)
-
-Libraries_libTestRunnerInjectedBundle_la_SOURCES = \
- Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp \
- Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h \
- Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.cpp \
- Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.h \
- Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.cpp \
- Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.h \
- Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp \
- Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h \
- Tools/WebKitTestRunner/InjectedBundle/ActivateFonts.h \
- Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityControllerAtk.cpp \
- Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.cpp \
- Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.h \
- Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp \
- Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrappable.h \
- Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrapper.cpp \
- Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrapper.h \
- Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp \
- Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h \
- Tools/WebKitTestRunner/InjectedBundle/GCController.cpp \
- Tools/WebKitTestRunner/InjectedBundle/GCController.h \
- Tools/WebKitTestRunner/InjectedBundle/gtk/ActivateFontsGtk.cpp \
- Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleGtk.cpp \
- Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.cpp \
- Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.h \
- Tools/WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp \
- Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp \
- Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h \
- Tools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp \
- Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp \
- Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h \
- Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp \
- Tools/WebKitTestRunner/InjectedBundle/TestRunner.h \
- Tools/WebKitTestRunner/InjectedBundle/TextInputController.cpp \
- Tools/WebKitTestRunner/InjectedBundle/TextInputController.h
-
-Libraries_libTestRunnerInjectedBundle_la_LIBADD = \
- libWebCoreInternals.la
-
-Libraries_libTestRunnerInjectedBundle_la_LDFLAGS = \
- -rpath ${shell pwd}/$(top_builddir)/../unix/TestNetscapePlugin/.libs \
- $(no_undefined) \
- -avoid-version \
- -module
-
-Libraries_libTestRunnerInjectedBundle_la_CPPFLAGS = \
- -DFONTS_CONF_DIR=\"${shell pwd}/${srcdir}/Tools/DumpRenderTree/gtk/fonts\" \
- -DTOP_LEVEL_DIR=\"${shell pwd}/${srcdir}\" \
- -include Tools/WebKitTestRunner/WebKitTestRunnerPrefix.h \
- -I$(srcdir)/Tools/WebKitTestRunner \
- -I$(srcdir)/Tools/WebKitTestRunner/InjectedBundle \
- -I$(srcdir)/Tools/WebKitTestRunner/InjectedBundle/Bindings \
- -I$(srcdir)/Tools/WebKitTestRunner/InjectedBundle/atk \
- -I$(srcdir)/Source/WebCore/testing/js \
- -I$(top_builddir)/DerivedSources/InjectedBundle \
- -I$(top_builddir)/DerivedSources/WebKit2/include \
- $(global_cppflags) \
- $(javascriptcore_cppflags) \
- $(webcore_cppflags) \
- $(CAIRO_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(GTK_CFLAGS) \
- $(LIBSOUP_CFLAGS)
-Libraries_libTestRunnerInjectedBundle_la_CXXFLAGS = $(global_cxxflags)
-Libraries_libTestRunnerInjectedBundle_la_CFLAGS = $(global_cflags)
-
-code_generation_dependencies = \
- Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm \
- Source/WebCore/bindings/scripts/CodeGenerator.pm \
- Source/WebCore/bindings/scripts/IDLParser.pm \
- Source/WebCore/bindings/scripts/InFilesParser.pm \
- Source/WebCore/bindings/scripts/generate-bindings.pl
-
-DerivedSources/InjectedBundle/JS%.cpp: Tools/WebKitTestRunner/InjectedBundle/Bindings/%.idl $(code_generation_dependencies)
- $(AM_V_GEN)$(PERL) \
- -I $(srcdir)/Source/WebCore/bindings/scripts \
- -I $(srcdir)/Tools/WebKitTestRunner/InjectedBundle/Bindings \
- $(srcdir)/Source/WebCore/bindings/scripts/generate-bindings.pl \
- --defines "$(feature_defines)" --generator TestRunner \
- --include $(srcdir)/Tools/InjectedBundle/Bindings \
- --outputDir $(top_builddir)/DerivedSources/InjectedBundle \
- $<
-
-EXTRA_DIST += \
- $(srcdir)/Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm \
- $(srcdir)/Source/WebCore/bindings/scripts/CodeGenerator.pm \
- $(srcdir)/Source/WebCore/bindings/scripts/IDLParser.pm \
- $(srcdir)/Source/WebCore/bindings/scripts/InFilesParser.pm \
- $(srcdir)/Source/WebCore/bindings/scripts/generate-bindings.pl \
- $(shell ls $(srcdir)/Tools/WebKitTestRunner/InjectedBundle/Bindings/*.idl)
diff --git a/Tools/WebKitTestRunner/GeolocationProviderMock.cpp b/Tools/WebKitTestRunner/GeolocationProviderMock.cpp
index 9120258c7..ad4164966 100644
--- a/Tools/WebKitTestRunner/GeolocationProviderMock.cpp
+++ b/Tools/WebKitTestRunner/GeolocationProviderMock.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "GeolocationProviderMock.h"
-#include <WebKit2/WKGeolocationManager.h>
+#include <WebKit/WKGeolocationManager.h>
#include <string.h>
#include <wtf/Assertions.h>
#include <wtf/CurrentTime.h>
@@ -52,7 +52,7 @@ GeolocationProviderMock::GeolocationProviderMock(WKContextRef context)
m_geolocationManager = WKContextGetGeolocationManager(context);
WKGeolocationProviderV1 providerCallback;
- memset(&providerCallback, 0, sizeof(WKGeolocationProvider));
+ memset(&providerCallback, 0, sizeof(WKGeolocationProviderV1));
providerCallback.base.version = 1;
providerCallback.base.clientInfo = this;
providerCallback.startUpdating = startUpdatingCallback;
diff --git a/Tools/WebKitTestRunner/GeolocationProviderMock.h b/Tools/WebKitTestRunner/GeolocationProviderMock.h
index ff5537e46..802223ec3 100644
--- a/Tools/WebKitTestRunner/GeolocationProviderMock.h
+++ b/Tools/WebKitTestRunner/GeolocationProviderMock.h
@@ -26,7 +26,7 @@
#ifndef GeolocationProviderMock_h
#define GeolocationProviderMock_h
-#include <WebKit2/WKRetainPtr.h>
+#include <WebKit/WKRetainPtr.h>
namespace WTR {
@@ -41,6 +41,8 @@ public:
void startUpdating(WKGeolocationManagerRef);
void stopUpdating(WKGeolocationManagerRef);
+ bool isActive() const { return m_isActive; }
+
private:
void sendPositionIfNeeded();
void sendErrorIfNeeded();
diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp
index f5d1bd58b..0a130d4e8 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp
@@ -32,15 +32,15 @@
#include "JSAccessibilityController.h"
#include <JavaScriptCore/JSRetainPtr.h>
-#include <WebKit2/WKBundle.h>
-#include <WebKit2/WKBundlePage.h>
-#include <WebKit2/WKBundlePagePrivate.h>
+#include <WebKit/WKBundle.h>
+#include <WebKit/WKBundlePage.h>
+#include <WebKit/WKBundlePagePrivate.h>
namespace WTR {
-PassRefPtr<AccessibilityController> AccessibilityController::create()
+Ref<AccessibilityController> AccessibilityController::create()
{
- return adoptRef(new AccessibilityController);
+ return adoptRef(*new AccessibilityController);
}
AccessibilityController::AccessibilityController()
@@ -61,44 +61,43 @@ JSClassRef AccessibilityController::wrapperClass()
return JSAccessibilityController::accessibilityControllerClass();
}
+void AccessibilityController::enableEnhancedAccessibility(bool enable)
+{
+ WKAccessibilityEnableEnhancedAccessibility(enable);
+}
+
+bool AccessibilityController::enhancedAccessibilityEnabled()
+{
+ return WKAccessibilityEnhancedAccessibilityEnabled();
+}
+
#if !PLATFORM(GTK) && !PLATFORM(EFL)
-PassRefPtr<AccessibilityUIElement> AccessibilityController::rootElement()
+Ref<AccessibilityUIElement> AccessibilityController::rootElement()
{
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
void* root = WKAccessibilityRootObject(page);
return AccessibilityUIElement::create(static_cast<PlatformUIElement>(root));
}
-PassRefPtr<AccessibilityUIElement> AccessibilityController::focusedElement()
+Ref<AccessibilityUIElement> AccessibilityController::focusedElement()
{
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
void* root = WKAccessibilityFocusedObject(page);
return AccessibilityUIElement::create(static_cast<PlatformUIElement>(root));
}
#endif
-PassRefPtr<AccessibilityUIElement> AccessibilityController::elementAtPoint(int x, int y)
+RefPtr<AccessibilityUIElement> AccessibilityController::elementAtPoint(int x, int y)
{
- RefPtr<AccessibilityUIElement> uiElement = rootElement();
+ Ref<AccessibilityUIElement> uiElement = rootElement();
return uiElement->elementAtPoint(x, y);
}
-// Unsupported methods on various platforms.
-// As they're implemented on other platforms this list should be modified.
-#if (!PLATFORM(GTK) && !PLATFORM(MAC) && !PLATFORM(EFL)) || !HAVE(ACCESSIBILITY)
-bool AccessibilityController::addNotificationListener(JSValueRef) { return false; }
-bool AccessibilityController::removeNotificationListener() { return false; }
-PassRefPtr<AccessibilityUIElement> AccessibilityController::accessibleElementById(JSStringRef attribute) { return nullptr; }
-void AccessibilityController::logAccessibilityEvents() { }
-void AccessibilityController::resetToConsistentState() { }
-JSRetainPtr<JSStringRef> AccessibilityController::platformName() { return JSRetainPtr<JSStringRef>(Adopt, JSStringCreateWithUTF8CString("")); }
-#endif
-
#if !HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
-PassRefPtr<AccessibilityUIElement> AccessibilityController::rootElement() { return nullptr; }
-PassRefPtr<AccessibilityUIElement> AccessibilityController::focusedElement() { return nullptr; }
+RefPtr<AccessibilityUIElement> AccessibilityController::rootElement() { return nullptr; }
+RefPtr<AccessibilityUIElement> AccessibilityController::focusedElement() { return nullptr; }
#endif
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h
index 7ce1a45c3..5cf0d739c 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h
@@ -23,14 +23,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef AccessibilityController_h
-#define AccessibilityController_h
+#pragma once
+
+#if HAVE(ACCESSIBILITY)
#include "AccessibilityUIElement.h"
#include "JSWrappable.h"
#include <JavaScriptCore/JSObjectRef.h>
#include <wtf/Platform.h>
-#if HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
+#if PLATFORM(GTK) || PLATFORM(EFL)
#include "AccessibilityNotificationHandlerAtk.h"
#endif
@@ -38,19 +39,23 @@ namespace WTR {
class AccessibilityController : public JSWrappable {
public:
- static PassRefPtr<AccessibilityController> create();
+ static Ref<AccessibilityController> create();
~AccessibilityController();
void makeWindowObject(JSContextRef, JSObjectRef windowObject, JSValueRef* exception);
virtual JSClassRef wrapperClass();
+ // Enhanced accessibility.
+ void enableEnhancedAccessibility(bool);
+ bool enhancedAccessibilityEnabled();
+
JSRetainPtr<JSStringRef> platformName();
// Controller Methods - platform-independent implementations.
- PassRefPtr<AccessibilityUIElement> rootElement();
- PassRefPtr<AccessibilityUIElement> focusedElement();
- PassRefPtr<AccessibilityUIElement> elementAtPoint(int x, int y);
- PassRefPtr<AccessibilityUIElement> accessibleElementById(JSStringRef idAttribute);
+ Ref<AccessibilityUIElement> rootElement();
+ Ref<AccessibilityUIElement> focusedElement();
+ RefPtr<AccessibilityUIElement> elementAtPoint(int x, int y);
+ RefPtr<AccessibilityUIElement> accessibleElementById(JSStringRef idAttribute);
bool addNotificationListener(JSValueRef functionCallback);
bool removeNotificationListener();
@@ -59,22 +64,20 @@ public:
void logFocusEvents() { }
void logValueChangeEvents() { }
void logScrollingStartEvents() { }
- void logAccessibilityEvents();
+ void logAccessibilityEvents() { };
void resetToConsistentState();
private:
AccessibilityController();
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
RetainPtr<NotificationHandler> m_globalNotificationHandler;
-#endif
-
-#if HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
+#else
RefPtr<AccessibilityNotificationHandler> m_globalNotificationHandler;
#endif
};
} // namespace WTR
-#endif // AccessibilityController_h
+#endif // HAVE(ACCESSIBILITY)
diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.cpp b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.cpp
index a7a4b7def..7e99fbb12 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.cpp
@@ -33,14 +33,14 @@
namespace WTR {
-PassRefPtr<AccessibilityTextMarker> AccessibilityTextMarker::create(PlatformTextMarker marker)
+Ref<AccessibilityTextMarker> AccessibilityTextMarker::create(PlatformTextMarker marker)
{
- return adoptRef(new AccessibilityTextMarker(marker));
+ return adoptRef(*new AccessibilityTextMarker(marker));
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityTextMarker::create(const AccessibilityTextMarker& marker)
+Ref<AccessibilityTextMarker> AccessibilityTextMarker::create(const AccessibilityTextMarker& marker)
{
- return adoptRef(new AccessibilityTextMarker(marker));
+ return adoptRef(*new AccessibilityTextMarker(marker));
}
AccessibilityTextMarker::AccessibilityTextMarker(PlatformTextMarker marker)
@@ -60,7 +60,7 @@ AccessibilityTextMarker::~AccessibilityTextMarker()
PlatformTextMarker AccessibilityTextMarker::platformTextMarker() const
{
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
return m_textMarker.get();
#else
return m_textMarker;
diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.h b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.h
index c4d4d0481..041f81bc7 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.h
@@ -23,15 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef AccessibilityTextMarker_h
-#define AccessibilityTextMarker_h
+#pragma once
#include "JSWrappable.h"
#include <JavaScriptCore/JSObjectRef.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/Platform.h>
+#include <wtf/Ref.h>
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#include <wtf/RetainPtr.h>
typedef CFTypeRef PlatformTextMarker;
#else
@@ -44,8 +43,8 @@ class AccessibilityUIElement;
class AccessibilityTextMarker : public JSWrappable {
public:
- static PassRefPtr<AccessibilityTextMarker> create(PlatformTextMarker);
- static PassRefPtr<AccessibilityTextMarker> create(const AccessibilityTextMarker&);
+ static Ref<AccessibilityTextMarker> create(PlatformTextMarker);
+ static Ref<AccessibilityTextMarker> create(const AccessibilityTextMarker&);
~AccessibilityTextMarker();
@@ -59,17 +58,15 @@ private:
AccessibilityTextMarker(PlatformTextMarker);
AccessibilityTextMarker(const AccessibilityTextMarker&);
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
RetainPtr<PlatformTextMarker> m_textMarker;
#else
PlatformTextMarker m_textMarker;
#endif
};
-#if !PLATFORM(MAC)
+#if !PLATFORM(COCOA)
inline bool AccessibilityTextMarker::isEqual(AccessibilityTextMarker*) { return false; }
#endif
} // namespace WTR
-
-#endif // AccessibilityTextMarker_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.cpp b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.cpp
index 3613f3728..7444f3522 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.cpp
@@ -33,14 +33,14 @@
namespace WTR {
-PassRefPtr<AccessibilityTextMarkerRange> AccessibilityTextMarkerRange::create(PlatformTextMarkerRange markerRange)
+Ref<AccessibilityTextMarkerRange> AccessibilityTextMarkerRange::create(PlatformTextMarkerRange markerRange)
{
- return adoptRef(new AccessibilityTextMarkerRange(markerRange));
+ return adoptRef(*new AccessibilityTextMarkerRange(markerRange));
}
-PassRefPtr<AccessibilityTextMarkerRange> AccessibilityTextMarkerRange::create(const AccessibilityTextMarkerRange& markerRange)
+Ref<AccessibilityTextMarkerRange> AccessibilityTextMarkerRange::create(const AccessibilityTextMarkerRange& markerRange)
{
- return adoptRef(new AccessibilityTextMarkerRange(markerRange));
+ return adoptRef(*new AccessibilityTextMarkerRange(markerRange));
}
AccessibilityTextMarkerRange::AccessibilityTextMarkerRange(PlatformTextMarkerRange markerRange)
@@ -60,7 +60,7 @@ AccessibilityTextMarkerRange::~AccessibilityTextMarkerRange()
PlatformTextMarkerRange AccessibilityTextMarkerRange::platformTextMarkerRange() const
{
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
return m_textMarkerRange.get();
#else
return m_textMarkerRange;
diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.h b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.h
index e57a29cd7..18c18d48e 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.h
@@ -23,15 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef AccessibilityTextMarkerRange_h
-#define AccessibilityTextMarkerRange_h
+#pragma once
#include "JSWrappable.h"
#include <JavaScriptCore/JSObjectRef.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/Platform.h>
+#include <wtf/Ref.h>
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#include <wtf/RetainPtr.h>
typedef CFTypeRef PlatformTextMarkerRange;
#else
@@ -42,8 +41,8 @@ namespace WTR {
class AccessibilityTextMarkerRange : public JSWrappable {
public:
- static PassRefPtr<AccessibilityTextMarkerRange> create(PlatformTextMarkerRange);
- static PassRefPtr<AccessibilityTextMarkerRange> create(const AccessibilityTextMarkerRange&);
+ static Ref<AccessibilityTextMarkerRange> create(PlatformTextMarkerRange);
+ static Ref<AccessibilityTextMarkerRange> create(const AccessibilityTextMarkerRange&);
~AccessibilityTextMarkerRange();
@@ -57,17 +56,15 @@ private:
AccessibilityTextMarkerRange(PlatformTextMarkerRange);
AccessibilityTextMarkerRange(const AccessibilityTextMarkerRange&);
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
RetainPtr<PlatformTextMarkerRange> m_textMarkerRange;
#else
PlatformTextMarkerRange m_textMarkerRange;
#endif
};
-#if !PLATFORM(MAC)
+#if !PLATFORM(COCOA)
inline bool AccessibilityTextMarkerRange::isEqual(AccessibilityTextMarkerRange*) { return false; }
#endif
} // namespace WTR
-
-#endif // AccessibilityTextMarkerRange_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp
index 00e965ff3..233ff7d20 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp
@@ -31,14 +31,14 @@
namespace WTR {
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::create(PlatformUIElement uiElement)
+Ref<AccessibilityUIElement> AccessibilityUIElement::create(PlatformUIElement uiElement)
{
- return adoptRef(new AccessibilityUIElement(uiElement));
+ return adoptRef(*new AccessibilityUIElement(uiElement));
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::create(const AccessibilityUIElement& uiElement)
+Ref<AccessibilityUIElement> AccessibilityUIElement::create(const AccessibilityUIElement& uiElement)
{
- return adoptRef(new AccessibilityUIElement(uiElement));
+ return adoptRef(*new AccessibilityUIElement(uiElement));
}
JSClassRef AccessibilityUIElement::wrapperClass()
@@ -53,154 +53,55 @@ bool AccessibilityUIElement::isValid() const
return m_element;
}
+// iOS specific methods
+#if !PLATFORM(IOS)
+JSRetainPtr<JSStringRef> AccessibilityUIElement::identifier() { return nullptr; }
+JSRetainPtr<JSStringRef> AccessibilityUIElement::traits() { return nullptr; }
+int AccessibilityUIElement::elementTextPosition() { return 0; }
+int AccessibilityUIElement::elementTextLength() { return 0; }
+JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForSelection() { return nullptr; }
+JSValueRef AccessibilityUIElement::elementsForRange(unsigned, unsigned) { return nullptr; }
+void AccessibilityUIElement::increaseTextSelection() { }
+void AccessibilityUIElement::decreaseTextSelection() { }
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedElement() { return nullptr; }
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::headerElementAtIndex(unsigned) { return nullptr; }
+void AccessibilityUIElement::assistiveTechnologySimulatedFocus() { return; }
+bool AccessibilityUIElement::scrollPageUp() { return false; }
+bool AccessibilityUIElement::scrollPageDown() { return false; }
+bool AccessibilityUIElement::scrollPageLeft() { return false; }
+bool AccessibilityUIElement::scrollPageRight() { return false; }
+bool AccessibilityUIElement::hasContainedByFieldsetTrait() { return false; }
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::fieldsetAncestorElement() { return nullptr; }
+bool AccessibilityUIElement::isSearchField() const { return false; }
+bool AccessibilityUIElement::isTextArea() const { return false; }
+
+#endif
+
// Unsupported methods on various platforms. As they're implemented on other platforms this list should be modified.
#if (!PLATFORM(GTK) && !PLATFORM(EFL)) || !HAVE(ACCESSIBILITY)
-JSRetainPtr<JSStringRef> AccessibilityUIElement::characterAtOffset(int) { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::wordAtOffset(int) { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::lineAtOffset(int) { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::sentenceAtOffset(int) { return 0; }
+JSRetainPtr<JSStringRef> AccessibilityUIElement::characterAtOffset(int) { return nullptr; }
+JSRetainPtr<JSStringRef> AccessibilityUIElement::wordAtOffset(int) { return nullptr; }
+JSRetainPtr<JSStringRef> AccessibilityUIElement::lineAtOffset(int) { return nullptr; }
+JSRetainPtr<JSStringRef> AccessibilityUIElement::sentenceAtOffset(int) { return nullptr; }
#endif
-#if (!PLATFORM(MAC) && !PLATFORM(GTK) && !PLATFORM(EFL)) || !HAVE(ACCESSIBILITY)
-AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement) { }
-AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement&) { }
-AccessibilityUIElement::~AccessibilityUIElement() { }
-bool AccessibilityUIElement::isEqual(AccessibilityUIElement*) { return false; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int, int) { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned) { return 0; }
-unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement*) { return 0; }
-int AccessibilityUIElement::childrenCount() { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement() { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement() { return 0; }
-void AccessibilityUIElement::takeFocus() { }
-void AccessibilityUIElement::takeSelection() { }
-void AccessibilityUIElement::addSelection() { }
-void AccessibilityUIElement::removeSelection() { }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements() { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned) { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames() { return 0; }
-void AccessibilityUIElement::increment() { }
-void AccessibilityUIElement::decrement() { }
-void AccessibilityUIElement::showMenu() { }
-void AccessibilityUIElement::press() { }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef) { return 0; }
-JSValueRef AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef) const { return nullptr; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef) const { return 0; }
-double AccessibilityUIElement::numberAttributeValue(JSStringRef) { return 0; }
-bool AccessibilityUIElement::boolAttributeValue(JSStringRef) { return false; }
-bool AccessibilityUIElement::isAttributeSupported(JSStringRef) { return false; }
-bool AccessibilityUIElement::isAttributeSettable(JSStringRef) { return false; }
-bool AccessibilityUIElement::isPressActionSupported() { return false; }
-bool AccessibilityUIElement::isIncrementActionSupported() { return false; }
-bool AccessibilityUIElement::isDecrementActionSupported() { return false; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::role() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::title() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::description() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::language() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const { return 0; }
-double AccessibilityUIElement::x() { return 0; }
-double AccessibilityUIElement::y() { return 0; }
-double AccessibilityUIElement::width() { return 0; }
-double AccessibilityUIElement::height() { return 0; }
-double AccessibilityUIElement::intValue() const { return 0; }
-double AccessibilityUIElement::minValue() { return 0; }
-double AccessibilityUIElement::maxValue() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription() { return 0; }
-int AccessibilityUIElement::insertionPointLineNumber() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange() { return 0; }
-bool AccessibilityUIElement::isEnabled() { return false; }
-bool AccessibilityUIElement::isRequired() const { return false; }
-bool AccessibilityUIElement::isFocused() const { return false; }
-bool AccessibilityUIElement::isFocusable() const { return false; }
-bool AccessibilityUIElement::isSelected() const { return false; }
-bool AccessibilityUIElement::isSelectedOptionActive() const { return false; }
-bool AccessibilityUIElement::isSelectable() const { return false; }
-bool AccessibilityUIElement::isMultiSelectable() const { return false; }
-void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement*) const { }
-unsigned AccessibilityUIElement::selectedChildrenCount() const { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned) const { return 0; }
-bool AccessibilityUIElement::isExpanded() const { return false; }
-bool AccessibilityUIElement::isChecked() const { return false; }
-bool AccessibilityUIElement::isIndeterminate() const { return false; }
-bool AccessibilityUIElement::isVisible() const { return false; }
-bool AccessibilityUIElement::isOffScreen() const { return false; }
-bool AccessibilityUIElement::isCollapsed() const { return false; }
-bool AccessibilityUIElement::isIgnored() const { return false; }
-bool AccessibilityUIElement::hasPopup() const { return false; }
-int AccessibilityUIElement::hierarchicalLevel() const { return 0; }
-double AccessibilityUIElement::clickPointX() { return 0; }
-double AccessibilityUIElement::clickPointY() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::url() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::speak() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader() { return 0; }
-int AccessibilityUIElement::indexInTable() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange() { return 0; }
-int AccessibilityUIElement::rowCount() { return 0; }
-int AccessibilityUIElement::columnCount() { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned) { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow() { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned) { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned) { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned) { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned) { return 0; }
-bool AccessibilityUIElement::ariaIsGrabbed() const { return false; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::classList() const { return 0; }
-int AccessibilityUIElement::lineForIndex(int) { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int) { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int, int) { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned, unsigned) { return 0; }
-bool AccessibilityUIElement::setSelectedTextRange(unsigned, unsigned) { return false; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned, unsigned) { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned, unsigned) { return 0; }
-bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned, unsigned) { return false; }
-unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement*, bool, JSValueRef, JSStringRef, bool) { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement*, bool, JSValueRef, JSStringRef, bool) { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned, unsigned) { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const { return 0; }
-bool AccessibilityUIElement::addNotificationListener(JSValueRef) { return false; }
-bool AccessibilityUIElement::removeNotificationListener() { return false; }
-PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement*) { return 0; }
-int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange*) { return 0; }
-PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker*, AccessibilityTextMarker*) { return 0; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*) { return 0; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*) { return 0; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker*) { return 0; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForBounds(int x, int y, int width, int height) { return 0; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForBounds(int x, int y, int width, int height) { return 0; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int, int) { return 0; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker*) { return 0; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker*) { return 0; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarker() { return 0; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarker() { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange*) { return 0; }
-bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef, AccessibilityTextMarkerRange*) { return false; }
-int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker*) { return -1; }
-bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker*) { return false; }
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int) { return 0; }
-void AccessibilityUIElement::scrollToMakeVisible() { }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPostscriptsDescription() const { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPrescriptsDescription() const { return 0; }
-JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const { return 0; }
+#if !PLATFORM(MAC) || !HAVE(ACCESSIBILITY)
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::selectedTextMarkerRange() { return nullptr; }
+void AccessibilityUIElement::resetSelectedTextMarkerRange() { }
+void AccessibilityUIElement::setBoolAttributeValue(JSStringRef, bool) { }
+#endif
+#if !PLATFORM(COCOA) || !HAVE(ACCESSIBILITY)
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::leftWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::sentenceTextMarkerRangeForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextSentenceEndTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousSentenceStartTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
#endif
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h
index 807b82446..5509af217 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef AccessibilityUIElement_h
-#define AccessibilityUIElement_h
+#pragma once
#include "AccessibilityTextMarker.h"
#include "AccessibilityTextMarkerRange.h"
@@ -35,7 +34,7 @@
#include <wtf/Platform.h>
#include <wtf/Vector.h>
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#ifdef __OBJC__
typedef id PlatformUIElement;
#else
@@ -44,13 +43,13 @@ typedef struct objc_object* PlatformUIElement;
#elif HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
#include "AccessibilityNotificationHandlerAtk.h"
#include <atk/atk.h>
-#include <wtf/gobject/GRefPtr.h>
+#include <wtf/glib/GRefPtr.h>
typedef GRefPtr<AtkObject> PlatformUIElement;
#else
typedef void* PlatformUIElement;
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#ifdef __OBJC__
typedef id NotificationHandler;
#else
@@ -62,8 +61,8 @@ namespace WTR {
class AccessibilityUIElement : public JSWrappable {
public:
- static PassRefPtr<AccessibilityUIElement> create(PlatformUIElement);
- static PassRefPtr<AccessibilityUIElement> create(const AccessibilityUIElement&);
+ static Ref<AccessibilityUIElement> create(PlatformUIElement);
+ static Ref<AccessibilityUIElement> create(const AccessibilityUIElement&);
~AccessibilityUIElement();
@@ -74,12 +73,12 @@ public:
bool isEqual(AccessibilityUIElement* otherElement);
- PassRefPtr<AccessibilityUIElement> elementAtPoint(int x, int y);
- PassRefPtr<AccessibilityUIElement> childAtIndex(unsigned);
+ RefPtr<AccessibilityUIElement> elementAtPoint(int x, int y);
+ RefPtr<AccessibilityUIElement> childAtIndex(unsigned);
unsigned indexOfChild(AccessibilityUIElement*);
int childrenCount();
- PassRefPtr<AccessibilityUIElement> titleUIElement();
- PassRefPtr<AccessibilityUIElement> parentElement();
+ RefPtr<AccessibilityUIElement> titleUIElement();
+ RefPtr<AccessibilityUIElement> parentElement();
void takeFocus();
void takeSelection();
@@ -89,7 +88,7 @@ public:
// Methods - platform-independent implementations
JSRetainPtr<JSStringRef> allAttributes();
JSRetainPtr<JSStringRef> attributesOfLinkedUIElements();
- PassRefPtr<AccessibilityUIElement> linkedUIElementAtIndex(unsigned);
+ RefPtr<AccessibilityUIElement> linkedUIElementAtIndex(unsigned);
JSRetainPtr<JSStringRef> attributesOfDocumentLinks();
JSRetainPtr<JSStringRef> attributesOfChildren();
@@ -103,8 +102,9 @@ public:
JSRetainPtr<JSStringRef> stringAttributeValue(JSStringRef attribute);
double numberAttributeValue(JSStringRef attribute);
JSValueRef uiElementArrayAttributeValue(JSStringRef attribute) const;
- PassRefPtr<AccessibilityUIElement> uiElementAttributeValue(JSStringRef attribute) const;
+ RefPtr<AccessibilityUIElement> uiElementAttributeValue(JSStringRef attribute) const;
bool boolAttributeValue(JSStringRef attribute);
+ void setBoolAttributeValue(JSStringRef attribute, bool value);
bool isAttributeSupported(JSStringRef attribute);
bool isAttributeSettable(JSStringRef attribute);
bool isPressActionSupported();
@@ -113,6 +113,7 @@ public:
JSRetainPtr<JSStringRef> role();
JSRetainPtr<JSStringRef> subrole();
JSRetainPtr<JSStringRef> roleDescription();
+ JSRetainPtr<JSStringRef> computedRoleString();
JSRetainPtr<JSStringRef> title();
JSRetainPtr<JSStringRef> description();
JSRetainPtr<JSStringRef> language();
@@ -140,8 +141,11 @@ public:
bool isSelectable() const;
bool isMultiSelectable() const;
void setSelectedChild(AccessibilityUIElement*) const;
+ void setSelectedChildAtIndex(unsigned) const;
+ void removeSelectionAtIndex(unsigned) const;
+ void clearSelectedChildren() const;
unsigned selectedChildrenCount() const;
- PassRefPtr<AccessibilityUIElement> selectedChildAtIndex(unsigned) const;
+ RefPtr<AccessibilityUIElement> selectedChildAtIndex(unsigned) const;
bool isValid() const;
bool isExpanded() const;
@@ -151,6 +155,8 @@ public:
bool isOffScreen() const;
bool isCollapsed() const;
bool isIgnored() const;
+ bool isSingleLine() const;
+ bool isMultiLine() const;
bool hasPopup() const;
int hierarchicalLevel() const;
double clickPointX();
@@ -179,14 +185,15 @@ public:
JSValueRef columnHeaders() const;
// Tree/Outline specific attributes
- PassRefPtr<AccessibilityUIElement> selectedRowAtIndex(unsigned);
- PassRefPtr<AccessibilityUIElement> disclosedByRow();
- PassRefPtr<AccessibilityUIElement> disclosedRowAtIndex(unsigned);
- PassRefPtr<AccessibilityUIElement> rowAtIndex(unsigned);
+ RefPtr<AccessibilityUIElement> selectedRowAtIndex(unsigned);
+ RefPtr<AccessibilityUIElement> disclosedByRow();
+ RefPtr<AccessibilityUIElement> disclosedRowAtIndex(unsigned);
+ RefPtr<AccessibilityUIElement> rowAtIndex(unsigned);
// ARIA specific
- PassRefPtr<AccessibilityUIElement> ariaOwnsElementAtIndex(unsigned);
- PassRefPtr<AccessibilityUIElement> ariaFlowToElementAtIndex(unsigned);
+ RefPtr<AccessibilityUIElement> ariaOwnsElementAtIndex(unsigned);
+ RefPtr<AccessibilityUIElement> ariaFlowToElementAtIndex(unsigned);
+ RefPtr<AccessibilityUIElement> ariaControlsElementAtIndex(unsigned);
// ARIA Drag and Drop
bool ariaIsGrabbed() const;
@@ -202,8 +209,9 @@ public:
JSRetainPtr<JSStringRef> stringForRange(unsigned location, unsigned length);
JSRetainPtr<JSStringRef> attributedStringForRange(unsigned location, unsigned length);
bool attributedStringRangeIsMisspelled(unsigned location, unsigned length);
- unsigned uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly);
- PassRefPtr<AccessibilityUIElement> uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly);
+ unsigned uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
+ RefPtr<AccessibilityUIElement> uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
+ JSRetainPtr<JSStringRef> selectTextWithCriteria(JSContextRef, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity);
// Text-specific
JSRetainPtr<JSStringRef> characterAtOffset(int offset);
@@ -212,33 +220,49 @@ public:
JSRetainPtr<JSStringRef> sentenceAtOffset(int offset);
// Table-specific
- PassRefPtr<AccessibilityUIElement> cellForColumnAndRow(unsigned column, unsigned row);
+ RefPtr<AccessibilityUIElement> cellForColumnAndRow(unsigned column, unsigned row);
// Scrollarea-specific
- PassRefPtr<AccessibilityUIElement> horizontalScrollbar() const;
- PassRefPtr<AccessibilityUIElement> verticalScrollbar() const;
+ RefPtr<AccessibilityUIElement> horizontalScrollbar() const;
+ RefPtr<AccessibilityUIElement> verticalScrollbar() const;
void scrollToMakeVisible();
+ void scrollToGlobalPoint(int x, int y);
+ void scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height);
// Text markers.
- PassRefPtr<AccessibilityTextMarkerRange> textMarkerRangeForElement(AccessibilityUIElement*);
- PassRefPtr<AccessibilityTextMarkerRange> textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker);
- PassRefPtr<AccessibilityTextMarker> startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
- PassRefPtr<AccessibilityTextMarker> endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
- PassRefPtr<AccessibilityTextMarker> endTextMarkerForBounds(int x, int y, int width, int height);
- PassRefPtr<AccessibilityTextMarker> startTextMarkerForBounds(int x, int y, int width, int height);
- PassRefPtr<AccessibilityTextMarker> textMarkerForPoint(int x, int y);
- PassRefPtr<AccessibilityTextMarker> previousTextMarker(AccessibilityTextMarker*);
- PassRefPtr<AccessibilityTextMarker> nextTextMarker(AccessibilityTextMarker*);
- PassRefPtr<AccessibilityUIElement> accessibilityElementForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarkerRange> lineTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarkerRange> textMarkerRangeForElement(AccessibilityUIElement*);
+ RefPtr<AccessibilityTextMarkerRange> textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker);
+ RefPtr<AccessibilityTextMarkerRange> selectedTextMarkerRange();
+ void resetSelectedTextMarkerRange();
+ RefPtr<AccessibilityTextMarker> startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
+ RefPtr<AccessibilityTextMarker> endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
+ RefPtr<AccessibilityTextMarker> endTextMarkerForBounds(int x, int y, int width, int height);
+ RefPtr<AccessibilityTextMarker> startTextMarkerForBounds(int x, int y, int width, int height);
+ RefPtr<AccessibilityTextMarker> textMarkerForPoint(int x, int y);
+ RefPtr<AccessibilityTextMarker> previousTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarker> nextTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityUIElement> accessibilityElementForTextMarker(AccessibilityTextMarker*);
JSRetainPtr<JSStringRef> stringForTextMarkerRange(AccessibilityTextMarkerRange*);
int textMarkerRangeLength(AccessibilityTextMarkerRange*);
bool attributedStringForTextMarkerRangeContainsAttribute(JSStringRef, AccessibilityTextMarkerRange*);
int indexForTextMarker(AccessibilityTextMarker*);
bool isTextMarkerValid(AccessibilityTextMarker*);
- PassRefPtr<AccessibilityTextMarker> textMarkerForIndex(int);
- PassRefPtr<AccessibilityTextMarker> startTextMarker();
- PassRefPtr<AccessibilityTextMarker> endTextMarker();
+ RefPtr<AccessibilityTextMarker> textMarkerForIndex(int);
+ RefPtr<AccessibilityTextMarker> startTextMarker();
+ RefPtr<AccessibilityTextMarker> endTextMarker();
+ bool setSelectedVisibleTextRange(AccessibilityTextMarkerRange*);
+ RefPtr<AccessibilityTextMarkerRange> leftWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarkerRange> rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarker> previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarker> nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarkerRange> paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarker> nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarker> previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarkerRange> sentenceTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarker> nextSentenceEndTextMarkerForTextMarker(AccessibilityTextMarker*);
+ RefPtr<AccessibilityTextMarker> previousSentenceStartTextMarkerForTextMarker(AccessibilityTextMarker*);
// Returns an ordered list of supported actions for an element.
JSRetainPtr<JSStringRef> supportedActions() const;
@@ -253,6 +277,29 @@ public:
// Make sure you call remove, because you can't rely on objects being deallocated in a timely fashion.
bool removeNotificationListener();
+ JSRetainPtr<JSStringRef> identifier();
+ JSRetainPtr<JSStringRef> traits();
+ int elementTextPosition();
+ int elementTextLength();
+ JSRetainPtr<JSStringRef> stringForSelection();
+ JSValueRef elementsForRange(unsigned location, unsigned length);
+ void increaseTextSelection();
+ void decreaseTextSelection();
+ RefPtr<AccessibilityUIElement> linkedElement();
+ RefPtr<AccessibilityUIElement> headerElementAtIndex(unsigned index);
+ void assistiveTechnologySimulatedFocus();
+ bool isSearchField() const;
+ bool isTextArea() const;
+
+ bool scrollPageUp();
+ bool scrollPageDown();
+ bool scrollPageLeft();
+ bool scrollPageRight();
+
+ // Fieldset
+ bool hasContainedByFieldsetTrait();
+ RefPtr<AccessibilityUIElement> fieldsetAncestorElement();
+
private:
AccessibilityUIElement(PlatformUIElement);
AccessibilityUIElement(const AccessibilityUIElement&);
@@ -261,7 +308,7 @@ private:
// A retained, platform specific object used to help manage notifications for this object.
#if HAVE(ACCESSIBILITY)
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
NotificationHandler m_notificationHandler;
void getLinkedUIElements(Vector<RefPtr<AccessibilityUIElement> >&);
@@ -270,7 +317,7 @@ private:
void getUIElementsWithAttribute(JSStringRef, Vector<RefPtr<AccessibilityUIElement> >&) const;
#endif
-#if PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(EFL)
+#if PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(EFL)
void getChildren(Vector<RefPtr<AccessibilityUIElement> >&);
void getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >&, unsigned location, unsigned length);
#endif
@@ -282,5 +329,3 @@ private:
};
} // namespace WTR
-
-#endif // AccessibilityUIElement_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityController.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityController.idl
new file mode 100644
index 000000000..d50a2033f
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityController.idl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface AccessibilityController {
+ void enableEnhancedAccessibility(boolean enable);
+ readonly attribute boolean enhancedAccessibilityEnabled;
+
+ readonly attribute DOMString platformName;
+ readonly attribute AccessibilityUIElement rootElement;
+ readonly attribute AccessibilityUIElement focusedElement;
+ AccessibilityUIElement elementAtPoint(long x, long y);
+ AccessibilityUIElement accessibleElementById(DOMString id);
+
+ boolean addNotificationListener(object functionCallback);
+ boolean removeNotificationListener();
+
+ void logFocusEvents();
+ void logValueChangeEvents();
+ void logScrollingStartEvents();
+ void logAccessibilityEvents();
+ void resetToConsistentState();
+};
+
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityTextMarker.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityTextMarker.idl
new file mode 100644
index 000000000..149c95f34
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityTextMarker.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface AccessibilityTextMarker {
+ boolean isEqual(AccessibilityTextMarker otherMarker);
+};
+
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityTextMarkerRange.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityTextMarkerRange.idl
new file mode 100644
index 000000000..962c584e6
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityTextMarkerRange.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface AccessibilityTextMarkerRange {
+ boolean isEqual(AccessibilityTextMarkerRange otherMarkerRange);
+};
+
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl
new file mode 100644
index 000000000..967cb975d
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface AccessibilityUIElement {
+ boolean isEqual(AccessibilityUIElement otherElement);
+
+ // Document information
+ readonly attribute DOMString documentEncoding;
+ readonly attribute DOMString documentURI;
+
+ // Element access.
+ AccessibilityUIElement elementAtPoint(long x, long y);
+ AccessibilityUIElement childAtIndex(unsigned long index);
+ unsigned long indexOfChild(AccessibilityUIElement child);
+ AccessibilityUIElement linkedUIElementAtIndex(unsigned long index);
+ AccessibilityUIElement selectedChildAtIndex(unsigned long index);
+ void setSelectedChild(AccessibilityUIElement element);
+ void setSelectedChildAtIndex(unsigned long index);
+ void removeSelectionAtIndex(unsigned long index);
+ void clearSelectedChildren();
+ AccessibilityUIElement titleUIElement();
+ AccessibilityUIElement parentElement();
+
+ readonly attribute DOMString role;
+ readonly attribute DOMString subrole;
+ readonly attribute DOMString roleDescription;
+ readonly attribute DOMString computedRoleString;
+ readonly attribute DOMString title;
+ readonly attribute DOMString description;
+ readonly attribute DOMString language;
+ readonly attribute DOMString helpText;
+ readonly attribute DOMString valueDescription;
+ readonly attribute DOMString url;
+ readonly attribute DOMString speak;
+ readonly attribute DOMString orientation;
+ readonly attribute long insertionPointLineNumber;
+ readonly attribute DOMString selectedTextRange;
+
+ DOMString stringAttributeValue(DOMString attr);
+ double numberAttributeValue(DOMString attr);
+ object uiElementArrayAttributeValue(DOMString attr);
+ AccessibilityUIElement uiElementAttributeValue(DOMString attr);
+ boolean boolAttributeValue(DOMString attr);
+ void setBoolAttributeValue(DOMString attr, boolean value);
+ boolean isAttributeSupported(DOMString attr);
+ boolean isAttributeSettable(DOMString attr);
+ boolean isPressActionSupported();
+ boolean isIncrementActionSupported();
+ boolean isDecrementActionSupported();
+
+ readonly attribute DOMString stringValue;
+ readonly attribute long intValue;
+ readonly attribute long minValue;
+ readonly attribute long maxValue;
+
+ readonly attribute boolean isEnabled;
+ readonly attribute boolean isRequired;
+ readonly attribute boolean isFocused;
+ readonly attribute boolean isFocusable;
+ readonly attribute boolean isSelectable;
+ readonly attribute boolean isSelected;
+ readonly attribute boolean isSelectedOptionActive;
+ readonly attribute boolean isMultiSelectable;
+ readonly attribute boolean isExpanded;
+ readonly attribute boolean isChecked;
+ readonly attribute boolean isIndeterminate;
+ readonly attribute boolean isVisible;
+ readonly attribute boolean isCollapsed;
+ readonly attribute boolean hasPopup;
+ readonly attribute boolean isIgnored;
+ readonly attribute boolean isSingleLine;
+ readonly attribute boolean isMultiLine;
+ readonly attribute boolean isOffScreen;
+ readonly attribute boolean isValid;
+ readonly attribute long hierarchicalLevel;
+ readonly attribute boolean ariaIsGrabbed;
+ readonly attribute DOMString ariaDropEffects;
+ readonly attribute DOMString classList;
+
+ readonly attribute long x;
+ readonly attribute long y;
+ readonly attribute long width;
+ readonly attribute long height;
+ readonly attribute long clickPointX;
+ readonly attribute long clickPointY;
+
+ readonly attribute long childrenCount;
+ readonly attribute long selectedChildrenCount;
+ readonly attribute long rowCount;
+ readonly attribute long columnCount;
+
+ // Actions.
+ void increment();
+ void decrement();
+ void press();
+ void showMenu();
+
+ // Attribute info.
+ DOMString allAttributes();
+ DOMString attributesOfChildren();
+ DOMString attributesOfLinkedUIElements();
+ DOMString attributesOfDocumentLinks();
+
+ // Text info.
+ DOMString characterAtOffset(long offset);
+ DOMString wordAtOffset(long offset);
+ DOMString lineAtOffset(long offset);
+ DOMString sentenceAtOffset(long offset);
+
+ // Table info.
+ DOMString attributesOfColumnHeaders();
+ DOMString attributesOfRowHeaders();
+ DOMString attributesOfColumns();
+ DOMString attributesOfRows();
+ DOMString attributesOfVisibleCells();
+ DOMString attributesOfHeader();
+ AccessibilityUIElement cellForColumnAndRow(unsigned long column, unsigned long row);
+ AccessibilityUIElement selectedRowAtIndex(unsigned long index);
+ AccessibilityUIElement disclosedByRow();
+ AccessibilityUIElement disclosedRowAtIndex(unsigned long index);
+ AccessibilityUIElement rowAtIndex(unsigned long index);
+ long indexInTable();
+ DOMString rowIndexRange();
+ DOMString columnIndexRange();
+ long rowCount();
+ long columnCount();
+ object columnHeaders();
+ object rowHeaders();
+
+ AccessibilityUIElement ariaOwnsElementAtIndex(unsigned long index);
+ AccessibilityUIElement ariaFlowToElementAtIndex(unsigned long index);
+ AccessibilityUIElement ariaControlsElementAtIndex(unsigned long index);
+
+ // Paramaterized attributes.
+ DOMString parameterizedAttributeNames();
+ long lineForIndex(long index);
+ DOMString rangeForLine(long index);
+ DOMString rangeForPosition(long x, long y);
+ DOMString boundsForRange(unsigned long location, unsigned long length);
+ DOMString stringForRange(unsigned long location, unsigned long length);
+ DOMString attributedStringForRange(unsigned long location, unsigned long length);
+ boolean attributedStringRangeIsMisspelled(unsigned long location, unsigned long length);
+ [PassContext] unsigned long uiElementCountForSearchPredicate(AccessibilityUIElement startElement, boolean isDirectionNext, object searchKey, DOMString searchText, boolean visibleOnly, boolean immediateDescendantsOnly);
+ [PassContext] AccessibilityUIElement uiElementForSearchPredicate(AccessibilityUIElement startElement, boolean isDirectionNext, object searchKey, DOMString searchText, boolean visibleOnly, boolean immediateDescendantsOnly);
+ [PassContext] DOMString selectTextWithCriteria(DOMString ambiguityResolution, object searchStrings, DOMString replacementString, DOMString activity);
+ boolean setSelectedTextRange(unsigned long location, unsigned long length);
+
+ // Scroll area attributes.
+ readonly attribute AccessibilityUIElement horizontalScrollbar;
+ readonly attribute AccessibilityUIElement verticalScrollbar;
+
+ void scrollToMakeVisible();
+ void scrollToGlobalPoint(long x, long y);
+ void scrollToMakeVisibleWithSubFocus(long x, long y, long width, long height);
+
+ void takeFocus();
+ boolean scrollPageDown();
+ boolean scrollPageUp();
+ boolean scrollPageLeft();
+ boolean scrollPageRight();
+
+ // Text markers.
+ AccessibilityTextMarkerRange lineTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarkerRange textMarkerRangeForElement(AccessibilityUIElement element);
+ AccessibilityTextMarkerRange textMarkerRangeForMarkers(AccessibilityTextMarker startMarker, AccessibilityTextMarker endMarker);
+ AccessibilityTextMarkerRange selectedTextMarkerRange();
+ void resetSelectedTextMarkerRange();
+ AccessibilityTextMarker startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange range);
+ AccessibilityTextMarker endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange range);
+ AccessibilityTextMarker endTextMarkerForBounds(long x, long y, long width, long height);
+ AccessibilityTextMarker startTextMarkerForBounds(long x, long y, long width, long height);
+ AccessibilityTextMarker textMarkerForPoint(long x, long y);
+ AccessibilityTextMarker previousTextMarker(AccessibilityTextMarker marker);
+ AccessibilityTextMarker nextTextMarker(AccessibilityTextMarker marker);
+ AccessibilityUIElement accessibilityElementForTextMarker(AccessibilityTextMarker marker);
+ DOMString stringForTextMarkerRange(AccessibilityTextMarkerRange range);
+ long textMarkerRangeLength(AccessibilityTextMarkerRange range);
+ boolean attributedStringForTextMarkerRangeContainsAttribute(DOMString attr, AccessibilityTextMarkerRange range);
+ long indexForTextMarker(AccessibilityTextMarker marker);
+ boolean isTextMarkerValid(AccessibilityTextMarker marker);
+ AccessibilityTextMarker textMarkerForIndex(long textIndex);
+ readonly attribute AccessibilityTextMarker startTextMarker;
+ readonly attribute AccessibilityTextMarker endTextMarker;
+ boolean setSelectedVisibleTextRange(AccessibilityTextMarkerRange range);
+ AccessibilityTextMarkerRange leftWordTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarkerRange rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarker previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarker nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarkerRange paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarker previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarker nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarkerRange sentenceTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarker previousSentenceStartTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
+ AccessibilityTextMarker nextSentenceEndTextMarkerForTextMarker(AccessibilityTextMarker textMarker);
+
+ // Returns an ordered list of supported actions for an element.
+ readonly attribute DOMString supportedActions;
+ readonly attribute DOMString mathPostscriptsDescription;
+ readonly attribute DOMString mathPrescriptsDescription;
+
+ readonly attribute DOMString pathDescription;
+
+ // iOS specific accessibility methods.
+ readonly attribute DOMString identifier;
+ readonly attribute DOMString traits;
+ readonly attribute long elementTextPosition;
+ readonly attribute long elementTextLength;
+ readonly attribute DOMString stringForSelection;
+ object elementsForRange(unsigned long location, unsigned long length);
+ void increaseTextSelection();
+ void decreaseTextSelection();
+ AccessibilityUIElement linkedElement();
+ AccessibilityUIElement headerElementAtIndex(unsigned long index);
+ // This will simulate the accessibilityDidBecomeFocused API in UIKit.
+ void assistiveTechnologySimulatedFocus();
+ readonly attribute boolean isSearchField;
+ readonly attribute boolean isTextArea;
+
+ // Fieldset
+ readonly attribute boolean hasContainedByFieldsetTrait;
+ AccessibilityUIElement fieldsetAncestorElement();
+
+ // Notification support.
+ boolean addNotificationListener(object callbackFunction);
+ boolean removeNotificationListener();
+};
+
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm b/Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm
new file mode 100644
index 000000000..98d37dab9
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm
@@ -0,0 +1,577 @@
+# Copyright (C) 2010 Apple Inc. All rights reserved.
+# Copyright (C) 2012 Samsung Electronics
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+use warnings;
+use File::Spec;
+
+package CodeGeneratorTestRunner;
+
+use Carp qw<longmess>;
+use Data::Dumper;
+
+sub assert
+{
+ my $message = shift;
+
+ my $mess = longmess();
+ print Dumper($mess);
+
+ die $message;
+}
+
+sub new
+{
+ my ($class, $codeGenerator, $writeDependencies, $verbose, $idlFilePath) = @_;
+
+ my $reference = {
+ codeGenerator => $codeGenerator,
+ idlFilePath => $idlFilePath,
+ };
+
+ bless($reference, $class);
+ return $reference;
+}
+
+sub GenerateInterface
+{
+}
+
+sub WriteData
+{
+ my ($self, $interface, $outputDir) = @_;
+
+ foreach my $file ($self->_generateHeaderFile($interface), $self->_generateImplementationFile($interface)) {
+ $$self{codeGenerator}->UpdateFile(File::Spec->catfile($outputDir, $$file{name}), join("", @{$$file{contents}}));
+ }
+}
+
+sub _className
+{
+ my ($type) = @_;
+
+ return "JS" . _implementationClassName($type);
+}
+
+sub _classRefGetter
+{
+ my ($self, $type) = @_;
+
+ return $$self{codeGenerator}->WK_lcfirst(_implementationClassName($type)) . "Class";
+}
+
+sub _parseLicenseBlock
+{
+ my ($fileHandle) = @_;
+
+ my ($copyright, $readCount, $buffer, $currentCharacter, $previousCharacter);
+ my $startSentinel = "/*";
+ my $lengthOfStartSentinel = length($startSentinel);
+ $readCount = read($fileHandle, $buffer, $lengthOfStartSentinel);
+ return "" if ($readCount < $lengthOfStartSentinel || $buffer ne $startSentinel);
+ $copyright = $buffer;
+
+ while ($readCount = read($fileHandle, $currentCharacter, 1)) {
+ $copyright .= $currentCharacter;
+ return $copyright if $currentCharacter eq "/" && $previousCharacter eq "*";
+ $previousCharacter = $currentCharacter;
+ }
+
+ return "";
+}
+
+sub _parseLicenseBlockFromFile
+{
+ my ($path) = @_;
+ open my $fileHandle, "<", $path or die "Failed to open $path for reading: $!";
+ my $licenseBlock = _parseLicenseBlock($fileHandle);
+ close($fileHandle);
+ return $licenseBlock;
+}
+
+sub _defaultLicenseBlock
+{
+ return <<EOF;
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+EOF
+}
+
+sub _licenseBlock
+{
+ my ($self) = @_;
+ return $self->{licenseBlock} if $self->{licenseBlock};
+
+ my $licenseBlock = _parseLicenseBlockFromFile($self->{idlFilePath}) || _defaultLicenseBlock();
+ $self->{licenseBlock} = $licenseBlock;
+ return $licenseBlock;
+}
+
+sub _generateHeaderFile
+{
+ my ($self, $interface) = @_;
+
+ my @contents = ();
+
+ my $type = $interface->type;
+ my $className = _className($type);
+ my $implementationClassName = _implementationClassName($type);
+ my $filename = $className . ".h";
+
+ push(@contents, $self->_licenseBlock());
+
+ my $parentClassName = _parentClassName($interface);
+
+ push(@contents, <<EOF);
+
+#ifndef ${className}_h
+#define ${className}_h
+
+#include "${parentClassName}.h"
+EOF
+ push(@contents, <<EOF);
+
+namespace WTR {
+
+class ${implementationClassName};
+
+class ${className} : public ${parentClassName} {
+public:
+ static JSClassRef @{[$self->_classRefGetter($type)]}();
+
+private:
+ static const JSStaticFunction* staticFunctions();
+ static const JSStaticValue* staticValues();
+EOF
+
+ if (my @functions = @{$interface->functions}) {
+ push(@contents, "\n // Functions\n\n");
+ foreach my $function (@functions) {
+ push(@contents, " static JSValueRef @{[$function->name]}(JSContextRef, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef*);\n");
+ }
+ }
+
+ if (my @attributes = @{$interface->attributes}) {
+ push(@contents, "\n // Attributes\n\n");
+ foreach my $attribute (@attributes) {
+ push(@contents, " static JSValueRef @{[$self->_getterName($attribute)]}(JSContextRef, JSObjectRef, JSStringRef, JSValueRef*);\n");
+ push(@contents, " static bool @{[$self->_setterName($attribute)]}(JSContextRef, JSObjectRef, JSStringRef, JSValueRef, JSValueRef*);\n") unless $attribute->isReadOnly;
+ }
+ }
+
+ push(@contents, <<EOF);
+};
+
+${implementationClassName}* to${implementationClassName}(JSContextRef, JSValueRef);
+
+} // namespace WTR
+
+#endif // ${className}_h
+EOF
+
+ return { name => $filename, contents => \@contents };
+}
+
+sub _generateImplementationFile
+{
+ my ($self, $interface) = @_;
+
+ my @contentsPrefix = ();
+ my %contentsIncludes = ();
+ my @contents = ();
+
+ my $type = $interface->type;
+ my $className = _className($type);
+ my $implementationClassName = _implementationClassName($type);
+ my $filename = $className . ".cpp";
+
+ push(@contentsPrefix, $self->_licenseBlock());
+
+ my $classRefGetter = $self->_classRefGetter($type);
+ my $parentClassName = _parentClassName($interface);
+
+ $contentsIncludes{"${className}.h"} = 1;
+ $contentsIncludes{"${implementationClassName}.h"} = 1;
+
+ push(@contentsPrefix, <<EOF);
+
+EOF
+
+ push(@contents, <<EOF);
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <wtf/GetPtr.h>
+
+namespace WTR {
+
+${implementationClassName}* to${implementationClassName}(JSContextRef context, JSValueRef value)
+{
+ if (!context || !value || !${className}::${classRefGetter}() || !JSValueIsObjectOfClass(context, value, ${className}::${classRefGetter}()))
+ return 0;
+ return static_cast<${implementationClassName}*>(JSWrapper::unwrap(context, value));
+}
+
+JSClassRef ${className}::${classRefGetter}()
+{
+ static JSClassRef jsClass;
+ if (!jsClass) {
+ JSClassDefinition definition = kJSClassDefinitionEmpty;
+ definition.className = "@{[$type->name]}";
+ definition.parentClass = @{[$self->_parentClassRefGetterExpression($interface)]};
+ definition.staticValues = staticValues();
+ definition.staticFunctions = staticFunctions();
+EOF
+
+ push(@contents, " definition.initialize = initialize;\n") unless _parentInterface($interface);
+ push(@contents, " definition.finalize = finalize;\n") unless _parentInterface($interface);
+
+ push(@contents, <<EOF);
+ jsClass = JSClassCreate(&definition);
+ }
+ return jsClass;
+}
+
+EOF
+
+ push(@contents, $self->_staticFunctionsGetterImplementation($interface), "\n");
+ push(@contents, $self->_staticValuesGetterImplementation($interface));
+
+ if (my @functions = @{$interface->functions}) {
+ push(@contents, "\n// Functions\n");
+
+ foreach my $function (@functions) {
+ push(@contents, <<EOF);
+
+JSValueRef ${className}::@{[$function->name]}(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ ${implementationClassName}* impl = to${implementationClassName}(context, thisObject);
+ if (!impl)
+ return JSValueMakeUndefined(context);
+
+EOF
+ my $functionCall;
+ if ($function->extendedAttributes->{"CustomArgumentHandling"}) {
+ $functionCall = "impl->" . $function->name . "(context, argumentCount, arguments, exception)";
+ } else {
+ my @arguments = ();
+ my @specifiedArguments = @{$function->arguments};
+
+ $self->_includeHeaders(\%contentsIncludes, $function->type);
+
+ if ($function->extendedAttributes->{"PassContext"}) {
+ push(@arguments, "context");
+ }
+
+ foreach my $i (0..$#specifiedArguments) {
+ my $argument = $specifiedArguments[$i];
+
+ $self->_includeHeaders(\%contentsIncludes, $type);
+
+ push(@contents, " " . $self->_platformTypeVariableDeclaration($argument->type, $argument->name, "arguments[$i]", "argumentCount > $i") . "\n");
+
+ push(@arguments, $self->_argumentExpression($argument));
+ }
+
+ $functionCall = "impl->" . $function->name . "(" . join(", ", @arguments) . ")";
+ }
+
+ push(@contents, " ${functionCall};\n\n") if $function->type->name eq "void";
+ push(@contents, " return " . $self->_returnExpression($function->type, $functionCall) . ";\n}\n");
+ }
+ }
+
+ if (my @attributes = @{$interface->attributes}) {
+ push(@contents, "\n// Attributes\n");
+ foreach my $attribute (@attributes) {
+ $self->_includeHeaders(\%contentsIncludes, $attribute->type);
+
+ my $getterName = $self->_getterName($attribute);
+ my $getterExpression = "impl->${getterName}()";
+
+ push(@contents, <<EOF);
+
+JSValueRef ${className}::${getterName}(JSContextRef context, JSObjectRef object, JSStringRef, JSValueRef* exception)
+{
+ ${implementationClassName}* impl = to${implementationClassName}(context, object);
+ if (!impl)
+ return JSValueMakeUndefined(context);
+
+ return @{[$self->_returnExpression($attribute->type, $getterExpression)]};
+}
+EOF
+
+ unless ($attribute->isReadOnly) {
+ push(@contents, <<EOF);
+
+bool ${className}::@{[$self->_setterName($attribute)]}(JSContextRef context, JSObjectRef object, JSStringRef, JSValueRef value, JSValueRef* exception)
+{
+ ${implementationClassName}* impl = to${implementationClassName}(context, object);
+ if (!impl)
+ return false;
+
+EOF
+
+ my $platformValue = $self->_platformTypeConstructor($attribute->type, "value");
+
+ push(@contents, <<EOF);
+ impl->@{[$self->_setterName($attribute)]}(${platformValue});
+
+ return true;
+}
+EOF
+ }
+ }
+ }
+
+ push(@contents, <<EOF);
+
+} // namespace WTR
+
+EOF
+
+ unshift(@contents, map { "#include \"$_\"\n" } sort keys(%contentsIncludes));
+ unshift(@contents, "#include \"config.h\"\n");
+ unshift(@contents, @contentsPrefix);
+
+ return { name => $filename, contents => \@contents };
+}
+
+sub _getterName
+{
+ my ($self, $attribute) = @_;
+
+ return $attribute->name;
+}
+
+sub _includeHeaders
+{
+ my ($self, $headers, $type) = @_;
+
+ return unless defined $type;
+ return if $type->name eq "boolean";
+ return if $type->name eq "object";
+ return if $$self{codeGenerator}->IsNonPointerType($type);
+ return if $$self{codeGenerator}->IsStringType($type);
+
+ $$headers{_className($type) . ".h"} = 1;
+ $$headers{_implementationClassName($type) . ".h"} = 1;
+}
+
+sub _implementationClassName
+{
+ my ($type) = @_;
+
+ return $type->name;
+}
+
+sub _parentClassName
+{
+ my ($interface) = @_;
+
+ my $parentInterface = _parentInterface($interface);
+ return $parentInterface ? _className($parentInterface) : "JSWrapper";
+}
+
+sub _parentClassRefGetterExpression
+{
+ my ($self, $interface) = @_;
+
+ my $parentInterface = _parentInterface($interface);
+ return $parentInterface ? $self->_classRefGetter($parentInterface) . "()" : "0";
+}
+
+sub _parentInterface
+{
+ my ($interface) = @_;
+ return $interface->parentType;
+}
+
+sub _platformType
+{
+ my ($self, $type) = @_;
+
+ return undef unless defined $type;
+
+ return "bool" if $type->name eq "boolean";
+ return "JSValueRef" if $type->name eq "object";
+ return "JSRetainPtr<JSStringRef>" if $$self{codeGenerator}->IsStringType($type);
+ return "double" if $$self{codeGenerator}->IsNonPointerType($type);
+ return _implementationClassName($type);
+}
+
+sub _platformTypeConstructor
+{
+ my ($self, $type, $argumentName) = @_;
+
+ return "JSValueToNullableBoolean(context, $argumentName)" if $type->name eq "boolean" && $type->isNullable;
+ return "JSValueToBoolean(context, $argumentName)" if $type->name eq "boolean";
+ return "$argumentName" if $type->name eq "object";
+ return "JSRetainPtr<JSStringRef>(Adopt, JSValueToStringCopy(context, $argumentName, 0))" if $$self{codeGenerator}->IsStringType($type);
+ return "JSValueToNumber(context, $argumentName, 0)" if $$self{codeGenerator}->IsNonPointerType($type);
+ return "to" . _implementationClassName($type) . "(context, $argumentName)";
+}
+
+sub _platformTypeVariableDeclaration
+{
+ my ($self, $type, $variableName, $argumentName, $condition) = @_;
+
+ my $platformType = $self->_platformType($type);
+ my $constructor = $self->_platformTypeConstructor($type, $argumentName);
+
+ my %nonPointerTypes = (
+ "bool" => 1,
+ "double" => 1,
+ "JSRetainPtr<JSStringRef>" => 1,
+ "JSValueRef" => 1,
+ );
+
+ my $nullValue = "0";
+ if ($platformType eq "JSValueRef") {
+ $nullValue = "JSValueMakeUndefined(context)";
+ } elsif (defined $nonPointerTypes{$platformType} && $platformType ne "double") {
+ $nullValue = "$platformType()";
+ }
+
+ $platformType .= "*" unless defined $nonPointerTypes{$platformType};
+
+ return "$platformType $variableName = $condition && $constructor;" if $condition && $platformType eq "bool";
+ return "$platformType $variableName = $condition ? $constructor : $nullValue;" if $condition;
+ return "$platformType $variableName = $constructor;";
+}
+
+sub _returnExpression
+{
+ my ($self, $returnType, $expression) = @_;
+
+ return "JSValueMakeUndefined(context)" if $returnType->name eq "void";
+ return "JSValueMakeBooleanOrNull(context, ${expression})" if $returnType->name eq "boolean" && $returnType->isNullable;
+ return "JSValueMakeBoolean(context, ${expression})" if $returnType->name eq "boolean";
+ return "${expression}" if $returnType->name eq "object";
+ return "JSValueMakeNumber(context, ${expression})" if $$self{codeGenerator}->IsNonPointerType($returnType);
+ return "JSValueMakeStringOrNull(context, ${expression}.get())" if $$self{codeGenerator}->IsStringType($returnType);
+ return "toJS(context, WTF::getPtr(${expression}))";
+}
+
+sub _argumentExpression
+{
+ my ($self, $argument) = @_;
+
+ my $type = $argument->type;
+ my $name = $argument->name;
+
+ return "${name}.get()" if $$self{codeGenerator}->IsStringType($type);
+ return $name;
+}
+
+sub _setterName
+{
+ my ($self, $attribute) = @_;
+
+ my $name = $attribute->name;
+
+ return "set" . $$self{codeGenerator}->WK_ucfirst($name);
+}
+
+sub _staticFunctionsGetterImplementation
+{
+ my ($self, $interface) = @_;
+
+ my $mapFunction = sub {
+ my $name = $_->name;
+ my @attributes = qw(kJSPropertyAttributeDontDelete kJSPropertyAttributeReadOnly);
+ push(@attributes, "kJSPropertyAttributeDontEnum") if $_->extendedAttributes->{"DontEnum"};
+
+ return "{ \"$name\", $name, " . join(" | ", @attributes) . " }";
+ };
+
+ return $self->_staticFunctionsOrValuesGetterImplementation($interface, "function", "{ 0, 0, 0 }", $mapFunction, $interface->functions);
+}
+
+sub _staticFunctionsOrValuesGetterImplementation
+{
+ my ($self, $interface, $functionOrValue, $arrayTerminator, $mapFunction, $functionsOrAttributes) = @_;
+
+ my $className = _className($interface->type);
+ my $uppercaseFunctionOrValue = $$self{codeGenerator}->WK_ucfirst($functionOrValue);
+
+ my $result = <<EOF;
+const JSStatic${uppercaseFunctionOrValue}* ${className}::static${uppercaseFunctionOrValue}s()
+{
+EOF
+
+ my @initializers = map(&$mapFunction, @{$functionsOrAttributes});
+ return $result . " return 0;\n}\n" unless @initializers;
+
+ $result .= <<EOF
+ static const JSStatic${uppercaseFunctionOrValue} ${functionOrValue}s[] = {
+ @{[join(",\n ", @initializers)]},
+ ${arrayTerminator}
+ };
+ return ${functionOrValue}s;
+}
+EOF
+}
+
+sub _staticValuesGetterImplementation
+{
+ my ($self, $interface) = @_;
+
+ my $mapFunction = sub {
+ return if $_->extendedAttributes->{"NoImplementation"};
+
+ my $attributeName = $_->name;
+ my $getterName = $self->_getterName($_);
+ my $setterName = $_->isReadOnly ? "0" : $self->_setterName($_);
+ my @attributes = qw(kJSPropertyAttributeDontDelete);
+ push(@attributes, "kJSPropertyAttributeReadOnly") if $_->isReadOnly;
+ push(@attributes, "kJSPropertyAttributeDontEnum") if $_->extendedAttributes->{"DontEnum"};
+
+ return "{ \"$attributeName\", $getterName, $setterName, " . join(" | ", @attributes) . " }";
+ };
+
+ return $self->_staticFunctionsOrValuesGetterImplementation($interface, "value", "{ 0, 0, 0, 0 }", $mapFunction, $interface->attributes);
+}
+
+1;
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl
new file mode 100644
index 000000000..f3280bb94
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010, 2011, 2014-2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface EventSendingController {
+ void mouseDown(long buttonNumber, object modifierArray);
+ void mouseUp(long buttonNumber, object modifierArray);
+ void mouseMoveTo(long x, long y);
+ void mouseForceClick();
+ void startAndCancelMouseForceClick();
+ void mouseForceDown();
+ void mouseForceUp();
+ void mouseForceChanged(double force);
+ void mouseScrollBy(long x, long y);
+ void mouseScrollByWithWheelAndMomentumPhases(long x, long y, DOMString phase, DOMString momentum);
+ void swipeGestureWithWheelAndMomentumPhases(long x, long y, DOMString phase, DOMString momentum);
+ void continuousMouseScrollBy(long x, long y, optional boolean paged);
+ object contextClick();
+ void scheduleAsynchronousClick();
+
+ void leapForward(long milliseconds);
+
+ void keyDown(DOMString key, object modifierArray, long location);
+ void scheduleAsynchronousKeyDown(DOMString key);
+
+ // Zoom functions.
+ void textZoomIn();
+ void textZoomOut();
+ void zoomPageIn();
+ void zoomPageOut();
+ void scalePageBy(double scale, double x, double y);
+
+ void monitorWheelEvents();
+ void callAfterScrollingCompletes(object functionCallback);
+
+#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
+ // Touch events.
+ void addTouchPoint(long x, long y);
+ void updateTouchPoint(long index, long x, long y);
+ void setTouchModifier(DOMString modifier, boolean enable);
+ void setTouchPointRadius(long radiusX, long radiusY);
+ void touchStart();
+ void touchMove();
+ void touchEnd();
+ void touchCancel();
+ void clearTouchPoints();
+ void releaseTouchPoint(long index);
+ void cancelTouchPoint(long index);
+#endif
+};
+
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrappable.h b/Tools/WebKitTestRunner/InjectedBundle/Bindings/GCController.idl
index 5ec7197c5..fb933834d 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrappable.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/GCController.idl
@@ -23,25 +23,9 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef JSWrappable_h
-#define JSWrappable_h
-
-#include <JavaScriptCore/JavaScript.h>
-#include <wtf/RefCounted.h>
-
-namespace WTR {
-
-class JSWrappable : public RefCounted<JSWrappable> {
-public:
- virtual ~JSWrappable() { }
- virtual JSClassRef wrapperClass() = 0;
+interface GCController {
+ void collect();
+ void collectOnAlternateThread(boolean waitUntilDone);
+ unsigned long long getJSObjectCount();
};
-inline JSValueRef JSValueMakeStringOrNull(JSContextRef context, JSStringRef stringOrNull)
-{
- return stringOrNull ? JSValueMakeString(context, stringOrNull) : JSValueMakeNull(context);
-}
-
-} // namespace WTR
-
-#endif // JSWrappable_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
new file mode 100644
index 000000000..352fa0ae7
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface TestRunner {
+ readonly attribute boolean isWebKit2;
+
+ // The basics.
+ void dumpAsText(boolean dumpPixels);
+ void dumpChildFramesAsText();
+ void waitForPolicyDelegate();
+ void waitUntilDone();
+ void waitUntilDownloadFinished();
+ void notifyDone();
+ double preciseTime();
+ readonly attribute double timeout;
+
+ // Other dumping.
+ void dumpBackForwardList();
+ void dumpChildFrameScrollPositions();
+ void dumpEditingCallbacks();
+ void dumpSelectionRect();
+ void dumpStatusCallbacks();
+ void dumpTitleChanges();
+ void dumpFullScreenCallbacks();
+ void dumpFrameLoadCallbacks();
+ void dumpProgressFinishedCallback();
+ void dumpResourceLoadCallbacks();
+ void dumpResourceResponseMIMETypes();
+ void dumpWillCacheResponse();
+ void dumpApplicationCacheDelegateCallbacks();
+ void dumpDatabaseCallbacks();
+ void dumpDOMAsWebArchive();
+ void dumpPolicyDelegateCallbacks();
+
+ // Special options.
+ void keepWebHistory();
+ void setAcceptsEditing(boolean value);
+ void setCanOpenWindows(boolean value);
+ void setCloseRemainingWindowsWhenComplete(boolean value);
+ void setXSSAuditorEnabled(boolean value);
+ void setAllowUniversalAccessFromFileURLs(boolean value);
+ void setAllowFileAccessFromFileURLs(boolean value);
+ void setNeedsStorageAccessFromFileURLsQuirk(boolean value);
+ void setPluginsEnabled(boolean value);
+ void setJavaScriptCanAccessClipboard(boolean value);
+ void setPrivateBrowsingEnabled(boolean value);
+ void setUseDashboardCompatibilityMode(boolean value);
+ void setPopupBlockingEnabled(boolean value);
+ void setAuthorAndUserStylesEnabled(boolean value);
+ void setCustomPolicyDelegate(boolean enabled, boolean permissive);
+ void addOriginAccessWhitelistEntry(DOMString sourceOrigin, DOMString destinationProtocol, DOMString destinationHost, boolean allowDestinationSubdomains);
+ void removeOriginAccessWhitelistEntry(DOMString sourceOrigin, DOMString destinationProtocol, DOMString destinationHost, boolean allowDestinationSubdomains);
+ void setUserStyleSheetEnabled(boolean value);
+ void setUserStyleSheetLocation(DOMString location);
+ void setSpatialNavigationEnabled(boolean value);
+ void setTabKeyCyclesThroughElements(boolean enabled);
+ void setSerializeHTTPLoads();
+ void dispatchPendingLoadRequests();
+ void setCacheModel(long model);
+ void setAsynchronousSpellCheckingEnabled(boolean value);
+ void setPrinting();
+ void setShouldDecideNavigationPolicyAfterDelay(boolean value);
+ void setNavigationGesturesEnabled(boolean value);
+ void setIgnoresViewportScaleLimits(boolean value);
+ void setShouldDownloadUndisplayableMIMETypes(boolean value);
+
+ // Special DOM functions.
+ void clearBackForwardList();
+ void execCommand(DOMString name, DOMString argument);
+ boolean isCommandEnabled(DOMString name);
+ unsigned long windowCount();
+
+ // Special DOM variables.
+ attribute boolean globalFlag;
+
+ // Repaint testing.
+ void testRepaint();
+ void repaintSweepHorizontally();
+ void display();
+
+ // Printing
+ boolean isPageBoxVisible(long pageIndex);
+
+ [PassContext] void setValueForUser(object element, DOMString value);
+
+ // UserContent testing.
+ void addUserScript(DOMString source, boolean runAtStart, boolean allFrames);
+ void addUserStyleSheet(DOMString source, boolean allFrames);
+
+ // Local storage API
+ void clearAllDatabases();
+ void setDatabaseQuota(unsigned long long quota);
+ DOMString pathToLocalResource(DOMString url);
+
+ attribute double databaseDefaultQuota;
+ attribute double databaseMaxQuota;
+
+ // Application Cache API
+ void clearAllApplicationCaches();
+ void setAppCacheMaximumSize(unsigned long long size);
+ long long applicationCacheDiskUsageForOrigin(DOMString origin);
+ void clearApplicationCacheForOrigin(DOMString name);
+ void disallowIncreaseForApplicationCacheQuota();
+ object originsWithApplicationCache();
+
+ // Text search testing.
+ boolean findString(DOMString target, object optionsArray);
+
+ // Evaluating script in a special context.
+ [PassContext] void evaluateScriptInIsolatedWorld(unsigned long worldID, DOMString script);
+
+ // For Web Inspector tests
+ void showWebInspector();
+ void closeWebInspector();
+ void evaluateInWebInspector(DOMString script);
+ readonly attribute DOMString inspectorTestStubURL;
+
+ void setPOSIXLocale(DOMString locale);
+
+ void setTextDirection(DOMString direction);
+
+ void setWillSendRequestReturnsNull(boolean flag);
+ void setWillSendRequestReturnsNullOnRedirect(boolean flag);
+ void setWillSendRequestAddsHTTPBody(DOMString body);
+
+ void setShouldStayOnPageAfterHandlingBeforeUnload(boolean flag);
+
+ void setDefersLoading(boolean flag);
+ void setStopProvisionalFrameLoads();
+
+ // Focus testing.
+ void addChromeInputField(object callback);
+ void removeChromeInputField(object callback);
+ void focusWebView(object callback);
+
+ // Window/view state
+ void setBackingScaleFactor(double backingScaleFactor, object callback);
+
+ void setWindowIsKey(boolean isKey);
+ void setViewSize(double width, double height);
+
+ // Cookies testing
+ void setAlwaysAcceptCookies(boolean accept);
+
+ void overridePreference(DOMString preference, DOMString value);
+
+ // Page Visibility API
+ void setPageVisibility(DOMString state);
+ void resetPageVisibility();
+
+ // Control full screen behavior.
+ void setHasCustomFullScreenBehavior(boolean value);
+
+ // Web notifications support
+ void grantWebNotificationPermission(DOMString origin);
+ void denyWebNotificationPermission(DOMString origin);
+ void removeAllWebNotificationPermissions();
+ void simulateWebNotificationClick(object notification);
+
+ // Geolocation
+ void setGeolocationPermission(boolean value);
+ void setMockGeolocationPosition(double latitude, double longitude, double accuracy, optional object altitude, optional object altitudeAccuracy, optional object heading, optional object speed);
+ void setMockGeolocationPositionUnavailableError(DOMString errorMessage);
+ boolean isGeolocationProviderActive();
+
+ // MediaStream
+ void setUserMediaPermission(boolean value);
+ void setUserMediaPersistentPermissionForOrigin(boolean permission, DOMString origin, DOMString parentOrigin);
+ unsigned long userMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin);
+ void resetUserMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin);
+
+ // Audio testing.
+ [PassContext] void setAudioResult(object data);
+
+ boolean callShouldCloseOnWebView();
+
+ // Work queue.
+ void queueBackNavigation(unsigned long howFarBackward);
+ void queueForwardNavigation(unsigned long howFarForward);
+ void queueLoad(DOMString url, DOMString target, optional boolean shouldOpenExternalURLs);
+ void queueLoadHTMLString(DOMString content, optional DOMString baseURL, optional DOMString unreachableURL);
+ void queueReload();
+ void queueLoadingScript(DOMString script);
+ void queueNonLoadingScript(DOMString script);
+
+ // Authentication
+ void setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(boolean value);
+ void setHandlesAuthenticationChallenges(boolean value);
+ void setShouldLogCanAuthenticateAgainstProtectionSpace(boolean value);
+ void setAuthenticationUsername(DOMString username);
+ void setAuthenticationPassword(DOMString password);
+
+ void setAllowsAnySSLCertificate(boolean value);
+
+ // Secure text input mode (Mac only)
+ readonly attribute boolean secureEventInputIsEnabled;
+
+ // Override plugin load policy.
+ void setBlockAllPlugins(boolean shouldBlock);
+
+ // Hooks to the JSC compiler.
+ object failNextNewCodeBlock();
+ object numberOfDFGCompiles(object function);
+ object neverInlineFunction(object function);
+
+ // Swipe gestures
+ void installDidBeginSwipeCallback(object callback);
+ void installWillEndSwipeCallback(object callback);
+ void installDidEndSwipeCallback(object callback);
+ void installDidRemoveSwipeSnapshotCallback(object callback);
+
+ unsigned long imageCountInGeneralPasteboard();
+
+ // UI Process Testing
+ void runUIScript(DOMString script, object callback);
+
+ void clearTestRunnerCallbacks();
+
+ void accummulateLogsForChannel(DOMString channel);
+
+ // Gamepad
+ void setMockGamepadDetails(unsigned long index, DOMString id, unsigned long axisCount, unsigned long buttonCount);
+ void setMockGamepadAxisValue(unsigned long index, unsigned long axisIndex, double value);
+ void setMockGamepadButtonValue(unsigned long index, unsigned long buttonIndex, double value);
+ void connectMockGamepad(unsigned long index);
+ void disconnectMockGamepad(unsigned long index);
+
+ // Resource Load Statistics
+ void installStatisticsDidModifyDataRecordsCallback(object callback);
+ void setStatisticsPrevalentResource(DOMString hostName, boolean value);
+ boolean isStatisticsPrevalentResource(DOMString hostName);
+ void setStatisticsHasHadUserInteraction(DOMString hostName, boolean value);
+ boolean isStatisticsHasHadUserInteraction(DOMString hostName);
+ void setStatisticsTimeToLiveUserInteraction(double seconds);
+ void statisticsFireDataModificationHandler();
+ void setStatisticsNotifyPagesWhenDataRecordsWereScanned(boolean value);
+ void setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(boolean value);
+ void setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double seconds);
+ void statisticsResetToConsistentState();
+};
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl
new file mode 100644
index 000000000..d95a6985d
--- /dev/null
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface TextInputController {
+ void setMarkedText(DOMString string, long from, long length);
+ boolean hasMarkedText();
+ void unmarkText();
+ void insertText(DOMString string);
+};
+
diff --git a/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp b/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp
index 65e355652..6bd165288 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2014-2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,13 +30,13 @@
#include "InjectedBundlePage.h"
#include "JSEventSendingController.h"
#include "StringFunctions.h"
-#include <WebKit2/WKBundle.h>
-#include <WebKit2/WKBundleFrame.h>
-#include <WebKit2/WKBundlePagePrivate.h>
-#include <WebKit2/WKBundlePrivate.h>
-#include <WebKit2/WKContextMenuItem.h>
-#include <WebKit2/WKMutableDictionary.h>
-#include <WebKit2/WKNumber.h>
+#include <WebKit/WKBundle.h>
+#include <WebKit/WKBundleFrame.h>
+#include <WebKit/WKBundlePagePrivate.h>
+#include <WebKit/WKBundlePrivate.h>
+#include <WebKit/WKContextMenuItem.h>
+#include <WebKit/WKMutableDictionary.h>
+#include <WebKit/WKNumber.h>
#include <wtf/StdLibExtras.h>
namespace WTR {
@@ -116,6 +116,8 @@ static WKEventModifiers parseModifier(JSStringRef modifier)
return kWKEventModifiersAltKey;
if (JSStringIsEqualToUTF8CString(modifier, "metaKey"))
return kWKEventModifiersMetaKey;
+ if (JSStringIsEqualToUTF8CString(modifier, "capsLockKey"))
+ return kWKEventModifiersCapsLockKey;
if (JSStringIsEqualToUTF8CString(modifier, "addSelectionKey")) {
#if OS(MAC_OS_X)
return kWKEventModifiersMetaKey;
@@ -164,9 +166,9 @@ static WKEventModifiers parseModifierArray(JSContextRef context, JSValueRef arra
return modifiers;
}
-PassRefPtr<EventSendingController> EventSendingController::create()
+Ref<EventSendingController> EventSendingController::create()
{
- return adoptRef(new EventSendingController);
+ return adoptRef(*new EventSendingController);
}
EventSendingController::EventSendingController()
@@ -208,7 +210,8 @@ static WKMutableDictionaryRef createMouseMessageBody(MouseState state, int butto
void EventSendingController::mouseDown(int button, JSValueRef modifierArray)
{
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundlePageRef page = injectedBundle.page()->page();
WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
WKEventModifiers modifiers = parseModifierArray(context, modifierArray);
@@ -216,12 +219,12 @@ void EventSendingController::mouseDown(int button, JSValueRef modifierArray)
WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, createMouseMessageBody(MouseDown, button, modifiers));
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(page, EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::mouseUp(int button, JSValueRef modifierArray)
{
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
WKEventModifiers modifiers = parseModifierArray(context, modifierArray);
@@ -229,7 +232,7 @@ void EventSendingController::mouseUp(int button, JSValueRef modifierArray)
WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, createMouseMessageBody(MouseUp, button, modifiers));
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::mouseMoveTo(int x, int y)
@@ -249,7 +252,73 @@ void EventSendingController::mouseMoveTo(int x, int y)
WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ m_position = WKPointMake(x, y);
+
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+}
+
+void EventSendingController::mouseForceClick()
+{
+ WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
+ WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
+ WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseForceClick"));
+ WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
+
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+}
+
+void EventSendingController::startAndCancelMouseForceClick()
+{
+ WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
+ WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
+ WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("StartAndCancelMouseForceClick"));
+ WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
+
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+}
+
+void EventSendingController::mouseForceDown()
+{
+ WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
+ WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
+ WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseForceDown"));
+ WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
+
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+}
+
+void EventSendingController::mouseForceUp()
+{
+ WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
+ WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
+ WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseForceUp"));
+ WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
+
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+}
+
+void EventSendingController::mouseForceChanged(double force)
+{
+ WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
+ WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
+ WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseForceChanged"));
+ WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
+
+ WKRetainPtr<WKStringRef> forceKey(AdoptWK, WKStringCreateWithUTF8CString("Force"));
+ WKRetainPtr<WKDoubleRef> forceRef(AdoptWK, WKDoubleCreate(force));
+ WKDictionarySetItem(EventSenderMessageBody.get(), forceKey.get(), forceRef.get());
+
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::leapForward(int milliseconds)
@@ -265,7 +334,7 @@ void EventSendingController::leapForward(int milliseconds)
WKRetainPtr<WKUInt64Ref> timeRef(AdoptWK, WKUInt64Create(milliseconds));
WKDictionarySetItem(EventSenderMessageBody.get(), timeKey.get(), timeRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::scheduleAsynchronousClick()
@@ -277,11 +346,11 @@ void EventSendingController::scheduleAsynchronousClick()
// Asynchronous mouse down.
WKRetainPtr<WKMutableDictionaryRef> mouseDownMessageBody(AdoptWK, createMouseMessageBody(MouseDown, button, modifiers));
- WKBundlePostMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), mouseDownMessageBody.get());
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), mouseDownMessageBody.get());
// Asynchronous mouse up.
WKRetainPtr<WKMutableDictionaryRef> mouseUpMessageBody(AdoptWK, createMouseMessageBody(MouseUp, button, modifiers));
- WKBundlePostMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), mouseUpMessageBody.get());
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), mouseUpMessageBody.get());
}
static WKRetainPtr<WKMutableDictionaryRef> createKeyDownMessageBody(JSStringRef key, WKEventModifiers modifiers, int location)
@@ -308,7 +377,7 @@ static WKRetainPtr<WKMutableDictionaryRef> createKeyDownMessageBody(JSStringRef
void EventSendingController::keyDown(JSStringRef key, JSValueRef modifierArray, int location)
{
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
WKEventModifiers modifiers = parseModifierArray(context, modifierArray);
@@ -316,7 +385,7 @@ void EventSendingController::keyDown(JSStringRef key, JSValueRef modifierArray,
WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
WKRetainPtr<WKMutableDictionaryRef> keyDownMessageBody = createKeyDownMessageBody(key, modifiers, location);
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), keyDownMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), keyDownMessageBody.get(), 0);
}
void EventSendingController::scheduleAsynchronousKeyDown(JSStringRef key)
@@ -324,7 +393,7 @@ void EventSendingController::scheduleAsynchronousKeyDown(JSStringRef key)
WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
WKRetainPtr<WKMutableDictionaryRef> keyDownMessageBody = createKeyDownMessageBody(key, 0 /* modifiers */, 0 /* location */);
- WKBundlePostMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), keyDownMessageBody.get());
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), keyDownMessageBody.get());
}
void EventSendingController::mouseScrollBy(int x, int y)
@@ -344,7 +413,106 @@ void EventSendingController::mouseScrollBy(int x, int y)
WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePageForceRepaint(InjectedBundle::singleton().page()->page()); // Triggers a scrolling tree commit.
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get());
+}
+
+static uint64_t cgEventPhaseFromString(JSStringRef phaseStr)
+{
+ if (JSStringIsEqualToUTF8CString(phaseStr, "none"))
+ return 0;
+ if (JSStringIsEqualToUTF8CString(phaseStr, "began"))
+ return 1; // kCGScrollPhaseBegan
+ if (JSStringIsEqualToUTF8CString(phaseStr, "changed"))
+ return 2; // kCGScrollPhaseChanged
+ if (JSStringIsEqualToUTF8CString(phaseStr, "ended"))
+ return 4; // kCGScrollPhaseEnded
+ if (JSStringIsEqualToUTF8CString(phaseStr, "cancelled"))
+ return 8; // kCGScrollPhaseCancelled
+ if (JSStringIsEqualToUTF8CString(phaseStr, "maybegin"))
+ return 128; // kCGScrollPhaseMayBegin
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+static uint64_t cgEventMomentumPhaseFromString(JSStringRef phaseStr)
+{
+ if (JSStringIsEqualToUTF8CString(phaseStr, "none"))
+ return 0; // kCGMomentumScrollPhaseNone
+ if (JSStringIsEqualToUTF8CString(phaseStr, "begin"))
+ return 1; // kCGMomentumScrollPhaseBegin
+ if (JSStringIsEqualToUTF8CString(phaseStr, "continue"))
+ return 2; // kCGMomentumScrollPhaseContinue
+ if (JSStringIsEqualToUTF8CString(phaseStr, "end"))
+ return 3; // kCGMomentumScrollPhaseEnd
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void EventSendingController::mouseScrollByWithWheelAndMomentumPhases(int x, int y, JSStringRef phaseStr, JSStringRef momentumStr)
+{
+ WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
+ WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
+ WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseScrollByWithWheelAndMomentumPhases"));
+ WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
+
+ WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
+ WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
+ WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
+
+ WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
+ WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
+ WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
+
+ uint64_t phase = cgEventPhaseFromString(phaseStr);
+ uint64_t momentum = cgEventMomentumPhaseFromString(momentumStr);
+
+ WKRetainPtr<WKStringRef> phaseKey(AdoptWK, WKStringCreateWithUTF8CString("Phase"));
+ WKRetainPtr<WKUInt64Ref> phaseRef(AdoptWK, WKUInt64Create(phase));
+ WKDictionarySetItem(EventSenderMessageBody.get(), phaseKey.get(), phaseRef.get());
+
+ WKRetainPtr<WKStringRef> momentumKey(AdoptWK, WKStringCreateWithUTF8CString("Momentum"));
+ WKRetainPtr<WKUInt64Ref> momentumRef(AdoptWK, WKUInt64Create(momentum));
+ WKDictionarySetItem(EventSenderMessageBody.get(), momentumKey.get(), momentumRef.get());
+
+ WKBundlePageForceRepaint(InjectedBundle::singleton().page()->page()); // Triggers a scrolling tree commit.
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get());
+}
+
+void EventSendingController::swipeGestureWithWheelAndMomentumPhases(int x, int y, JSStringRef phaseStr, JSStringRef momentumStr)
+{
+ WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
+ WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
+ WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("SwipeGestureWithWheelAndMomentumPhases"));
+ WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
+
+ WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
+ WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
+ WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
+
+ WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
+ WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
+ WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
+
+ uint64_t phase = cgEventPhaseFromString(phaseStr);
+ uint64_t momentum = cgEventMomentumPhaseFromString(momentumStr);
+
+ WKRetainPtr<WKStringRef> phaseKey(AdoptWK, WKStringCreateWithUTF8CString("Phase"));
+ WKRetainPtr<WKUInt64Ref> phaseRef(AdoptWK, WKUInt64Create(phase));
+ WKDictionarySetItem(EventSenderMessageBody.get(), phaseKey.get(), phaseRef.get());
+
+ WKRetainPtr<WKStringRef> momentumKey(AdoptWK, WKStringCreateWithUTF8CString("Momentum"));
+ WKRetainPtr<WKUInt64Ref> momentumRef(AdoptWK, WKUInt64Create(momentum));
+ WKDictionarySetItem(EventSenderMessageBody.get(), momentumKey.get(), momentumRef.get());
+
+ WKBundlePageForceRepaint(InjectedBundle::singleton().page()->page()); // Triggers a scrolling tree commit.
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get());
}
void EventSendingController::continuousMouseScrollBy(int x, int y, bool paged)
@@ -368,31 +536,33 @@ void EventSendingController::continuousMouseScrollBy(int x, int y, bool paged)
WKRetainPtr<WKUInt64Ref> pagedRef(AdoptWK, WKUInt64Create(paged));
WKDictionarySetItem(EventSenderMessageBody.get(), pagedKey.get(), pagedRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ // FIXME: This message should be asynchronous, as scrolling is intrinsically asynchronous.
+ // See also: <https://bugs.webkit.org/show_bug.cgi?id=148256>.
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
JSValueRef EventSendingController::contextClick()
{
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
#if ENABLE(CONTEXT_MENUS)
- // Do mouse context click.
- mouseDown(2, 0);
- mouseUp(2, 0);
+ WKRetainPtr<WKArrayRef> menuEntries = adoptWK(WKBundlePageCopyContextMenuAtPointInWindow(page, m_position));
+ JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0);
+ if (!menuEntries)
+ return arrayResult;
- WKRetainPtr<WKArrayRef> menuEntries = adoptWK(WKBundlePageCopyContextMenuItems(page));
+ JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0);
size_t entriesSize = WKArrayGetSize(menuEntries.get());
- auto jsValuesArray = std::make_unique<JSValueRef[]>(entriesSize);
for (size_t i = 0; i < entriesSize; ++i) {
ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(menuEntries.get(), i)) == WKContextMenuItemGetTypeID());
WKContextMenuItemRef item = static_cast<WKContextMenuItemRef>(WKArrayGetItemAtIndex(menuEntries.get(), i));
MenuItemPrivateData* privateData = new MenuItemPrivateData(page, item);
- jsValuesArray[i] = JSObjectMake(context, getMenuItemClass(), privateData);
+ JSObjectSetPropertyAtIndex(context, arrayObj, i, JSObjectMake(context, getMenuItemClass(), privateData), 0);
}
- return JSObjectMakeArray(context, entriesSize, jsValuesArray.get(), 0);
+ return arrayResult;
#else
return JSValueMakeUndefined(context);
#endif
@@ -400,44 +570,96 @@ JSValueRef EventSendingController::contextClick()
void EventSendingController::textZoomIn()
{
+ auto& injectedBundle = InjectedBundle::singleton();
// Ensure page zoom is reset.
- WKBundlePageSetPageZoomFactor(InjectedBundle::shared().page()->page(), 1);
+ WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), 1);
- double zoomFactor = WKBundlePageGetTextZoomFactor(InjectedBundle::shared().page()->page());
- WKBundlePageSetTextZoomFactor(InjectedBundle::shared().page()->page(), zoomFactor * ZoomMultiplierRatio);
+ double zoomFactor = WKBundlePageGetTextZoomFactor(injectedBundle.page()->page());
+ WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), zoomFactor * ZoomMultiplierRatio);
}
void EventSendingController::textZoomOut()
{
+ auto& injectedBundle = InjectedBundle::singleton();
// Ensure page zoom is reset.
- WKBundlePageSetPageZoomFactor(InjectedBundle::shared().page()->page(), 1);
+ WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), 1);
- double zoomFactor = WKBundlePageGetTextZoomFactor(InjectedBundle::shared().page()->page());
- WKBundlePageSetTextZoomFactor(InjectedBundle::shared().page()->page(), zoomFactor / ZoomMultiplierRatio);
+ double zoomFactor = WKBundlePageGetTextZoomFactor(injectedBundle.page()->page());
+ WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), zoomFactor / ZoomMultiplierRatio);
}
void EventSendingController::zoomPageIn()
{
+ auto& injectedBundle = InjectedBundle::singleton();
// Ensure text zoom is reset.
- WKBundlePageSetTextZoomFactor(InjectedBundle::shared().page()->page(), 1);
+ WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), 1);
- double zoomFactor = WKBundlePageGetPageZoomFactor(InjectedBundle::shared().page()->page());
- WKBundlePageSetPageZoomFactor(InjectedBundle::shared().page()->page(), zoomFactor * ZoomMultiplierRatio);
+ double zoomFactor = WKBundlePageGetPageZoomFactor(injectedBundle.page()->page());
+ WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), zoomFactor * ZoomMultiplierRatio);
}
void EventSendingController::zoomPageOut()
{
+ auto& injectedBundle = InjectedBundle::singleton();
// Ensure text zoom is reset.
- WKBundlePageSetTextZoomFactor(InjectedBundle::shared().page()->page(), 1);
+ WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), 1);
- double zoomFactor = WKBundlePageGetPageZoomFactor(InjectedBundle::shared().page()->page());
- WKBundlePageSetPageZoomFactor(InjectedBundle::shared().page()->page(), zoomFactor / ZoomMultiplierRatio);
+ double zoomFactor = WKBundlePageGetPageZoomFactor(injectedBundle.page()->page());
+ WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), zoomFactor / ZoomMultiplierRatio);
}
void EventSendingController::scalePageBy(double scale, double x, double y)
{
WKPoint origin = { x, y };
- WKBundlePageSetScaleAtOrigin(InjectedBundle::shared().page()->page(), scale, origin);
+ WKBundlePageSetScaleAtOrigin(InjectedBundle::singleton().page()->page(), scale, origin);
+}
+
+void EventSendingController::monitorWheelEvents()
+{
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
+
+ WKBundlePageStartMonitoringScrollOperations(page);
+}
+
+struct ScrollCompletionCallbackData {
+ JSContextRef m_context;
+ JSObjectRef m_function;
+
+ ScrollCompletionCallbackData(JSContextRef context, JSObjectRef function)
+ : m_context(context), m_function(function)
+ {
+ }
+};
+
+static void executeCallback(void* context)
+{
+ if (!context)
+ return;
+
+ std::unique_ptr<ScrollCompletionCallbackData> callBackData(reinterpret_cast<ScrollCompletionCallbackData*>(context));
+
+ JSObjectCallAsFunction(callBackData->m_context, callBackData->m_function, nullptr, 0, nullptr, nullptr);
+ JSValueUnprotect(callBackData->m_context, callBackData->m_function);
+}
+
+void EventSendingController::callAfterScrollingCompletes(JSValueRef functionCallback)
+{
+ if (!functionCallback)
+ return;
+
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
+ JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+
+ JSObjectRef functionCallbackObject = JSValueToObject(context, functionCallback, nullptr);
+ if (!functionCallbackObject)
+ return;
+
+ JSValueProtect(context, functionCallbackObject);
+
+ auto scrollCompletionCallbackData = std::make_unique<ScrollCompletionCallbackData>(context, functionCallbackObject);
+
+ WKBundlePageRegisterScrollOperationCompletionCallback(page, executeCallback, scrollCompletionCallbackData.release());
}
#if ENABLE(TOUCH_EVENTS)
@@ -458,7 +680,7 @@ void EventSendingController::addTouchPoint(int x, int y)
WKRetainPtr<WKUInt64Ref> yRef(AdoptWK, WKUInt64Create(y));
WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::updateTouchPoint(int index, int x, int y)
@@ -482,7 +704,7 @@ void EventSendingController::updateTouchPoint(int index, int x, int y)
WKRetainPtr<WKUInt64Ref> yRef(AdoptWK, WKUInt64Create(y));
WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::setTouchModifier(const JSStringRef &modifier, bool enable)
@@ -512,7 +734,7 @@ void EventSendingController::setTouchModifier(const JSStringRef &modifier, bool
WKRetainPtr<WKUInt64Ref> enableRef(AdoptWK, WKUInt64Create(enable));
WKDictionarySetItem(EventSenderMessageBody.get(), enableKey.get(), enableRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
@@ -533,7 +755,7 @@ void EventSendingController::setTouchPointRadius(int radiusX, int radiusY)
WKRetainPtr<WKUInt64Ref> yRef(AdoptWK, WKUInt64Create(radiusY));
WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::touchStart()
@@ -545,7 +767,7 @@ void EventSendingController::touchStart()
WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchStart"));
WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::touchMove()
@@ -557,7 +779,7 @@ void EventSendingController::touchMove()
WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchMove"));
WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::touchEnd()
@@ -569,7 +791,7 @@ void EventSendingController::touchEnd()
WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchEnd"));
WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::touchCancel()
@@ -581,7 +803,7 @@ void EventSendingController::touchCancel()
WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchCancel"));
WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::clearTouchPoints()
@@ -593,7 +815,7 @@ void EventSendingController::clearTouchPoints()
WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("ClearTouchPoints"));
WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::releaseTouchPoint(int index)
@@ -609,7 +831,7 @@ void EventSendingController::releaseTouchPoint(int index)
WKRetainPtr<WKUInt64Ref> indexRef(AdoptWK, WKUInt64Create(index));
WKDictionarySetItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
void EventSendingController::cancelTouchPoint(int index)
@@ -625,7 +847,7 @@ void EventSendingController::cancelTouchPoint(int index)
WKRetainPtr<WKUInt64Ref> indexRef(AdoptWK, WKUInt64Create(index));
WKDictionarySetItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
}
#endif
diff --git a/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h b/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h
index c6a9131e4..3eb8129c7 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2014-2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,19 +23,18 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef EventSendingController_h
-#define EventSendingController_h
+#pragma once
#include "JSWrappable.h"
-#include <WebKit2/WKEvent.h>
-#include <WebKit2/WKGeometry.h>
-#include <wtf/PassRefPtr.h>
+#include <WebKit/WKEvent.h>
+#include <WebKit/WKGeometry.h>
+#include <wtf/Ref.h>
namespace WTR {
class EventSendingController : public JSWrappable {
public:
- static PassRefPtr<EventSendingController> create();
+ static Ref<EventSendingController> create();
virtual ~EventSendingController();
void makeWindowObject(JSContextRef, JSObjectRef windowObject, JSValueRef* exception);
@@ -46,11 +45,20 @@ public:
void mouseDown(int button, JSValueRef modifierArray);
void mouseUp(int button, JSValueRef modifierArray);
void mouseMoveTo(int x, int y);
+ void mouseForceClick();
+ void startAndCancelMouseForceClick();
+ void mouseForceDown();
+ void mouseForceUp();
+ void mouseForceChanged(double force);
void mouseScrollBy(int x, int y);
+ void mouseScrollByWithWheelAndMomentumPhases(int x, int y, JSStringRef phase, JSStringRef momentum);
+ void swipeGestureWithWheelAndMomentumPhases(int x, int y, JSStringRef phase, JSStringRef momentum);
void continuousMouseScrollBy(int x, int y, bool paged);
JSValueRef contextClick();
void leapForward(int milliseconds);
void scheduleAsynchronousClick();
+ void monitorWheelEvents();
+ void callAfterScrollingCompletes(JSValueRef functionCallback);
void keyDown(JSStringRef key, JSValueRef modifierArray, int location);
void scheduleAsynchronousKeyDown(JSStringRef key);
@@ -79,8 +87,7 @@ public:
private:
EventSendingController();
+ WKPoint m_position;
};
} // namespace WTR
-
-#endif // EventSendingController_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/GCController.cpp b/Tools/WebKitTestRunner/InjectedBundle/GCController.cpp
index 10c21dba8..9358f4a0d 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/GCController.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/GCController.cpp
@@ -28,13 +28,13 @@
#include "InjectedBundle.h"
#include "JSGCController.h"
-#include <WebKit2/WKBundlePrivate.h>
+#include <WebKit/WKBundlePrivate.h>
namespace WTR {
-PassRefPtr<GCController> GCController::create()
+Ref<GCController> GCController::create()
{
- return adoptRef(new GCController);
+ return adoptRef(*new GCController);
}
GCController::GCController()
@@ -52,17 +52,17 @@ JSClassRef GCController::wrapperClass()
void GCController::collect()
{
- WKBundleGarbageCollectJavaScriptObjects(InjectedBundle::shared().bundle());
+ WKBundleGarbageCollectJavaScriptObjects(InjectedBundle::singleton().bundle());
}
void GCController::collectOnAlternateThread(bool waitUntilDone)
{
- WKBundleGarbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(InjectedBundle::shared().bundle(), waitUntilDone);
+ WKBundleGarbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(InjectedBundle::singleton().bundle(), waitUntilDone);
}
size_t GCController::getJSObjectCount()
{
- return WKBundleGetJavaScriptObjectsCount(InjectedBundle::shared().bundle());
+ return WKBundleGetJavaScriptObjectsCount(InjectedBundle::singleton().bundle());
}
// Object Creation
diff --git a/Tools/WebKitTestRunner/InjectedBundle/GCController.h b/Tools/WebKitTestRunner/InjectedBundle/GCController.h
index 760fbb1e6..d349c1ce9 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/GCController.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/GCController.h
@@ -23,17 +23,16 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef GCController_h
-#define GCController_h
+#pragma once
#include "JSWrappable.h"
-#include <wtf/PassRefPtr.h>
+#include <wtf/Ref.h>
namespace WTR {
class GCController : public JSWrappable {
public:
- static PassRefPtr<GCController> create();
+ static Ref<GCController> create();
virtual ~GCController();
void makeWindowObject(JSContextRef, JSObjectRef windowObject, JSValueRef* exception);
@@ -50,5 +49,3 @@ private:
};
} // namespace WTR
-
-#endif // GCController_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
index f71fe9360..f247b362b 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,20 +29,20 @@
#include "ActivateFonts.h"
#include "InjectedBundlePage.h"
#include "StringFunctions.h"
-#include <WebKit2/WKBundle.h>
-#include <WebKit2/WKBundlePage.h>
-#include <WebKit2/WKBundlePagePrivate.h>
-#include <WebKit2/WKBundlePrivate.h>
-#include <WebKit2/WKRetainPtr.h>
-#include <WebKit2/WebKit2_C.h>
-#include <wtf/PassOwnPtr.h>
+#include "WebCoreTestSupport.h"
+#include <WebKit/WKBundle.h>
+#include <WebKit/WKBundlePage.h>
+#include <WebKit/WKBundlePagePrivate.h>
+#include <WebKit/WKBundlePrivate.h>
+#include <WebKit/WKRetainPtr.h>
+#include <WebKit/WebKit2_C.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/Vector.h>
namespace WTR {
-InjectedBundle& InjectedBundle::shared()
+InjectedBundle& InjectedBundle::singleton()
{
static InjectedBundle& shared = *new InjectedBundle;
return shared;
@@ -101,23 +101,18 @@ void InjectedBundle::initialize(WKBundleRef bundle, WKTypeRef initializationUser
platformInitialize(initializationUserData);
activateFonts();
- WKBundleActivateMacFontAscentHack(m_bundle);
}
void InjectedBundle::didCreatePage(WKBundlePageRef page)
{
- m_pages.append(adoptPtr(new InjectedBundlePage(page)));
+ m_pages.append(std::make_unique<InjectedBundlePage>(page));
}
void InjectedBundle::willDestroyPage(WKBundlePageRef page)
{
- size_t size = m_pages.size();
- for (size_t i = 0; i < size; ++i) {
- if (m_pages[i]->page() == page) {
- m_pages.remove(i);
- break;
- }
- }
+ m_pages.removeFirstMatching([page](auto& current) {
+ return current->page() == page;
+ });
}
void InjectedBundle::didInitializePageGroup(WKBundlePageGroupRef pageGroup)
@@ -139,6 +134,13 @@ void InjectedBundle::resetLocalSettings()
void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody)
{
+ WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
+ WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
+ WKBundlePostMessage(m_bundle, errorMessageName.get(), errorMessageBody.get());
+}
+
+void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody)
+{
if (WKStringIsEqualToUTF8CString(messageName, "BeginTest")) {
ASSERT(messageBody);
ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
@@ -153,13 +155,18 @@ void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messag
WKRetainPtr<WKStringRef> timeoutKey(AdoptWK, WKStringCreateWithUTF8CString("Timeout"));
m_timeout = (int)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, timeoutKey.get())));
+ WKRetainPtr<WKStringRef> dumpJSConsoleLogInStdErrKey(AdoptWK, WKStringCreateWithUTF8CString("DumpJSConsoleLogInStdErr"));
+ m_dumpJSConsoleLogInStdErr = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, dumpJSConsoleLogInStdErrKey.get())));
+
WKRetainPtr<WKStringRef> ackMessageName(AdoptWK, WKStringCreateWithUTF8CString("Ack"));
WKRetainPtr<WKStringRef> ackMessageBody(AdoptWK, WKStringCreateWithUTF8CString("BeginTest"));
- WKBundlePostMessage(m_bundle, ackMessageName.get(), ackMessageBody.get());
+ WKBundlePagePostMessage(page, ackMessageName.get(), ackMessageBody.get());
beginTesting(messageBodyDictionary);
return;
- } else if (WKStringIsEqualToUTF8CString(messageName, "Reset")) {
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "Reset")) {
ASSERT(messageBody);
ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
@@ -170,48 +177,103 @@ void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messag
if (shouldGC)
WKBundleGarbageCollectJavaScriptObjects(m_bundle);
+ WKRetainPtr<WKStringRef> allowedHostsKey(AdoptWK, WKStringCreateWithUTF8CString("AllowedHosts"));
+ WKTypeRef allowedHostsValue = WKDictionaryGetItemForKey(messageBodyDictionary, allowedHostsKey.get());
+ if (allowedHostsValue && WKGetTypeID(allowedHostsValue) == WKArrayGetTypeID()) {
+ WKArrayRef allowedHostsArray = static_cast<WKArrayRef>(allowedHostsValue);
+ for (size_t i = 0, size = WKArrayGetSize(allowedHostsArray); i < size; ++i) {
+ WKTypeRef item = WKArrayGetItemAtIndex(allowedHostsArray, i);
+ if (item && WKGetTypeID(item) == WKStringGetTypeID())
+ m_allowedHosts.append(toWTFString(static_cast<WKStringRef>(item)));
+ }
+ }
+
m_state = Idle;
m_dumpPixels = false;
+ m_pixelResultIsPending = false;
resetLocalSettings();
- m_testRunner->removeAllWebNotificationPermissions();
+ TestRunner::removeAllWebNotificationPermissions();
- page()->resetAfterTest();
+ InjectedBundle::page()->resetAfterTest();
return;
}
+
if (WKStringIsEqualToUTF8CString(messageName, "CallAddChromeInputFieldCallback")) {
m_testRunner->callAddChromeInputFieldCallback();
return;
}
+
if (WKStringIsEqualToUTF8CString(messageName, "CallRemoveChromeInputFieldCallback")) {
m_testRunner->callRemoveChromeInputFieldCallback();
return;
}
+
if (WKStringIsEqualToUTF8CString(messageName, "CallFocusWebViewCallback")) {
m_testRunner->callFocusWebViewCallback();
return;
}
+
if (WKStringIsEqualToUTF8CString(messageName, "CallSetBackingScaleFactorCallback")) {
m_testRunner->callSetBackingScaleFactorCallback();
return;
- }
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "CallDidBeginSwipeCallback")) {
+ m_testRunner->callDidBeginSwipeCallback();
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "CallWillEndSwipeCallback")) {
+ m_testRunner->callWillEndSwipeCallback();
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "CallDidEndSwipeCallback")) {
+ m_testRunner->callDidEndSwipeCallback();
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "CallDidRemoveSwipeSnapshotCallback")) {
+ m_testRunner->callDidRemoveSwipeSnapshotCallback();
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "NotifyDownloadDone")) {
+ m_testRunner->notifyDone();
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "CallUISideScriptCallback")) {
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+
+ WKRetainPtr<WKStringRef> resultKey(AdoptWK, WKStringCreateWithUTF8CString("Result"));
+ WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID"));
+
+ unsigned callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
+
+ WKStringRef resultString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, resultKey.get()));
+ auto resultJSString = toJS(resultString);
+
+ m_testRunner->runUIScriptCallback(callbackID, resultJSString.get());
+ return;
+ }
+
if (WKStringIsEqualToUTF8CString(messageName, "WorkQueueProcessedCallback")) {
if (!topLoadingFrame() && !m_testRunner->waitToDump())
- page()->dump();
+ InjectedBundle::page()->dump();
return;
}
- WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
- WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
- WKBundlePostMessage(m_bundle, errorMessageName.get(), errorMessageBody.get());
-}
+ if (WKStringIsEqualToUTF8CString(messageName, "WebsiteDataDeletionForTopPrivatelyOwnedDomainsFinished")) {
+ m_testRunner->statisticsDidModifyDataRecordsCallback();
+ return;
+ }
-void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody)
-{
WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
- WKBundlePostMessage(m_bundle, errorMessageName.get(), errorMessageBody.get());
+ WKBundlePagePostMessage(page, errorMessageName.get(), errorMessageBody.get());
}
bool InjectedBundle::booleanForKey(WKDictionaryRef dictionary, const char* key)
@@ -236,41 +298,60 @@ void InjectedBundle::beginTesting(WKDictionaryRef settings)
m_gcController = GCController::create();
m_eventSendingController = EventSendingController::create();
m_textInputController = TextInputController::create();
+#if HAVE(ACCESSIBILITY)
m_accessibilityController = AccessibilityController::create();
+#endif
- WKBundleSetShouldTrackVisitedLinks(m_bundle, false);
- WKBundleRemoveAllVisitedLinks(m_bundle);
WKBundleSetAllowUniversalAccessFromFileURLs(m_bundle, m_pageGroup, true);
WKBundleSetJavaScriptCanAccessClipboard(m_bundle, m_pageGroup, true);
WKBundleSetPrivateBrowsingEnabled(m_bundle, m_pageGroup, false);
+ WKBundleSetUseDashboardCompatibilityMode(m_bundle, m_pageGroup, false);
WKBundleSetAuthorAndUserStylesEnabled(m_bundle, m_pageGroup, true);
WKBundleSetFrameFlatteningEnabled(m_bundle, m_pageGroup, false);
WKBundleSetMinimumLogicalFontSize(m_bundle, m_pageGroup, 9);
WKBundleSetSpatialNavigationEnabled(m_bundle, m_pageGroup, false);
WKBundleSetAllowFileAccessFromFileURLs(m_bundle, m_pageGroup, true);
- WKBundleSetPluginsEnabled(m_bundle, m_pageGroup, true);
WKBundleSetPopupBlockingEnabled(m_bundle, m_pageGroup, false);
- WKBundleSetAlwaysAcceptCookies(m_bundle, false);
- WKBundleSetSerialLoadingEnabled(m_bundle, false);
- WKBundleSetShadowDOMEnabled(m_bundle, true);
- WKBundleSetSeamlessIFramesEnabled(m_bundle, true);
- WKBundleSetCacheModel(m_bundle, 1 /*CacheModelDocumentBrowser*/);
+ WKBundleSetAllowStorageAccessFromFileURLS(m_bundle, m_pageGroup, false);
- WKBundleRemoveAllUserContent(m_bundle, m_pageGroup);
+#if PLATFORM(IOS)
+ WKBundlePageSetUseTestingViewportConfiguration(page()->page(), !booleanForKey(settings, "UseFlexibleViewport"));
+#endif
+
+ m_testRunner->setPluginsEnabled(true);
m_testRunner->setShouldDumpFrameLoadCallbacks(booleanForKey(settings, "DumpFrameLoadDelegates"));
m_testRunner->setUserStyleSheetEnabled(false);
m_testRunner->setXSSAuditorEnabled(false);
+
+ m_testRunner->setShadowDOMEnabled(true);
+ m_testRunner->setCustomElementsEnabled(true);
+
+ m_testRunner->setWebGL2Enabled(true);
+
+ m_testRunner->setFetchAPIEnabled(true);
+
+ m_testRunner->setDownloadAttributeEnabled(true);
+
+ m_testRunner->setEncryptedMediaAPIEnabled(true);
+
m_testRunner->setCloseRemainingWindowsWhenComplete(false);
m_testRunner->setAcceptsEditing(true);
m_testRunner->setTabKeyCyclesThroughElements(true);
+ m_testRunner->clearTestRunnerCallbacks();
+
+ m_testRunner->setSubtleCryptoEnabled(true);
- m_testRunner->setCustomTimeout(m_timeout);
+ m_testRunner->setMediaStreamEnabled(true);
+ m_testRunner->setPeerConnectionEnabled(true);
+
+ if (m_timeout > 0)
+ m_testRunner->setCustomTimeout(m_timeout);
page()->prepare();
WKBundleClearAllDatabases(m_bundle);
- WKBundleClearApplicationCache(m_bundle);
+ WKBundlePageClearApplicationCache(page()->page());
WKBundleResetOriginAccessWhitelists(m_bundle);
// [WK2] REGRESSION(r128623): It made layout tests extremely slow
@@ -287,13 +368,21 @@ void InjectedBundle::done()
page()->stopLoading();
setTopLoadingFrame(0);
+ m_testRunner->invalidateWaitToDumpWatchdogTimer();
+
m_accessibilityController->resetToConsistentState();
WKRetainPtr<WKStringRef> doneMessageName(AdoptWK, WKStringCreateWithUTF8CString("Done"));
WKRetainPtr<WKMutableDictionaryRef> doneMessageBody(AdoptWK, WKMutableDictionaryCreate());
- WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
- WKDictionarySetItem(doneMessageBody.get(), pixelResultKey.get(), m_pixelResult.get());
+ WKRetainPtr<WKStringRef> pixelResultIsPendingKey = adoptWK(WKStringCreateWithUTF8CString("PixelResultIsPending"));
+ WKRetainPtr<WKBooleanRef> pixelResultIsPending(AdoptWK, WKBooleanCreate(m_pixelResultIsPending));
+ WKDictionarySetItem(doneMessageBody.get(), pixelResultIsPendingKey.get(), pixelResultIsPending.get());
+
+ if (!m_pixelResultIsPending) {
+ WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
+ WKDictionarySetItem(doneMessageBody.get(), pixelResultKey.get(), m_pixelResult.get());
+ }
WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects"));
WKDictionarySetItem(doneMessageBody.get(), repaintRectsKey.get(), m_repaintRects.get());
@@ -301,7 +390,7 @@ void InjectedBundle::done()
WKRetainPtr<WKStringRef> audioResultKey = adoptWK(WKStringCreateWithUTF8CString("AudioResult"));
WKDictionarySetItem(doneMessageBody.get(), audioResultKey.get(), m_audioResult.get());
- WKBundlePostMessage(m_bundle, doneMessageName.get(), doneMessageBody.get());
+ WKBundlePagePostMessage(page()->page(), doneMessageName.get(), doneMessageBody.get());
closeOtherPages();
@@ -326,6 +415,17 @@ void InjectedBundle::dumpBackForwardListsForAllPages(StringBuilder& stringBuilde
m_pages[i]->dumpBackForwardList(stringBuilder);
}
+void InjectedBundle::dumpToStdErr(const String& output)
+{
+ if (m_state != Testing)
+ return;
+ if (output.isEmpty())
+ return;
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("DumpToStdErr"));
+ WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithUTF8CString(output.utf8().data()));
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
+}
+
void InjectedBundle::outputText(const String& output)
{
if (m_state != Testing)
@@ -334,60 +434,85 @@ void InjectedBundle::outputText(const String& output)
return;
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("TextOutput"));
WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithUTF8CString(output.utf8().data()));
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
void InjectedBundle::postNewBeforeUnloadReturnValue(bool value)
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("BeforeUnloadReturnValue"));
WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
void InjectedBundle::postAddChromeInputField()
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("AddChromeInputField"));
- WKBundlePostMessage(m_bundle, messageName.get(), 0);
+ WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
}
void InjectedBundle::postRemoveChromeInputField()
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("RemoveChromeInputField"));
- WKBundlePostMessage(m_bundle, messageName.get(), 0);
+ WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
}
void InjectedBundle::postFocusWebView()
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("FocusWebView"));
- WKBundlePostMessage(m_bundle, messageName.get(), 0);
+ WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
}
void InjectedBundle::postSetBackingScaleFactor(double backingScaleFactor)
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetBackingScaleFactor"));
WKRetainPtr<WKDoubleRef> messageBody(AdoptWK, WKDoubleCreate(backingScaleFactor));
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
void InjectedBundle::postSetWindowIsKey(bool isKey)
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetWindowIsKey"));
WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(isKey));
- WKBundlePostSynchronousMessage(m_bundle, messageName.get(), messageBody.get(), 0);
+ WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), 0);
+}
+
+void InjectedBundle::postSetViewSize(double width, double height)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetViewSize"));
+
+ WKRetainPtr<WKStringRef> widthKey(AdoptWK, WKStringCreateWithUTF8CString("width"));
+ WKRetainPtr<WKStringRef> heightKey(AdoptWK, WKStringCreateWithUTF8CString("height"));
+
+ WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKDoubleRef> widthWK(AdoptWK, WKDoubleCreate(width));
+ WKDictionarySetItem(messageBody.get(), widthKey.get(), widthWK.get());
+
+ WKRetainPtr<WKDoubleRef> heightWK(AdoptWK, WKDoubleCreate(height));
+ WKDictionarySetItem(messageBody.get(), heightKey.get(), heightWK.get());
+
+ WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), 0);
}
void InjectedBundle::postSimulateWebNotificationClick(uint64_t notificationID)
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SimulateWebNotificationClick"));
WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(notificationID));
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
+}
+
+void InjectedBundle::postSetAddsVisitedLinks(bool addsVisitedLinks)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetAddsVisitedLinks"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(addsVisitedLinks));
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
void InjectedBundle::setGeolocationPermission(bool enabled)
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetGeolocationPermission"));
WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(enabled));
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
void InjectedBundle::setMockGeolocationPosition(double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed)
@@ -440,13 +565,90 @@ void InjectedBundle::setMockGeolocationPosition(double latitude, double longitud
WKRetainPtr<WKDoubleRef> speedWK(AdoptWK, WKDoubleCreate(speed));
WKDictionarySetItem(messageBody.get(), speedKeyWK.get(), speedWK.get());
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
void InjectedBundle::setMockGeolocationPositionUnavailableError(WKStringRef errorMessage)
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGeolocationPositionUnavailableError"));
- WKBundlePostMessage(m_bundle, messageName.get(), errorMessage);
+ WKBundlePagePostMessage(page()->page(), messageName.get(), errorMessage);
+}
+
+bool InjectedBundle::isGeolocationProviderActive() const
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsGeolocationClientActive"));
+ WKTypeRef resultToPass = 0;
+ WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), 0, &resultToPass);
+ WKRetainPtr<WKBooleanRef> isActive(AdoptWK, static_cast<WKBooleanRef>(resultToPass));
+
+ return WKBooleanGetValue(isActive.get());
+}
+
+unsigned InjectedBundle::imageCountInGeneralPasteboard() const
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ImageCountInGeneralPasteboard"));
+ WKTypeRef resultToPass = 0;
+ WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), 0, &resultToPass);
+ WKRetainPtr<WKUInt64Ref> imageCount(AdoptWK, static_cast<WKUInt64Ref>(resultToPass));
+
+ return static_cast<unsigned>(WKUInt64GetValue(imageCount.get()));
+}
+
+void InjectedBundle::setUserMediaPermission(bool enabled)
+{
+ auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetUserMediaPermission"));
+ auto messageBody = adoptWK(WKBooleanCreate(enabled));
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
+}
+
+void InjectedBundle::setUserMediaPersistentPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin)
+{
+ auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetUserMediaPersistentPermissionForOrigin"));
+ WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> permissionKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permission"));
+ WKRetainPtr<WKBooleanRef> permissionWK(AdoptWK, WKBooleanCreate(permission));
+ WKDictionarySetItem(messageBody.get(), permissionKeyWK.get(), permissionWK.get());
+
+ WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
+ WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
+
+ WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
+ WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
+
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
+}
+
+unsigned InjectedBundle::userMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin) const
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("UserMediaPermissionRequestCountForOrigin"));
+ WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
+ WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
+
+ WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
+ WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
+
+ WKTypeRef resultToPass = 0;
+ WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), &resultToPass);
+ WKRetainPtr<WKUInt64Ref> count(AdoptWK, static_cast<WKUInt64Ref>(resultToPass));
+
+ return static_cast<unsigned>(WKUInt64GetValue(count.get()));
+}
+
+void InjectedBundle::resetUserMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ResetUserMediaPermissionRequestCountForOrigin"));
+ WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
+ WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
+
+ WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
+ WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
+
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
void InjectedBundle::setCustomPolicyDelegate(bool enabled, bool permissive)
@@ -463,23 +665,26 @@ void InjectedBundle::setCustomPolicyDelegate(bool enabled, bool permissive)
WKRetainPtr<WKBooleanRef> permissiveWK(AdoptWK, WKBooleanCreate(permissive));
WKDictionarySetItem(messageBody.get(), permissiveKeyWK.get(), permissiveWK.get());
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
-void InjectedBundle::setVisibilityState(WKPageVisibilityState visibilityState, bool isInitialState)
+void InjectedBundle::setHidden(bool hidden)
{
- WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetVisibilityState"));
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetHidden"));
WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
- WKRetainPtr<WKStringRef> visibilityStateKeyWK(AdoptWK, WKStringCreateWithUTF8CString("visibilityState"));
- WKRetainPtr<WKUInt64Ref> visibilityStateWK(AdoptWK, WKUInt64Create(visibilityState));
- WKDictionarySetItem(messageBody.get(), visibilityStateKeyWK.get(), visibilityStateWK.get());
-
- WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("isInitialState"));
- WKRetainPtr<WKBooleanRef> isInitialWK(AdoptWK, WKBooleanCreate(isInitialState));
+ WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("hidden"));
+ WKRetainPtr<WKBooleanRef> isInitialWK(AdoptWK, WKBooleanCreate(hidden));
WKDictionarySetItem(messageBody.get(), isInitialKeyWK.get(), isInitialWK.get());
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
+}
+
+void InjectedBundle::setCacheModel(int model)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetCacheModel"));
+ WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(model));
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
bool InjectedBundle::shouldProcessWorkQueue() const
@@ -489,7 +694,7 @@ bool InjectedBundle::shouldProcessWorkQueue() const
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsWorkQueueEmpty"));
WKTypeRef resultToPass = 0;
- WKBundlePostSynchronousMessage(m_bundle, messageName.get(), 0, &resultToPass);
+ WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), 0, &resultToPass);
WKRetainPtr<WKBooleanRef> isEmpty(AdoptWK, static_cast<WKBooleanRef>(resultToPass));
return !WKBooleanGetValue(isEmpty.get());
@@ -498,7 +703,7 @@ bool InjectedBundle::shouldProcessWorkQueue() const
void InjectedBundle::processWorkQueue()
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ProcessWorkQueue"));
- WKBundlePostMessage(m_bundle, messageName.get(), 0);
+ WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
}
void InjectedBundle::queueBackNavigation(unsigned howFarBackward)
@@ -507,7 +712,7 @@ void InjectedBundle::queueBackNavigation(unsigned howFarBackward)
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueBackNavigation"));
WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(howFarBackward));
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
void InjectedBundle::queueForwardNavigation(unsigned howFarForward)
@@ -516,10 +721,10 @@ void InjectedBundle::queueForwardNavigation(unsigned howFarForward)
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueForwardNavigation"));
WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(howFarForward));
- WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
}
-void InjectedBundle::queueLoad(WKStringRef url, WKStringRef target)
+void InjectedBundle::queueLoad(WKStringRef url, WKStringRef target, bool shouldOpenExternalURLs)
{
m_useWorkQueue = true;
@@ -533,7 +738,11 @@ void InjectedBundle::queueLoad(WKStringRef url, WKStringRef target)
WKRetainPtr<WKStringRef> targetKey(AdoptWK, WKStringCreateWithUTF8CString("target"));
WKDictionarySetItem(loadData.get(), targetKey.get(), target);
- WKBundlePostMessage(m_bundle, messageName.get(), loadData.get());
+ WKRetainPtr<WKStringRef> shouldOpenExternalURLsKey(AdoptWK, WKStringCreateWithUTF8CString("shouldOpenExternalURLs"));
+ WKRetainPtr<WKBooleanRef> shouldOpenExternalURLsValue(AdoptWK, WKBooleanCreate(shouldOpenExternalURLs));
+ WKDictionarySetItem(loadData.get(), shouldOpenExternalURLsKey.get(), shouldOpenExternalURLsValue.get());
+
+ WKBundlePagePostMessage(page()->page(), messageName.get(), loadData.get());
}
void InjectedBundle::queueLoadHTMLString(WKStringRef content, WKStringRef baseURL, WKStringRef unreachableURL)
@@ -557,7 +766,7 @@ void InjectedBundle::queueLoadHTMLString(WKStringRef content, WKStringRef baseUR
WKDictionarySetItem(loadData.get(), unreachableURLKey.get(), unreachableURL);
}
- WKBundlePostMessage(m_bundle, messageName.get(), loadData.get());
+ WKBundlePagePostMessage(page()->page(), messageName.get(), loadData.get());
}
void InjectedBundle::queueReload()
@@ -565,7 +774,7 @@ void InjectedBundle::queueReload()
m_useWorkQueue = true;
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueReload"));
- WKBundlePostMessage(m_bundle, messageName.get(), 0);
+ WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
}
void InjectedBundle::queueLoadingScript(WKStringRef script)
@@ -573,7 +782,7 @@ void InjectedBundle::queueLoadingScript(WKStringRef script)
m_useWorkQueue = true;
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoadingScript"));
- WKBundlePostMessage(m_bundle, messageName.get(), script);
+ WKBundlePagePostMessage(page()->page(), messageName.get(), script);
}
void InjectedBundle::queueNonLoadingScript(WKStringRef script)
@@ -581,7 +790,19 @@ void InjectedBundle::queueNonLoadingScript(WKStringRef script)
m_useWorkQueue = true;
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueNonLoadingScript"));
- WKBundlePostMessage(m_bundle, messageName.get(), script);
+ WKBundlePagePostMessage(page()->page(), messageName.get(), script);
+}
+
+bool InjectedBundle::isAllowedHost(WKStringRef host)
+{
+ if (m_allowedHosts.isEmpty())
+ return false;
+ return m_allowedHosts.contains(toWTFString(host));
+}
+
+void InjectedBundle::setAllowsAnySSLCertificate(bool allowsAnySSLCertificate)
+{
+ WebCoreTestSupport::setAllowsAnySSLCertificate(allowsAnySSLCertificate);
}
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
index 170c8ac70..2edd5e797 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,29 +23,30 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef InjectedBundle_h
-#define InjectedBundle_h
+#pragma once
-#include "AccessibilityController.h"
#include "EventSendingController.h"
#include "GCController.h"
#include "TestRunner.h"
#include "TextInputController.h"
-#include <WebKit2/WKBase.h>
-#include <WebKit2/WKRetainPtr.h>
+#include <WebKit/WKBase.h>
+#include <WebKit/WKRetainPtr.h>
#include <sstream>
#include <wtf/Forward.h>
-#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
+#if HAVE(ACCESSIBILITY)
+#include "AccessibilityController.h"
+#endif
+
namespace WTR {
class InjectedBundlePage;
class InjectedBundle {
public:
- static InjectedBundle& shared();
+ static InjectedBundle& singleton();
// Initialize the InjectedBundle.
void initialize(WKBundleRef, WKTypeRef initializationUserData);
@@ -57,7 +58,9 @@ public:
GCController* gcController() { return m_gcController.get(); }
EventSendingController* eventSendingController() { return m_eventSendingController.get(); }
TextInputController* textInputController() { return m_textInputController.get(); }
+#if HAVE(ACCESSIBILITY)
AccessibilityController* accessibilityController() { return m_accessibilityController.get(); }
+#endif
InjectedBundlePage* page() const;
size_t pageCount() const { return m_pages.size(); }
@@ -67,7 +70,8 @@ public:
void done();
void setAudioResult(WKDataRef audioData) { m_audioResult = audioData; }
- void setPixelResult(WKImageRef image) { m_pixelResult = image; }
+ void setPixelResult(WKImageRef image) { m_pixelResult = image; m_pixelResultIsPending = false; }
+ void setPixelResultIsPending(bool isPending) { m_pixelResultIsPending = isPending; }
void setRepaintRects(WKArrayRef rects) { m_repaintRects = rects; }
bool isTestRunning() { return m_state == Testing; }
@@ -77,38 +81,58 @@ public:
bool shouldDumpPixels() const { return m_dumpPixels; }
bool useWaitToDumpWatchdogTimer() const { return m_useWaitToDumpWatchdogTimer; }
-
+ bool dumpJSConsoleLogInStdErr() const { return m_dumpJSConsoleLogInStdErr; };
+
void outputText(const String&);
+ void dumpToStdErr(const String&);
void postNewBeforeUnloadReturnValue(bool);
void postAddChromeInputField();
void postRemoveChromeInputField();
void postFocusWebView();
void postSetBackingScaleFactor(double);
void postSetWindowIsKey(bool);
+ void postSetViewSize(double width, double height);
void postSimulateWebNotificationClick(uint64_t notificationID);
+ void postSetAddsVisitedLinks(bool);
// Geolocation.
void setGeolocationPermission(bool);
void setMockGeolocationPosition(double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed);
void setMockGeolocationPositionUnavailableError(WKStringRef errorMessage);
+ bool isGeolocationProviderActive() const;
+
+ // MediaStream.
+ void setUserMediaPermission(bool);
+ void setUserMediaPersistentPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin);
+ unsigned userMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin) const;
+ void resetUserMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin);
// Policy delegate.
void setCustomPolicyDelegate(bool enabled, bool permissive);
// Page Visibility.
- void setVisibilityState(WKPageVisibilityState, bool isInitialState);
+ void setHidden(bool);
+
+ // Cache.
+ void setCacheModel(int);
// Work queue.
bool shouldProcessWorkQueue() const;
void processWorkQueue();
void queueBackNavigation(unsigned howFarBackward);
void queueForwardNavigation(unsigned howFarForward);
- void queueLoad(WKStringRef url, WKStringRef target);
+ void queueLoad(WKStringRef url, WKStringRef target, bool shouldOpenExternalURLs = false);
void queueLoadHTMLString(WKStringRef content, WKStringRef baseURL = 0, WKStringRef unreachableURL = 0);
void queueReload();
void queueLoadingScript(WKStringRef script);
void queueNonLoadingScript(WKStringRef script);
+ bool isAllowedHost(WKStringRef);
+
+ unsigned imageCountInGeneralPasteboard() const;
+
+ void setAllowsAnySSLCertificate(bool);
+
private:
InjectedBundle();
~InjectedBundle();
@@ -134,9 +158,11 @@ private:
WKBundleRef m_bundle;
WKBundlePageGroupRef m_pageGroup;
- Vector<OwnPtr<InjectedBundlePage> > m_pages;
+ Vector<std::unique_ptr<InjectedBundlePage>> m_pages;
+#if HAVE(ACCESSIBILITY)
RefPtr<AccessibilityController> m_accessibilityController;
+#endif
RefPtr<TestRunner> m_testRunner;
RefPtr<GCController> m_gcController;
RefPtr<EventSendingController> m_eventSendingController;
@@ -155,12 +181,14 @@ private:
bool m_useWaitToDumpWatchdogTimer;
bool m_useWorkQueue;
int m_timeout;
+ bool m_pixelResultIsPending { false };
+ bool m_dumpJSConsoleLogInStdErr { false };
WKRetainPtr<WKDataRef> m_audioResult;
WKRetainPtr<WKImageRef> m_pixelResult;
WKRetainPtr<WKArrayRef> m_repaintRects;
+
+ Vector<String> m_allowedHosts;
};
} // namespace WTR
-
-#endif // InjectedBundle_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp
index 58af68221..4f1272214 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp
@@ -26,10 +26,10 @@
#include "config.h"
#include "InjectedBundle.h"
-#include <WebKit2/WKBundleInitialize.h>
+#include <WebKit/WKBundleInitialize.h>
extern "C"
void WKBundleInitialize(WKBundleRef bundle, WKTypeRef initializationUserData)
{
- WTR::InjectedBundle::shared().initialize(bundle, initializationUserData);
+ WTR::InjectedBundle::singleton().initialize(bundle, initializationUserData);
}
diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
index e161156a7..61c59b2e3 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,19 +31,20 @@
#include "WebCoreTestSupport.h"
#include <cmath>
#include <JavaScriptCore/JSRetainPtr.h>
-#include <WebKit2/WKArray.h>
-#include <WebKit2/WKBundle.h>
-#include <WebKit2/WKBundleBackForwardList.h>
-#include <WebKit2/WKBundleBackForwardListItem.h>
-#include <WebKit2/WKBundleFrame.h>
-#include <WebKit2/WKBundleFramePrivate.h>
-#include <WebKit2/WKBundleHitTestResult.h>
-#include <WebKit2/WKBundleNavigationAction.h>
-#include <WebKit2/WKBundleNodeHandlePrivate.h>
-#include <WebKit2/WKBundlePagePrivate.h>
-#include <WebKit2/WKBundlePrivate.h>
-#include <WebKit2/WKSecurityOrigin.h>
-#include <WebKit2/WKURLRequest.h>
+#include <WebKit/WKArray.h>
+#include <WebKit/WKBundle.h>
+#include <WebKit/WKBundleBackForwardList.h>
+#include <WebKit/WKBundleBackForwardListItem.h>
+#include <WebKit/WKBundleFrame.h>
+#include <WebKit/WKBundleFramePrivate.h>
+#include <WebKit/WKBundleHitTestResult.h>
+#include <WebKit/WKBundleNavigationAction.h>
+#include <WebKit/WKBundleNavigationActionPrivate.h>
+#include <WebKit/WKBundleNodeHandlePrivate.h>
+#include <WebKit/WKBundlePagePrivate.h>
+#include <WebKit/WKBundlePrivate.h>
+#include <WebKit/WKSecurityOriginRef.h>
+#include <WebKit/WKURLRequest.h>
#include <wtf/HashMap.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
@@ -240,7 +241,7 @@ static inline WTF::String pathSuitableForTestResult(WKURLRef fileUrl)
if (!isLocalFileScheme(schemeString.get()))
return toWTFString(adoptWK(WKURLCopyString(fileUrl)));
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
WKRetainPtr<WKURLRef> mainFrameURL = adoptWK(WKBundleFrameCopyURL(mainFrame));
if (!mainFrameURL)
mainFrameURL = adoptWK(WKBundleFrameCopyProvisionalURL(mainFrame));
@@ -268,8 +269,8 @@ InjectedBundlePage::InjectedBundlePage(WKBundlePageRef page)
: m_page(page)
, m_world(AdoptWK, WKBundleScriptWorldCreateWorld())
{
- WKBundlePageLoaderClientV7 loaderClient = {
- { 7, this },
+ WKBundlePageLoaderClientV8 loaderClient = {
+ { 8, this },
didStartProvisionalLoadForFrame,
didReceiveServerRedirectForProvisionalLoadForFrame,
didFailProvisionalLoadWithErrorForFrame,
@@ -304,7 +305,8 @@ InjectedBundlePage::InjectedBundlePage(WKBundlePageRef page)
0, // featuresUsedInPage
0, // willLoadURLRequest
0, // willLoadDataRequest
- 0, // willDestroyFrame
+ 0, // willDestroyFrame_unavailable
+ 0, // userAgentForURL
};
WKBundlePageSetPageLoaderClient(m_page, &loaderClient.base);
@@ -412,14 +414,26 @@ void InjectedBundlePage::prepare()
WKBundleFrameClearOpener(WKBundlePageGetMainFrame(m_page));
WKBundlePageSetTracksRepaints(m_page, false);
+
+ // Force consistent "responsive" behavior for WebPage::eventThrottlingDelay() for testing. Tests can override via internals.
+ WKEventThrottlingBehavior behavior = kWKEventThrottlingBehaviorResponsive;
+ WKBundlePageSetEventThrottlingBehaviorOverride(m_page, &behavior);
}
void InjectedBundlePage::resetAfterTest()
{
WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page);
+
+ // WebKit currently doesn't reset focus even when navigating to a new page. This may or may not be a bug
+ // (see <https://bugs.webkit.org/show_bug.cgi?id=138334>), however for tests, we want to start each one with a clean state.
+ WKBundleFrameFocus(frame);
+
JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
WebCoreTestSupport::resetInternalsObject(context);
assignedUrlsCache.clear();
+
+ // User scripts need to be removed after the test and before loading about:blank, as otherwise they would run in about:blank, and potentially leak results into a subsequest test.
+ WKBundlePageRemoveAllUserContent(m_page);
}
// Loader Client Callbacks
@@ -457,7 +471,7 @@ static void dumpLoadEvent(WKBundleFrameRef frame, const char* eventName)
stringBuilder.appendLiteral(" - ");
stringBuilder.append(eventName);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ InjectedBundle::singleton().outputText(stringBuilder.toString());
}
static inline void dumpRequestDescriptionSuitableForTestResult(WKURLRequestRef request, StringBuilder& stringBuilder)
@@ -646,49 +660,64 @@ bool InjectedBundlePage::shouldCacheResponse(WKBundlePageRef page, WKBundleFrame
void InjectedBundlePage::didStartProvisionalLoadForFrame(WKBundleFrameRef frame)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
+ if (!injectedBundle.testRunner()->testURL()) {
+ WKRetainPtr<WKURLRef> testURL = adoptWK(WKBundleFrameCopyProvisionalURL(frame));
+ injectedBundle.testRunner()->setTestURL(testURL.get());
+ }
+
platformDidStartProvisionalLoadForFrame(frame);
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
dumpLoadEvent(frame, "didStartProvisionalLoadForFrame");
- if (!InjectedBundle::shared().topLoadingFrame())
- InjectedBundle::shared().setTopLoadingFrame(frame);
+ if (!injectedBundle.topLoadingFrame())
+ injectedBundle.setTopLoadingFrame(frame);
- if (InjectedBundle::shared().testRunner()->shouldStopProvisionalFrameLoads())
+ if (injectedBundle.testRunner()->shouldStopProvisionalFrameLoads())
dumpLoadEvent(frame, "stopping load in didStartProvisionalLoadForFrame callback");
}
void InjectedBundlePage::didReceiveServerRedirectForProvisionalLoadForFrame(WKBundleFrameRef frame)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
return;
dumpLoadEvent(frame, "didReceiveServerRedirectForProvisionalLoadForFrame");
}
-void InjectedBundlePage::didFailProvisionalLoadWithErrorForFrame(WKBundleFrameRef frame, WKErrorRef)
+void InjectedBundlePage::didFailProvisionalLoadWithErrorForFrame(WKBundleFrameRef frame, WKErrorRef error)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks()) {
dumpLoadEvent(frame, "didFailProvisionalLoadWithError");
+ auto code = WKErrorGetErrorCode(error);
+ if (code == kWKErrorCodeCannotShowURL)
+ dumpLoadEvent(frame, "(ErrorCodeCannotShowURL)");
+ else if (code == kWKErrorCodeFrameLoadBlockedByContentBlocker)
+ dumpLoadEvent(frame, "(kWKErrorCodeFrameLoadBlockedByContentBlocker)");
+ }
frameDidChangeLocation(frame);
}
void InjectedBundlePage::didCommitLoadForFrame(WKBundleFrameRef frame)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
return;
dumpLoadEvent(frame, "didCommitLoadForFrame");
@@ -696,13 +725,14 @@ void InjectedBundlePage::didCommitLoadForFrame(WKBundleFrameRef frame)
void InjectedBundlePage::didFinishProgress()
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpProgressFinishedCallback())
+ if (!injectedBundle.testRunner()->shouldDumpProgressFinishedCallback())
return;
- InjectedBundle::shared().outputText("postProgressFinishedNotification\n");
+ injectedBundle.outputText("postProgressFinishedNotification\n");
}
enum FrameNamePolicy { ShouldNotIncludeFrameName, ShouldIncludeFrameName };
@@ -816,16 +846,15 @@ void InjectedBundlePage::dumpDOMAsWebArchive(WKBundleFrameRef frame, StringBuild
#if USE(CF)
WKRetainPtr<WKDataRef> wkData = adoptWK(WKBundleFrameCopyWebArchive(frame));
RetainPtr<CFDataRef> cfData = adoptCF(CFDataCreate(0, WKDataGetBytes(wkData.get()), WKDataGetSize(wkData.get())));
- RetainPtr<CFStringRef> cfString = adoptCF(createXMLStringFromWebArchiveData(cfData.get()));
+ RetainPtr<CFStringRef> cfString = adoptCF(WebCoreTestSupport::createXMLStringFromWebArchiveData(cfData.get()));
stringBuilder.append(cfString.get());
#endif
}
void InjectedBundlePage::dump()
{
- ASSERT(InjectedBundle::shared().isTestRunning());
-
- InjectedBundle::shared().testRunner()->invalidateWaitToDumpWatchdogTimer();
+ auto& injectedBundle = InjectedBundle::singleton();
+ ASSERT(injectedBundle.isTestRunning());
// Force a paint before dumping. This matches DumpRenderTree on Windows. (DumpRenderTree on Mac
// does this at a slightly different time.) See <http://webkit.org/b/55469> for details.
@@ -836,13 +865,13 @@ void InjectedBundlePage::dump()
String url = toWTFString(adoptWK(WKURLCopyString(urlRef.get())));
WKRetainPtr<WKStringRef> mimeType = adoptWK(WKBundleFrameCopyMIMETypeForResourceWithURL(frame, urlRef.get()));
if (url.find("dumpAsText/") != notFound || WKStringIsEqualToUTF8CString(mimeType.get(), "text/plain"))
- InjectedBundle::shared().testRunner()->dumpAsText(false);
+ injectedBundle.testRunner()->dumpAsText(false);
StringBuilder stringBuilder;
- switch (InjectedBundle::shared().testRunner()->whatToDump()) {
+ switch (injectedBundle.testRunner()->whatToDump()) {
case TestRunner::RenderTree: {
- if (InjectedBundle::shared().testRunner()->isPrinting())
+ if (injectedBundle.testRunner()->isPrinting())
stringBuilder.append(toWTFString(adoptWK(WKBundlePageCopyRenderTreeExternalRepresentationForPrinting(m_page)).get()));
else
stringBuilder.append(toWTFString(adoptWK(WKBundlePageCopyRenderTreeExternalRepresentation(m_page)).get()));
@@ -861,34 +890,47 @@ void InjectedBundlePage::dump()
break;
}
- if (InjectedBundle::shared().testRunner()->shouldDumpAllFrameScrollPositions())
+ if (injectedBundle.testRunner()->shouldDumpAllFrameScrollPositions())
dumpAllFrameScrollPositions(stringBuilder);
- else if (InjectedBundle::shared().testRunner()->shouldDumpMainFrameScrollPosition())
+ else if (injectedBundle.testRunner()->shouldDumpMainFrameScrollPosition())
dumpFrameScrollPosition(WKBundlePageGetMainFrame(m_page), stringBuilder);
- if (InjectedBundle::shared().testRunner()->shouldDumpBackForwardListsForAllWindows())
- InjectedBundle::shared().dumpBackForwardListsForAllPages(stringBuilder);
+ if (injectedBundle.testRunner()->shouldDumpBackForwardListsForAllWindows())
+ injectedBundle.dumpBackForwardListsForAllPages(stringBuilder);
+
+ if (injectedBundle.shouldDumpPixels() && injectedBundle.testRunner()->shouldDumpPixels()) {
+ bool shouldCreateSnapshot = injectedBundle.testRunner()->isPrinting();
+ if (shouldCreateSnapshot) {
+ WKSnapshotOptions options = kWKSnapshotOptionsShareable;
+ WKRect snapshotRect = WKBundleFrameGetVisibleContentBounds(WKBundlePageGetMainFrame(m_page));
- if (InjectedBundle::shared().shouldDumpPixels() && InjectedBundle::shared().testRunner()->shouldDumpPixels()) {
- WKSnapshotOptions options = kWKSnapshotOptionsShareable | kWKSnapshotOptionsInViewCoordinates;
- if (InjectedBundle::shared().testRunner()->shouldDumpSelectionRect())
- options |= kWKSnapshotOptionsPaintSelectionRectangle;
+ if (injectedBundle.testRunner()->isPrinting())
+ options |= kWKSnapshotOptionsPrinting;
+ else {
+ options |= kWKSnapshotOptionsInViewCoordinates;
+ if (injectedBundle.testRunner()->shouldDumpSelectionRect())
+ options |= kWKSnapshotOptionsPaintSelectionRectangle;
+ }
+
+ injectedBundle.setPixelResult(adoptWK(WKBundlePageCreateSnapshotWithOptions(m_page, snapshotRect, options)).get());
+ } else
+ injectedBundle.setPixelResultIsPending(true);
- InjectedBundle::shared().setPixelResult(adoptWK(WKBundlePageCreateSnapshotWithOptions(m_page, WKBundleFrameGetVisibleContentBounds(WKBundlePageGetMainFrame(m_page)), options)).get());
- if (WKBundlePageIsTrackingRepaints(m_page))
- InjectedBundle::shared().setRepaintRects(adoptWK(WKBundlePageCopyTrackedRepaintRects(m_page)).get());
+ if (WKBundlePageIsTrackingRepaints(m_page) && !injectedBundle.testRunner()->isPrinting())
+ injectedBundle.setRepaintRects(adoptWK(WKBundlePageCopyTrackedRepaintRects(m_page)).get());
}
- InjectedBundle::shared().outputText(stringBuilder.toString());
- InjectedBundle::shared().done();
+ injectedBundle.outputText(stringBuilder.toString());
+ injectedBundle.done();
}
void InjectedBundlePage::didFinishLoadForFrame(WKBundleFrameRef frame)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
dumpLoadEvent(frame, "didFinishLoadForFrame");
frameDidChangeLocation(frame, /*shouldDump*/ true);
@@ -896,10 +938,11 @@ void InjectedBundlePage::didFinishLoadForFrame(WKBundleFrameRef frame)
void InjectedBundlePage::didFailLoadWithErrorForFrame(WKBundleFrameRef frame, WKErrorRef)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
dumpLoadEvent(frame, "didFailLoadWithError");
frameDidChangeLocation(frame);
@@ -907,29 +950,31 @@ void InjectedBundlePage::didFailLoadWithErrorForFrame(WKBundleFrameRef frame, WK
void InjectedBundlePage::didReceiveTitleForFrame(WKStringRef title, WKBundleFrameRef frame)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
StringBuilder stringBuilder;
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks()) {
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks()) {
dumpFrameDescriptionSuitableForTestResult(frame, stringBuilder);
stringBuilder.appendLiteral(" - didReceiveTitle: ");
stringBuilder.append(toWTFString(title));
stringBuilder.append('\n');
}
- if (InjectedBundle::shared().testRunner()->shouldDumpTitleChanges()) {
+ if (injectedBundle.testRunner()->shouldDumpTitleChanges()) {
stringBuilder.appendLiteral("TITLE CHANGED: '");
stringBuilder.append(toWTFString(title));
stringBuilder.appendLiteral("'\n");
}
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::didClearWindowForFrame(WKBundleFrameRef frame, WKBundleScriptWorldRef world)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
JSGlobalContextRef context = WKBundleFrameGetJavaScriptContextForWorld(frame, world);
@@ -940,22 +985,23 @@ void InjectedBundlePage::didClearWindowForFrame(WKBundleFrameRef frame, WKBundle
return;
}
- JSValueRef exception = 0;
- InjectedBundle::shared().testRunner()->makeWindowObject(context, window, &exception);
- InjectedBundle::shared().gcController()->makeWindowObject(context, window, &exception);
- InjectedBundle::shared().eventSendingController()->makeWindowObject(context, window, &exception);
- InjectedBundle::shared().textInputController()->makeWindowObject(context, window, &exception);
- InjectedBundle::shared().accessibilityController()->makeWindowObject(context, window, &exception);
+ JSValueRef exception = nullptr;
+ injectedBundle.testRunner()->makeWindowObject(context, window, &exception);
+ injectedBundle.gcController()->makeWindowObject(context, window, &exception);
+ injectedBundle.eventSendingController()->makeWindowObject(context, window, &exception);
+ injectedBundle.textInputController()->makeWindowObject(context, window, &exception);
+ injectedBundle.accessibilityController()->makeWindowObject(context, window, &exception);
WebCoreTestSupport::injectInternalsObject(context);
}
void InjectedBundlePage::didCancelClientRedirectForFrame(WKBundleFrameRef frame)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
return;
dumpLoadEvent(frame, "didCancelClientRedirectForFrame");
@@ -963,10 +1009,11 @@ void InjectedBundlePage::didCancelClientRedirectForFrame(WKBundleFrameRef frame)
void InjectedBundlePage::willPerformClientRedirectForFrame(WKBundlePageRef, WKBundleFrameRef frame, WKURLRef url, double delay, double date)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
return;
StringBuilder stringBuilder;
@@ -974,19 +1021,31 @@ void InjectedBundlePage::willPerformClientRedirectForFrame(WKBundlePageRef, WKBu
stringBuilder.appendLiteral(" - willPerformClientRedirectToURL: ");
stringBuilder.append(pathSuitableForTestResult(url));
stringBuilder.appendLiteral(" \n");
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::didSameDocumentNavigationForFrame(WKBundleFrameRef frame, WKSameDocumentNavigationType type)
{
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
+ return;
+
+ if (!injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
+ return;
+
+ if (type != kWKSameDocumentNavigationAnchorNavigation)
+ return;
+
+ dumpLoadEvent(frame, "didChangeLocationWithinPageForFrame");
}
void InjectedBundlePage::didFinishDocumentLoadForFrame(WKBundleFrameRef frame)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
dumpLoadEvent(frame, "didFinishDocumentLoadForFrame");
unsigned pendingFrameUnloadEvents = WKBundleFrameGetPendingUnloadCount(frame);
@@ -996,40 +1055,44 @@ void InjectedBundlePage::didFinishDocumentLoadForFrame(WKBundleFrameRef frame)
stringBuilder.appendLiteral(" - has ");
stringBuilder.appendNumber(pendingFrameUnloadEvents);
stringBuilder.appendLiteral(" onunload handler(s)\n");
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
}
void InjectedBundlePage::didHandleOnloadEventsForFrame(WKBundleFrameRef frame)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
dumpLoadEvent(frame, "didHandleOnloadEventsForFrame");
}
-void InjectedBundlePage::didDisplayInsecureContentForFrame(WKBundleFrameRef frame)
+void InjectedBundlePage::didDisplayInsecureContentForFrame(WKBundleFrameRef)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
- InjectedBundle::shared().outputText("didDisplayInsecureContent\n");
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
+ injectedBundle.outputText("didDisplayInsecureContent\n");
}
-void InjectedBundlePage::didRunInsecureContentForFrame(WKBundleFrameRef frame)
+void InjectedBundlePage::didRunInsecureContentForFrame(WKBundleFrameRef)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
- InjectedBundle::shared().outputText("didRunInsecureContent\n");
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
+ injectedBundle.outputText("didRunInsecureContent\n");
}
-void InjectedBundlePage::didDetectXSSForFrame(WKBundleFrameRef frame)
+void InjectedBundlePage::didDetectXSSForFrame(WKBundleFrameRef)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpFrameLoadCallbacks())
- InjectedBundle::shared().outputText("didDetectXSS\n");
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpFrameLoadCallbacks())
+ injectedBundle.outputText("didDetectXSS\n");
}
void InjectedBundlePage::didInitiateLoadForResource(WKBundlePageRef page, WKBundleFrameRef, uint64_t identifier, WKURLRequestRef request, bool)
{
- if (!InjectedBundle::shared().isTestRunning())
+ if (!InjectedBundle::singleton().isTestRunning())
return;
WKRetainPtr<WKURLRef> url = adoptWK(WKURLRequestCopyURL(request));
@@ -1048,10 +1111,16 @@ static inline bool isHTTPOrHTTPSScheme(WKStringRef scheme)
return WKStringIsEqualToUTF8CStringIgnoringCase(scheme, "http") || WKStringIsEqualToUTF8CStringIgnoringCase(scheme, "https");
}
+static inline bool isAllowedHost(WKStringRef host)
+{
+ return InjectedBundle::singleton().isAllowedHost(host);
+}
+
WKURLRequestRef InjectedBundlePage::willSendRequestForFrame(WKBundlePageRef page, WKBundleFrameRef frame, uint64_t identifier, WKURLRequestRef request, WKURLResponseRef response)
{
- if (InjectedBundle::shared().isTestRunning()
- && InjectedBundle::shared().testRunner()->shouldDumpResourceLoadCallbacks()) {
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.isTestRunning()
+ && injectedBundle.testRunner()->shouldDumpResourceLoadCallbacks()) {
StringBuilder stringBuilder;
dumpResourceURL(identifier, stringBuilder);
stringBuilder.appendLiteral(" - willSendRequest ");
@@ -1059,16 +1128,16 @@ WKURLRequestRef InjectedBundlePage::willSendRequestForFrame(WKBundlePageRef page
stringBuilder.appendLiteral(" redirectResponse ");
dumpResponseDescriptionSuitableForTestResult(response, stringBuilder);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- if (InjectedBundle::shared().isTestRunning() && InjectedBundle::shared().testRunner()->willSendRequestReturnsNull())
- return 0;
+ if (injectedBundle.isTestRunning() && injectedBundle.testRunner()->willSendRequestReturnsNull())
+ return nullptr;
WKRetainPtr<WKURLRef> redirectURL = adoptWK(WKURLResponseCopyURL(response));
- if (InjectedBundle::shared().isTestRunning() && InjectedBundle::shared().testRunner()->willSendRequestReturnsNullOnRedirect() && redirectURL) {
- InjectedBundle::shared().outputText("Returning null for this redirect\n");
- return 0;
+ if (injectedBundle.isTestRunning() && injectedBundle.testRunner()->willSendRequestReturnsNullOnRedirect() && redirectURL) {
+ injectedBundle.outputText("Returning null for this redirect\n");
+ return nullptr;
}
WKRetainPtr<WKURLRef> url = adoptWK(WKURLRequestCopyURL(request));
@@ -1080,23 +1149,31 @@ WKURLRequestRef InjectedBundlePage::willSendRequestForFrame(WKBundlePageRef page
&& !WKStringIsEqualToUTF8CString(host.get(), "255.255.255.255") // Used in some tests that expect to get back an error.
&& !isLocalHost(host.get())) {
bool mainFrameIsExternal = false;
- if (InjectedBundle::shared().isTestRunning()) {
- WKBundleFrameRef mainFrame = InjectedBundle::shared().topLoadingFrame();
+ if (injectedBundle.isTestRunning()) {
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(m_page);
WKRetainPtr<WKURLRef> mainFrameURL = adoptWK(WKBundleFrameCopyURL(mainFrame));
if (!mainFrameURL || WKStringIsEqualToUTF8CString(adoptWK(WKURLCopyString(mainFrameURL.get())).get(), "about:blank"))
mainFrameURL = adoptWK(WKBundleFrameCopyProvisionalURL(mainFrame));
- WKRetainPtr<WKStringRef> mainFrameHost = WKURLCopyHostName(mainFrameURL.get());
- WKRetainPtr<WKStringRef> mainFrameScheme = WKURLCopyScheme(mainFrameURL.get());
+ WKRetainPtr<WKStringRef> mainFrameHost = adoptWK(WKURLCopyHostName(mainFrameURL.get()));
+ WKRetainPtr<WKStringRef> mainFrameScheme = adoptWK(WKURLCopyScheme(mainFrameURL.get()));
mainFrameIsExternal = isHTTPOrHTTPSScheme(mainFrameScheme.get()) && !isLocalHost(mainFrameHost.get());
}
- if (!mainFrameIsExternal) {
+ if (!mainFrameIsExternal && !isAllowedHost(host.get())) {
StringBuilder stringBuilder;
stringBuilder.appendLiteral("Blocked access to external URL ");
stringBuilder.append(toWTFString(urlString));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
- return 0;
+ injectedBundle.outputText(stringBuilder.toString());
+ return nullptr;
+ }
+ }
+
+ if (injectedBundle.isTestRunning()) {
+ String body = injectedBundle.testRunner()->willSendRequestHTTPBody();
+ if (!body.isEmpty()) {
+ CString cBody = body.utf8();
+ return WKURLRequestCopySettingHTTPBody(request, WKDataCreate(reinterpret_cast<const unsigned char*>(cBody.data()), cBody.length()));
}
}
@@ -1106,20 +1183,21 @@ WKURLRequestRef InjectedBundlePage::willSendRequestForFrame(WKBundlePageRef page
void InjectedBundlePage::didReceiveResponseForResource(WKBundlePageRef page, WKBundleFrameRef, uint64_t identifier, WKURLResponseRef response)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (InjectedBundle::shared().testRunner()->shouldDumpResourceLoadCallbacks()) {
+ if (injectedBundle.testRunner()->shouldDumpResourceLoadCallbacks()) {
StringBuilder stringBuilder;
dumpResourceURL(identifier, stringBuilder);
stringBuilder.appendLiteral(" - didReceiveResponse ");
dumpResponseDescriptionSuitableForTestResult(response, stringBuilder);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- if (!InjectedBundle::shared().testRunner()->shouldDumpResourceResponseMIMETypes())
+ if (!injectedBundle.testRunner()->shouldDumpResourceResponseMIMETypes())
return;
WKRetainPtr<WKURLRef> url = adoptWK(WKURLResponseCopyURL(response));
@@ -1130,8 +1208,16 @@ void InjectedBundlePage::didReceiveResponseForResource(WKBundlePageRef page, WKB
stringBuilder.append(toWTFString(urlString));
stringBuilder.appendLiteral(" has MIME type ");
stringBuilder.append(toWTFString(mimeTypeString));
+
+ String platformMimeType = platformResponseMimeType(response);
+ if (!platformMimeType.isEmpty() && platformMimeType != toWTFString(mimeTypeString)) {
+ stringBuilder.appendLiteral(" but platform response has ");
+ stringBuilder.append(platformMimeType);
+ }
+
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::didReceiveContentLengthForResource(WKBundlePageRef, WKBundleFrameRef, uint64_t, uint64_t)
@@ -1140,24 +1226,26 @@ void InjectedBundlePage::didReceiveContentLengthForResource(WKBundlePageRef, WKB
void InjectedBundlePage::didFinishLoadForResource(WKBundlePageRef, WKBundleFrameRef, uint64_t identifier)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpResourceLoadCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpResourceLoadCallbacks())
return;
StringBuilder stringBuilder;
dumpResourceURL(identifier, stringBuilder);
stringBuilder.appendLiteral(" - didFinishLoading\n");
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::didFailLoadForResource(WKBundlePageRef, WKBundleFrameRef, uint64_t identifier, WKErrorRef error)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpResourceLoadCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpResourceLoadCallbacks())
return;
StringBuilder stringBuilder;
@@ -1166,21 +1254,22 @@ void InjectedBundlePage::didFailLoadForResource(WKBundlePageRef, WKBundleFrameRe
dumpErrorDescriptionSuitableForTestResult(error, stringBuilder);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
bool InjectedBundlePage::shouldCacheResponse(WKBundlePageRef, WKBundleFrameRef, uint64_t identifier)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return true;
- if (!InjectedBundle::shared().testRunner()->shouldDumpWillCacheResponse())
+ if (!injectedBundle.testRunner()->shouldDumpWillCacheResponse())
return true;
StringBuilder stringBuilder;
stringBuilder.appendNumber(identifier);
stringBuilder.appendLiteral(" - willCacheResponse: called\n");
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
// The default behavior is the cache the response.
return true;
@@ -1211,11 +1300,30 @@ void InjectedBundlePage::unableToImplementPolicy(WKBundlePageRef page, WKBundleF
WKBundlePagePolicyAction InjectedBundlePage::decidePolicyForNavigationAction(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleNavigationActionRef navigationAction, WKURLRequestRef request, WKTypeRef* userData)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return WKBundlePagePolicyActionUse;
- if (!InjectedBundle::shared().testRunner()->isPolicyDelegateEnabled())
- return WKBundlePagePolicyActionUse;
+ if (injectedBundle.testRunner()->shouldDumpPolicyCallbacks()) {
+ StringBuilder stringBuilder;
+ stringBuilder.appendLiteral(" - decidePolicyForNavigationAction \n");
+ dumpRequestDescriptionSuitableForTestResult(request, stringBuilder);
+ stringBuilder.appendLiteral(" is main frame - ");
+ stringBuilder.append(WKBundleFrameIsMainFrame(frame) ? "yes" : "no");
+ stringBuilder.appendLiteral(" should open URLs externally - ");
+ stringBuilder.append(WKBundleNavigationActionGetShouldOpenExternalURLs(navigationAction) ? "yes" : "no");
+ stringBuilder.append('\n');
+ injectedBundle.outputText(stringBuilder.toString());
+ }
+
+ if (injectedBundle.testRunner()->shouldDecideNavigationPolicyAfterDelay())
+ return WKBundlePagePolicyActionPassThrough;
+
+ if (!injectedBundle.testRunner()->isPolicyDelegateEnabled()) {
+ WKRetainPtr<WKStringRef> downloadAttributeRef(AdoptWK, WKBundleNavigationActionCopyDownloadAttribute(navigationAction));
+ String downloadAttribute = toWTFString(downloadAttributeRef);
+ return downloadAttribute.isNull() ? WKBundlePagePolicyActionUse : WKBundlePagePolicyActionPassThrough;
+ }
WKRetainPtr<WKURLRef> url = adoptWK(WKURLRequestCopyURL(request));
WKRetainPtr<WKStringRef> urlScheme = adoptWK(WKURLCopyScheme(url.get()));
@@ -1239,10 +1347,10 @@ WKBundlePagePolicyAction InjectedBundlePage::decidePolicyForNavigationAction(WKB
}
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
- InjectedBundle::shared().testRunner()->notifyDone();
+ injectedBundle.outputText(stringBuilder.toString());
+ injectedBundle.testRunner()->notifyDone();
- if (InjectedBundle::shared().testRunner()->isPolicyDelegatePermissive())
+ if (injectedBundle.testRunner()->isPolicyDelegatePermissive())
return WKBundlePagePolicyActionUse;
return WKBundlePagePolicyActionPassThrough;
}
@@ -1254,13 +1362,13 @@ WKBundlePagePolicyAction InjectedBundlePage::decidePolicyForNewWindowAction(WKBu
WKBundlePagePolicyAction InjectedBundlePage::decidePolicyForResponse(WKBundlePageRef page, WKBundleFrameRef, WKURLResponseRef response, WKURLRequestRef, WKTypeRef*)
{
- if (WKURLResponseIsAttachment(response)) {
+ if (InjectedBundle::singleton().testRunner()->isPolicyDelegateEnabled() && WKURLResponseIsAttachment(response)) {
StringBuilder stringBuilder;
WKRetainPtr<WKStringRef> filename = adoptWK(WKURLResponseCopySuggestedFilename(response));
stringBuilder.appendLiteral("Policy delegate: resource is an attachment, suggested file name \'");
stringBuilder.append(toWTFString(filename));
stringBuilder.appendLiteral("\'\n");
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ InjectedBundle::singleton().outputText(stringBuilder.toString());
}
WKRetainPtr<WKStringRef> mimeType = adoptWK(WKURLResponseCopyMIMEType(response));
@@ -1330,7 +1438,8 @@ static WTF::String lastFileURLPathComponent(const WTF::String& path)
void InjectedBundlePage::willAddMessageToConsole(WKStringRef message, uint32_t lineNumber)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
WTF::String messageString = toWTFString(message);
@@ -1352,46 +1461,53 @@ void InjectedBundlePage::willAddMessageToConsole(WKStringRef message, uint32_t l
}
stringBuilder.append(messageString);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+
+ if (injectedBundle.dumpJSConsoleLogInStdErr())
+ injectedBundle.dumpToStdErr(stringBuilder.toString());
+ else
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::willSetStatusbarText(WKStringRef statusbarText)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpStatusCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpStatusCallbacks())
return;
StringBuilder stringBuilder;
stringBuilder.appendLiteral("UI DELEGATE STATUS CALLBACK: setStatusText:");
stringBuilder.append(toWTFString(statusbarText));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::willRunJavaScriptAlert(WKStringRef message, WKBundleFrameRef)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
StringBuilder stringBuilder;
stringBuilder.appendLiteral("ALERT: ");
stringBuilder.append(toWTFString(message));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::willRunJavaScriptConfirm(WKStringRef message, WKBundleFrameRef)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
StringBuilder stringBuilder;
stringBuilder.appendLiteral("CONFIRM: ");
stringBuilder.append(toWTFString(message));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::willRunJavaScriptPrompt(WKStringRef message, WKStringRef defaultValue, WKBundleFrameRef)
@@ -1402,12 +1518,13 @@ void InjectedBundlePage::willRunJavaScriptPrompt(WKStringRef message, WKStringRe
stringBuilder.appendLiteral(", default text: ");
stringBuilder.append(toWTFString(defaultValue));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ InjectedBundle::singleton().outputText(stringBuilder.toString());
}
void InjectedBundlePage::didReachApplicationCacheOriginQuota(WKSecurityOriginRef origin, int64_t totalBytesNeeded)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpApplicationCacheDelegateCallbacks()) {
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpApplicationCacheDelegateCallbacks()) {
// For example, numbers from 30000 - 39999 will output as 30000.
// Rounding up or down does not really matter for these tests. It's
// sufficient to just get a range of 10000 to determine if we were
@@ -1420,36 +1537,37 @@ void InjectedBundlePage::didReachApplicationCacheOriginQuota(WKSecurityOriginRef
stringBuilder.appendLiteral(" totalSpaceNeeded:~");
stringBuilder.appendNumber(truncatedSpaceNeeded);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- if (InjectedBundle::shared().testRunner()->shouldDisallowIncreaseForApplicationCacheQuota())
+ if (injectedBundle.testRunner()->shouldDisallowIncreaseForApplicationCacheQuota())
return;
// Reset default application cache quota.
- WKBundleResetApplicationCacheOriginQuota(InjectedBundle::shared().bundle(), adoptWK(WKSecurityOriginCopyToString(origin)).get());
+ WKBundlePageResetApplicationCacheOriginQuota(injectedBundle.page()->page(), adoptWK(WKSecurityOriginCopyToString(origin)).get());
}
uint64_t InjectedBundlePage::didExceedDatabaseQuota(WKSecurityOriginRef origin, WKStringRef databaseName, WKStringRef databaseDisplayName, uint64_t currentQuotaBytes, uint64_t currentOriginUsageBytes, uint64_t currentDatabaseUsageBytes, uint64_t expectedUsageBytes)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpDatabaseCallbacks()) {
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpDatabaseCallbacks()) {
StringBuilder stringBuilder;
stringBuilder.appendLiteral("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:");
stringBuilder.append(securityOriginToStr(origin));
stringBuilder.appendLiteral(" database:");
stringBuilder.append(toWTFString(databaseName));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
uint64_t defaultQuota = 5 * 1024 * 1024;
- double testDefaultQuota = InjectedBundle::shared().testRunner()->databaseDefaultQuota();
+ double testDefaultQuota = injectedBundle.testRunner()->databaseDefaultQuota();
if (testDefaultQuota >= 0)
defaultQuota = testDefaultQuota;
unsigned long long newQuota = defaultQuota;
- double maxQuota = InjectedBundle::shared().testRunner()->databaseMaxQuota();
+ double maxQuota = injectedBundle.testRunner()->databaseMaxQuota();
if (maxQuota >= 0) {
if (defaultQuota < expectedUsageBytes && expectedUsageBytes <= maxQuota) {
newQuota = expectedUsageBytes;
@@ -1458,7 +1576,7 @@ uint64_t InjectedBundlePage::didExceedDatabaseQuota(WKSecurityOriginRef origin,
stringBuilder.appendLiteral("UI DELEGATE DATABASE CALLBACK: increased quota to ");
stringBuilder.appendNumber(newQuota);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
}
return newQuota;
@@ -1523,37 +1641,40 @@ void InjectedBundlePage::didChangeSelection(WKBundlePageRef page, WKStringRef no
bool InjectedBundlePage::shouldBeginEditing(WKBundleRangeHandleRef range)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return true;
- if (InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks()) {
+ if (injectedBundle.testRunner()->shouldDumpEditingCallbacks()) {
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: shouldBeginEditingInDOMRange:");
stringBuilder.append(rangeToStr(m_page, m_world.get(), range));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- return InjectedBundle::shared().testRunner()->shouldAllowEditing();
+ return injectedBundle.testRunner()->shouldAllowEditing();
}
bool InjectedBundlePage::shouldEndEditing(WKBundleRangeHandleRef range)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return true;
- if (InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks()) {
+ if (injectedBundle.testRunner()->shouldDumpEditingCallbacks()) {
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: shouldEndEditingInDOMRange:");
stringBuilder.append(rangeToStr(m_page, m_world.get(), range));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- return InjectedBundle::shared().testRunner()->shouldAllowEditing();
+ return injectedBundle.testRunner()->shouldAllowEditing();
}
bool InjectedBundlePage::shouldInsertNode(WKBundleNodeHandleRef node, WKBundleRangeHandleRef rangeToReplace, WKInsertActionType action)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return true;
static const char* insertactionstring[] = {
@@ -1562,7 +1683,7 @@ bool InjectedBundlePage::shouldInsertNode(WKBundleNodeHandleRef node, WKBundleRa
"WebViewInsertActionDropped",
};
- if (InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks()) {
+ if (injectedBundle.testRunner()->shouldDumpEditingCallbacks()) {
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: shouldInsertNode:");
stringBuilder.append(dumpPath(m_page, m_world.get(), node));
@@ -1571,14 +1692,15 @@ bool InjectedBundlePage::shouldInsertNode(WKBundleNodeHandleRef node, WKBundleRa
stringBuilder.appendLiteral(" givenAction:");
stringBuilder.append(insertactionstring[action]);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- return InjectedBundle::shared().testRunner()->shouldAllowEditing();
+ return injectedBundle.testRunner()->shouldAllowEditing();
}
bool InjectedBundlePage::shouldInsertText(WKStringRef text, WKBundleRangeHandleRef rangeToReplace, WKInsertActionType action)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return true;
static const char *insertactionstring[] = {
@@ -1587,7 +1709,7 @@ bool InjectedBundlePage::shouldInsertText(WKStringRef text, WKBundleRangeHandleR
"WebViewInsertActionDropped",
};
- if (InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks()) {
+ if (injectedBundle.testRunner()->shouldDumpEditingCallbacks()) {
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: shouldInsertText:");
stringBuilder.append(toWTFString(text));
@@ -1596,29 +1718,31 @@ bool InjectedBundlePage::shouldInsertText(WKStringRef text, WKBundleRangeHandleR
stringBuilder.appendLiteral(" givenAction:");
stringBuilder.append(insertactionstring[action]);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- return InjectedBundle::shared().testRunner()->shouldAllowEditing();
+ return injectedBundle.testRunner()->shouldAllowEditing();
}
bool InjectedBundlePage::shouldDeleteRange(WKBundleRangeHandleRef range)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return true;
- if (InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks()) {
+ if (injectedBundle.testRunner()->shouldDumpEditingCallbacks()) {
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: shouldDeleteDOMRange:");
stringBuilder.append(rangeToStr(m_page, m_world.get(), range));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- return InjectedBundle::shared().testRunner()->shouldAllowEditing();
+ return injectedBundle.testRunner()->shouldAllowEditing();
}
bool InjectedBundlePage::shouldChangeSelectedRange(WKBundleRangeHandleRef fromRange, WKBundleRangeHandleRef toRange, WKAffinityType affinity, bool stillSelecting)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return true;
static const char *affinitystring[] = {
@@ -1630,7 +1754,7 @@ bool InjectedBundlePage::shouldChangeSelectedRange(WKBundleRangeHandleRef fromRa
"TRUE"
};
- if (InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks()) {
+ if (injectedBundle.testRunner()->shouldDumpEditingCallbacks()) {
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: shouldChangeSelectedDOMRange:");
stringBuilder.append(rangeToStr(m_page, m_world.get(), fromRange));
@@ -1641,98 +1765,105 @@ bool InjectedBundlePage::shouldChangeSelectedRange(WKBundleRangeHandleRef fromRa
stringBuilder.appendLiteral(" stillSelecting:");
stringBuilder.append(boolstring[stillSelecting]);
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- return InjectedBundle::shared().testRunner()->shouldAllowEditing();
+ return injectedBundle.testRunner()->shouldAllowEditing();
}
bool InjectedBundlePage::shouldApplyStyle(WKBundleCSSStyleDeclarationRef style, WKBundleRangeHandleRef range)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return true;
- if (InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks()) {
+ if (injectedBundle.testRunner()->shouldDumpEditingCallbacks()) {
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: shouldApplyStyle:");
stringBuilder.append(styleDecToStr(style));
stringBuilder.appendLiteral(" toElementsInDOMRange:");
stringBuilder.append(rangeToStr(m_page, m_world.get(), range));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
- return InjectedBundle::shared().testRunner()->shouldAllowEditing();
+ return injectedBundle.testRunner()->shouldAllowEditing();
}
void InjectedBundlePage::didBeginEditing(WKStringRef notificationName)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpEditingCallbacks())
return;
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: webViewDidBeginEditing:");
stringBuilder.append(toWTFString(notificationName));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::didEndEditing(WKStringRef notificationName)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpEditingCallbacks())
return;
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: webViewDidEndEditing:");
stringBuilder.append(toWTFString(notificationName));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::didChange(WKStringRef notificationName)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpEditingCallbacks())
return;
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: webViewDidChange:");
stringBuilder.append(toWTFString(notificationName));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
void InjectedBundlePage::didChangeSelection(WKStringRef notificationName)
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (!InjectedBundle::shared().testRunner()->shouldDumpEditingCallbacks())
+ if (!injectedBundle.testRunner()->shouldDumpEditingCallbacks())
return;
StringBuilder stringBuilder;
stringBuilder.appendLiteral("EDITING DELEGATE: webViewDidChangeSelection:");
stringBuilder.append(toWTFString(notificationName));
stringBuilder.append('\n');
- InjectedBundle::shared().outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString());
}
#if ENABLE(FULLSCREEN_API)
bool InjectedBundlePage::supportsFullScreen(WKBundlePageRef pageRef, WKFullScreenKeyboardRequestType requestType)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpFullScreenCallbacks())
- InjectedBundle::shared().outputText("supportsFullScreen() == true\n");
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpFullScreenCallbacks())
+ injectedBundle.outputText("supportsFullScreen() == true\n");
return true;
}
void InjectedBundlePage::enterFullScreenForElement(WKBundlePageRef pageRef, WKBundleNodeHandleRef elementRef)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpFullScreenCallbacks())
- InjectedBundle::shared().outputText("enterFullScreenForElement()\n");
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpFullScreenCallbacks())
+ injectedBundle.outputText("enterFullScreenForElement()\n");
- if (!InjectedBundle::shared().testRunner()->hasCustomFullScreenBehavior()) {
+ if (!injectedBundle.testRunner()->hasCustomFullScreenBehavior()) {
WKBundlePageWillEnterFullScreen(pageRef);
WKBundlePageDidEnterFullScreen(pageRef);
}
@@ -1740,10 +1871,11 @@ void InjectedBundlePage::enterFullScreenForElement(WKBundlePageRef pageRef, WKBu
void InjectedBundlePage::exitFullScreenForElement(WKBundlePageRef pageRef, WKBundleNodeHandleRef elementRef)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpFullScreenCallbacks())
- InjectedBundle::shared().outputText("exitFullScreenForElement()\n");
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpFullScreenCallbacks())
+ injectedBundle.outputText("exitFullScreenForElement()\n");
- if (!InjectedBundle::shared().testRunner()->hasCustomFullScreenBehavior()) {
+ if (!injectedBundle.testRunner()->hasCustomFullScreenBehavior()) {
WKBundlePageWillExitFullScreen(pageRef);
WKBundlePageDidExitFullScreen(pageRef);
}
@@ -1751,22 +1883,25 @@ void InjectedBundlePage::exitFullScreenForElement(WKBundlePageRef pageRef, WKBun
void InjectedBundlePage::beganEnterFullScreen(WKBundlePageRef, WKRect, WKRect)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpFullScreenCallbacks())
- InjectedBundle::shared().outputText("beganEnterFullScreen()\n");
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpFullScreenCallbacks())
+ injectedBundle.outputText("beganEnterFullScreen()\n");
}
void InjectedBundlePage::beganExitFullScreen(WKBundlePageRef, WKRect, WKRect)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpFullScreenCallbacks())
- InjectedBundle::shared().outputText("beganExitFullScreen()\n");
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpFullScreenCallbacks())
+ injectedBundle.outputText("beganExitFullScreen()\n");
}
void InjectedBundlePage::closeFullScreen(WKBundlePageRef pageRef)
{
- if (InjectedBundle::shared().testRunner()->shouldDumpFullScreenCallbacks())
- InjectedBundle::shared().outputText("closeFullScreen()\n");
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (injectedBundle.testRunner()->shouldDumpFullScreenCallbacks())
+ injectedBundle.outputText("closeFullScreen()\n");
- if (!InjectedBundle::shared().testRunner()->hasCustomFullScreenBehavior()) {
+ if (!injectedBundle.testRunner()->hasCustomFullScreenBehavior()) {
WKBundlePageWillExitFullScreen(pageRef);
WKBundlePageDidExitFullScreen(pageRef);
}
@@ -1862,31 +1997,37 @@ void InjectedBundlePage::dumpBackForwardList(StringBuilder& stringBuilder)
stringBuilder.appendLiteral("===============================================\n");
}
-#if !PLATFORM(MAC)
+#if !PLATFORM(COCOA)
void InjectedBundlePage::platformDidStartProvisionalLoadForFrame(WKBundleFrameRef)
{
}
+
+String InjectedBundlePage::platformResponseMimeType(WKURLResponseRef)
+{
+ return String();
+}
#endif
void InjectedBundlePage::frameDidChangeLocation(WKBundleFrameRef frame, bool shouldDump)
{
- if (frame != InjectedBundle::shared().topLoadingFrame())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (frame != injectedBundle.topLoadingFrame())
return;
- InjectedBundle::shared().setTopLoadingFrame(0);
+ injectedBundle.setTopLoadingFrame(nullptr);
- if (InjectedBundle::shared().testRunner()->waitToDump())
+ if (injectedBundle.testRunner()->waitToDump())
return;
- if (InjectedBundle::shared().shouldProcessWorkQueue()) {
- InjectedBundle::shared().processWorkQueue();
+ if (injectedBundle.shouldProcessWorkQueue()) {
+ injectedBundle.processWorkQueue();
return;
}
if (shouldDump)
- InjectedBundle::shared().page()->dump();
+ injectedBundle.page()->dump();
else
- InjectedBundle::shared().done();
+ injectedBundle.done();
}
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
index f01b50b54..746fc33c5 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
@@ -26,9 +26,9 @@
#ifndef InjectedBundlePage_h
#define InjectedBundlePage_h
-#include <WebKit2/WKBundlePage.h>
-#include <WebKit2/WKBundleScriptWorld.h>
-#include <WebKit2/WKRetainPtr.h>
+#include <WebKit/WKBundlePage.h>
+#include <WebKit/WKBundleScriptWorld.h>
+#include <WebKit/WKRetainPtr.h>
#include <wtf/text/WTFString.h>
namespace WTR {
@@ -169,6 +169,7 @@ private:
void dumpDOMAsWebArchive(WKBundleFrameRef, WTF::StringBuilder&);
void platformDidStartProvisionalLoadForFrame(WKBundleFrameRef);
+ String platformResponseMimeType(WKURLResponseRef);
void frameDidChangeLocation(WKBundleFrameRef, bool shouldDump = false);
diff --git a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
index 2b30f5df6..6f7eb0c07 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,20 +33,22 @@
#include "StringFunctions.h"
#include "TestController.h"
#include <JavaScriptCore/JSCTestRunnerUtils.h>
-#include <WebKit2/WKBundle.h>
-#include <WebKit2/WKBundleBackForwardList.h>
-#include <WebKit2/WKBundleFrame.h>
-#include <WebKit2/WKBundleFramePrivate.h>
-#include <WebKit2/WKBundleInspector.h>
-#include <WebKit2/WKBundleNodeHandlePrivate.h>
-#include <WebKit2/WKBundlePage.h>
-#include <WebKit2/WKBundlePagePrivate.h>
-#include <WebKit2/WKBundlePrivate.h>
-#include <WebKit2/WKBundleScriptWorld.h>
-#include <WebKit2/WKData.h>
-#include <WebKit2/WKRetainPtr.h>
-#include <WebKit2/WKSerializedScriptValue.h>
-#include <WebKit2/WebKit2_C.h>
+#include <WebCore/ResourceLoadObserver.h>
+#include <WebKit/WKBundle.h>
+#include <WebKit/WKBundleBackForwardList.h>
+#include <WebKit/WKBundleFrame.h>
+#include <WebKit/WKBundleFramePrivate.h>
+#include <WebKit/WKBundleInspector.h>
+#include <WebKit/WKBundleNodeHandlePrivate.h>
+#include <WebKit/WKBundlePage.h>
+#include <WebKit/WKBundlePagePrivate.h>
+#include <WebKit/WKBundlePrivate.h>
+#include <WebKit/WKBundleScriptWorld.h>
+#include <WebKit/WKData.h>
+#include <WebKit/WKPagePrivate.h>
+#include <WebKit/WKRetainPtr.h>
+#include <WebKit/WKSerializedScriptValue.h>
+#include <WebKit/WebKit2_C.h>
#include <wtf/CurrentTime.h>
#include <wtf/HashMap.h>
#include <wtf/StdLibExtras.h>
@@ -55,11 +57,9 @@
namespace WTR {
-const double TestRunner::waitToDumpWatchdogTimerInterval = 30;
-
-PassRefPtr<TestRunner> TestRunner::create()
+Ref<TestRunner> TestRunner::create()
{
- return adoptRef(new TestRunner);
+ return adoptRef(*new TestRunner);
}
TestRunner::TestRunner()
@@ -93,10 +93,14 @@ TestRunner::TestRunner()
, m_policyDelegatePermissive(false)
, m_globalFlag(false)
, m_customFullScreenBehavior(false)
+ , m_timeout(30000)
, m_databaseDefaultQuota(-1)
, m_databaseMaxQuota(-1)
, m_userStyleSheetEnabled(false)
, m_userStyleSheetLocation(adoptWK(WKStringCreateWithUTF8CString("")))
+#if PLATFORM(GTK)
+ , m_waitToDumpWatchdogTimer(RunLoop::main(), this, &TestRunner::waitToDumpWatchdogTimerFired)
+#endif
{
platformInitialize();
}
@@ -112,7 +116,7 @@ JSClassRef TestRunner::wrapperClass()
void TestRunner::display()
{
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
WKBundlePageForceRepaint(page);
WKBundlePageSetTracksRepaints(page, true);
WKBundlePageResetTrackedRepaints(page);
@@ -130,7 +134,7 @@ void TestRunner::setCustomPolicyDelegate(bool enabled, bool permissive)
m_policyDelegateEnabled = enabled;
m_policyDelegatePermissive = permissive;
- InjectedBundle::shared().setCustomPolicyDelegate(enabled, permissive);
+ InjectedBundle::singleton().setCustomPolicyDelegate(enabled, permissive);
}
void TestRunner::waitForPolicyDelegate()
@@ -139,42 +143,58 @@ void TestRunner::waitForPolicyDelegate()
waitUntilDone();
}
+void TestRunner::waitUntilDownloadFinished()
+{
+ m_shouldFinishAfterDownload = true;
+ waitUntilDone();
+}
+
void TestRunner::waitUntilDone()
{
m_waitToDump = true;
- if (InjectedBundle::shared().useWaitToDumpWatchdogTimer())
+ if (InjectedBundle::singleton().useWaitToDumpWatchdogTimer())
initializeWaitToDumpWatchdogTimerIfNeeded();
}
void TestRunner::waitToDumpWatchdogTimerFired()
{
invalidateWaitToDumpWatchdogTimer();
- InjectedBundle::shared().outputText("FAIL: Timed out waiting for notifyDone to be called\n\n");
- InjectedBundle::shared().done();
+ auto& injectedBundle = InjectedBundle::singleton();
+#if PLATFORM(COCOA)
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "#PID UNRESPONSIVE - %s (pid %d)\n", getprogname(), getpid());
+ injectedBundle.outputText(buffer);
+#endif
+ injectedBundle.outputText("FAIL: Timed out waiting for notifyDone to be called\n\n");
+ injectedBundle.done();
}
void TestRunner::notifyDone()
{
- if (!InjectedBundle::shared().isTestRunning())
+ auto& injectedBundle = InjectedBundle::singleton();
+ if (!injectedBundle.isTestRunning())
return;
- if (m_waitToDump && !InjectedBundle::shared().topLoadingFrame())
- InjectedBundle::shared().page()->dump();
+ if (m_waitToDump && !injectedBundle.topLoadingFrame())
+ injectedBundle.page()->dump();
+
+ // We don't call invalidateWaitToDumpWatchdogTimer() here, even if we continue to wait for a load to finish.
+ // The test is still subject to timeout checking - it is better to detect an async timeout inside WebKitTestRunner
+ // than to let webkitpy do that, because WebKitTestRunner will dump partial results.
m_waitToDump = false;
}
-void TestRunner::setCustomTimeout(int timeout)
+unsigned TestRunner::imageCountInGeneralPasteboard() const
{
- m_timeout = timeout;
+ return InjectedBundle::singleton().imageCountInGeneralPasteboard();
}
void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
{
WKRetainPtr<WKStringRef> sourceWK = toWK(source);
- WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld());
- WKBundleAddUserScript(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), scriptWorld.get(), sourceWK.get(), 0, 0, 0,
+ WKBundlePageAddUserScript(InjectedBundle::singleton().page()->page(), sourceWK.get(),
(runAtStart ? kWKInjectAtDocumentStart : kWKInjectAtDocumentEnd),
(allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly));
}
@@ -182,27 +202,27 @@ void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFram
void TestRunner::addUserStyleSheet(JSStringRef source, bool allFrames)
{
WKRetainPtr<WKStringRef> sourceWK = toWK(source);
- WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld());
- WKBundleAddUserStyleSheet(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), scriptWorld.get(), sourceWK.get(), 0, 0, 0,
+ WKBundlePageAddUserStyleSheet(InjectedBundle::singleton().page()->page(), sourceWK.get(),
(allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly));
}
void TestRunner::keepWebHistory()
{
- WKBundleSetShouldTrackVisitedLinks(InjectedBundle::shared().bundle(), true);
+ InjectedBundle::singleton().postSetAddsVisitedLinks(true);
}
void TestRunner::execCommand(JSStringRef name, JSStringRef argument)
{
- WKBundlePageExecuteEditingCommand(InjectedBundle::shared().page()->page(), toWK(name).get(), toWK(argument).get());
+ WKBundlePageExecuteEditingCommand(InjectedBundle::singleton().page()->page(), toWK(name).get(), toWK(argument).get());
}
bool TestRunner::findString(JSStringRef target, JSValueRef optionsArrayAsValue)
{
WKFindOptions options = 0;
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page());
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
JSRetainPtr<JSStringRef> lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length"));
JSObjectRef optionsArray = JSValueToObject(context, optionsArrayAsValue, 0);
@@ -233,37 +253,42 @@ bool TestRunner::findString(JSStringRef target, JSValueRef optionsArrayAsValue)
}
}
- return WKBundlePageFindString(InjectedBundle::shared().page()->page(), toWK(target).get(), options);
+ return WKBundlePageFindString(injectedBundle.page()->page(), toWK(target).get(), options);
}
void TestRunner::clearAllDatabases()
{
- WKBundleClearAllDatabases(InjectedBundle::shared().bundle());
+ WKBundleClearAllDatabases(InjectedBundle::singleton().bundle());
+
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("DeleteAllIndexedDatabases"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(true));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
}
void TestRunner::setDatabaseQuota(uint64_t quota)
{
- return WKBundleSetDatabaseQuota(InjectedBundle::shared().bundle(), quota);
+ return WKBundleSetDatabaseQuota(InjectedBundle::singleton().bundle(), quota);
}
void TestRunner::clearAllApplicationCaches()
{
- WKBundleClearApplicationCache(InjectedBundle::shared().bundle());
+ WKBundlePageClearApplicationCache(InjectedBundle::singleton().page()->page());
}
void TestRunner::clearApplicationCacheForOrigin(JSStringRef origin)
{
- WKBundleClearApplicationCacheForOrigin(InjectedBundle::shared().bundle(), toWK(origin).get());
+ WKBundlePageClearApplicationCacheForOrigin(InjectedBundle::singleton().page()->page(), toWK(origin).get());
}
void TestRunner::setAppCacheMaximumSize(uint64_t size)
{
- WKBundleSetAppCacheMaximumSize(InjectedBundle::shared().bundle(), size);
+ WKBundlePageSetAppCacheMaximumSize(InjectedBundle::singleton().page()->page(), size);
}
long long TestRunner::applicationCacheDiskUsageForOrigin(JSStringRef origin)
{
- return WKBundleGetAppCacheUsageForOrigin(InjectedBundle::shared().bundle(), toWK(origin).get());
+ return WKBundlePageGetAppCacheUsageForOrigin(InjectedBundle::singleton().page()->page(), toWK(origin).get());
}
void TestRunner::disallowIncreaseForApplicationCacheQuota()
@@ -275,21 +300,24 @@ static inline JSValueRef stringArrayToJS(JSContextRef context, WKArrayRef string
{
const size_t count = WKArrayGetSize(strings);
- auto jsStringsArray = std::make_unique<JSValueRef[]>(count);
+ JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0);
+ JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0);
for (size_t i = 0; i < count; ++i) {
WKStringRef stringRef = static_cast<WKStringRef>(WKArrayGetItemAtIndex(strings, i));
JSRetainPtr<JSStringRef> stringJS = toJS(stringRef);
- jsStringsArray[i] = JSValueMakeString(context, stringJS.get());
+ JSObjectSetPropertyAtIndex(context, arrayObj, i, JSValueMakeString(context, stringJS.get()), 0);
}
- return JSObjectMakeArray(context, count, jsStringsArray.get(), 0);
+ return arrayResult;
}
JSValueRef TestRunner::originsWithApplicationCache()
{
- WKRetainPtr<WKArrayRef> origins(AdoptWK, WKBundleCopyOriginsWithApplicationCache(InjectedBundle::shared().bundle()));
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
+
+ WKRetainPtr<WKArrayRef> origins(AdoptWK, WKBundlePageCopyOriginsWithApplicationCache(page));
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
return stringArrayToJS(context, origins.get());
@@ -297,70 +325,174 @@ JSValueRef TestRunner::originsWithApplicationCache()
bool TestRunner::isCommandEnabled(JSStringRef name)
{
- return WKBundlePageIsEditingCommandEnabled(InjectedBundle::shared().page()->page(), toWK(name).get());
+ return WKBundlePageIsEditingCommandEnabled(InjectedBundle::singleton().page()->page(), toWK(name).get());
}
void TestRunner::setCanOpenWindows(bool)
{
- // It's not clear if or why any tests require opening windows be forbidden.
- // For now, just ignore this setting, and if we find later it's needed we can add it.
+ // The test plugins/get-url-with-blank-target.html requires that the embedding client forbid
+ // opening windows (by omitting a call to this function) so as to test that NPN_GetURL()
+ // with a blank target will return an error.
+ //
+ // It is not clear if we should implement this functionality or remove it and plugins/get-url-with-blank-target.html
+ // per the remark in <https://trac.webkit.org/changeset/64504/trunk/LayoutTests/platform/mac-wk2/Skipped>.
+ // For now, just ignore this setting.
}
void TestRunner::setXSSAuditorEnabled(bool enabled)
{
WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitXSSAuditorEnabled"));
- WKBundleOverrideBoolPreferenceForTestRunner(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), key.get(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setShadowDOMEnabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitShadowDOMEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setCustomElementsEnabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitCustomElementsEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setSubtleCryptoEnabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitSubtleCryptoEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setMediaStreamEnabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitMediaStreamEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setPeerConnectionEnabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitPeerConnectionEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setModernMediaControlsEnabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitModernMediaControlsEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setWebGL2Enabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitWebGL2Enabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setFetchAPIEnabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitFetchAPIEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setDownloadAttributeEnabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitDownloadAttributeEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setEncryptedMediaAPIEnabled(bool enabled)
+{
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitEncryptedMediaAPIEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
+void TestRunner::setAllowsAnySSLCertificate(bool enabled)
+{
+ InjectedBundle::singleton().setAllowsAnySSLCertificate(enabled);
}
void TestRunner::setAllowUniversalAccessFromFileURLs(bool enabled)
{
- WKBundleSetAllowUniversalAccessFromFileURLs(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetAllowUniversalAccessFromFileURLs(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled);
}
void TestRunner::setAllowFileAccessFromFileURLs(bool enabled)
{
- WKBundleSetAllowFileAccessFromFileURLs(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetAllowFileAccessFromFileURLs(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled);
}
+void TestRunner::setNeedsStorageAccessFromFileURLsQuirk(bool needsQuirk)
+{
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetAllowStorageAccessFromFileURLS(injectedBundle.bundle(), injectedBundle.pageGroup(), needsQuirk);
+}
+
void TestRunner::setPluginsEnabled(bool enabled)
{
- WKBundleSetPluginsEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled);
+ WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitPluginsEnabled"));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
}
void TestRunner::setJavaScriptCanAccessClipboard(bool enabled)
{
- WKBundleSetJavaScriptCanAccessClipboard(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetJavaScriptCanAccessClipboard(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled);
}
void TestRunner::setPrivateBrowsingEnabled(bool enabled)
{
- WKBundleSetPrivateBrowsingEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetPrivateBrowsingEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled);
}
+void TestRunner::setUseDashboardCompatibilityMode(bool enabled)
+{
+#if ENABLE(DASHBOARD_SUPPORT)
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetUseDashboardCompatibilityMode(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled);
+#endif
+}
+
void TestRunner::setPopupBlockingEnabled(bool enabled)
{
- WKBundleSetPopupBlockingEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetPopupBlockingEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled);
}
void TestRunner::setAuthorAndUserStylesEnabled(bool enabled)
{
- WKBundleSetAuthorAndUserStylesEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetAuthorAndUserStylesEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled);
}
void TestRunner::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
{
- WKBundleAddOriginAccessWhitelistEntry(InjectedBundle::shared().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains);
+ WKBundleAddOriginAccessWhitelistEntry(InjectedBundle::singleton().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains);
}
void TestRunner::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
{
- WKBundleRemoveOriginAccessWhitelistEntry(InjectedBundle::shared().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains);
+ WKBundleRemoveOriginAccessWhitelistEntry(InjectedBundle::singleton().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains);
}
bool TestRunner::isPageBoxVisible(int pageIndex)
{
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
- return WKBundleIsPageBoxVisible(InjectedBundle::shared().bundle(), mainFrame, pageIndex);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page());
+ return WKBundleIsPageBoxVisible(injectedBundle.bundle(), mainFrame, pageIndex);
}
void TestRunner::setValueForUser(JSContextRef context, JSValueRef element, JSStringRef value)
@@ -374,21 +506,22 @@ void TestRunner::setValueForUser(JSContextRef context, JSValueRef element, JSStr
void TestRunner::setAudioResult(JSContextRef context, JSValueRef data)
{
+ auto& injectedBundle = InjectedBundle::singleton();
// FIXME (123058): Use a JSC API to get buffer contents once such is exposed.
- WKRetainPtr<WKDataRef> audioData(AdoptWK, WKBundleCreateWKDataFromUInt8Array(InjectedBundle::shared().bundle(), context, data));
- InjectedBundle::shared().setAudioResult(audioData.get());
+ WKRetainPtr<WKDataRef> audioData(AdoptWK, WKBundleCreateWKDataFromUInt8Array(injectedBundle.bundle(), context, data));
+ injectedBundle.setAudioResult(audioData.get());
m_whatToDump = Audio;
m_dumpPixels = false;
}
unsigned TestRunner::windowCount()
{
- return InjectedBundle::shared().pageCount();
+ return InjectedBundle::singleton().pageCount();
}
void TestRunner::clearBackForwardList()
{
- WKBundleBackForwardListClear(WKBundlePageGetBackForwardList(InjectedBundle::shared().page()->page()));
+ WKBundleBackForwardListClear(WKBundlePageGetBackForwardList(InjectedBundle::singleton().page()->page()));
}
// Object Creation
@@ -400,24 +533,18 @@ void TestRunner::makeWindowObject(JSContextRef context, JSObjectRef windowObject
void TestRunner::showWebInspector()
{
-#if ENABLE(INSPECTOR)
- WKBundleInspectorShow(WKBundlePageGetInspector(InjectedBundle::shared().page()->page()));
-#endif // ENABLE(INSPECTOR)
+ WKBundleInspectorShow(WKBundlePageGetInspector(InjectedBundle::singleton().page()->page()));
}
void TestRunner::closeWebInspector()
{
-#if ENABLE(INSPECTOR)
- WKBundleInspectorClose(WKBundlePageGetInspector(InjectedBundle::shared().page()->page()));
-#endif // ENABLE(INSPECTOR)
+ WKBundleInspectorClose(WKBundlePageGetInspector(InjectedBundle::singleton().page()->page()));
}
-void TestRunner::evaluateInWebInspector(long callID, JSStringRef script)
+void TestRunner::evaluateInWebInspector(JSStringRef script)
{
-#if ENABLE(INSPECTOR)
WKRetainPtr<WKStringRef> scriptWK = toWK(script);
- WKBundleInspectorEvaluateScriptForTest(WKBundlePageGetInspector(InjectedBundle::shared().page()->page()), callID, scriptWK.get());
-#endif // ENABLE(INSPECTOR)
+ WKBundleInspectorEvaluateScriptForTest(WKBundlePageGetInspector(InjectedBundle::singleton().page()->page()), scriptWK.get());
}
typedef WTF::HashMap<unsigned, WKRetainPtr<WKBundleScriptWorldRef> > WorldMap;
@@ -454,7 +581,7 @@ void TestRunner::evaluateScriptInIsolatedWorld(JSContextRef context, unsigned wo
WKBundleFrameRef frame = WKBundleFrameForJavaScriptContext(context);
if (!frame)
- frame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ frame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
JSGlobalContextRef jsContext = WKBundleFrameGetJavaScriptContextForWorld(frame, world.get());
JSEvaluateScript(jsContext, script, 0, 0, 0, 0);
@@ -469,35 +596,28 @@ void TestRunner::setPOSIXLocale(JSStringRef locale)
void TestRunner::setTextDirection(JSStringRef direction)
{
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
return WKBundleFrameSetTextDirection(mainFrame, toWK(direction).get());
}
void TestRunner::setShouldStayOnPageAfterHandlingBeforeUnload(bool shouldStayOnPage)
{
- InjectedBundle::shared().postNewBeforeUnloadReturnValue(!shouldStayOnPage);
+ InjectedBundle::singleton().postNewBeforeUnloadReturnValue(!shouldStayOnPage);
}
void TestRunner::setDefersLoading(bool shouldDeferLoading)
{
- WKBundlePageSetDefersLoading(InjectedBundle::shared().page()->page(), shouldDeferLoading);
+ WKBundlePageSetDefersLoading(InjectedBundle::singleton().page()->page(), shouldDeferLoading);
}
void TestRunner::setPageVisibility(JSStringRef state)
{
- WKPageVisibilityState visibilityState = kWKPageVisibilityStateVisible;
-
- if (JSStringIsEqualToUTF8CString(state, "hidden"))
- visibilityState = kWKPageVisibilityStateHidden;
- else if (JSStringIsEqualToUTF8CString(state, "prerender"))
- visibilityState = kWKPageVisibilityStatePrerender;
-
- InjectedBundle::shared().setVisibilityState(visibilityState, false);
+ InjectedBundle::singleton().setHidden(JSStringIsEqualToUTF8CString(state, "hidden") || JSStringIsEqualToUTF8CString(state, "prerender"));
}
void TestRunner::resetPageVisibility()
{
- InjectedBundle::shared().setVisibilityState(kWKPageVisibilityStateVisible, true);
+ InjectedBundle::singleton().setHidden(false);
}
typedef WTF::HashMap<unsigned, JSValueRef> CallbackMap;
@@ -511,7 +631,13 @@ enum {
AddChromeInputFieldCallbackID = 1,
RemoveChromeInputFieldCallbackID,
FocusWebViewCallbackID,
- SetBackingScaleFactorCallbackID
+ SetBackingScaleFactorCallbackID,
+ DidBeginSwipeCallbackID,
+ WillEndSwipeCallbackID,
+ DidEndSwipeCallbackID,
+ DidRemoveSwipeSnapshotCallbackID,
+ StatisticsDidModifyDataRecordsCallbackID,
+ FirstUIScriptCallbackID = 100
};
static void cacheTestRunnerCallback(unsigned index, JSValueRef callback)
@@ -519,50 +645,77 @@ static void cacheTestRunnerCallback(unsigned index, JSValueRef callback)
if (!callback)
return;
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ if (callbackMap().contains(index)) {
+ InjectedBundle::singleton().outputText(String::format("FAIL: Tried to install a second TestRunner callback for the same event (id %d)\n\n", index));
+ return;
+ }
+
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
JSValueProtect(context, callback);
callbackMap().add(index, callback);
}
-static void callTestRunnerCallback(unsigned index)
+static void callTestRunnerCallback(unsigned index, size_t argumentCount = 0, const JSValueRef arguments[] = nullptr)
{
if (!callbackMap().contains(index))
return;
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
JSObjectRef callback = JSValueToObject(context, callbackMap().take(index), 0);
- JSObjectCallAsFunction(context, callback, JSContextGetGlobalObject(context), 0, 0, 0);
+ JSObjectCallAsFunction(context, callback, JSContextGetGlobalObject(context), argumentCount, arguments, 0);
JSValueUnprotect(context, callback);
}
+void TestRunner::clearTestRunnerCallbacks()
+{
+ for (auto& iter : callbackMap()) {
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
+ JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+ JSObjectRef callback = JSValueToObject(context, iter.value, 0);
+ JSValueUnprotect(context, callback);
+ }
+
+ callbackMap().clear();
+}
+
+void TestRunner::accummulateLogsForChannel(JSStringRef)
+{
+ // FIXME: Implement getting the call to all processes.
+}
+
void TestRunner::addChromeInputField(JSValueRef callback)
{
cacheTestRunnerCallback(AddChromeInputFieldCallbackID, callback);
- InjectedBundle::shared().postAddChromeInputField();
+ InjectedBundle::singleton().postAddChromeInputField();
}
void TestRunner::removeChromeInputField(JSValueRef callback)
{
cacheTestRunnerCallback(RemoveChromeInputFieldCallbackID, callback);
- InjectedBundle::shared().postRemoveChromeInputField();
+ InjectedBundle::singleton().postRemoveChromeInputField();
}
void TestRunner::focusWebView(JSValueRef callback)
{
cacheTestRunnerCallback(FocusWebViewCallbackID, callback);
- InjectedBundle::shared().postFocusWebView();
+ InjectedBundle::singleton().postFocusWebView();
}
void TestRunner::setBackingScaleFactor(double backingScaleFactor, JSValueRef callback)
{
cacheTestRunnerCallback(SetBackingScaleFactorCallbackID, callback);
- InjectedBundle::shared().postSetBackingScaleFactor(backingScaleFactor);
+ InjectedBundle::singleton().postSetBackingScaleFactor(backingScaleFactor);
}
void TestRunner::setWindowIsKey(bool isKey)
{
- InjectedBundle::shared().postSetWindowIsKey(isKey);
+ InjectedBundle::singleton().postSetWindowIsKey(isKey);
+}
+
+void TestRunner::setViewSize(double width, double height)
+{
+ InjectedBundle::singleton().postSetViewSize(width, height);
}
void TestRunner::callAddChromeInputFieldCallback()
@@ -592,13 +745,18 @@ static inline bool toBool(JSStringRef value)
void TestRunner::overridePreference(JSStringRef preference, JSStringRef value)
{
+ auto& injectedBundle = InjectedBundle::singleton();
// FIXME: handle non-boolean preferences.
- WKBundleOverrideBoolPreferenceForTestRunner(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), toWK(preference).get(), toBool(value));
+ WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), toWK(preference).get(), toBool(value));
}
void TestRunner::setAlwaysAcceptCookies(bool accept)
{
- WKBundleSetAlwaysAcceptCookies(InjectedBundle::shared().bundle(), accept);
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetAlwaysAcceptCookies"));
+
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(accept));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
}
double TestRunner::preciseTime()
@@ -612,7 +770,8 @@ void TestRunner::setUserStyleSheetEnabled(bool enabled)
WKRetainPtr<WKStringRef> emptyUrl = adoptWK(WKStringCreateWithUTF8CString(""));
WKStringRef location = enabled ? m_userStyleSheetLocation.get() : emptyUrl.get();
- WKBundleSetUserStyleSheetLocation(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), location);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetUserStyleSheetLocation(injectedBundle.bundle(), injectedBundle.pageGroup(), location);
}
void TestRunner::setUserStyleSheetLocation(JSStringRef location)
@@ -625,68 +784,81 @@ void TestRunner::setUserStyleSheetLocation(JSStringRef location)
void TestRunner::setSpatialNavigationEnabled(bool enabled)
{
- WKBundleSetSpatialNavigationEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetSpatialNavigationEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled);
}
void TestRunner::setTabKeyCyclesThroughElements(bool enabled)
{
- WKBundleSetTabKeyCyclesThroughElements(InjectedBundle::shared().bundle(), InjectedBundle::shared().page()->page(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetTabKeyCyclesThroughElements(injectedBundle.bundle(), injectedBundle.page()->page(), enabled);
}
void TestRunner::setSerializeHTTPLoads()
{
- WKBundleSetSerialLoadingEnabled(InjectedBundle::shared().bundle(), true);
+ // WK2 doesn't reorder loads.
}
void TestRunner::dispatchPendingLoadRequests()
{
- WKBundleDispatchPendingLoadRequests(InjectedBundle::shared().bundle());
+ // WK2 doesn't keep pending requests.
}
void TestRunner::setCacheModel(int model)
{
- WKBundleSetCacheModel(InjectedBundle::shared().bundle(), model);
+ InjectedBundle::singleton().setCacheModel(model);
}
void TestRunner::setAsynchronousSpellCheckingEnabled(bool enabled)
{
- WKBundleSetAsynchronousSpellCheckingEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetAsynchronousSpellCheckingEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled);
}
void TestRunner::grantWebNotificationPermission(JSStringRef origin)
{
WKRetainPtr<WKStringRef> originWK = toWK(origin);
- WKBundleSetWebNotificationPermission(InjectedBundle::shared().bundle(), InjectedBundle::shared().page()->page(), originWK.get(), true);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetWebNotificationPermission(injectedBundle.bundle(), injectedBundle.page()->page(), originWK.get(), true);
}
void TestRunner::denyWebNotificationPermission(JSStringRef origin)
{
WKRetainPtr<WKStringRef> originWK = toWK(origin);
- WKBundleSetWebNotificationPermission(InjectedBundle::shared().bundle(), InjectedBundle::shared().page()->page(), originWK.get(), false);
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleSetWebNotificationPermission(injectedBundle.bundle(), injectedBundle.page()->page(), originWK.get(), false);
}
void TestRunner::removeAllWebNotificationPermissions()
{
- WKBundleRemoveAllWebNotificationPermissions(InjectedBundle::shared().bundle(), InjectedBundle::shared().page()->page());
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleRemoveAllWebNotificationPermissions(injectedBundle.bundle(), injectedBundle.page()->page());
}
void TestRunner::simulateWebNotificationClick(JSValueRef notification)
{
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page());
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
- uint64_t notificationID = WKBundleGetWebNotificationID(InjectedBundle::shared().bundle(), context, notification);
- InjectedBundle::shared().postSimulateWebNotificationClick(notificationID);
+ uint64_t notificationID = WKBundleGetWebNotificationID(injectedBundle.bundle(), context, notification);
+ injectedBundle.postSimulateWebNotificationClick(notificationID);
}
void TestRunner::setGeolocationPermission(bool enabled)
{
// FIXME: this should be done by frame.
- InjectedBundle::shared().setGeolocationPermission(enabled);
+ InjectedBundle::singleton().setGeolocationPermission(enabled);
+}
+
+bool TestRunner::isGeolocationProviderActive()
+{
+ return InjectedBundle::singleton().isGeolocationProviderActive();
}
void TestRunner::setMockGeolocationPosition(double latitude, double longitude, double accuracy, JSValueRef jsAltitude, JSValueRef jsAltitudeAccuracy, JSValueRef jsHeading, JSValueRef jsSpeed)
{
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page());
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
bool providesAltitude = false;
@@ -717,38 +889,66 @@ void TestRunner::setMockGeolocationPosition(double latitude, double longitude, d
speed = JSValueToNumber(context, jsSpeed, 0);
}
- InjectedBundle::shared().setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed);
+ injectedBundle.setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed);
}
void TestRunner::setMockGeolocationPositionUnavailableError(JSStringRef message)
{
WKRetainPtr<WKStringRef> messageWK = toWK(message);
- InjectedBundle::shared().setMockGeolocationPositionUnavailableError(messageWK.get());
+ InjectedBundle::singleton().setMockGeolocationPositionUnavailableError(messageWK.get());
+}
+
+void TestRunner::setUserMediaPermission(bool enabled)
+{
+ // FIXME: this should be done by frame.
+ InjectedBundle::singleton().setUserMediaPermission(enabled);
+}
+
+void TestRunner::setUserMediaPersistentPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin)
+{
+ WKRetainPtr<WKStringRef> originWK = toWK(origin);
+ WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin);
+ InjectedBundle::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK.get(), parentOriginWK.get());
+}
+
+unsigned TestRunner::userMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) const
+{
+ WKRetainPtr<WKStringRef> originWK = toWK(origin);
+ WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin);
+ return InjectedBundle::singleton().userMediaPermissionRequestCountForOrigin(originWK.get(), parentOriginWK.get());
+}
+
+void TestRunner::resetUserMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin)
+{
+ WKRetainPtr<WKStringRef> originWK = toWK(origin);
+ WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin);
+ InjectedBundle::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK.get(), parentOriginWK.get());
}
bool TestRunner::callShouldCloseOnWebView()
{
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
return WKBundleFrameCallShouldCloseOnWebView(mainFrame);
}
void TestRunner::queueBackNavigation(unsigned howFarBackward)
{
- InjectedBundle::shared().queueBackNavigation(howFarBackward);
+ InjectedBundle::singleton().queueBackNavigation(howFarBackward);
}
void TestRunner::queueForwardNavigation(unsigned howFarForward)
{
- InjectedBundle::shared().queueForwardNavigation(howFarForward);
+ InjectedBundle::singleton().queueForwardNavigation(howFarForward);
}
-void TestRunner::queueLoad(JSStringRef url, JSStringRef target)
+void TestRunner::queueLoad(JSStringRef url, JSStringRef target, bool shouldOpenExternalURLs)
{
- WKRetainPtr<WKURLRef> baseURLWK(AdoptWK, WKBundleFrameCopyURL(WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page())));
+ auto& injectedBundle = InjectedBundle::singleton();
+ WKRetainPtr<WKURLRef> baseURLWK(AdoptWK, WKBundleFrameCopyURL(WKBundlePageGetMainFrame(injectedBundle.page()->page())));
WKRetainPtr<WKURLRef> urlWK(AdoptWK, WKURLCreateWithBaseURL(baseURLWK.get(), toWTFString(toWK(url)).utf8().data()));
WKRetainPtr<WKStringRef> urlStringWK(AdoptWK, WKURLCopyString(urlWK.get()));
- InjectedBundle::shared().queueLoad(urlStringWK.get(), toWK(target).get());
+ injectedBundle.queueLoad(urlStringWK.get(), toWK(target).get(), shouldOpenExternalURLs);
}
void TestRunner::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL, JSStringRef unreachableURL)
@@ -757,45 +957,59 @@ void TestRunner::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL, J
WKRetainPtr<WKStringRef> baseURLWK = baseURL ? toWK(baseURL) : WKRetainPtr<WKStringRef>();
WKRetainPtr<WKStringRef> unreachableURLWK = unreachableURL ? toWK(unreachableURL) : WKRetainPtr<WKStringRef>();
- InjectedBundle::shared().queueLoadHTMLString(contentWK.get(), baseURLWK.get(), unreachableURLWK.get());
+ InjectedBundle::singleton().queueLoadHTMLString(contentWK.get(), baseURLWK.get(), unreachableURLWK.get());
}
void TestRunner::queueReload()
{
- InjectedBundle::shared().queueReload();
+ InjectedBundle::singleton().queueReload();
}
void TestRunner::queueLoadingScript(JSStringRef script)
{
WKRetainPtr<WKStringRef> scriptWK = toWK(script);
- InjectedBundle::shared().queueLoadingScript(scriptWK.get());
+ InjectedBundle::singleton().queueLoadingScript(scriptWK.get());
}
void TestRunner::queueNonLoadingScript(JSStringRef script)
{
WKRetainPtr<WKStringRef> scriptWK = toWK(script);
- InjectedBundle::shared().queueNonLoadingScript(scriptWK.get());
+ InjectedBundle::singleton().queueNonLoadingScript(scriptWK.get());
}
+void TestRunner::setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(bool value)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
+}
+
void TestRunner::setHandlesAuthenticationChallenges(bool handlesAuthenticationChallenges)
{
- WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetHandlesAuthenticationChallenge"));
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetHandlesAuthenticationChallenges"));
WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(handlesAuthenticationChallenges));
- WKBundlePostMessage(InjectedBundle::shared().bundle(), messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
+}
+
+void TestRunner::setShouldLogCanAuthenticateAgainstProtectionSpace(bool value)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetShouldLogCanAuthenticateAgainstProtectionSpace"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
}
void TestRunner::setAuthenticationUsername(JSStringRef username)
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetAuthenticationUsername"));
WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(username));
- WKBundlePostMessage(InjectedBundle::shared().bundle(), messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
}
void TestRunner::setAuthenticationPassword(JSStringRef password)
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetAuthenticationPassword"));
WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(password));
- WKBundlePostMessage(InjectedBundle::shared().bundle(), messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
}
bool TestRunner::secureEventInputIsEnabled() const
@@ -803,7 +1017,7 @@ bool TestRunner::secureEventInputIsEnabled() const
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SecureEventInputIsEnabled"));
WKTypeRef returnData = 0;
- WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), messageName.get(), 0, &returnData);
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), 0, &returnData);
return WKBooleanGetValue(static_cast<WKBooleanRef>(returnData));
}
@@ -811,21 +1025,386 @@ void TestRunner::setBlockAllPlugins(bool shouldBlock)
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetBlockAllPlugins"));
WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(shouldBlock));
- WKBundlePostMessage(InjectedBundle::shared().bundle(), messageName.get(), messageBody.get());
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
+}
+
+JSValueRef TestRunner::failNextNewCodeBlock()
+{
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
+ JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+ return JSC::failNextNewCodeBlock(context);
}
JSValueRef TestRunner::numberOfDFGCompiles(JSValueRef theFunction)
{
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
return JSC::numberOfDFGCompiles(context, theFunction);
}
JSValueRef TestRunner::neverInlineFunction(JSValueRef theFunction)
{
- WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
return JSC::setNeverInline(context, theFunction);
}
+void TestRunner::setShouldDecideNavigationPolicyAfterDelay(bool value)
+{
+ m_shouldDecideNavigationPolicyAfterDelay = value;
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetShouldDecideNavigationPolicyAfterDelay"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
+}
+
+void TestRunner::setNavigationGesturesEnabled(bool value)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetNavigationGesturesEnabled"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
+}
+
+void TestRunner::setIgnoresViewportScaleLimits(bool value)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetIgnoresViewportScaleLimits"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
+}
+
+void TestRunner::setShouldDownloadUndisplayableMIMETypes(bool value)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetShouldDownloadUndisplayableMIMETypes"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
+}
+
+static unsigned nextUIScriptCallbackID()
+{
+ static unsigned callbackID = FirstUIScriptCallbackID;
+ return callbackID++;
+}
+
+void TestRunner::runUIScript(JSStringRef script, JSValueRef callback)
+{
+ unsigned callbackID = nextUIScriptCallbackID();
+ cacheTestRunnerCallback(callbackID, callback);
+
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("RunUIProcessScript"));
+
+ WKRetainPtr<WKMutableDictionaryRef> testDictionary(AdoptWK, WKMutableDictionaryCreate());
+
+ WKRetainPtr<WKStringRef> scriptKey(AdoptWK, WKStringCreateWithUTF8CString("Script"));
+ WKRetainPtr<WKStringRef> scriptValue(AdoptWK, WKStringCreateWithJSString(script));
+
+ WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID"));
+ WKRetainPtr<WKUInt64Ref> callbackIDValue = adoptWK(WKUInt64Create(callbackID));
+
+ WKDictionarySetItem(testDictionary.get(), scriptKey.get(), scriptValue.get());
+ WKDictionarySetItem(testDictionary.get(), callbackIDKey.get(), callbackIDValue.get());
+
+ WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), testDictionary.get());
+}
+
+void TestRunner::runUIScriptCallback(unsigned callbackID, JSStringRef result)
+{
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
+ JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+
+ JSValueRef resultValue = JSValueMakeString(context, result);
+ callTestRunnerCallback(callbackID, 1, &resultValue);
+}
+
+void TestRunner::installDidBeginSwipeCallback(JSValueRef callback)
+{
+ cacheTestRunnerCallback(DidBeginSwipeCallbackID, callback);
+}
+
+void TestRunner::installWillEndSwipeCallback(JSValueRef callback)
+{
+ cacheTestRunnerCallback(WillEndSwipeCallbackID, callback);
+}
+
+void TestRunner::installDidEndSwipeCallback(JSValueRef callback)
+{
+ cacheTestRunnerCallback(DidEndSwipeCallbackID, callback);
+}
+
+void TestRunner::installDidRemoveSwipeSnapshotCallback(JSValueRef callback)
+{
+ cacheTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID, callback);
+}
+
+void TestRunner::callDidBeginSwipeCallback()
+{
+ callTestRunnerCallback(DidBeginSwipeCallbackID);
+}
+
+void TestRunner::callWillEndSwipeCallback()
+{
+ callTestRunnerCallback(WillEndSwipeCallbackID);
+}
+
+void TestRunner::callDidEndSwipeCallback()
+{
+ callTestRunnerCallback(DidEndSwipeCallbackID);
+}
+
+void TestRunner::callDidRemoveSwipeSnapshotCallback()
+{
+ callTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID);
+}
+
+void TestRunner::setStatisticsPrevalentResource(JSStringRef hostName, bool value)
+{
+ Vector<WKRetainPtr<WKStringRef>> keys;
+ Vector<WKRetainPtr<WKTypeRef>> values;
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("HostName") });
+ values.append({ AdoptWK, WKStringCreateWithJSString(hostName) });
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") });
+ values.append({ AdoptWK, WKBooleanCreate(value) });
+
+ Vector<WKStringRef> rawKeys;
+ Vector<WKTypeRef> rawValues;
+ rawKeys.resize(keys.size());
+ rawValues.resize(values.size());
+
+ for (size_t i = 0; i < keys.size(); ++i) {
+ rawKeys[i] = keys[i].get();
+ rawValues[i] = values[i].get();
+ }
+
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsPrevalentResource"));
+ WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+bool TestRunner::isStatisticsPrevalentResource(JSStringRef hostName)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsStatisticsPrevalentResource"));
+ WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(hostName));
+ WKTypeRef returnData = 0;
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData);
+ return WKBooleanGetValue(static_cast<WKBooleanRef>(returnData));
+}
+
+void TestRunner::setStatisticsHasHadUserInteraction(JSStringRef hostName, bool value)
+{
+ Vector<WKRetainPtr<WKStringRef>> keys;
+ Vector<WKRetainPtr<WKTypeRef>> values;
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("HostName") });
+ values.append({ AdoptWK, WKStringCreateWithJSString(hostName) });
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") });
+ values.append({ AdoptWK, WKBooleanCreate(value) });
+
+ Vector<WKStringRef> rawKeys;
+ Vector<WKTypeRef> rawValues;
+ rawKeys.resize(keys.size());
+ rawValues.resize(values.size());
+
+ for (size_t i = 0; i < keys.size(); ++i) {
+ rawKeys[i] = keys[i].get();
+ rawValues[i] = values[i].get();
+ }
+
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsHasHadUserInteraction"));
+ WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+bool TestRunner::isStatisticsHasHadUserInteraction(JSStringRef hostName)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsStatisticsHasHadUserInteraction"));
+ WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(hostName));
+ WKTypeRef returnData = 0;
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData);
+ return WKBooleanGetValue(static_cast<WKBooleanRef>(returnData));
+}
+
+void TestRunner::setStatisticsTimeToLiveUserInteraction(double seconds)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsTimeToLiveUserInteraction"));
+ WKRetainPtr<WKDoubleRef> messageBody(AdoptWK, WKDoubleCreate(seconds));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::installStatisticsDidModifyDataRecordsCallback(JSValueRef callback)
+{
+ cacheTestRunnerCallback(StatisticsDidModifyDataRecordsCallbackID, callback);
+}
+
+void TestRunner::statisticsDidModifyDataRecordsCallback()
+{
+ callTestRunnerCallback(StatisticsDidModifyDataRecordsCallbackID);
+}
+
+void TestRunner::statisticsFireDataModificationHandler()
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsFireDataModificationHandler"));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, nullptr);
+}
+
+void TestRunner::setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool value)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsNotifyPagesWhenDataRecordsWereScanned"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool value)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval"));
+ WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double seconds)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsMinimumTimeBetweeenDataRecordsRemoval"));
+ WKRetainPtr<WKDoubleRef> messageBody(AdoptWK, WKDoubleCreate(seconds));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::statisticsResetToConsistentState()
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsResetToConsistentState"));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, nullptr);
+}
+
+#if PLATFORM(MAC)
+void TestRunner::connectMockGamepad(unsigned index)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ConnectMockGamepad"));
+ WKRetainPtr<WKTypeRef> messageBody(AdoptWK, WKUInt64Create(index));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::disconnectMockGamepad(unsigned index)
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("DisconnectMockGamepad"));
+ WKRetainPtr<WKTypeRef> messageBody(AdoptWK, WKUInt64Create(index));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setMockGamepadDetails(unsigned index, JSStringRef gamepadID, unsigned axisCount, unsigned buttonCount)
+{
+ Vector<WKRetainPtr<WKStringRef>> keys;
+ Vector<WKRetainPtr<WKTypeRef>> values;
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadID") });
+ values.append(toWK(gamepadID));
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex") });
+ values.append({ AdoptWK, WKUInt64Create(index) });
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("AxisCount") });
+ values.append({ AdoptWK, WKUInt64Create(axisCount) });
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("ButtonCount") });
+ values.append({ AdoptWK, WKUInt64Create(buttonCount) });
+
+ Vector<WKStringRef> rawKeys;
+ Vector<WKTypeRef> rawValues;
+ rawKeys.resize(keys.size());
+ rawValues.resize(values.size());
+
+ for (size_t i = 0; i < keys.size(); ++i) {
+ rawKeys[i] = keys[i].get();
+ rawValues[i] = values[i].get();
+ }
+
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGamepadDetails"));
+ WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value)
+{
+ Vector<WKRetainPtr<WKStringRef>> keys;
+ Vector<WKRetainPtr<WKTypeRef>> values;
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex") });
+ values.append({ AdoptWK, WKUInt64Create(index) });
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("AxisIndex") });
+ values.append({ AdoptWK, WKUInt64Create(axisIndex) });
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") });
+ values.append({ AdoptWK, WKDoubleCreate(value) });
+
+ Vector<WKStringRef> rawKeys;
+ Vector<WKTypeRef> rawValues;
+ rawKeys.resize(keys.size());
+ rawValues.resize(values.size());
+
+ for (size_t i = 0; i < keys.size(); ++i) {
+ rawKeys[i] = keys[i].get();
+ rawValues[i] = values[i].get();
+ }
+
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGamepadAxisValue"));
+ WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value)
+{
+ Vector<WKRetainPtr<WKStringRef>> keys;
+ Vector<WKRetainPtr<WKTypeRef>> values;
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex") });
+ values.append({ AdoptWK, WKUInt64Create(index) });
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("ButtonIndex") });
+ values.append({ AdoptWK, WKUInt64Create(buttonIndex) });
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") });
+ values.append({ AdoptWK, WKDoubleCreate(value) });
+
+ Vector<WKStringRef> rawKeys;
+ Vector<WKTypeRef> rawValues;
+ rawKeys.resize(keys.size());
+ rawValues.resize(values.size());
+
+ for (size_t i = 0; i < keys.size(); ++i) {
+ rawKeys[i] = keys[i].get();
+ rawValues[i] = values[i].get();
+ }
+
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGamepadButtonValue"));
+ WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+#else
+void TestRunner::connectMockGamepad(unsigned)
+{
+}
+
+void TestRunner::disconnectMockGamepad(unsigned)
+{
+}
+
+void TestRunner::setMockGamepadDetails(unsigned, JSStringRef, unsigned, unsigned)
+{
+}
+
+void TestRunner::setMockGamepadAxisValue(unsigned, unsigned, double)
+{
+}
+
+void TestRunner::setMockGamepadButtonValue(unsigned, unsigned, double)
+{
+}
+#endif // PLATFORM(MAC)
+
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
index cefb6a5d1..764c9e4a9 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,28 +23,28 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef TestRunner_h
-#define TestRunner_h
+#pragma once
#include "JSWrappable.h"
+#include "StringFunctions.h"
#include <JavaScriptCore/JSRetainPtr.h>
-#include <WebKit2/WKBundleScriptWorld.h>
-#include <WebKit2/WKRetainPtr.h>
+#include <WebKit/WKBundleScriptWorld.h>
+#include <WebKit/WKRetainPtr.h>
#include <string>
-#include <wtf/PassRefPtr.h>
+#include <wtf/Ref.h>
+#include <wtf/text/WTFString.h>
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#include <wtf/RetainPtr.h>
#include <CoreFoundation/CFRunLoop.h>
typedef RetainPtr<CFRunLoopTimerRef> PlatformTimerRef;
#elif PLATFORM(GTK)
-typedef unsigned int PlatformTimerRef;
+#include <wtf/RunLoop.h>
+namespace WTR {
+class TestRunner;
+typedef RunLoop::Timer<TestRunner> PlatformTimerRef;
+}
#elif PLATFORM(EFL)
-#if USE(EO)
-typedef struct _Eo_Opaque Ecore_Timer;
-#else
-typedef struct _Ecore_Timer Ecore_Timer;
-#endif
typedef Ecore_Timer* PlatformTimerRef;
#endif
@@ -52,7 +52,7 @@ namespace WTR {
class TestRunner : public JSWrappable {
public:
- static PassRefPtr<TestRunner> create();
+ static Ref<TestRunner> create();
virtual ~TestRunner();
// JSWrappable
@@ -60,13 +60,19 @@ public:
void makeWindowObject(JSContextRef, JSObjectRef windowObject, JSValueRef* exception);
+ bool isWebKit2() const { return true; }
+
// The basics.
+ WKURLRef testURL() const { return m_testURL.get(); }
+ void setTestURL(WKURLRef url) { m_testURL = url; }
void dumpAsText(bool dumpPixels);
void waitForPolicyDelegate();
void dumpChildFramesAsText() { m_whatToDump = AllFramesText; }
+ void waitUntilDownloadFinished();
void waitUntilDone();
void notifyDone();
double preciseTime();
+ double timeout() { return m_timeout; }
// Other dumping.
void dumpBackForwardList() { m_shouldDumpBackForwardListsForAllWindows = true; }
@@ -84,6 +90,7 @@ public:
void dumpApplicationCacheDelegateCallbacks() { m_dumpApplicationCacheDelegateCallbacks = true; }
void dumpDatabaseCallbacks() { m_dumpDatabaseCallbacks = true; }
void dumpDOMAsWebArchive() { m_whatToDump = DOMAsWebArchive; }
+ void dumpPolicyDelegateCallbacks() { m_dumpPolicyCallbacks = true; }
void setShouldDumpFrameLoadCallbacks(bool value) { m_dumpFrameLoadCallbacks = value; }
void setShouldDumpProgressFinishedCallback(bool value) { m_dumpProgressFinishedCallback = value; }
@@ -94,11 +101,18 @@ public:
void setCanOpenWindows(bool);
void setCloseRemainingWindowsWhenComplete(bool value) { m_shouldCloseExtraWindows = value; }
void setXSSAuditorEnabled(bool);
+ void setShadowDOMEnabled(bool);
+ void setCustomElementsEnabled(bool);
+ void setModernMediaControlsEnabled(bool);
+ void setWebGL2Enabled(bool);
+ void setFetchAPIEnabled(bool);
void setAllowUniversalAccessFromFileURLs(bool);
void setAllowFileAccessFromFileURLs(bool);
+ void setNeedsStorageAccessFromFileURLsQuirk(bool);
void setPluginsEnabled(bool);
void setJavaScriptCanAccessClipboard(bool);
void setPrivateBrowsingEnabled(bool);
+ void setUseDashboardCompatibilityMode(bool);
void setPopupBlockingEnabled(bool);
void setAuthorAndUserStylesEnabled(bool);
void setCustomPolicyDelegate(bool enabled, bool permissive = false);
@@ -112,6 +126,12 @@ public:
void dispatchPendingLoadRequests();
void setCacheModel(int);
void setAsynchronousSpellCheckingEnabled(bool);
+ void setDownloadAttributeEnabled(bool);
+ void setAllowsAnySSLCertificate(bool);
+ void setEncryptedMediaAPIEnabled(bool);
+ void setSubtleCryptoEnabled(bool);
+ void setMediaStreamEnabled(bool);
+ void setPeerConnectionEnabled(bool);
// Special DOM functions.
void clearBackForwardList();
@@ -151,7 +171,9 @@ public:
void setPrinting() { m_isPrinting = true; }
// Authentication
+ void setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(bool);
void setHandlesAuthenticationChallenges(bool);
+ void setShouldLogCanAuthenticateAgainstProtectionSpace(bool);
void setAuthenticationUsername(JSStringRef);
void setAuthenticationPassword(JSStringRef);
@@ -181,6 +203,7 @@ public:
bool shouldDumpApplicationCacheDelegateCallbacks() const { return m_dumpApplicationCacheDelegateCallbacks; }
bool shouldDumpDatabaseCallbacks() const { return m_dumpDatabaseCallbacks; }
bool shouldDumpSelectionRect() const { return m_dumpSelectionRect; }
+ bool shouldDumpPolicyCallbacks() const { return m_dumpPolicyCallbacks; }
bool isPolicyDelegateEnabled() const { return m_policyDelegateEnabled; }
bool isPolicyDelegatePermissive() const { return m_policyDelegatePermissive; }
@@ -188,6 +211,7 @@ public:
bool waitToDump() const { return m_waitToDump; }
void waitToDumpWatchdogTimerFired();
void invalidateWaitToDumpWatchdogTimer();
+ bool shouldFinishAfterDownload() const { return m_shouldFinishAfterDownload; }
bool shouldAllowEditing() const { return m_shouldAllowEditing; }
@@ -198,7 +222,8 @@ public:
void showWebInspector();
void closeWebInspector();
- void evaluateInWebInspector(long callId, JSStringRef script);
+ void evaluateInWebInspector(JSStringRef script);
+ JSRetainPtr<JSStringRef> inspectorTestStubURL();
void setPOSIXLocale(JSStringRef);
@@ -206,6 +231,8 @@ public:
void setWillSendRequestReturnsNull(bool f) { m_willSendRequestReturnsNull = f; }
bool willSendRequestReturnsNullOnRedirect() const { return m_willSendRequestReturnsNullOnRedirect; }
void setWillSendRequestReturnsNullOnRedirect(bool f) { m_willSendRequestReturnsNullOnRedirect = f; }
+ void setWillSendRequestAddsHTTPBody(JSStringRef body) { m_willSendRequestHTTPBody = toWTFString(toWK(body)); }
+ String willSendRequestHTTPBody() const { return m_willSendRequestHTTPBody; }
void setTextDirection(JSStringRef);
@@ -232,6 +259,8 @@ public:
void setWindowIsKey(bool);
+ void setViewSize(double width, double height);
+
void callAddChromeInputFieldCallback();
void callRemoveChromeInputFieldCallback();
void callFocusWebViewCallback();
@@ -247,45 +276,98 @@ public:
bool hasCustomFullScreenBehavior() const { return m_customFullScreenBehavior; }
// Web notifications.
- void grantWebNotificationPermission(JSStringRef origin);
- void denyWebNotificationPermission(JSStringRef origin);
- void removeAllWebNotificationPermissions();
- void simulateWebNotificationClick(JSValueRef notification);
+ static void grantWebNotificationPermission(JSStringRef origin);
+ static void denyWebNotificationPermission(JSStringRef origin);
+ static void removeAllWebNotificationPermissions();
+ static void simulateWebNotificationClick(JSValueRef notification);
// Geolocation.
void setGeolocationPermission(bool);
void setMockGeolocationPosition(double latitude, double longitude, double accuracy, JSValueRef altitude, JSValueRef altitudeAccuracy, JSValueRef heading, JSValueRef speed);
void setMockGeolocationPositionUnavailableError(JSStringRef message);
+ bool isGeolocationProviderActive();
+
+ // MediaStream
+ void setUserMediaPermission(bool);
+ void setUserMediaPersistentPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin);
+ unsigned userMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) const;
+ void resetUserMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin);
void setPageVisibility(JSStringRef state);
void resetPageVisibility();
bool callShouldCloseOnWebView();
- void setCustomTimeout(int duration);
+ void setCustomTimeout(int duration) { m_timeout = duration; }
// Work queue.
void queueBackNavigation(unsigned howFarBackward);
void queueForwardNavigation(unsigned howFarForward);
- void queueLoad(JSStringRef url, JSStringRef target);
+ void queueLoad(JSStringRef url, JSStringRef target, bool shouldOpenExternalURLs);
void queueLoadHTMLString(JSStringRef content, JSStringRef baseURL, JSStringRef unreachableURL);
void queueReload();
void queueLoadingScript(JSStringRef script);
void queueNonLoadingScript(JSStringRef script);
bool secureEventInputIsEnabled() const;
-
+
+ JSValueRef failNextNewCodeBlock();
JSValueRef numberOfDFGCompiles(JSValueRef theFunction);
JSValueRef neverInlineFunction(JSValueRef theFunction);
-private:
- static const double waitToDumpWatchdogTimerInterval;
+ bool shouldDecideNavigationPolicyAfterDelay() const { return m_shouldDecideNavigationPolicyAfterDelay; }
+ void setShouldDecideNavigationPolicyAfterDelay(bool);
+ void setNavigationGesturesEnabled(bool);
+ void setIgnoresViewportScaleLimits(bool);
+ void setShouldDownloadUndisplayableMIMETypes(bool);
+
+ void runUIScript(JSStringRef script, JSValueRef callback);
+ void runUIScriptCallback(unsigned callbackID, JSStringRef result);
+
+ void installDidBeginSwipeCallback(JSValueRef);
+ void installWillEndSwipeCallback(JSValueRef);
+ void installDidEndSwipeCallback(JSValueRef);
+ void installDidRemoveSwipeSnapshotCallback(JSValueRef);
+ void callDidBeginSwipeCallback();
+ void callWillEndSwipeCallback();
+ void callDidEndSwipeCallback();
+ void callDidRemoveSwipeSnapshotCallback();
+
+ void clearTestRunnerCallbacks();
+ void accummulateLogsForChannel(JSStringRef channel);
+
+ unsigned imageCountInGeneralPasteboard() const;
+
+ // Gamepads
+ void connectMockGamepad(unsigned index);
+ void disconnectMockGamepad(unsigned index);
+ void setMockGamepadDetails(unsigned index, JSStringRef gamepadID, unsigned axisCount, unsigned buttonCount);
+ void setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value);
+ void setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value);
+
+ // Resource Load Statistics
+ void installStatisticsDidModifyDataRecordsCallback(JSValueRef callback);
+ void statisticsDidModifyDataRecordsCallback();
+ void statisticsFireDataModificationHandler();
+ void setStatisticsPrevalentResource(JSStringRef hostName, bool value);
+ bool isStatisticsPrevalentResource(JSStringRef hostName);
+ void setStatisticsHasHadUserInteraction(JSStringRef hostName, bool value);
+ bool isStatisticsHasHadUserInteraction(JSStringRef hostName);
+ void setStatisticsTimeToLiveUserInteraction(double seconds);
+ void setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool);
+ void setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool);
+ void setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double);
+ void statisticsResetToConsistentState();
+
+private:
TestRunner();
void platformInitialize();
void initializeWaitToDumpWatchdogTimerIfNeeded();
+ WKRetainPtr<WKURLRef> m_testURL; // Set by InjectedBundlePage once provisional load starts.
+
WhatToDump m_whatToDump;
bool m_shouldDumpAllFrameScrollPositions;
bool m_shouldDumpBackForwardListsForAllWindows;
@@ -306,6 +388,7 @@ private:
bool m_dumpWillCacheResponse;
bool m_dumpApplicationCacheDelegateCallbacks;
bool m_dumpDatabaseCallbacks;
+ bool m_dumpPolicyCallbacks { false };
bool m_disallowIncreaseForApplicationCacheQuota;
bool m_waitToDump; // True if waitUntilDone() has been called, but notifyDone() has not yet been called.
bool m_testRepaint;
@@ -315,6 +398,7 @@ private:
bool m_willSendRequestReturnsNull;
bool m_willSendRequestReturnsNullOnRedirect;
bool m_shouldStopProvisionalFrameLoads;
+ String m_willSendRequestHTTPBody;
bool m_policyDelegateEnabled;
bool m_policyDelegatePermissive;
@@ -327,12 +411,17 @@ private:
double m_databaseDefaultQuota;
double m_databaseMaxQuota;
+ bool m_shouldDecideNavigationPolicyAfterDelay { false };
+ bool m_shouldFinishAfterDownload { false };
+
bool m_userStyleSheetEnabled;
WKRetainPtr<WKStringRef> m_userStyleSheetLocation;
+ WKRetainPtr<WKArrayRef> m_allowedHosts;
+
+ size_t m_userMediaPermissionRequestCount { 0 };
+
PlatformTimerRef m_waitToDumpWatchdogTimer;
};
} // namespace WTR
-
-#endif // TestRunner_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/TextInputController.cpp b/Tools/WebKitTestRunner/InjectedBundle/TextInputController.cpp
index 0087aa301..2e304e28c 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/TextInputController.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/TextInputController.cpp
@@ -30,13 +30,13 @@
#include "InjectedBundlePage.h"
#include "JSTextInputController.h"
#include "StringFunctions.h"
-#include <WebKit2/WKBundlePagePrivate.h>
+#include <WebKit/WKBundlePagePrivate.h>
namespace WTR {
-PassRefPtr<TextInputController> TextInputController::create()
+Ref<TextInputController> TextInputController::create()
{
- return adoptRef(new TextInputController);
+ return adoptRef(*new TextInputController);
}
TextInputController::TextInputController()
@@ -59,22 +59,22 @@ void TextInputController::makeWindowObject(JSContextRef context, JSObjectRef win
void TextInputController::setMarkedText(JSStringRef text, int from, int length)
{
- WKBundlePageSetComposition(InjectedBundle::shared().page()->page(), toWK(text).get(), from, length);
+ WKBundlePageSetComposition(InjectedBundle::singleton().page()->page(), toWK(text).get(), from, length);
}
bool TextInputController::hasMarkedText()
{
- return WKBundlePageHasComposition(InjectedBundle::shared().page()->page());
+ return WKBundlePageHasComposition(InjectedBundle::singleton().page()->page());
}
void TextInputController::unmarkText()
{
- WKBundlePageConfirmComposition(InjectedBundle::shared().page()->page());
+ WKBundlePageConfirmComposition(InjectedBundle::singleton().page()->page());
}
void TextInputController::insertText(JSStringRef text)
{
- WKBundlePageConfirmCompositionWithText(InjectedBundle::shared().page()->page(), toWK(text).get());
+ WKBundlePageConfirmCompositionWithText(InjectedBundle::singleton().page()->page(), toWK(text).get());
}
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/InjectedBundle/TextInputController.h b/Tools/WebKitTestRunner/InjectedBundle/TextInputController.h
index 71a043752..ed174816f 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/TextInputController.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/TextInputController.h
@@ -23,17 +23,16 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef TextInputController_h
-#define TextInputController_h
+#pragma once
#include "JSWrappable.h"
-#include <wtf/PassRefPtr.h>
+#include <wtf/Ref.h>
namespace WTR {
class TextInputController : public JSWrappable {
public:
- static PassRefPtr<TextInputController> create();
+ static Ref<TextInputController> create();
virtual ~TextInputController();
// JSWrappable
@@ -51,5 +50,3 @@ private:
};
} // namespace WTR
-
-#endif // TextInputController_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityControllerAtk.cpp b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityControllerAtk.cpp
index 3573a2a5c..a1a554a9d 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityControllerAtk.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityControllerAtk.cpp
@@ -33,35 +33,14 @@
#include "InjectedBundle.h"
#include "InjectedBundlePage.h"
-#include <WebKit2/WKBundlePagePrivate.h>
+#include <WebKit/WKBundlePagePrivate.h>
#include <atk/atk.h>
#include <cstdio>
-#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/StringBuilder.h>
namespace WTR {
-void AccessibilityController::logAccessibilityEvents()
-{
- // Ensure no callbacks are connected before.
- resetToConsistentState();
-
- // Ensure that accessibility is initialized for the WebView by querying for
- // the root accessible object, which will create the full hierarchy.
- rootElement();
-
- if (!m_globalNotificationHandler)
- m_globalNotificationHandler = AccessibilityNotificationHandler::create();
- m_globalNotificationHandler->logAccessibilityEvents();
-
- // Ensure the Atk interface types are registered, otherwise
- // the AtkDocument signal handlers below won't get registered.
- GObject* dummyAxObject = G_OBJECT(g_object_new(ATK_TYPE_OBJECT, nullptr));
- AtkObject* dummyNoOpAxObject = atk_no_op_object_new(dummyAxObject);
- g_object_unref(G_OBJECT(dummyNoOpAxObject));
- g_object_unref(dummyAxObject);
-}
-
void AccessibilityController::resetToConsistentState()
{
m_globalNotificationHandler = nullptr;
@@ -97,9 +76,9 @@ static AtkObject* childElementById(AtkObject* parent, const char* id)
return nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityController::accessibleElementById(JSStringRef id)
+RefPtr<AccessibilityUIElement> AccessibilityController::accessibleElementById(JSStringRef id)
{
- AtkObject* root = ATK_OBJECT(WKAccessibilityRootObject(InjectedBundle::shared().page()->page()));
+ AtkObject* root = ATK_OBJECT(WKAccessibilityRootObject(InjectedBundle::singleton().page()->page()));
if (!root)
return nullptr;
@@ -120,17 +99,17 @@ JSRetainPtr<JSStringRef> AccessibilityController::platformName()
return platformName;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityController::rootElement()
+Ref<AccessibilityUIElement> AccessibilityController::rootElement()
{
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
void* root = WKAccessibilityRootObject(page);
return AccessibilityUIElement::create(static_cast<AtkObject*>(root));
}
-PassRefPtr<AccessibilityUIElement> AccessibilityController::focusedElement()
+Ref<AccessibilityUIElement> AccessibilityController::focusedElement()
{
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
void* root = WKAccessibilityFocusedObject(page);
return AccessibilityUIElement::create(static_cast<AtkObject*>(root));
diff --git a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.cpp b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.cpp
index b6af081c2..bb2280877 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.cpp
@@ -25,12 +25,12 @@
#include "InjectedBundle.h"
#include "InjectedBundlePage.h"
#include "JSWrapper.h"
-#include <WebKit2/WKBundleFrame.h>
-#include <WebKit2/WKBundlePage.h>
-#include <WebKit2/WKBundlePagePrivate.h>
+#include <WebKit/WKBundleFrame.h>
+#include <WebKit/WKBundlePage.h>
+#include <WebKit/WKBundlePagePrivate.h>
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
-#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
@@ -43,29 +43,6 @@ typedef HashMap<AtkObject*, AccessibilityNotificationHandler*> NotificationHandl
WTF::Vector<unsigned> listenerIds;
NotificationHandlersMap notificationHandlers;
AccessibilityNotificationHandler* globalNotificationHandler = nullptr;
-bool loggingAccessibilityEvents = false;
-
-void printAccessibilityEvent(AtkObject* accessible, const char* signalName, const char* signalValue)
-{
- // Do not handle state-change:defunct signals, as the AtkObject
- // associated to them will not be valid at this point already.
- if (!signalName || !g_strcmp0(signalName, "state-change:defunct"))
- return;
-
- if (!accessible || !ATK_IS_OBJECT(accessible))
- return;
-
- const char* objectName = atk_object_get_name(accessible);
- AtkRole objectRole = atk_object_get_role(accessible);
-
- // Try to always provide a name to be logged for the object.
- if (!objectName || *objectName == '\0')
- objectName = "(No name)";
-
- GUniquePtr<char> signalNameAndValue(signalValue ? g_strdup_printf("%s = %s", signalName, signalValue) : g_strdup(signalName));
- GUniquePtr<char> accessibilityEventString(g_strdup_printf("Accessibility object emitted \"%s\" / Name: \"%s\" / Role: %d\n", signalNameAndValue.get(), objectName, objectRole));
- InjectedBundle::shared().outputText(String::fromUTF8(accessibilityEventString.get()));
-}
gboolean axObjectEventListener(GSignalInvocationHint* signalHint, unsigned numParamValues, const GValue* paramValues, gpointer data)
{
@@ -78,7 +55,7 @@ gboolean axObjectEventListener(GSignalInvocationHint* signalHint, unsigned numPa
return true;
#if PLATFORM(GTK) || PLATFORM(EFL)
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
JSContextRef jsContext = WKBundleFrameGetJavaScriptContext(mainFrame);
#else
@@ -86,47 +63,39 @@ gboolean axObjectEventListener(GSignalInvocationHint* signalHint, unsigned numPa
#endif
GSignalQuery signalQuery;
- GUniquePtr<char> signalName;
- GUniquePtr<char> signalValue;
const char* notificationName = nullptr;
Vector<JSValueRef> extraArgs;
g_signal_query(signalHint->signal_id, &signalQuery);
if (!g_strcmp0(signalQuery.signal_name, "state-change")) {
- signalName.reset(g_strdup_printf("state-change:%s", g_value_get_string(&paramValues[1])));
- signalValue.reset(g_strdup_printf("%d", g_value_get_boolean(&paramValues[2])));
if (!g_strcmp0(g_value_get_string(&paramValues[1]), "checked"))
notificationName = "CheckedStateChanged";
else if (!g_strcmp0(g_value_get_string(&paramValues[1]), "invalid-entry"))
notificationName = "AXInvalidStatusChanged";
} else if (!g_strcmp0(signalQuery.signal_name, "focus-event")) {
- signalName.reset(g_strdup("focus-event"));
- signalValue.reset(g_strdup_printf("%d", g_value_get_boolean(&paramValues[1])));
if (g_value_get_boolean(&paramValues[1]))
notificationName = "AXFocusedUIElementChanged";
+ } else if (!g_strcmp0(signalQuery.signal_name, "selection-changed")) {
+ notificationName = "AXSelectedChildrenChanged";
} else if (!g_strcmp0(signalQuery.signal_name, "children-changed")) {
const gchar* childrenChangedDetail = g_quark_to_string(signalHint->detail);
- signalName.reset(g_strdup_printf("children-changed:%s", childrenChangedDetail));
- signalValue.reset(g_strdup_printf("%d", g_value_get_uint(&paramValues[1])));
notificationName = !g_strcmp0(childrenChangedDetail, "add") ? "AXChildrenAdded" : "AXChildrenRemoved";
+ gpointer child = g_value_get_pointer(&paramValues[2]);
+ if (ATK_IS_OBJECT(child))
+ extraArgs.append(toJS(jsContext, WTF::getPtr(WTR::AccessibilityUIElement::create(ATK_OBJECT(child)))));
} else if (!g_strcmp0(signalQuery.signal_name, "property-change")) {
- signalName.reset(g_strdup_printf("property-change:%s", g_quark_to_string(signalHint->detail)));
if (!g_strcmp0(g_quark_to_string(signalHint->detail), "accessible-value"))
notificationName = "AXValueChanged";
} else if (!g_strcmp0(signalQuery.signal_name, "load-complete"))
notificationName = "AXLoadComplete";
else if (!g_strcmp0(signalQuery.signal_name, "text-caret-moved")) {
notificationName = "AXTextCaretMoved";
- signalName.reset(g_strdup(signalQuery.signal_name));
- signalValue.reset(g_strdup_printf("%d", g_value_get_int(&paramValues[1])));
+ GUniquePtr<char> signalValue(g_strdup_printf("%d", g_value_get_int(&paramValues[1])));
JSRetainPtr<JSStringRef> jsSignalValue(Adopt, JSStringCreateWithUTF8CString(signalValue.get()));
extraArgs.append(JSValueMakeString(jsContext, jsSignalValue.get()));
- } else
- signalName.reset(g_strdup(signalQuery.signal_name));
-
- if (loggingAccessibilityEvents)
- printAccessibilityEvent(accessible, signalName.get(), signalValue.get());
+ } else if (!g_strcmp0(signalQuery.signal_name, "text-insert") || !g_strcmp0(signalQuery.signal_name, "text-remove"))
+ notificationName = "AXTextChanged";
if (!jsContext)
return true;
@@ -174,12 +143,6 @@ AccessibilityNotificationHandler::~AccessibilityNotificationHandler()
disconnectAccessibilityCallbacks();
}
-void AccessibilityNotificationHandler::logAccessibilityEvents()
-{
- connectAccessibilityCallbacks();
- loggingAccessibilityEvents = true;
-}
-
void AccessibilityNotificationHandler::setNotificationFunctionCallback(JSValueRef notificationFunctionCallback)
{
if (!notificationFunctionCallback) {
@@ -191,7 +154,7 @@ void AccessibilityNotificationHandler::setNotificationFunctionCallback(JSValueRe
m_notificationFunctionCallback = notificationFunctionCallback;
#if PLATFORM(GTK) || PLATFORM(EFL)
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
JSContextRef jsContext = WKBundleFrameGetJavaScriptContext(mainFrame);
#else
@@ -222,7 +185,7 @@ void AccessibilityNotificationHandler::setNotificationFunctionCallback(JSValueRe
void AccessibilityNotificationHandler::removeAccessibilityNotificationHandler()
{
#if PLATFORM(GTK) || PLATFORM(EFL)
- WKBundlePageRef page = InjectedBundle::shared().page()->page();
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
JSContextRef jsContext = WKBundleFrameGetJavaScriptContext(mainFrame);
#else
@@ -257,7 +220,10 @@ void AccessibilityNotificationHandler::connectAccessibilityCallbacks()
"ATK:AtkObject:property-change",
"ATK:AtkObject:visible-data-changed",
"ATK:AtkDocument:load-complete",
+ "ATK:AtkSelection:selection-changed",
"ATK:AtkText:text-caret-moved",
+ "ATK:AtkText:text-insert",
+ "ATK:AtkText:text-remove",
0
};
@@ -271,7 +237,7 @@ void AccessibilityNotificationHandler::connectAccessibilityCallbacks()
unsigned id = atk_add_global_event_listener(axObjectEventListener, *signalName);
if (!id) {
String message = String::format("atk_add_global_event_listener failed for signal %s\n", *signalName);
- InjectedBundle::shared().outputText(message);
+ InjectedBundle::singleton().outputText(message);
continue;
}
diff --git a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.h b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.h
index 3443bce2c..da5d8ecdd 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityNotificationHandlerAtk.h
@@ -17,32 +17,29 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef AccessibilityNotificationHandlerAtk_h
-#define AccessibilityNotificationHandlerAtk_h
+#pragma once
#if HAVE(ACCESSIBILITY)
#include <JavaScriptCore/JSObjectRef.h>
#include <atk/atk.h>
#include <atk/atkobject.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/gobject/GRefPtr.h>
+#include <wtf/glib/GRefPtr.h>
namespace WTR {
class AccessibilityNotificationHandler : public RefCounted<AccessibilityNotificationHandler> {
public:
- static PassRefPtr<AccessibilityNotificationHandler> create()
+ static Ref<AccessibilityNotificationHandler> create()
{
- return adoptRef(new AccessibilityNotificationHandler());
+ return adoptRef(*new AccessibilityNotificationHandler());
}
~AccessibilityNotificationHandler();
void setPlatformElement(GRefPtr<AtkObject> platformElement) { m_platformElement = platformElement; }
GRefPtr<AtkObject> platformElement() const { return m_platformElement; }
void setNotificationFunctionCallback(JSValueRef);
JSValueRef notificationFunctionCallback() const { return m_notificationFunctionCallback; }
- void logAccessibilityEvents();
private:
AccessibilityNotificationHandler();
@@ -57,5 +54,3 @@ private:
} // namespace WTR
#endif // HAVE(ACCESSIBILITY)
-
-#endif // AccessibilityNotificationHandlerAtk_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp
index 440377937..7ecf65a29 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp
@@ -35,10 +35,13 @@
#include "NotImplemented.h"
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/OpaqueJSString.h>
+#if ATK_CHECK_VERSION(2,11,90)
+#include <WebKit/WKBundleFrame.h>
+#endif
#include <atk/atk.h>
#include <wtf/Assertions.h>
-#include <wtf/gobject/GRefPtr.h>
-#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/glib/GRefPtr.h>
+#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>
@@ -48,6 +51,13 @@ namespace WTR {
namespace {
+#if ATK_CHECK_VERSION(2,11,92)
+enum RangeLimit {
+ RangeLimitMinimum,
+ RangeLimitMaximum
+};
+#endif
+
enum AtkAttributeType {
ObjectAttributeType,
TextAttributeType
@@ -61,6 +71,8 @@ enum AttributeDomain {
enum AttributesIndex {
// Attribute names.
InvalidNameIndex = 0,
+ PosInSetIndex,
+ SetSizeIndex,
PlaceholderNameIndex,
SortNameIndex,
@@ -76,6 +88,8 @@ enum AttributesIndex {
const String attributesMap[][2] = {
// Attribute names.
{ "AXInvalid", "invalid" },
+ { "AXARIAPosInSet", "posinset" },
+ { "AXARIASetSize", "setsize" },
{ "AXPlaceholderValue", "placeholder-text" } ,
{ "AXSortDirection", "sort" },
@@ -91,6 +105,7 @@ const char* landmarkStringComplementary = "AXLandmarkComplementary";
const char* landmarkStringContentinfo = "AXLandmarkContentInfo";
const char* landmarkStringMain = "AXLandmarkMain";
const char* landmarkStringNavigation = "AXLandmarkNavigation";
+const char* landmarkStringRegion = "AXLandmarkRegion";
const char* landmarkStringSearch = "AXLandmarkSearch";
#endif
@@ -172,9 +187,8 @@ String getAttributeSetValueForId(AtkObject* accessible, AtkAttributeType type, S
return atkAttributeValueToCoreAttributeValue(type, id, attributeValue);
}
-String getAtkAttributeSetAsString(AtkObject* accessible, AtkAttributeType type)
+String attributeSetToString(AtkAttributeSet* attributeSet, String separator=", ")
{
- AtkAttributeSet* attributeSet = getAttributeSet(accessible, type);
if (!attributeSet)
return String();
@@ -184,13 +198,18 @@ String getAtkAttributeSetAsString(AtkObject* accessible, AtkAttributeType type)
GUniquePtr<gchar> attributeData(g_strconcat(attribute->name, ":", attribute->value, NULL));
builder.append(attributeData.get());
if (attributes->next)
- builder.append(", ");
+ builder.append(separator);
}
atk_attribute_set_free(attributeSet);
return builder.toString();
}
+String getAtkAttributeSetAsString(AtkObject* accessible, AtkAttributeType type, String separator=", ")
+{
+ return attributeSetToString(getAttributeSet(accessible, type), separator);
+}
+
bool checkElementState(PlatformUIElement element, AtkStateType stateType)
{
if (!ATK_IS_OBJECT(element.get()))
@@ -203,7 +222,10 @@ bool checkElementState(PlatformUIElement element, AtkStateType stateType)
JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)
{
GUniquePtr<gchar> rangeString(g_strdup("{0, 0}"));
-
+#if ATK_CHECK_VERSION(2,11,90)
+ if (!ATK_IS_TABLE_CELL(element.get()))
+ return JSStringCreateWithUTF8CString(rangeString.get());
+#else
if (!ATK_IS_OBJECT(element.get()))
return JSStringCreateWithUTF8CString(rangeString.get());
@@ -215,11 +237,20 @@ JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)
gint indexInParent = atk_object_get_index_in_parent(ATK_OBJECT(element.get()));
if (indexInParent == -1)
return JSStringCreateWithUTF8CString(rangeString.get());
+#endif
- int row = -1;
- int column = -1;
+ gint row = -1;
+ gint column = -1;
+ gint rowSpan = -1;
+ gint columnSpan = -1;
+#if ATK_CHECK_VERSION(2,11,90)
+ atk_table_cell_get_row_column_span(ATK_TABLE_CELL(element.get()), &row, &column, &rowSpan, &columnSpan);
+#else
row = atk_table_get_row_at_index(ATK_TABLE(axTable), indexInParent);
column = atk_table_get_column_at_index(ATK_TABLE(axTable), indexInParent);
+ rowSpan = atk_table_get_row_extent_at(ATK_TABLE(axTable), row, column);
+ columnSpan = atk_table_get_column_extent_at(ATK_TABLE(axTable), row, column);
+#endif
// Get the actual values, if row and columns are valid values.
if (row != -1 && column != -1) {
@@ -227,10 +258,10 @@ JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)
int length = 0;
if (isRowRange) {
base = row;
- length = atk_table_get_row_extent_at(ATK_TABLE(axTable), row, column);
+ length = rowSpan;
} else {
base = column;
- length = atk_table_get_column_extent_at(ATK_TABLE(axTable), row, column);
+ length = columnSpan;
}
rangeString.reset(g_strdup_printf("{%d, %d}", base, length));
}
@@ -243,6 +274,13 @@ void alterCurrentValue(PlatformUIElement element, int factor)
if (!ATK_IS_VALUE(element.get()))
return;
+#if ATK_CHECK_VERSION(2,11,92)
+ double currentValue;
+ atk_value_get_value_and_text(ATK_VALUE(element.get()), &currentValue, nullptr);
+
+ double increment = atk_value_get_increment(ATK_VALUE(element.get()));
+ atk_value_set_value(ATK_VALUE(element.get()), currentValue + factor * increment);
+#else
GValue currentValue = G_VALUE_INIT;
atk_value_get_current_value(ATK_VALUE(element.get()), &currentValue);
@@ -258,6 +296,7 @@ void alterCurrentValue(PlatformUIElement element, int factor)
g_value_unset(&newValue);
g_value_unset(&increment);
g_value_unset(&currentValue);
+#endif
}
gchar* replaceCharactersForResults(gchar* str)
@@ -283,17 +322,19 @@ const gchar* roleToString(AtkObject* object)
#if ATK_CHECK_VERSION(2, 11, 3)
if (role == ATK_ROLE_LANDMARK) {
String xmlRolesValue = getAttributeSetValueForId(object, ObjectAttributeType, "xml-roles");
- if (equalIgnoringCase(xmlRolesValue, "banner"))
+ if (equalLettersIgnoringASCIICase(xmlRolesValue, "banner"))
return landmarkStringBanner;
- if (equalIgnoringCase(xmlRolesValue, "complementary"))
+ if (equalLettersIgnoringASCIICase(xmlRolesValue, "complementary"))
return landmarkStringComplementary;
- if (equalIgnoringCase(xmlRolesValue, "contentinfo"))
+ if (equalLettersIgnoringASCIICase(xmlRolesValue, "contentinfo"))
return landmarkStringContentinfo;
- if (equalIgnoringCase(xmlRolesValue, "main"))
+ if (equalLettersIgnoringASCIICase(xmlRolesValue, "main"))
return landmarkStringMain;
- if (equalIgnoringCase(xmlRolesValue, "navigation"))
+ if (equalLettersIgnoringASCIICase(xmlRolesValue, "navigation"))
return landmarkStringNavigation;
- if (equalIgnoringCase(xmlRolesValue, "search"))
+ if (equalLettersIgnoringASCIICase(xmlRolesValue, "region"))
+ return landmarkStringRegion;
+ if (equalLettersIgnoringASCIICase(xmlRolesValue, "search"))
return landmarkStringSearch;
}
#endif
@@ -305,6 +346,8 @@ const gchar* roleToString(AtkObject* object)
return "AXDialog";
case ATK_ROLE_CANVAS:
return "AXCanvas";
+ case ATK_ROLE_CAPTION:
+ return "AXCaption";
case ATK_ROLE_CHECK_BOX:
return "AXCheckBox";
case ATK_ROLE_COLOR_CHOOSER:
@@ -339,6 +382,8 @@ const gchar* roleToString(AtkObject* object)
return "AXInvalid";
case ATK_ROLE_LABEL:
return "AXLabel";
+ case ATK_ROLE_LEVEL_BAR:
+ return "AXProgressIndicator";
case ATK_ROLE_LINK:
return "AXLink";
case ATK_ROLE_LIST:
@@ -420,6 +465,10 @@ const gchar* roleToString(AtkObject* object)
#if ATK_CHECK_VERSION(2, 11, 3)
case ATK_ROLE_ARTICLE:
return "AXArticle";
+ case ATK_ROLE_AUDIO:
+ return "AXAudio";
+ case ATK_ROLE_BLOCK_QUOTE:
+ return "AXBlockquote";
case ATK_ROLE_DEFINITION:
return "AXDefinition";
case ATK_ROLE_LOG:
@@ -430,6 +479,8 @@ const gchar* roleToString(AtkObject* object)
return "AXMath";
case ATK_ROLE_TIMER:
return "AXTimer";
+ case ATK_ROLE_VIDEO:
+ return "AXVideo";
#endif
#if ATK_CHECK_VERSION(2, 11, 4)
case ATK_ROLE_DESCRIPTION_LIST:
@@ -439,6 +490,20 @@ const gchar* roleToString(AtkObject* object)
case ATK_ROLE_DESCRIPTION_VALUE:
return "AXDescriptionValue";
#endif
+#if ATK_CHECK_VERSION(2, 15, 2)
+ case ATK_ROLE_STATIC:
+ return "AXStatic";
+#endif
+#if ATK_CHECK_VERSION(2, 15, 4)
+ case ATK_ROLE_MATH_FRACTION:
+ return "AXMathFraction";
+ case ATK_ROLE_MATH_ROOT:
+ return "AXMathRoot";
+ case ATK_ROLE_SUBSCRIPT:
+ return "AXSubscript";
+ case ATK_ROLE_SUPERSCRIPT:
+ return "AXSuperscript";
+#endif
default:
// We want to distinguish ATK_ROLE_UNKNOWN from a known AtkRole which
// our DRT isn't properly handling.
@@ -446,6 +511,19 @@ const gchar* roleToString(AtkObject* object)
}
}
+String selectedText(AtkObject* accessible)
+{
+ if (!ATK_IS_TEXT(accessible))
+ return String();
+
+ AtkText* text = ATK_TEXT(accessible);
+
+ gint start, end;
+ g_free(atk_text_get_selection(text, 0, &start, &end));
+
+ return atk_text_get_text(text, start, end);
+}
+
String attributesOfElement(AccessibilityUIElement* element)
{
StringBuilder builder;
@@ -552,6 +630,53 @@ static Vector<RefPtr<AccessibilityUIElement> > getVisibleCells(AccessibilityUIEl
return visibleCells;
}
+#if ATK_CHECK_VERSION(2,11,90)
+static Vector<RefPtr<AccessibilityUIElement>> convertGPtrArrayToVector(const GPtrArray* array)
+{
+ Vector<RefPtr<AccessibilityUIElement>> cells;
+ for (guint i = 0; i < array->len; i++) {
+ if (AtkObject* atkObject = static_cast<AtkObject*>(g_ptr_array_index(array, i)))
+ cells.append(AccessibilityUIElement::create(atkObject));
+ }
+ return cells;
+}
+
+static JSValueRef convertToJSObjectArray(const Vector<RefPtr<AccessibilityUIElement>>& children)
+{
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
+ JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+
+ size_t elementCount = children.size();
+ auto valueElements = std::make_unique<JSValueRef[]>(elementCount);
+ for (size_t i = 0; i < elementCount; i++)
+ valueElements[i] = JSObjectMake(context, children[i]->wrapperClass(), children[i].get());
+
+ return JSObjectMakeArray(context, elementCount, valueElements.get(), nullptr);
+}
+#endif
+
+#if ATK_CHECK_VERSION(2,11,92)
+static double rangeMinMaxValue(AtkValue* atkValue, RangeLimit rangeLimit)
+{
+ AtkRange* range = atk_value_get_range(atkValue);
+ if (!range)
+ return 0;
+
+ double rangeValue = 0;
+ switch (rangeLimit) {
+ case RangeLimitMinimum:
+ rangeValue = atk_range_get_lower_limit(range);
+ break;
+ case RangeLimitMaximum:
+ rangeValue = atk_range_get_upper_limit(range);
+ break;
+ };
+
+ atk_range_free(range);
+ return rangeValue;
+}
+#endif
+
} // namespace
AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
@@ -605,7 +730,7 @@ int AccessibilityUIElement::childrenCount()
return atk_object_get_n_accessible_children(ATK_OBJECT(m_element.get()));
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y)
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y)
{
if (!ATK_IS_COMPONENT(m_element.get()))
return nullptr;
@@ -630,7 +755,7 @@ unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
return 0;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned index)
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned index)
{
if (!ATK_IS_OBJECT(m_element.get()))
return nullptr;
@@ -644,28 +769,16 @@ PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned
return nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
-{
- // FIXME: implement
- return nullptr;
-}
-
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
+static RefPtr<AccessibilityUIElement> accessibilityElementAtIndex(AtkObject* element, AtkRelationType relationType, unsigned index)
{
- // FIXME: implement
- return nullptr;
-}
-
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
-{
- if (!ATK_IS_OBJECT(m_element.get()))
+ if (!ATK_IS_OBJECT(element))
return nullptr;
- AtkRelationSet* relationSet = atk_object_ref_relation_set(ATK_OBJECT(m_element.get()));
+ AtkRelationSet* relationSet = atk_object_ref_relation_set(element);
if (!relationSet)
return nullptr;
- AtkRelation* relation = atk_relation_set_get_relation_by_type(relationSet, ATK_RELATION_FLOWS_TO);
+ AtkRelation* relation = atk_relation_set_get_relation_by_type(relationSet, relationType);
if (!relation)
return nullptr;
@@ -673,43 +786,80 @@ PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIn
if (!targetList || !targetList->len || index >= targetList->len)
return nullptr;
+ AtkObject* target = static_cast<AtkObject*>(g_ptr_array_index(targetList, index));
g_object_unref(relationSet);
- AtkObject* target = static_cast<AtkObject*>(g_ptr_array_index(targetList, index));
- return target ? AccessibilityUIElement::create(target) : nullptr;
+ return target ? AccessibilityUIElement::create(target).ptr() : nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned index)
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned index) const
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
+{
+ return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_FLOWS_TO, index);
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaControlsElementAtIndex(unsigned index)
+{
+ return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_CONTROLLER_FOR, index);
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
{
// FIXME: implement
return nullptr;
}
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned index)
+{
+ // ATK doesn't have API to get an accessible row by index directly. It does, however, have
+ // API to get cells in the row specified by index. The parent of a cell should be the row.
+ AtkTable* axTable = ATK_TABLE(m_element.get());
+ unsigned nColumns = columnCount();
+ for (unsigned col = 0; col < nColumns; col++) {
+ // Find the first cell in this row that only spans one row.
+ if (atk_table_get_row_extent_at(axTable, index, col) == 1) {
+ AtkObject* cell = atk_table_ref_at(axTable, index, col);
+ return cell ? AccessibilityUIElement::create(atk_object_get_parent(cell)).ptr() : nullptr;
+ }
+ }
+
+ return nullptr;
+}
+
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned index) const
+{
+ if (!ATK_SELECTION(m_element.get()))
+ return nullptr;
+
+ GRefPtr<AtkObject> child = adoptGRef(atk_selection_ref_selection(ATK_SELECTION(m_element.get()), index));
+ return child ? AccessibilityUIElement::create(child.get()).ptr() : nullptr;
+}
+
unsigned AccessibilityUIElement::selectedChildrenCount() const
{
- // FIXME: implement
- return 0;
+ if (!ATK_IS_SELECTION(m_element.get()))
+ return 0;
+ return atk_selection_get_selection_count(ATK_SELECTION(m_element.get()));
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned index)
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned index)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
{
if (!ATK_IS_OBJECT(m_element.get()))
return nullptr;
@@ -730,19 +880,19 @@ PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
}
g_object_unref(set);
- return target ? AccessibilityUIElement::create(target) : nullptr;
+ return target ? AccessibilityUIElement::create(target).ptr() : nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
{
if (!ATK_IS_OBJECT(m_element.get()))
return nullptr;
AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element.get()));
- return parent ? AccessibilityUIElement::create(parent) : nullptr;
+ return parent ? AccessibilityUIElement::create(parent).ptr() : nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
{
// FIXME: implement
return nullptr;
@@ -786,7 +936,13 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRe
String atkAttributeName = coreAttributeToAtkAttribute(attribute);
- // Try object attributes first.
+ // The value of AXSelectedText is not exposed through any AtkAttribute.
+ if (atkAttributeName == "AXSelectedText") {
+ String string = selectedText(m_element.get());
+ return JSStringCreateWithUTF8CString(string.utf8().data());
+ }
+
+ // Try object attributes before text attributes.
String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName);
// Try text attributes if the requested one was not found and we have an AtkText object.
@@ -812,7 +968,19 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRe
double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
{
- // FIXME: implement
+ if (!ATK_IS_OBJECT(m_element.get()))
+ return 0;
+
+ String atkAttributeName = coreAttributeToAtkAttribute(attribute);
+ if (atkAttributeName.isEmpty())
+ return 0;
+
+ if (atkAttributeName == "setsize" || atkAttributeName == "posinset") {
+ String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName);
+ if (!attributeValue.isEmpty())
+ return attributeValue.toDouble();
+ }
+
return 0;
}
@@ -824,25 +992,87 @@ JSValueRef AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef attr
JSValueRef AccessibilityUIElement::rowHeaders() const
{
- // FIXME: implement
+#if ATK_CHECK_VERSION(2,11,90)
+ if (!ATK_IS_TABLE_CELL(m_element.get()))
+ return nullptr;
+
+ GRefPtr<GPtrArray> array = adoptGRef(atk_table_cell_get_row_header_cells(ATK_TABLE_CELL(m_element.get())));
+ if (!array)
+ return nullptr;
+
+ Vector<RefPtr<AccessibilityUIElement>> rows = convertGPtrArrayToVector(array.get());
+ return convertToJSObjectArray(rows);
+#else
return nullptr;
+#endif
}
JSValueRef AccessibilityUIElement::columnHeaders() const
{
- // FIXME: implement
+#if ATK_CHECK_VERSION(2,11,90)
+ if (!ATK_IS_TABLE_CELL(m_element.get()) && !ATK_IS_TABLE(m_element.get()))
+ return nullptr;
+
+ Vector<RefPtr<AccessibilityUIElement>> columns;
+ if (ATK_IS_TABLE_CELL(m_element.get())) {
+ GRefPtr<GPtrArray> array = adoptGRef(atk_table_cell_get_column_header_cells(ATK_TABLE_CELL(m_element.get())));
+ if (!array)
+ return nullptr;
+
+ columns = convertGPtrArrayToVector(array.get());
+ } else
+ columns = getColumnHeaders(ATK_TABLE(m_element.get()));
+ return convertToJSObjectArray(columns);
+#else
return nullptr;
+#endif
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
{
- // FIXME: implement
+ if (!ATK_IS_OBJECT(m_element.get()))
+ return nullptr;
+
+ // ATK does not have this API. So we're "faking it" here on a case-by-case basis.
+ String attributeString = jsStringToWTFString(attribute);
+ AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
+ if (role == ATK_ROLE_SPIN_BUTTON && const_cast<AccessibilityUIElement*>(this)->childrenCount() == 2) {
+ if (attributeString == "AXDecrementButton")
+ return const_cast<AccessibilityUIElement*>(this)->childAtIndex(0);
+ if (attributeString == "AXIncrementButton")
+ return const_cast<AccessibilityUIElement*>(this)->childAtIndex(1);
+ }
+
return nullptr;
}
bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
{
- // FIXME: implement
+ if (!ATK_IS_OBJECT(m_element.get()))
+ return false;
+
+ String attributeString = jsStringToWTFString(attribute);
+ if (attributeString == "AXElementBusy")
+ return checkElementState(m_element.get(), ATK_STATE_BUSY);
+ if (attributeString == "AXChecked")
+ return checkElementState(m_element.get(), ATK_STATE_CHECKED);
+ if (attributeString == "AXEnabled")
+ return checkElementState(m_element.get(), ATK_STATE_ENABLED);
+ if (attributeString == "AXExpanded")
+ return checkElementState(m_element.get(), ATK_STATE_EXPANDED);
+ if (attributeString == "AXFocused")
+ return checkElementState(m_element.get(), ATK_STATE_FOCUSED);
+ if (attributeString == "AXInvalid")
+ return checkElementState(m_element.get(), ATK_STATE_INVALID);
+ if (attributeString == "AXMultiSelectable")
+ return checkElementState(m_element.get(), ATK_STATE_MULTISELECTABLE);
+ if (attributeString == "AXRequired")
+ return checkElementState(m_element.get(), ATK_STATE_REQUIRED);
+ if (attributeString == "AXSelected")
+ return checkElementState(m_element.get(), ATK_STATE_SELECTED);
+ if (attributeString == "AXVisited")
+ return checkElementState(m_element.get(), ATK_STATE_VISITED);
+
return false;
}
@@ -852,8 +1082,51 @@ bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
return false;
String attributeString = jsStringToWTFString(attribute);
- if (attributeString == "AXValue")
- return checkElementState(m_element.get(), ATK_STATE_EDITABLE);
+ if (attributeString != "AXValue")
+ return false;
+
+ // ATK does not have a single state or property to indicate whether or not the value
+ // of an accessible object can be set. ATs look at several states and properties based
+ // on the type of object. If nothing explicitly indicates the value can or cannot be
+ // set, ATs make role- and interface-based decisions. We'll do something similar here.
+
+ // This state is expected to be present only for text widgets and contenteditable elements.
+ if (checkElementState(m_element.get(), ATK_STATE_EDITABLE))
+ return true;
+
+#if ATK_CHECK_VERSION(2,11,2)
+ // This state is applicable to checkboxes, radiobuttons, switches, etc.
+ if (checkElementState(m_element.get(), ATK_STATE_CHECKABLE))
+ return true;
+#endif
+
+#if ATK_CHECK_VERSION(2,15,3)
+ // This state is expected to be present only for controls and only if explicitly set.
+ if (checkElementState(m_element.get(), ATK_STATE_READ_ONLY))
+ return false;
+#endif
+
+ // We expose an object attribute to ATs when there is an author-provided ARIA property
+ // and also when there is a supported ARIA role but no author-provided value.
+ String isReadOnly = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "readonly");
+ if (!isReadOnly.isEmpty())
+ return isReadOnly == "true" ? false : true;
+
+ // If we have a native listbox or combobox and the value can be set, the options should
+ // have ATK_STATE_SELECTABLE.
+ AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
+ if (role == ATK_ROLE_LIST_BOX || role == ATK_ROLE_COMBO_BOX) {
+ if (GRefPtr<AtkObject> child = adoptGRef(atk_object_ref_accessible_child(ATK_OBJECT(m_element.get()), 0))) {
+ if (atk_object_get_role(ATK_OBJECT(child.get())) == ATK_ROLE_MENU)
+ child = adoptGRef(atk_object_ref_accessible_child(ATK_OBJECT(child.get()), 0));
+ return child && checkElementState(child.get(), ATK_STATE_SELECTABLE);
+ }
+ }
+
+ // If we have a native element which exposes a range whose value can be set, it should
+ // be focusable and have a true range.
+ if (ATK_IS_VALUE(m_element.get()) && checkElementState(m_element.get(), ATK_STATE_FOCUSABLE))
+ return minValue() != maxValue();
return false;
}
@@ -898,7 +1171,18 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole()
JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription()
{
- // FIXME: implement
+ String roleDescription = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "roledescription");
+ GUniquePtr<gchar> axRoleDescription(g_strdup_printf("AXRoleDescription: %s", roleDescription.utf8().data()));
+
+ return JSStringCreateWithUTF8CString(axRoleDescription.get());
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::computedRoleString()
+{
+ String role = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "computed-role");
+ if (!role.isEmpty())
+ return JSStringCreateWithUTF8CString(role.utf8().data());
+
return JSStringCreateWithCharacters(0, 0);
}
@@ -976,15 +1260,15 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const
AtkRelationSet* relationSet = atk_object_ref_relation_set(ATK_OBJECT(m_element.get()));
if (!relationSet)
- return nullptr;
+ return JSStringCreateWithCharacters(0, 0);
AtkRelation* relation = atk_relation_set_get_relation_by_type(relationSet, ATK_RELATION_DESCRIBED_BY);
if (!relation)
- return nullptr;
+ return JSStringCreateWithCharacters(0, 0);
GPtrArray* targetList = atk_relation_get_target(relation);
if (!targetList || !targetList->len)
- return nullptr;
+ return JSStringCreateWithCharacters(0, 0);
StringBuilder builder;
builder.append("AXHelp: ");
@@ -1008,8 +1292,12 @@ double AccessibilityUIElement::x()
if (!ATK_IS_COMPONENT(m_element.get()))
return 0;
- int x, y;
- atk_component_get_position(ATK_COMPONENT(m_element.get()), &x, &y, ATK_XY_SCREEN);
+ int x;
+#if ATK_CHECK_VERSION(2,11,90)
+ atk_component_get_extents(ATK_COMPONENT(m_element.get()), &x, nullptr, nullptr, nullptr, ATK_XY_SCREEN);
+#else
+ atk_component_get_position(ATK_COMPONENT(m_element.get()), &x, nullptr, ATK_XY_SCREEN);
+#endif
return x;
}
@@ -1018,8 +1306,12 @@ double AccessibilityUIElement::y()
if (!ATK_IS_COMPONENT(m_element.get()))
return 0;
- int x, y;
- atk_component_get_position(ATK_COMPONENT(m_element.get()), &x, &y, ATK_XY_SCREEN);
+ int y;
+#if ATK_CHECK_VERSION(2,11,90)
+ atk_component_get_extents(ATK_COMPONENT(m_element.get()), nullptr, &y, nullptr, nullptr, ATK_XY_SCREEN);
+#else
+ atk_component_get_position(ATK_COMPONENT(m_element.get()), nullptr, &y, ATK_XY_SCREEN);
+#endif
return y;
}
@@ -1028,8 +1320,12 @@ double AccessibilityUIElement::width()
if (!ATK_IS_COMPONENT(m_element.get()))
return 0;
- int width, height;
- atk_component_get_size(ATK_COMPONENT(m_element.get()), &width, &height);
+ int width;
+#if ATK_CHECK_VERSION(2,11,90)
+ atk_component_get_extents(ATK_COMPONENT(m_element.get()), nullptr, nullptr, &width, nullptr, ATK_XY_WINDOW);
+#else
+ atk_component_get_size(ATK_COMPONENT(m_element.get()), &width, nullptr);
+#endif
return width;
}
@@ -1038,8 +1334,12 @@ double AccessibilityUIElement::height()
if (!ATK_IS_COMPONENT(m_element.get()))
return 0;
- int width, height;
- atk_component_get_size(ATK_COMPONENT(m_element.get()), &width, &height);
+ int height;
+#if ATK_CHECK_VERSION(2,11,90)
+ atk_component_get_extents(ATK_COMPONENT(m_element.get()), nullptr, nullptr, nullptr, &height, ATK_XY_WINDOW);
+#else
+ atk_component_get_size(ATK_COMPONENT(m_element.get()), nullptr, &height);
+#endif
return height;
}
@@ -1048,11 +1348,13 @@ double AccessibilityUIElement::clickPointX()
if (!ATK_IS_COMPONENT(m_element.get()))
return 0;
- int x, y;
- atk_component_get_position(ATK_COMPONENT(m_element.get()), &x, &y, ATK_XY_WINDOW);
-
- int width, height;
- atk_component_get_size(ATK_COMPONENT(m_element.get()), &width, &height);
+ int x, width;
+#if ATK_CHECK_VERSION(2,11,90)
+ atk_component_get_extents(ATK_COMPONENT(m_element.get()), &x, nullptr, &width, nullptr, ATK_XY_WINDOW);
+#else
+ atk_component_get_position(ATK_COMPONENT(m_element.get()), &x, nullptr, ATK_XY_WINDOW);
+ atk_component_get_size(ATK_COMPONENT(m_element.get()), &width, nullptr);
+#endif
return x + width / 2.0;
}
@@ -1062,11 +1364,13 @@ double AccessibilityUIElement::clickPointY()
if (!ATK_IS_COMPONENT(m_element.get()))
return 0;
- int x, y;
- atk_component_get_position(ATK_COMPONENT(m_element.get()), &x, &y, ATK_XY_WINDOW);
-
- int width, height;
- atk_component_get_size(ATK_COMPONENT(m_element.get()), &width, &height);
+ int y, height;
+#if ATK_CHECK_VERSION(2,11,90)
+ atk_component_get_extents(ATK_COMPONENT(m_element.get()), nullptr, &y, nullptr, &height, ATK_XY_WINDOW);
+#else
+ atk_component_get_position(ATK_COMPONENT(m_element.get()), nullptr, &y, ATK_XY_WINDOW);
+ atk_component_get_size(ATK_COMPONENT(m_element.get()), nullptr, &height);
+#endif
return y + height / 2.0;
}
@@ -1077,11 +1381,17 @@ double AccessibilityUIElement::intValue() const
return 0;
if (ATK_IS_VALUE(m_element.get())) {
+#if ATK_CHECK_VERSION(2,11,92)
+ double value;
+ atk_value_get_value_and_text(ATK_VALUE(m_element.get()), &value, nullptr);
+ return value;
+#else
GValue value = G_VALUE_INIT;
atk_value_get_current_value(ATK_VALUE(m_element.get()), &value);
if (!G_VALUE_HOLDS_FLOAT(&value))
return 0;
return g_value_get_float(&value);
+#endif
}
// Consider headings as an special case when returning the "int value" of
@@ -1102,13 +1412,16 @@ double AccessibilityUIElement::minValue()
{
if (!ATK_IS_VALUE(m_element.get()))
return 0;
-
+#if ATK_CHECK_VERSION(2,11,92)
+ return rangeMinMaxValue(ATK_VALUE(m_element.get()), RangeLimitMinimum);
+#else
GValue value = G_VALUE_INIT;
atk_value_get_minimum_value(ATK_VALUE(m_element.get()), &value);
if (!G_VALUE_HOLDS_FLOAT(&value))
return 0;
return g_value_get_float(&value);
+#endif
}
double AccessibilityUIElement::maxValue()
@@ -1116,18 +1429,23 @@ double AccessibilityUIElement::maxValue()
if (!ATK_IS_VALUE(m_element.get()))
return 0;
+#if ATK_CHECK_VERSION(2,11,92)
+ return rangeMinMaxValue(ATK_VALUE(m_element.get()), RangeLimitMaximum);
+#else
GValue value = G_VALUE_INIT;
atk_value_get_maximum_value(ATK_VALUE(m_element.get()), &value);
if (!G_VALUE_HOLDS_FLOAT(&value))
return 0;
return g_value_get_float(&value);
+#endif
}
JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription()
{
- // FIXME: implement
- return JSStringCreateWithCharacters(0, 0);
+ String valueText = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "valuetext");
+ GUniquePtr<gchar> valueDescription(g_strdup_printf("AXValueDescription: %s", valueText.utf8().data()));
+ return JSStringCreateWithUTF8CString(valueDescription.get());
}
int AccessibilityUIElement::insertionPointLineNumber()
@@ -1142,7 +1460,7 @@ bool AccessibilityUIElement::isPressActionSupported()
return false;
const gchar* actionName = atk_action_get_name(ATK_ACTION(m_element.get()), 0);
- return equalIgnoringCase(actionName, String("press")) || equalIgnoringCase(actionName, String("jump"));
+ return equalLettersIgnoringASCIICase(String(actionName), "press") || equalLettersIgnoringASCIICase(String(actionName), "jump");
}
bool AccessibilityUIElement::isIncrementActionSupported()
@@ -1242,8 +1560,16 @@ int AccessibilityUIElement::lineForIndex(int index)
JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int line)
{
- // FIXME: implement
- return JSStringCreateWithCharacters(0, 0);
+ if (!ATK_IS_TEXT(m_element.get()))
+ return JSStringCreateWithCharacters(0, 0);
+
+ AtkText* text = ATK_TEXT(m_element.get());
+ gint startOffset = 0, endOffset = 0;
+ for (int i = 0; i <= line; ++i)
+ atk_text_get_string_at_offset(text, endOffset, ATK_TEXT_GRANULARITY_LINE, &startOffset, &endOffset);
+
+ GUniquePtr<gchar> range(g_strdup_printf("{%d, %d}", startOffset, endOffset - startOffset));
+ return JSStringCreateWithUTF8CString(range.get());
}
JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int x, int y)
@@ -1254,8 +1580,14 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int x, int y)
JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
{
- // FIXME: implement
- return JSStringCreateWithCharacters(0, 0);
+ if (!ATK_IS_TEXT(m_element.get()))
+ return JSStringCreateWithCharacters(0, 0);
+
+ AtkTextRectangle rect;
+ atk_text_get_range_extents(ATK_TEXT(m_element.get()), location, location + length, ATK_XY_WINDOW, &rect);
+
+ GUniquePtr<gchar> bounds(g_strdup_printf("{%d, %d, %d, %d}", rect.x, rect.y, rect.width, rect.height));
+ return JSStringCreateWithUTF8CString(bounds.get());
}
JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
@@ -1269,8 +1601,29 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned locatio
JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length)
{
- // FIXME: implement
- return JSStringCreateWithCharacters(0, 0);
+ if (!ATK_IS_TEXT(m_element.get()))
+ return JSStringCreateWithCharacters(0, 0);
+
+ StringBuilder builder;
+
+ // The default text attributes apply to the entire element.
+ builder.append("\n\tDefault text attributes:\n\t\t");
+ builder.append(attributeSetToString(getAttributeSet(m_element.get(), TextAttributeType), "\n\t\t"));
+
+ // The attribute run provides attributes specific to the range of text at the specified offset.
+ AtkAttributeSet* attributeSet;
+ AtkText* text = ATK_TEXT(m_element.get());
+ gint start = 0, end = 0;
+ for (int i = location; i < location + length; i = end) {
+ AtkAttributeSet* attributeSet = atk_text_get_run_attributes(text, i, &start, &end);
+ GUniquePtr<gchar> substring(replaceCharactersForResults(atk_text_get_text(text, start, end)));
+ builder.append(String::format("\n\tRange attributes for '%s':\n\t\t", substring.get()));
+ builder.append(attributeSetToString(attributeSet, "\n\t\t"));
+ }
+
+ atk_attribute_set_free(attributeSet);
+
+ return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
}
bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
@@ -1279,13 +1632,19 @@ bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location
return false;
}
-unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
+unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
{
// FIXME: implement
return 0;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
+{
+ // FIXME: implement
+ return nullptr;
+}
+
+JSRetainPtr<JSStringRef> AccessibilityUIElement::selectTextWithCriteria(JSContextRef context, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity)
{
// FIXME: implement
return nullptr;
@@ -1370,7 +1729,7 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange()
return indexRangeInTable(m_element.get(), false);
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
{
if (!ATK_IS_TABLE(m_element.get()))
return nullptr;
@@ -1378,16 +1737,16 @@ PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(u
// Adopt the AtkObject representing the cell because
// at_table_ref_at() transfers full ownership.
GRefPtr<AtkObject> foundCell = adoptGRef(atk_table_ref_at(ATK_TABLE(m_element.get()), row, col));
- return foundCell ? AccessibilityUIElement::create(foundCell.get()) : nullptr;
+ return foundCell ? AccessibilityUIElement::create(foundCell.get()).ptr() : nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
{
// FIXME: implement
return nullptr;
@@ -1445,6 +1804,30 @@ void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) c
// FIXME: implement
}
+void AccessibilityUIElement::setSelectedChildAtIndex(unsigned index) const
+{
+ if (!ATK_IS_SELECTION(m_element.get()))
+ return;
+
+ atk_selection_add_selection(ATK_SELECTION(m_element.get()), index);
+}
+
+void AccessibilityUIElement::removeSelectionAtIndex(unsigned index) const
+{
+ if (!ATK_IS_SELECTION(m_element.get()))
+ return;
+
+ atk_selection_remove_selection(ATK_SELECTION(m_element.get()), index);
+}
+
+void AccessibilityUIElement::clearSelectedChildren() const
+{
+ if (!ATK_IS_SELECTION(m_element.get()))
+ return;
+
+ atk_selection_clear_selection(ATK_SELECTION(m_element.get()));
+}
+
JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const
{
// FIXME: implement
@@ -1457,7 +1840,7 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding()
return JSStringCreateWithCharacters(0, 0);
AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
- if (role != ATK_ROLE_DOCUMENT_FRAME)
+ if (role != ATK_ROLE_DOCUMENT_WEB)
return JSStringCreateWithCharacters(0, 0);
return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element.get()), "Encoding"));
@@ -1469,7 +1852,7 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI()
return JSStringCreateWithCharacters(0, 0);
AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
- if (role != ATK_ROLE_DOCUMENT_FRAME)
+ if (role != ATK_ROLE_DOCUMENT_WEB)
return JSStringCreateWithCharacters(0, 0);
return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element.get()), "URI"));
@@ -1552,13 +1935,23 @@ bool AccessibilityUIElement::isIgnored() const
return false;
}
+bool AccessibilityUIElement::isSingleLine() const
+{
+ return checkElementState(m_element.get(), ATK_STATE_SINGLE_LINE);
+}
+
+bool AccessibilityUIElement::isMultiLine() const
+{
+ return checkElementState(m_element.get(), ATK_STATE_MULTI_LINE);
+}
+
bool AccessibilityUIElement::hasPopup() const
{
if (!ATK_IS_OBJECT(m_element.get()))
return false;
String hasPopupValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "haspopup");
- return equalIgnoringCase(hasPopupValue, "true");
+ return equalLettersIgnoringASCIICase(hasPopupValue, "true");
}
void AccessibilityUIElement::takeFocus()
@@ -1582,7 +1975,13 @@ void AccessibilityUIElement::removeSelection()
}
// Text markers
-PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::lineTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
+{
+ // FIXME: implement
+ return nullptr;
+}
+
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
{
// FIXME: implement
return nullptr;
@@ -1594,13 +1993,13 @@ int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange*
return 0;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker* textMarker)
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker* textMarker)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker* textMarker)
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker* textMarker)
{
// FIXME: implement
return nullptr;
@@ -1612,43 +2011,43 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(Access
return JSStringCreateWithCharacters(0, 0);
}
-PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForBounds(int x, int y, int width, int height)
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForBounds(int x, int y, int width, int height)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForBounds(int x, int y, int width, int height)
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForBounds(int x, int y, int width, int height)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y)
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
+RefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
{
// FIXME: implement
return nullptr;
@@ -1672,28 +2071,43 @@ bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker* textMark
return false;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int textIndex)
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int textIndex)
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarker()
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarker()
{
// FIXME: implement
return nullptr;
}
-PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarker()
+RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarker()
{
// FIXME: implement
return nullptr;
}
+bool AccessibilityUIElement::setSelectedVisibleTextRange(AccessibilityTextMarkerRange*)
+{
+ return false;
+}
+
void AccessibilityUIElement::scrollToMakeVisible()
{
// FIXME: implement
}
+
+void AccessibilityUIElement::scrollToGlobalPoint(int x, int y)
+{
+ // FIXME: implement
+}
+
+void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height)
+{
+ // FIXME: implement
+}
JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const
{
diff --git a/Tools/WebKitTestRunner/InjectedBundle/gtk/ActivateFontsGtk.cpp b/Tools/WebKitTestRunner/InjectedBundle/gtk/ActivateFontsGtk.cpp
index 7c9dab7b9..496c1bcbf 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/gtk/ActivateFontsGtk.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/gtk/ActivateFontsGtk.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2005, 2006 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2010 Igalia S.L.
*
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -34,8 +34,8 @@
#include "InjectedBundleUtilities.h"
#include <fontconfig/fontconfig.h>
#include <gtk/gtk.h>
-#include <wtf/gobject/GUniquePtr.h>
-#include <wtf/gobject/GlibUtilities.h>
+#include <wtf/glib/GLibUtilities.h>
+#include <wtf/glib/GUniquePtr.h>
namespace WTR {
@@ -68,7 +68,7 @@ CString getOutputDir()
static CString getFontsPath()
{
CString webkitOutputDir = getOutputDir();
- GUniquePtr<char> fontsPath(g_build_filename(webkitOutputDir.data(), "Dependencies", "Root", "webkitgtk-test-fonts", nullptr));
+ GUniquePtr<char> fontsPath(g_build_filename(webkitOutputDir.data(), "DependenciesGTK", "Root", "webkitgtk-test-fonts", nullptr));
if (g_file_test(fontsPath.get(), static_cast<GFileTest>(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
return fontsPath.get();
diff --git a/Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.cpp b/Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.cpp
index febdaad19..afbd3f74a 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -30,8 +30,8 @@
#include "InjectedBundleUtilities.h"
#include <gtk/gtk.h>
-#include <wtf/gobject/GUniquePtr.h>
-#include <wtf/gobject/GlibUtilities.h>
+#include <wtf/glib/GLibUtilities.h>
+#include <wtf/glib/GUniquePtr.h>
namespace WTR {
diff --git a/Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.h b/Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.h
index 50f89dead..4062c6d44 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleUtilities.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Tools/WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp b/Tools/WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp
index 254374884..a9f7f409c 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp
@@ -30,37 +30,25 @@
#include "InjectedBundle.h"
#include "InjectedBundleUtilities.h"
#include <glib.h>
-#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/glib/GUniquePtr.h>
namespace WTR {
-static gboolean waitToDumpWatchdogTimerCallback(gpointer)
-{
- InjectedBundle::shared().testRunner()->waitToDumpWatchdogTimerFired();
- return FALSE;
-}
-
void TestRunner::platformInitialize()
{
- m_waitToDumpWatchdogTimer = 0;
}
void TestRunner::invalidateWaitToDumpWatchdogTimer()
{
- if (!m_waitToDumpWatchdogTimer)
- return;
- g_source_remove(m_waitToDumpWatchdogTimer);
- m_waitToDumpWatchdogTimer = 0;
+ m_waitToDumpWatchdogTimer.stop();
}
void TestRunner::initializeWaitToDumpWatchdogTimerIfNeeded()
{
- if (m_waitToDumpWatchdogTimer)
+ if (m_waitToDumpWatchdogTimer.isActive())
return;
- m_waitToDumpWatchdogTimer = g_timeout_add(waitToDumpWatchdogTimerInterval * 1000,
- waitToDumpWatchdogTimerCallback, 0);
- g_source_set_name_by_id(m_waitToDumpWatchdogTimer, "[WebKit] waitToDumpWatchdogTimerCallback");
+ m_waitToDumpWatchdogTimer.startOneShot(m_timeout / 1000.0);
}
JSRetainPtr<JSStringRef> TestRunner::pathToLocalResource(JSStringRef url)
@@ -78,4 +66,9 @@ JSRetainPtr<JSStringRef> TestRunner::pathToLocalResource(JSStringRef url)
return JSStringCreateWithUTF8CString(testURI.get());
}
+JSRetainPtr<JSStringRef> TestRunner::inspectorTestStubURL()
+{
+ return JSStringCreateWithUTF8CString("resource:///org/webkitgtk/inspector/UserInterface/TestStub.html");
+}
+
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/Options.cpp b/Tools/WebKitTestRunner/Options.cpp
index 8fa6e6e0f..53f0253ac 100644
--- a/Tools/WebKitTestRunner/Options.cpp
+++ b/Tools/WebKitTestRunner/Options.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 University of Szeged. All rights reserved.
* Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,10 +32,8 @@
namespace WTR {
-Options::Options(double defaultLongTimeout, double defaultShortTimeout)
- : longTimeout(defaultLongTimeout)
- , shortTimeout(defaultShortTimeout)
- , useWaitToDumpWatchdogTimer(true)
+Options::Options()
+ : useWaitToDumpWatchdogTimer(true)
, forceNoTimeout(false)
, verbose(false)
, gcBetweenTests(false)
@@ -43,28 +42,13 @@ Options::Options(double defaultLongTimeout, double defaultShortTimeout)
, forceComplexText(false)
, shouldUseAcceleratedDrawing(false)
, shouldUseRemoteLayerTree(false)
- , defaultLongTimeout(defaultLongTimeout)
- , defaultShortTimeout(defaultShortTimeout)
+ , shouldShowWebView(false)
{
}
-bool handleOptionTimeout(Options& options, const char*, const char* argument)
-{
- options.longTimeout = atoi(argument);
- // Scale up the short timeout to match.
- options.shortTimeout = options.defaultShortTimeout * options.longTimeout / options.defaultLongTimeout;
- return true;
-}
-
bool handleOptionNoTimeout(Options& options, const char*, const char*)
{
options.useWaitToDumpWatchdogTimer = false;
- return true;
-}
-
-bool handleOptionNoTimeoutAtAll(Options& options, const char*, const char*)
-{
- options.useWaitToDumpWatchdogTimer = false;
options.forceNoTimeout = true;
return true;
}
@@ -111,6 +95,18 @@ bool handleOptionRemoteLayerTree(Options& options, const char*, const char*)
return true;
}
+bool handleOptionShowWebView(Options& options, const char*, const char*)
+{
+ options.shouldShowWebView = true;
+ return true;
+}
+
+bool handleOptionAllowedHost(Options& options, const char*, const char* host)
+{
+ options.allowedHosts.push_back(host);
+ return true;
+}
+
bool handleOptionUnmatched(Options& options, const char* option, const char*)
{
if (option[0] && option[1] && option[0] == '-' && option[1] == '-')
@@ -122,9 +118,7 @@ bool handleOptionUnmatched(Options& options, const char* option, const char*)
OptionsHandler::OptionsHandler(Options& o)
: options(o)
{
- optionList.append(Option("--timeout", "Sets long timeout to <param> and scales short timeout.", handleOptionTimeout, true));
- optionList.append(Option("--no-timeout", "Disables timeout.", handleOptionNoTimeout));
- optionList.append(Option("--no-timeout-at-all", "Disables all timeouts.", handleOptionNoTimeoutAtAll));
+ optionList.append(Option("--no-timeout", "Disables all timeouts.", handleOptionNoTimeout));
optionList.append(Option("--verbose", "Turns on messages.", handleOptionVerbose));
optionList.append(Option("--gc-between-tests", "Garbage collection between tests.", handleOptionGcBetweenTests));
optionList.append(Option("--pixel-tests", "Check pixels.", handleOptionPixelTests));
@@ -133,6 +127,9 @@ OptionsHandler::OptionsHandler(Options& o)
optionList.append(Option("--complex-text", "Force complex tests.", handleOptionComplexText));
optionList.append(Option("--accelerated-drawing", "Use accelerated drawing.", handleOptionAcceleratedDrawing));
optionList.append(Option("--remote-layer-tree", "Use remote layer tree.", handleOptionRemoteLayerTree));
+ optionList.append(Option("--allowed-host", "Allows access to the specified host from tests.", handleOptionAllowedHost, true));
+ optionList.append(Option("--show-webview", "Show the WebView during test runs (for Debugging)", handleOptionShowWebView));
+
optionList.append(Option(0, 0, handleOptionUnmatched));
}
diff --git a/Tools/WebKitTestRunner/Options.h b/Tools/WebKitTestRunner/Options.h
index a89d25c77..5549fe464 100644
--- a/Tools/WebKitTestRunner/Options.h
+++ b/Tools/WebKitTestRunner/Options.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 University of Szeged. All rights reserved.
* Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,9 +37,7 @@
namespace WTR {
struct Options {
- Options(double, double);
- double longTimeout;
- double shortTimeout;
+ Options();
bool useWaitToDumpWatchdogTimer;
bool forceNoTimeout;
bool verbose;
@@ -48,9 +47,9 @@ struct Options {
bool forceComplexText;
bool shouldUseAcceleratedDrawing;
bool shouldUseRemoteLayerTree;
+ bool shouldShowWebView;
std::vector<std::string> paths;
- double defaultLongTimeout;
- double defaultShortTimeout;
+ std::vector<std::string> allowedHosts;
};
class Option {
diff --git a/Tools/WebKitTestRunner/PixelDumpSupport.cpp b/Tools/WebKitTestRunner/PixelDumpSupport.cpp
index 76974737f..37b3047cb 100644
--- a/Tools/WebKitTestRunner/PixelDumpSupport.cpp
+++ b/Tools/WebKitTestRunner/PixelDumpSupport.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Tools/WebKitTestRunner/PixelDumpSupport.h b/Tools/WebKitTestRunner/PixelDumpSupport.h
index 41c6e38ea..324667f10 100644
--- a/Tools/WebKitTestRunner/PixelDumpSupport.h
+++ b/Tools/WebKitTestRunner/PixelDumpSupport.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Tools/WebKitTestRunner/PlatformGTK.cmake b/Tools/WebKitTestRunner/PlatformGTK.cmake
new file mode 100644
index 000000000..af53e220d
--- /dev/null
+++ b/Tools/WebKitTestRunner/PlatformGTK.cmake
@@ -0,0 +1,60 @@
+add_custom_target(WebKitTestRunner-forwarding-headers
+ COMMAND ${PERL_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-forwarding-headers.pl --include-path ${WEBKIT_TESTRUNNER_DIR} --include-path ${WEBKIT_TESTRUNNER_SHARED_DIR} --output ${FORWARDING_HEADERS_DIR} --platform gtk --platform soup
+)
+
+set(ForwardingHeadersForWebKitTestRunner_NAME WebKitTestRunner-forwarding-headers)
+
+list(APPEND WebKitTestRunner_SOURCES
+ ${WEBKIT_TESTRUNNER_DIR}/cairo/TestInvocationCairo.cpp
+
+ ${WEBKIT_TESTRUNNER_DIR}/gtk/EventSenderProxyGtk.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/gtk/PlatformWebViewGtk.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/gtk/TestControllerGtk.cpp
+ ${WEBKIT_TESTRUNNER_DIR}/gtk/main.cpp
+)
+
+list(APPEND WebKitTestRunner_INCLUDE_DIRECTORIES
+ ${FORWARDING_HEADERS_DIR}
+)
+
+list(APPEND WebKitTestRunner_SYSTEM_INCLUDE_DIRECTORIES
+ ${ATK_INCLUDE_DIRS}
+ ${CAIRO_INCLUDE_DIRS}
+ ${GTK3_INCLUDE_DIRS}
+ ${GLIB_INCLUDE_DIRS}
+)
+
+list(APPEND WebKitTestRunner_LIBRARIES
+ ${ATK_LIBRARIES}
+ ${CAIRO_LIBRARIES}
+ ${GTK3_LIBRARIES}
+ ${GLIB_LIBRARIES}
+ WTF
+ WebCore
+ WebCorePlatformGTK
+)
+
+set(WebKitTestRunnerInjectedBundle_LIBRARIES
+ ${ATK_LIBRARIES}
+ ${FONTCONFIG_LIBRARIES}
+ ${GLIB_LIBRARIES}
+ ${GTK3_LIBRARIES}
+ WebCoreTestSupport
+ WebKit2
+)
+
+list(APPEND WebKitTestRunnerInjectedBundle_SOURCES
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/atk/AccessibilityControllerAtk.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/atk/AccessibilityNotificationHandlerAtk.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/atk/AccessibilityUIElementAtk.cpp
+
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/gtk/ActivateFontsGtk.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/gtk/InjectedBundleGtk.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/gtk/InjectedBundleUtilities.cpp
+ ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/gtk/TestRunnerGtk.cpp
+)
+
+add_definitions(
+ -DFONTS_CONF_DIR="${TOOLS_DIR}/WebKitTestRunner/gtk/fonts"
+ -DTOP_LEVEL_DIR="${CMAKE_SOURCE_DIR}"
+)
diff --git a/Tools/WebKitTestRunner/PlatformWebView.h b/Tools/WebKitTestRunner/PlatformWebView.h
index fa8d1236c..aa0ab2e49 100644
--- a/Tools/WebKitTestRunner/PlatformWebView.h
+++ b/Tools/WebKitTestRunner/PlatformWebView.h
@@ -26,29 +26,28 @@
#ifndef PlatformWebView_h
#define PlatformWebView_h
-#include <WebKit2/WKRetainPtr.h>
+#include "TestOptions.h"
+#include <WebKit/WKRetainPtr.h>
-#if defined(__APPLE__) && __APPLE__
-#ifdef __OBJC__
-@class WKView;
-@class WebKitTestRunnerWindow;
+#if PLATFORM(COCOA) && !defined(BUILDING_GTK__)
+#include <WebKit/WKFoundation.h>
+OBJC_CLASS NSView;
+OBJC_CLASS UIView;
+OBJC_CLASS TestRunnerWKWebView;
+OBJC_CLASS WKWebViewConfiguration;
+OBJC_CLASS WebKitTestRunnerWindow;
+
+#if WK_API_ENABLED
+typedef TestRunnerWKWebView *PlatformWKView;
#else
-class WKView;
-class WebKitTestRunnerWindow;
+typedef NSView *PlatformWKView;
#endif
-typedef WKView* PlatformWKView;
-typedef WebKitTestRunnerWindow* PlatformWindow;
+typedef WebKitTestRunnerWindow *PlatformWindow;
#elif defined(BUILDING_GTK__)
typedef struct _GtkWidget GtkWidget;
typedef WKViewRef PlatformWKView;
typedef GtkWidget* PlatformWindow;
#elif PLATFORM(EFL)
-typedef struct _Ecore_Evas Ecore_Evas;
-#if USE(EO)
-typedef struct _Eo_Opaque Evas_Object;
-#else
-typedef struct _Evas_Object Evas_Object;
-#endif
typedef Evas_Object* PlatformWKView;
typedef Ecore_Evas* PlatformWindow;
#endif
@@ -57,43 +56,60 @@ namespace WTR {
class PlatformWebView {
public:
- PlatformWebView(WKContextRef, WKPageGroupRef, WKPageRef relatedPage, WKDictionaryRef options = 0);
+#if PLATFORM(COCOA)
+ PlatformWebView(WKWebViewConfiguration*, const TestOptions&);
+#else
+ PlatformWebView(WKPageConfigurationRef, const TestOptions&);
+#endif
~PlatformWebView();
WKPageRef page();
PlatformWKView platformView() { return m_view; }
PlatformWindow platformWindow() { return m_window; }
- void resizeTo(unsigned width, unsigned height);
- void focus();
+ static PlatformWindow keyWindow();
- // Window snapshot is always enabled by default on all other platform.
- static bool windowSnapshotEnabled() { return true; }
+ enum class WebViewSizingMode {
+ Default,
+ HeightRespectsStatusBar
+ };
+
+ void resizeTo(unsigned width, unsigned height, WebViewSizingMode = WebViewSizingMode::Default);
+ void focus();
WKRect windowFrame();
- void setWindowFrame(WKRect);
+ void setWindowFrame(WKRect, WebViewSizingMode = WebViewSizingMode::Default);
void didInitializeClients();
void addChromeInputField();
void removeChromeInputField();
void makeWebViewFirstResponder();
- void setWindowIsKey(bool isKey) { m_windowIsKey = isKey; }
+ void setWindowIsKey(bool);
bool windowIsKey() const { return m_windowIsKey; }
+
+ void removeFromWindow();
+ void addToWindow();
-#if PLATFORM(MAC) || PLATFORM(EFL)
- bool viewSupportsOptions(WKDictionaryRef) const;
-#else
- bool viewSupportsOptions(WKDictionaryRef) const { return true; }
-#endif
+ bool viewSupportsOptions(const TestOptions&) const;
WKRetainPtr<WKImageRef> windowSnapshotImage();
- WKDictionaryRef options() const { return m_options.get(); }
+ const TestOptions& options() const { return m_options; }
+
+ void changeWindowScaleIfNeeded(float newScale);
+ void setNavigationGesturesEnabled(bool);
+
+#if PLATFORM(GTK)
+ void dismissAllPopupMenus();
+#endif
private:
+ void forceWindowFramesChanged();
+
PlatformWKView m_view;
PlatformWindow m_window;
bool m_windowIsKey;
- WKRetainPtr<WKDictionaryRef> m_options;
+ const TestOptions m_options;
+
#if PLATFORM(EFL)
bool m_usingFixedLayout;
#endif
diff --git a/Tools/WebKitTestRunner/StringFunctions.h b/Tools/WebKitTestRunner/StringFunctions.h
index 551d86740..752731cbf 100644
--- a/Tools/WebKitTestRunner/StringFunctions.h
+++ b/Tools/WebKitTestRunner/StringFunctions.h
@@ -29,12 +29,12 @@
#include <JavaScriptCore/JSRetainPtr.h>
#include <JavaScriptCore/JavaScript.h>
+#include <WebKit/WKRetainPtr.h>
+#include <WebKit/WKString.h>
+#include <WebKit/WKStringPrivate.h>
+#include <WebKit/WKURL.h>
#include <sstream>
#include <string>
-#include <WebKit2/WKRetainPtr.h>
-#include <WebKit2/WKString.h>
-#include <WebKit2/WKStringPrivate.h>
-#include <WebKit2/WKURL.h>
#include <wtf/Platform.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
@@ -87,7 +87,7 @@ inline WTF::String toWTFString(WKStringRef string)
{
size_t bufferSize = WKStringGetMaximumUTF8CStringSize(string);
auto buffer = std::make_unique<char[]>(bufferSize);
- size_t stringLength = WKStringGetUTF8CString(string, buffer.get(), bufferSize);
+ size_t stringLength = WKStringGetUTF8CStringNonStrict(string, buffer.get(), bufferSize);
return WTF::String::fromUTF8WithLatin1Fallback(buffer.get(), stringLength - 1);
}
diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp
index 397815e63..df5392e74 100644
--- a/Tools/WebKitTestRunner/TestController.cpp
+++ b/Tools/WebKitTestRunner/TestController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2014-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,33 +31,55 @@
#include "PlatformWebView.h"
#include "StringFunctions.h"
#include "TestInvocation.h"
-#include <WebKit2/WKAuthenticationChallenge.h>
-#include <WebKit2/WKAuthenticationDecisionListener.h>
-#include <WebKit2/WKContextPrivate.h>
-#include <WebKit2/WKCredential.h>
-#include <WebKit2/WKIconDatabase.h>
-#include <WebKit2/WKNotification.h>
-#include <WebKit2/WKNotificationManager.h>
-#include <WebKit2/WKNotificationPermissionRequest.h>
-#include <WebKit2/WKNumber.h>
-#include <WebKit2/WKPageGroup.h>
-#include <WebKit2/WKPagePrivate.h>
-#include <WebKit2/WKPreferencesPrivate.h>
-#include <WebKit2/WKRetainPtr.h>
+#include "WebCoreTestSupport.h"
+#include <WebCore/UUID.h>
+#include <WebKit/WKArray.h>
+#include <WebKit/WKAuthenticationChallenge.h>
+#include <WebKit/WKAuthenticationDecisionListener.h>
+#include <WebKit/WKContextConfigurationRef.h>
+#include <WebKit/WKContextPrivate.h>
+#include <WebKit/WKCookieManager.h>
+#include <WebKit/WKCredential.h>
+#include <WebKit/WKFrameHandleRef.h>
+#include <WebKit/WKFrameInfoRef.h>
+#include <WebKit/WKIconDatabase.h>
+#include <WebKit/WKNavigationResponseRef.h>
+#include <WebKit/WKNotification.h>
+#include <WebKit/WKNotificationManager.h>
+#include <WebKit/WKNotificationPermissionRequest.h>
+#include <WebKit/WKNumber.h>
+#include <WebKit/WKOpenPanelResultListener.h>
+#include <WebKit/WKPageGroup.h>
+#include <WebKit/WKPageInjectedBundleClient.h>
+#include <WebKit/WKPagePrivate.h>
+#include <WebKit/WKPluginInformation.h>
+#include <WebKit/WKPreferencesRefPrivate.h>
+#include <WebKit/WKProtectionSpace.h>
+#include <WebKit/WKResourceLoadStatisticsManager.h>
+#include <WebKit/WKRetainPtr.h>
+#include <WebKit/WKSecurityOriginRef.h>
+#include <WebKit/WKTextChecker.h>
+#include <WebKit/WKUserMediaPermissionCheck.h>
#include <algorithm>
#include <cstdio>
#include <ctype.h>
+#include <fstream>
+#include <runtime/InitializeThreading.h>
#include <stdlib.h>
#include <string>
-#include <wtf/PassOwnPtr.h>
+#include <unistd.h>
+#include <wtf/CryptographicallyRandomNumber.h>
+#include <wtf/HexNumber.h>
+#include <wtf/MainThread.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RunLoop.h>
+#include <wtf/SetForScope.h>
#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
-#if PLATFORM(MAC)
-#include <WebKit2/WKPagePrivateMac.h>
-#endif
-
-#if !PLATFORM(MAC)
-#include <WebKit2/WKTextChecker.h>
+#if PLATFORM(COCOA)
+#include <WebKit/WKContextPrivateMac.h>
+#include <WebKit/WKPagePrivateMac.h>
#endif
namespace WTR {
@@ -68,12 +90,9 @@ const unsigned TestController::viewHeight = 600;
const unsigned TestController::w3cSVGViewWidth = 480;
const unsigned TestController::w3cSVGViewHeight = 360;
-// defaultLongTimeout + defaultShortTimeout should be less than 80,
-// the default timeout value of the test harness so we can detect an
-// unresponsive web process.
-static const double defaultLongTimeout = 60;
-static const double defaultShortTimeout = 15;
-static const double defaultNoTimeout = -1;
+const double TestController::defaultShortTimeout = 5.0;
+
+const double TestController::noTimeout = -1;
static WKURLRef blankURL()
{
@@ -81,40 +100,21 @@ static WKURLRef blankURL()
return staticBlankURL;
}
+static WKDataRef copyWebCryptoMasterKey(WKPageRef, const void*)
+{
+ // Any 128 bit key would do, all we need for testing is to implement the callback.
+ return WKDataCreate((const uint8_t*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16);
+}
+
static TestController* controller;
-TestController& TestController::shared()
+TestController& TestController::singleton()
{
ASSERT(controller);
return *controller;
}
TestController::TestController(int argc, const char* argv[])
- : m_verbose(false)
- , m_printSeparators(false)
- , m_usingServerMode(false)
- , m_gcBetweenTests(false)
- , m_shouldDumpPixelsForAllTests(false)
- , m_state(Initial)
- , m_doneResetting(false)
- , m_longTimeout(defaultLongTimeout)
- , m_shortTimeout(defaultShortTimeout)
- , m_noTimeout(defaultNoTimeout)
- , m_useWaitToDumpWatchdogTimer(true)
- , m_forceNoTimeout(false)
- , m_timeout(0)
- , m_didPrintWebProcessCrashedMessage(false)
- , m_shouldExitWhenWebProcessCrashes(true)
- , m_beforeUnloadReturnValue(true)
- , m_isGeolocationPermissionSet(false)
- , m_isGeolocationPermissionAllowed(false)
- , m_policyDelegateEnabled(false)
- , m_policyDelegatePermissive(false)
- , m_handlesAuthenticationChallenges(false)
- , m_shouldBlockAllPlugins(false)
- , m_forceComplexText(false)
- , m_shouldUseAcceleratedDrawing(false)
- , m_shouldUseRemoteLayerTree(false)
{
initialize(argc, argv);
controller = this;
@@ -124,7 +124,9 @@ TestController::TestController(int argc, const char* argv[])
TestController::~TestController()
{
- WKIconDatabaseClose(WKContextGetIconDatabase(m_context.get()));
+ // The context will be null if WebKitTestRunner was in server mode, but ran no tests.
+ if (m_context)
+ WKIconDatabaseClose(WKContextGetIconDatabase(m_context.get()));
platformDestroy();
}
@@ -144,7 +146,13 @@ static void setWindowFrame(WKPageRef page, WKRect frame, const void* clientInfo)
static bool runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKFrameRef frame, const void*)
{
printf("CONFIRM NAVIGATION: %s\n", toSTD(message).c_str());
- return TestController::shared().beforeUnloadReturnValue();
+ return TestController::singleton().beforeUnloadReturnValue();
+}
+
+static void runOpenPanel(WKPageRef page, WKFrameRef frame, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef resultListenerRef, const void*)
+{
+ printf("OPEN FILE PANEL\n");
+ WKOpenPanelResultListenerCancel(resultListenerRef);
}
void TestController::runModal(WKPageRef page, const void* clientInfo)
@@ -177,34 +185,44 @@ static void unfocus(WKPageRef page, const void* clientInfo)
static void decidePolicyForGeolocationPermissionRequest(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKGeolocationPermissionRequestRef permissionRequest, const void* clientInfo)
{
- TestController::shared().handleGeolocationPermissionRequest(permissionRequest);
+ TestController::singleton().handleGeolocationPermissionRequest(permissionRequest);
}
-int TestController::getCustomTimeout()
+static void decidePolicyForUserMediaPermissionRequest(WKPageRef, WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionRequestRef permissionRequest, const void* clientInfo)
{
- return m_timeout;
+ TestController::singleton().handleUserMediaPermissionRequest(frame, userMediaDocumentOrigin, topLevelDocumentOrigin, permissionRequest);
}
-WKPageRef TestController::createOtherPage(WKPageRef oldPage, WKURLRequestRef, WKDictionaryRef, WKEventModifiers, WKEventMouseButton, const void* clientInfo)
+static void checkUserMediaPermissionForOrigin(WKPageRef, WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionCheckRef checkRequest, const void*)
+{
+ TestController::singleton().handleCheckOfUserMediaPermissionForOrigin(frame, userMediaDocumentOrigin, topLevelDocumentOrigin, checkRequest);
+}
+
+static void requestPointerLock(WKPageRef page, const void*)
+{
+ WKPageDidAllowPointerLock(page);
+}
+
+WKPageRef TestController::createOtherPage(WKPageRef oldPage, WKPageConfigurationRef configuration, WKNavigationActionRef navigationAction, WKWindowFeaturesRef windowFeatures, const void *clientInfo)
{
PlatformWebView* parentView = static_cast<PlatformWebView*>(const_cast<void*>(clientInfo));
- PlatformWebView* view = new PlatformWebView(WKPageGetContext(oldPage), WKPageGetPageGroup(oldPage), oldPage, parentView->options());
+ PlatformWebView* view = platformCreateOtherPage(parentView, configuration, parentView->options());
WKPageRef newPage = view->page();
view->resizeTo(800, 600);
- WKPageUIClientV2 otherPageUIClient = {
- { 2, view },
+ WKPageUIClientV8 otherPageUIClient = {
+ { 8, view },
0, // createNewPage_deprecatedForUseWithV0
0, // showPage
closeOtherPage,
0, // takeFocus
focus,
unfocus,
- 0, // runJavaScriptAlert
- 0, // runJavaScriptConfirm
- 0, // runJavaScriptPrompt
+ 0, // runJavaScriptAlert_deprecatedForUseWithV0
+ 0, // runJavaScriptAlert_deprecatedForUseWithV0
+ 0, // runJavaScriptAlert_deprecatedForUseWithV0
0, // setStatusText
0, // mouseDidMoveOverElement_deprecatedForUseWithV0
0, // missingPluginButtonClicked
@@ -224,7 +242,7 @@ WKPageRef TestController::createOtherPage(WKPageRef oldPage, WKURLRequestRef, WK
0, // didDraw
0, // pageDidScroll
0, // exceededDatabaseQuota
- 0, // runOpenPanel
+ runOpenPanel,
decidePolicyForGeolocationPermissionRequest,
0, // headerHeight
0, // footerHeight
@@ -235,18 +253,66 @@ WKPageRef TestController::createOtherPage(WKPageRef oldPage, WKURLRequestRef, WK
0, // didCompleteRubberBandForMainFrame
0, // saveDataToFileInDownloadsFolder
0, // shouldInterruptJavaScript
- createOtherPage,
+ 0, // createNewPage_deprecatedForUseWithV1
0, // mouseDidMoveOverElement
0, // decidePolicyForNotificationPermissionRequest
0, // unavailablePluginButtonClicked_deprecatedForUseWithV1
0, // showColorPicker
0, // hideColorPicker
0, // unavailablePluginButtonClicked
+ 0, // pinnedStateDidChange
+ 0, // didBeginTrackingPotentialLongMousePress
+ 0, // didRecognizeLongMousePress
+ 0, // didCancelTrackingPotentialLongMousePress
+ 0, // isPlayingAudioDidChange
+ decidePolicyForUserMediaPermissionRequest,
+ 0, // didClickAutofillButton
+ 0, // runJavaScriptAlert
+ 0, // runJavaScriptConfirm
+ 0, // runJavaScriptPrompt
+ 0, // mediaSessionMetadataDidChange
+ createOtherPage,
+ 0, // runJavaScriptAlert
+ 0, // runJavaScriptConfirm
+ 0, // runJavaScriptPrompt
+ checkUserMediaPermissionForOrigin,
+ 0, // runBeforeUnloadConfirmPanel
+ 0, // fullscreenMayReturnToInline
+ requestPointerLock,
+ 0,
};
WKPageSetPageUIClient(newPage, &otherPageUIClient.base);
+
+ WKPageNavigationClientV0 pageNavigationClient = {
+ { 0, &TestController::singleton() },
+ decidePolicyForNavigationAction,
+ decidePolicyForNavigationResponse,
+ decidePolicyForPluginLoad,
+ 0, // didStartProvisionalNavigation
+ 0, // didReceiveServerRedirectForProvisionalNavigation
+ 0, // didFailProvisionalNavigation
+ 0, // didCommitNavigation
+ 0, // didFinishNavigation
+ 0, // didFailNavigation
+ 0, // didFailProvisionalLoadInSubframe
+ 0, // didFinishDocumentLoad
+ 0, // didSameDocumentNavigation
+ 0, // renderingProgressDidChange
+ canAuthenticateAgainstProtectionSpace,
+ didReceiveAuthenticationChallenge,
+ processDidCrash,
+ copyWebCryptoMasterKey,
+ didBeginNavigationGesture,
+ willEndNavigationGesture,
+ didEndNavigationGesture,
+ didRemoveNavigationGestureSnapshot
+ };
+ WKPageSetPageNavigationClient(newPage, &pageNavigationClient.base);
view->didInitializeClients();
+ TestController::singleton().updateWindowScaleForTest(view, *TestController::singleton().m_currentInvocation);
+
WKRetain(newPage);
return newPage;
}
@@ -262,12 +328,14 @@ const char* TestController::libraryPathForTesting()
return platformLibraryPathForTesting();
}
-
void TestController::initialize(int argc, const char* argv[])
{
+ JSC::initializeThreading();
+ RunLoop::initializeMainRunLoop();
+
platformInitialize();
- Options options(defaultLongTimeout, defaultShortTimeout);
+ Options options;
OptionsHandler optionsHandler(options);
if (argc < 2) {
@@ -277,8 +345,6 @@ void TestController::initialize(int argc, const char* argv[])
if (!optionsHandler.parse(argc, argv))
exit(1);
- m_longTimeout = options.longTimeout;
- m_shortTimeout = options.shortTimeout;
m_useWaitToDumpWatchdogTimer = options.useWaitToDumpWatchdogTimer;
m_forceNoTimeout = options.forceNoTimeout;
m_verbose = options.verbose;
@@ -288,6 +354,8 @@ void TestController::initialize(int argc, const char* argv[])
m_shouldUseAcceleratedDrawing = options.shouldUseAcceleratedDrawing;
m_shouldUseRemoteLayerTree = options.shouldUseRemoteLayerTree;
m_paths = options.paths;
+ m_allowedHosts = options.allowedHosts;
+ m_shouldShowWebView = options.shouldShowWebView;
if (options.printSupportedFeatures) {
// FIXME: On Windows, DumpRenderTree uses this to expose whether it supports 3d
@@ -305,32 +373,50 @@ void TestController::initialize(int argc, const char* argv[])
initializeInjectedBundlePath();
initializeTestPluginDirectory();
+#if PLATFORM(MAC)
+ WebCoreTestSupport::installMockGamepadProvider();
+#endif
WKRetainPtr<WKStringRef> pageGroupIdentifier(AdoptWK, WKStringCreateWithUTF8CString("WebKitTestRunnerPageGroup"));
m_pageGroup.adopt(WKPageGroupCreateWithIdentifier(pageGroupIdentifier.get()));
+}
- m_context.adopt(WKContextCreateWithInjectedBundlePath(injectedBundlePath()));
- m_geolocationProvider = adoptPtr(new GeolocationProviderMock(m_context.get()));
-
-#if PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED > 1080)
- WKContextSetUsesNetworkProcess(m_context.get(), true);
- WKContextSetProcessModel(m_context.get(), kWKProcessModelMultipleSecondaryProcesses);
-#endif
+WKRetainPtr<WKContextConfigurationRef> TestController::generateContextConfiguration() const
+{
+ auto configuration = adoptWK(WKContextConfigurationCreate());
+ WKContextConfigurationSetInjectedBundlePath(configuration.get(), injectedBundlePath());
+ WKContextConfigurationSetFullySynchronousModeIsAllowedForTesting(configuration.get(), true);
if (const char* dumpRenderTreeTemp = libraryPathForTesting()) {
String temporaryFolder = String::fromUTF8(dumpRenderTreeTemp);
- // WebCore::pathByAppendingComponent is not used here because of the namespace,
- // which leads us to this ugly #ifdef and file path concatenation.
const char separator = '/';
- WKContextSetApplicationCacheDirectory(m_context.get(), toWK(temporaryFolder + separator + "ApplicationCache").get());
- WKContextSetDatabaseDirectory(m_context.get(), toWK(temporaryFolder + separator + "Databases").get());
- WKContextSetLocalStorageDirectory(m_context.get(), toWK(temporaryFolder + separator + "LocalStorage").get());
- WKContextSetDiskCacheDirectory(m_context.get(), toWK(temporaryFolder + separator + "Cache").get());
- WKContextSetCookieStorageDirectory(m_context.get(), toWK(temporaryFolder + separator + "Cookies").get());
- WKContextSetIconDatabasePath(m_context.get(), toWK(temporaryFolder + separator + "IconDatabase" + separator + "WebpageIcons.db").get());
+ WKContextConfigurationSetApplicationCacheDirectory(configuration.get(), toWK(temporaryFolder + separator + "ApplicationCache").get());
+ WKContextConfigurationSetDiskCacheDirectory(configuration.get(), toWK(temporaryFolder + separator + "Cache").get());
+ WKContextConfigurationSetIndexedDBDatabaseDirectory(configuration.get(), toWK(temporaryFolder + separator + "Databases" + separator + "IndexedDB").get());
+ WKContextConfigurationSetLocalStorageDirectory(configuration.get(), toWK(temporaryFolder + separator + "LocalStorage").get());
+ WKContextConfigurationSetWebSQLDatabaseDirectory(configuration.get(), toWK(temporaryFolder + separator + "Databases" + separator + "WebSQL").get());
+ WKContextConfigurationSetMediaKeysStorageDirectory(configuration.get(), toWK(temporaryFolder + separator + "MediaKeys").get());
+ }
+ return configuration;
+}
+
+WKRetainPtr<WKPageConfigurationRef> TestController::generatePageConfiguration(WKContextConfigurationRef configuration)
+{
+ m_context = platformAdjustContext(adoptWK(WKContextCreateWithConfiguration(configuration)).get(), configuration);
+
+ m_geolocationProvider = std::make_unique<GeolocationProviderMock>(m_context.get());
+
+ if (const char* dumpRenderTreeTemp = libraryPathForTesting()) {
+ String temporaryFolder = String::fromUTF8(dumpRenderTreeTemp);
+
+ // FIXME: This should be migrated to WKContextConfigurationRef.
+ // Disable icon database to avoid fetching <http://127.0.0.1:8000/favicon.ico> and making tests flaky.
+ // Invividual tests can enable it using testRunner.setIconDatabaseEnabled, although it's not currently supported in WebKitTestRunner.
+ WKContextSetIconDatabasePath(m_context.get(), toWK(emptyString()).get());
}
+ WKContextSetDiskCacheSpeculativeValidationEnabled(m_context.get(), true);
WKContextUseTestingNetworkSession(m_context.get());
WKContextSetCacheModel(m_context.get(), kWKCacheModelDocumentBrowser);
@@ -340,10 +426,30 @@ void TestController::initialize(int argc, const char* argv[])
{ 1, this },
didReceiveMessageFromInjectedBundle,
didReceiveSynchronousMessageFromInjectedBundle,
- 0 // getInjectedBundleInitializationUserData
+ getInjectedBundleInitializationUserData,
};
WKContextSetInjectedBundleClient(m_context.get(), &injectedBundleClient.base);
+ WKContextClientV2 contextClient = {
+ { 2, this },
+ 0, // plugInAutoStartOriginHashesChanged
+ networkProcessDidCrash,
+ 0, // plugInInformationBecameAvailable
+ 0, // copyWebCryptoMasterKey
+ databaseProcessDidCrash,
+ };
+ WKContextSetClient(m_context.get(), &contextClient.base);
+
+ WKContextHistoryClientV0 historyClient = {
+ { 0, this },
+ didNavigateWithNavigationData,
+ didPerformClientRedirect,
+ didPerformServerRedirect,
+ didUpdateHistoryTitle,
+ 0, // populateVisitedLinks
+ };
+ WKContextSetHistoryClient(m_context.get(), &historyClient.base);
+
WKNotificationManagerRef notificationManager = WKContextGetNotificationManager(m_context.get());
WKNotificationProviderV0 notificationKit = m_webNotificationProvider.provider();
WKNotificationManagerSetProvider(notificationManager, &notificationKit.base);
@@ -354,34 +460,40 @@ void TestController::initialize(int argc, const char* argv[])
if (m_forceComplexText)
WKContextSetAlwaysUsesComplexTextCodePath(m_context.get(), true);
- // Some preferences (notably mock scroll bars setting) currently cannot be re-applied to an existing view, so we need to set them now.
- resetPreferencesToConsistentValues();
-
- WKRetainPtr<WKMutableDictionaryRef> viewOptions;
- if (m_shouldUseRemoteLayerTree) {
- viewOptions = adoptWK(WKMutableDictionaryCreate());
- WKRetainPtr<WKStringRef> useRemoteLayerTreeKey = adoptWK(WKStringCreateWithUTF8CString("RemoteLayerTree"));
- WKRetainPtr<WKBooleanRef> useRemoteLayerTreeValue = adoptWK(WKBooleanCreate(m_shouldUseRemoteLayerTree));
- WKDictionarySetItem(viewOptions.get(), useRemoteLayerTreeKey.get(), useRemoteLayerTreeValue.get());
- }
-
- createWebViewWithOptions(viewOptions.get());
+ auto pageConfiguration = adoptWK(WKPageConfigurationCreate());
+ WKPageConfigurationSetContext(pageConfiguration.get(), m_context.get());
+ WKPageConfigurationSetPageGroup(pageConfiguration.get(), m_pageGroup.get());
+ WKPageConfigurationSetUserContentController(pageConfiguration.get(), adoptWK(WKUserContentControllerCreate()).get());
+ return pageConfiguration;
}
-void TestController::createWebViewWithOptions(WKDictionaryRef options)
+void TestController::createWebViewWithOptions(const TestOptions& options)
{
- m_mainWebView = adoptPtr(new PlatformWebView(m_context.get(), m_pageGroup.get(), 0, options));
- WKPageUIClientV2 pageUIClient = {
- { 2, m_mainWebView.get() },
+ auto contextConfiguration = generateContextConfiguration();
+
+ WKRetainPtr<WKMutableArrayRef> overrideLanguages = adoptWK(WKMutableArrayCreate());
+ for (auto& language : options.overrideLanguages)
+ WKArrayAppendItem(overrideLanguages.get(), adoptWK(WKStringCreateWithUTF8CString(language.utf8().data())).get());
+ WKContextConfigurationSetOverrideLanguages(contextConfiguration.get(), overrideLanguages.get());
+
+ auto configuration = generatePageConfiguration(contextConfiguration.get());
+
+ // Some preferences (notably mock scroll bars setting) currently cannot be re-applied to an existing view, so we need to set them now.
+ // FIXME: Migrate these preferences to WKContextConfigurationRef.
+ resetPreferencesToConsistentValues(options);
+
+ platformCreateWebView(configuration.get(), options);
+ WKPageUIClientV8 pageUIClient = {
+ { 8, m_mainWebView.get() },
0, // createNewPage_deprecatedForUseWithV0
0, // showPage
0, // close
0, // takeFocus
focus,
unfocus,
- 0, // runJavaScriptAlert
- 0, // runJavaScriptConfirm
- 0, // runJavaScriptPrompt
+ 0, // runJavaScriptAlert_deprecatedForUseWithV0
+ 0, // runJavaScriptAlert_deprecatedForUseWithV0
+ 0, // runJavaScriptAlert_deprecatedForUseWithV0
0, // setStatusText
0, // mouseDidMoveOverElement_deprecatedForUseWithV0
0, // missingPluginButtonClicked
@@ -401,7 +513,7 @@ void TestController::createWebViewWithOptions(WKDictionaryRef options)
0, // didDraw
0, // pageDidScroll
0, // exceededDatabaseQuota,
- 0, // runOpenPanel
+ runOpenPanel,
decidePolicyForGeolocationPermissionRequest,
0, // headerHeight
0, // footerHeight
@@ -412,98 +524,128 @@ void TestController::createWebViewWithOptions(WKDictionaryRef options)
0, // didCompleteRubberBandForMainFrame
0, // saveDataToFileInDownloadsFolder
0, // shouldInterruptJavaScript
- createOtherPage,
+ 0, // createNewPage_deprecatedForUseWithV1
0, // mouseDidMoveOverElement
decidePolicyForNotificationPermissionRequest, // decidePolicyForNotificationPermissionRequest
0, // unavailablePluginButtonClicked_deprecatedForUseWithV1
0, // showColorPicker
0, // hideColorPicker
unavailablePluginButtonClicked,
+ 0, // pinnedStateDidChange
+ 0, // didBeginTrackingPotentialLongMousePress
+ 0, // didRecognizeLongMousePress
+ 0, // didCancelTrackingPotentialLongMousePress
+ 0, // isPlayingAudioDidChange
+ decidePolicyForUserMediaPermissionRequest,
+ 0, // didClickAutofillButton
+ 0, // runJavaScriptAlert
+ 0, // runJavaScriptConfirm
+ 0, // runJavaScriptPrompt
+ 0, // mediaSessionMetadataDidChange
+ createOtherPage,
+ 0, // runJavaScriptAlert
+ 0, // runJavaScriptConfirm
+ 0, // runJavaScriptPrompt
+ checkUserMediaPermissionForOrigin,
+ 0, // runBeforeUnloadConfirmPanel
+ 0, // fullscreenMayReturnToInline
+ requestPointerLock,
+ 0,
};
WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient.base);
- WKPageLoaderClientV4 pageLoaderClient = {
- { 4, this },
- 0, // didStartProvisionalLoadForFrame
- 0, // didReceiveServerRedirectForProvisionalLoadForFrame
- 0, // didFailProvisionalLoadWithErrorForFrame
- didCommitLoadForFrame,
- 0, // didFinishDocumentLoadForFrame
- didFinishLoadForFrame,
- 0, // didFailLoadWithErrorForFrame
- 0, // didSameDocumentNavigationForFrame
- 0, // didReceiveTitleForFrame
- 0, // didFirstLayoutForFrame
- 0, // didFirstVisuallyNonEmptyLayoutForFrame
- 0, // didRemoveFrameFromHierarchy
- 0, // didFailToInitializePlugin
- 0, // didDisplayInsecureContentForFrame
- 0, // canAuthenticateAgainstProtectionSpaceInFrame
- didReceiveAuthenticationChallengeInFrame, // didReceiveAuthenticationChallengeInFrame
- 0, // didStartProgress
- 0, // didChangeProgress
- 0, // didFinishProgress
- 0, // didBecomeUnresponsive
- 0, // didBecomeResponsive
+ WKPageNavigationClientV0 pageNavigationClient = {
+ { 0, this },
+ decidePolicyForNavigationAction,
+ decidePolicyForNavigationResponse,
+ decidePolicyForPluginLoad,
+ 0, // didStartProvisionalNavigation
+ 0, // didReceiveServerRedirectForProvisionalNavigation
+ 0, // didFailProvisionalNavigation
+ didCommitNavigation,
+ didFinishNavigation,
+ 0, // didFailNavigation
+ 0, // didFailProvisionalLoadInSubframe
+ 0, // didFinishDocumentLoad
+ 0, // didSameDocumentNavigation
+ 0, // renderingProgressDidChange
+ canAuthenticateAgainstProtectionSpace,
+ didReceiveAuthenticationChallenge,
processDidCrash,
- 0, // didChangeBackForwardList
- 0, // shouldGoToBackForwardListItem
- 0, // didRunInsecureContentForFrame
- 0, // didDetectXSSForFrame
- 0, // didNewFirstVisuallyNonEmptyLayout_unavailable
- 0, // willGoToBackForwardListItem
- 0, // interactionOccurredWhileProcessUnresponsive
- 0, // pluginDidFail_deprecatedForUseWithV1
- 0, // didReceiveIntentForFrame
- 0, // registerIntentServiceForFrame
- 0, // didLayout
- 0, // pluginLoadPolicy_deprecatedForUseWithV2
- 0, // pluginDidFail
- pluginLoadPolicy, // pluginLoadPolicy
- 0, // webGLLoadPolicy
+ copyWebCryptoMasterKey,
+ didBeginNavigationGesture,
+ willEndNavigationGesture,
+ didEndNavigationGesture,
+ didRemoveNavigationGestureSnapshot
};
- WKPageSetPageLoaderClient(m_mainWebView->page(), &pageLoaderClient.base);
-
- WKPagePolicyClientV1 pagePolicyClient = {
- { 1, this },
- 0, // decidePolicyForNavigationAction_deprecatedForUseWithV0
- 0, // decidePolicyForNewWindowAction
- 0, // decidePolicyForResponse_deprecatedForUseWithV0
- 0, // unableToImplementPolicy
- decidePolicyForNavigationAction,
- decidePolicyForResponse,
+ WKPageSetPageNavigationClient(m_mainWebView->page(), &pageNavigationClient.base);
+
+ WKContextDownloadClientV0 downloadClient = {
+ { 0, this },
+ downloadDidStart,
+ 0, // didReceiveAuthenticationChallenge
+ 0, // didReceiveResponse
+ 0, // didReceiveData
+ 0, // shouldDecodeSourceDataOfMIMEType
+ decideDestinationWithSuggestedFilename,
+ 0, // didCreateDestination
+ downloadDidFinish,
+ downloadDidFail,
+ downloadDidCancel,
+ 0 // processDidCrash;
+ };
+ WKContextSetDownloadClient(context(), &downloadClient.base);
+
+ // this should just be done on the page?
+ WKPageInjectedBundleClientV0 injectedBundleClient = {
+ { 0, this },
+ didReceivePageMessageFromInjectedBundle,
+ didReceiveSynchronousPageMessageFromInjectedBundle
};
- WKPageSetPagePolicyClient(m_mainWebView->page(), &pagePolicyClient.base);
+ WKPageSetPageInjectedBundleClient(m_mainWebView->page(), &injectedBundleClient.base);
m_mainWebView->didInitializeClients();
+
+ // Generally, the tests should default to running at 1x. updateWindowScaleForTest() will adjust the scale to
+ // something else for specific tests that need to run at a different window scale.
+ m_mainWebView->changeWindowScaleIfNeeded(1);
}
-void TestController::ensureViewSupportsOptions(WKDictionaryRef options)
+void TestController::ensureViewSupportsOptionsForTest(const TestInvocation& test)
{
- if (m_mainWebView && !m_mainWebView->viewSupportsOptions(options)) {
- WKPageSetPageUIClient(m_mainWebView->page(), 0);
- WKPageSetPageLoaderClient(m_mainWebView->page(), 0);
- WKPageSetPagePolicyClient(m_mainWebView->page(), 0);
+ auto options = test.options();
+
+ if (m_mainWebView) {
+ if (m_mainWebView->viewSupportsOptions(options))
+ return;
+
+ WKPageSetPageUIClient(m_mainWebView->page(), nullptr);
+ WKPageSetPageNavigationClient(m_mainWebView->page(), nullptr);
WKPageClose(m_mainWebView->page());
-
- m_mainWebView = nullptr;
- createWebViewWithOptions(options);
- resetStateToConsistentValues();
+ m_mainWebView = nullptr;
}
+
+ createWebViewWithOptions(options);
+
+ if (!resetStateToConsistentValues(options))
+ TestInvocation::dumpWebProcessUnresponsiveness("<unknown> - TestController::run - Failed to reset state to consistent values\n");
}
-void TestController::resetPreferencesToConsistentValues()
+void TestController::resetPreferencesToConsistentValues(const TestOptions& options)
{
// Reset preferences
- WKPreferencesRef preferences = WKPageGroupGetPreferences(m_pageGroup.get());
+ WKPreferencesRef preferences = platformPreferences();
WKPreferencesResetTestRunnerOverrides(preferences);
+ WKPreferencesEnableAllExperimentalFeatures(preferences);
+ WKPreferencesSetPageVisibilityBasedProcessSuppressionEnabled(preferences, false);
WKPreferencesSetOfflineWebApplicationCacheEnabled(preferences, true);
WKPreferencesSetFontSmoothingLevel(preferences, kWKFontSmoothingLevelNoSubpixelAntiAliasing);
WKPreferencesSetXSSAuditorEnabled(preferences, false);
WKPreferencesSetWebAudioEnabled(preferences, true);
+ WKPreferencesSetMediaStreamEnabled(preferences, true);
WKPreferencesSetDeveloperExtrasEnabled(preferences, true);
- WKPreferencesSetJavaScriptExperimentsEnabled(preferences, true);
+ WKPreferencesSetJavaScriptRuntimeFlags(preferences, kWKJavaScriptRuntimeFlagsAllEnabled);
WKPreferencesSetJavaScriptCanOpenWindowsAutomatically(preferences, true);
WKPreferencesSetJavaScriptCanAccessClipboard(preferences, true);
WKPreferencesSetDOMPasteAllowed(preferences, true);
@@ -518,7 +660,14 @@ void TestController::resetPreferencesToConsistentValues()
WKPreferencesSetArtificialPluginInitializationDelayEnabled(preferences, false);
WKPreferencesSetTabToLinksEnabled(preferences, false);
WKPreferencesSetInteractiveFormValidationEnabled(preferences, true);
- WKPreferencesSetMockScrollbarsEnabled(preferences, true);
+
+ WKPreferencesSetMockScrollbarsEnabled(preferences, options.useMockScrollbars);
+ WKPreferencesSetNeedsSiteSpecificQuirks(preferences, options.needsSiteSpecificQuirks);
+ WKPreferencesSetIntersectionObserverEnabled(preferences, options.enableIntersectionObserver);
+ WKPreferencesSetModernMediaControlsEnabled(preferences, options.enableModernMediaControls);
+
+ static WKStringRef defaultTextEncoding = WKStringCreateWithUTF8CString("ISO-8859-1");
+ WKPreferencesSetDefaultTextEncodingName(preferences, defaultTextEncoding);
static WKStringRef standardFontFamily = WKStringCreateWithUTF8CString("Times");
static WKStringRef cursiveFontFamily = WKStringCreateWithUTF8CString("Apple Chancery");
@@ -528,6 +677,7 @@ void TestController::resetPreferencesToConsistentValues()
static WKStringRef sansSerifFontFamily = WKStringCreateWithUTF8CString("Helvetica");
static WKStringRef serifFontFamily = WKStringCreateWithUTF8CString("Times");
+ WKPreferencesSetMinimumFontSize(preferences, 0);
WKPreferencesSetStandardFontFamily(preferences, standardFontFamily);
WKPreferencesSetCursiveFontFamily(preferences, cursiveFontFamily);
WKPreferencesSetFantasyFontFamily(preferences, fantasyFontFamily);
@@ -535,21 +685,40 @@ void TestController::resetPreferencesToConsistentValues()
WKPreferencesSetPictographFontFamily(preferences, pictographFontFamily);
WKPreferencesSetSansSerifFontFamily(preferences, sansSerifFontFamily);
WKPreferencesSetSerifFontFamily(preferences, serifFontFamily);
- WKPreferencesSetScreenFontSubstitutionEnabled(preferences, true);
WKPreferencesSetAsynchronousSpellCheckingEnabled(preferences, false);
#if ENABLE(WEB_AUDIO)
WKPreferencesSetMediaSourceEnabled(preferences, true);
#endif
+ WKPreferencesSetHiddenPageDOMTimerThrottlingEnabled(preferences, false);
+ WKPreferencesSetHiddenPageCSSAnimationSuspensionEnabled(preferences, false);
+
WKPreferencesSetAcceleratedDrawingEnabled(preferences, m_shouldUseAcceleratedDrawing);
+ // FIXME: We should be testing the default.
+ WKPreferencesSetStorageBlockingPolicy(preferences, kWKAllowAllStorage);
+
+ WKPreferencesSetResourceTimingEnabled(preferences, true);
+
+ WKPreferencesSetMediaPlaybackAllowsInline(preferences, true);
+ WKPreferencesSetInlineMediaPlaybackRequiresPlaysInlineAttribute(preferences, false);
+
+ WKCookieManagerDeleteAllCookies(WKContextGetCookieManager(m_context.get()));
+
+ WKPreferencesSetMockCaptureDevicesEnabled(preferences, true);
+
+ platformResetPreferencesToConsistentValues();
}
-bool TestController::resetStateToConsistentValues()
+bool TestController::resetStateToConsistentValues(const TestOptions& options)
{
- m_state = Resetting;
-
+ SetForScope<State> changeState(m_state, Resetting);
m_beforeUnloadReturnValue = true;
+ // This setting differs between the antique and modern Mac WebKit2 API.
+ // For now, maintain the antique behavior, because some tests depend on it!
+ // FIXME: We should be testing the default.
+ WKPageSetBackgroundExtendsBeyondPage(m_mainWebView->page(), false);
+
WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("Reset"));
WKRetainPtr<WKMutableDictionaryRef> resetMessageBody = adoptWK(WKMutableDictionaryCreate());
@@ -557,39 +726,58 @@ bool TestController::resetStateToConsistentValues()
WKRetainPtr<WKBooleanRef> shouldGCValue = adoptWK(WKBooleanCreate(m_gcBetweenTests));
WKDictionarySetItem(resetMessageBody.get(), shouldGCKey.get(), shouldGCValue.get());
- WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), resetMessageBody.get());
+ WKRetainPtr<WKStringRef> allowedHostsKey = adoptWK(WKStringCreateWithUTF8CString("AllowedHosts"));
+ WKRetainPtr<WKMutableArrayRef> allowedHostsValue = adoptWK(WKMutableArrayCreate());
+ for (auto& host : m_allowedHosts) {
+ WKRetainPtr<WKStringRef> wkHost = adoptWK(WKStringCreateWithUTF8CString(host.c_str()));
+ WKArrayAppendItem(allowedHostsValue.get(), wkHost.get());
+ }
+ WKDictionarySetItem(resetMessageBody.get(), allowedHostsKey.get(), allowedHostsValue.get());
+
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), resetMessageBody.get());
+
+ WKContextSetShouldUseFontSmoothing(TestController::singleton().context(), false);
- WKContextSetShouldUseFontSmoothing(TestController::shared().context(), false);
+ WKContextSetCacheModel(TestController::singleton().context(), kWKCacheModelDocumentBrowser);
- WKContextSetCacheModel(TestController::shared().context(), kWKCacheModelDocumentBrowser);
+ WKContextClearCachedCredentials(TestController::singleton().context());
// FIXME: This function should also ensure that there is only one page open.
// Reset the EventSender for each test.
- m_eventSenderProxy = adoptPtr(new EventSenderProxy(this));
+ m_eventSenderProxy = std::make_unique<EventSenderProxy>(this);
// FIXME: Is this needed? Nothing in TestController changes preferences during tests, and if there is
// some other code doing this, it should probably be responsible for cleanup too.
- resetPreferencesToConsistentValues();
+ resetPreferencesToConsistentValues(options);
-#if !PLATFORM(MAC)
+#if !PLATFORM(COCOA)
WKTextCheckerContinuousSpellCheckingEnabledStateChanged(true);
#endif
- // in the case that a test using the chrome input field failed, be sure to clean up for the next test
+ // Make sure the view is in the window (a test can unparent it).
+ m_mainWebView->addToWindow();
+
+ // In the case that a test using the chrome input field failed, be sure to clean up for the next test.
m_mainWebView->removeChromeInputField();
m_mainWebView->focus();
// Re-set to the default backing scale factor by setting the custom scale factor to 0.
WKPageSetCustomBackingScaleFactor(m_mainWebView->page(), 0);
+ WKPageClearWheelEventTestTrigger(m_mainWebView->page());
+
#if PLATFORM(EFL)
- // EFL use a real window while other ports such as Qt don't.
+ // EFL uses a real window while other ports such as Qt don't.
// In EFL, we need to resize the window to the original size after calls to window.resizeTo.
WKRect rect = m_mainWebView->windowFrame();
m_mainWebView->setWindowFrame(WKRectMake(rect.origin.x, rect.origin.y, TestController::viewWidth, TestController::viewHeight));
#endif
+ WKPageSetMuted(m_mainWebView->page(), true);
+
+ WKPageClearUserMediaState(m_mainWebView->page());
+
// Reset notification permissions
m_webNotificationProvider.reset();
@@ -598,33 +786,250 @@ bool TestController::resetStateToConsistentValues()
m_isGeolocationPermissionSet = false;
m_isGeolocationPermissionAllowed = false;
+ // Reset UserMedia permissions.
+ m_userMediaPermissionRequests.clear();
+ m_cachedUserMediaPermissions.clear();
+ m_isUserMediaPermissionSet = false;
+ m_isUserMediaPermissionAllowed = false;
+
// Reset Custom Policy Delegate.
setCustomPolicyDelegate(false, false);
+ m_shouldDownloadUndisplayableMIMETypes = false;
+
m_workQueueManager.clearWorkQueue();
+ m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges = false;
m_handlesAuthenticationChallenges = false;
m_authenticationUsername = String();
m_authenticationPassword = String();
m_shouldBlockAllPlugins = false;
+ m_shouldLogHistoryClientCallbacks = false;
+ m_shouldLogCanAuthenticateAgainstProtectionSpace = false;
+
+ setHidden(false);
+
+ platformResetStateToConsistentValues();
+
// Reset main page back to about:blank
m_doneResetting = false;
+ m_shouldDecideNavigationPolicyAfterDelay = false;
+
+ setNavigationGesturesEnabled(false);
+
+ setIgnoresViewportScaleLimits(options.ignoresViewportScaleLimits);
+
WKPageLoadURL(m_mainWebView->page(), blankURL());
- runUntil(m_doneResetting, ShortTimeout);
+ runUntil(m_doneResetting, m_currentInvocation->shortTimeout());
return m_doneResetting;
}
-struct TestCommand {
- TestCommand() : shouldDumpPixels(false), timeout(0) { }
+void TestController::terminateWebContentProcess()
+{
+ WKPageTerminate(m_mainWebView->page());
+}
- std::string pathOrURL;
- bool shouldDumpPixels;
- std::string expectedPixelHash;
- int timeout;
-};
+void TestController::reattachPageToWebProcess()
+{
+ // Loading a web page is the only way to reattach an existing page to a process.
+ m_doneResetting = false;
+ WKPageLoadURL(m_mainWebView->page(), blankURL());
+ runUntil(m_doneResetting, m_currentInvocation->shortTimeout());
+}
+
+const char* TestController::webProcessName()
+{
+ // FIXME: Find a way to not hardcode the process name.
+#if PLATFORM(COCOA)
+ return "com.apple.WebKit.WebContent.Development";
+#else
+ return "WebProcess";
+#endif
+}
+
+const char* TestController::networkProcessName()
+{
+ // FIXME: Find a way to not hardcode the process name.
+#if PLATFORM(COCOA)
+ return "com.apple.WebKit.Networking.Development";
+#else
+ return "NetworkProcess";
+#endif
+}
+
+const char* TestController::databaseProcessName()
+{
+ // FIXME: Find a way to not hardcode the process name.
+#if PLATFORM(COCOA)
+ return "com.apple.WebKit.Databases.Development";
+#else
+ return "DatabaseProcess";
+#endif
+}
+
+static std::string testPath(WKURLRef url)
+{
+ auto scheme = adoptWK(WKURLCopyScheme(url));
+ if (WKStringIsEqualToUTF8CStringIgnoringCase(scheme.get(), "file")) {
+ auto path = adoptWK(WKURLCopyPath(url));
+ auto buffer = std::vector<char>(WKStringGetMaximumUTF8CStringSize(path.get()));
+ auto length = WKStringGetUTF8CString(path.get(), buffer.data(), buffer.size());
+ return std::string(buffer.data(), length);
+ }
+ return std::string();
+}
+
+static WKURLRef createTestURL(const char* pathOrURL)
+{
+ if (strstr(pathOrURL, "http://") || strstr(pathOrURL, "https://") || strstr(pathOrURL, "file://"))
+ return WKURLCreateWithUTF8CString(pathOrURL);
+
+ // Creating from filesytem path.
+ size_t length = strlen(pathOrURL);
+ if (!length)
+ return 0;
+
+ const char separator = '/';
+ bool isAbsolutePath = pathOrURL[0] == separator;
+ const char* filePrefix = "file://";
+ static const size_t prefixLength = strlen(filePrefix);
+
+ std::unique_ptr<char[]> buffer;
+ if (isAbsolutePath) {
+ buffer = std::make_unique<char[]>(prefixLength + length + 1);
+ strcpy(buffer.get(), filePrefix);
+ strcpy(buffer.get() + prefixLength, pathOrURL);
+ } else {
+ buffer = std::make_unique<char[]>(prefixLength + PATH_MAX + length + 2); // 1 for the separator
+ strcpy(buffer.get(), filePrefix);
+ if (!getcwd(buffer.get() + prefixLength, PATH_MAX))
+ return 0;
+ size_t numCharacters = strlen(buffer.get());
+ buffer[numCharacters] = separator;
+ strcpy(buffer.get() + numCharacters + 1, pathOrURL);
+ }
+
+ return WKURLCreateWithUTF8CString(buffer.get());
+}
+
+static bool parseBooleanTestHeaderValue(const std::string& value)
+{
+ if (value == "true")
+ return true;
+ if (value == "false")
+ return false;
+
+ LOG_ERROR("Found unexpected value '%s' for boolean option. Expected 'true' or 'false'.", value.c_str());
+ return false;
+}
+
+static void updateTestOptionsFromTestHeader(TestOptions& testOptions, const std::string& pathOrURL, const std::string& absolutePath)
+{
+ std::string filename = absolutePath;
+ if (filename.empty()) {
+ // Gross. Need to reduce conversions between all the string types and URLs.
+ WKRetainPtr<WKURLRef> wkURL(AdoptWK, createTestURL(pathOrURL.c_str()));
+ filename = testPath(wkURL.get());
+ }
+
+ if (filename.empty())
+ return;
+
+ std::string options;
+ std::ifstream testFile(filename.data());
+ if (!testFile.good())
+ return;
+ getline(testFile, options);
+ std::string beginString("webkit-test-runner [ ");
+ std::string endString(" ]");
+ size_t beginLocation = options.find(beginString);
+ if (beginLocation == std::string::npos)
+ return;
+ size_t endLocation = options.find(endString, beginLocation);
+ if (endLocation == std::string::npos) {
+ LOG_ERROR("Could not find end of test header in %s", filename.c_str());
+ return;
+ }
+ std::string pairString = options.substr(beginLocation + beginString.size(), endLocation - (beginLocation + beginString.size()));
+ size_t pairStart = 0;
+ while (pairStart < pairString.size()) {
+ size_t pairEnd = pairString.find(" ", pairStart);
+ if (pairEnd == std::string::npos)
+ pairEnd = pairString.size();
+ size_t equalsLocation = pairString.find("=", pairStart);
+ if (equalsLocation == std::string::npos) {
+ LOG_ERROR("Malformed option in test header (could not find '=' character) in %s", filename.c_str());
+ break;
+ }
+ auto key = pairString.substr(pairStart, equalsLocation - pairStart);
+ auto value = pairString.substr(equalsLocation + 1, pairEnd - (equalsLocation + 1));
+ if (key == "language")
+ String(value.c_str()).split(",", false, testOptions.overrideLanguages);
+ if (key == "useThreadedScrolling")
+ testOptions.useThreadedScrolling = parseBooleanTestHeaderValue(value);
+ if (key == "useFlexibleViewport")
+ testOptions.useFlexibleViewport = parseBooleanTestHeaderValue(value);
+ if (key == "useDataDetection")
+ testOptions.useDataDetection = parseBooleanTestHeaderValue(value);
+ if (key == "useMockScrollbars")
+ testOptions.useMockScrollbars = parseBooleanTestHeaderValue(value);
+ if (key == "needsSiteSpecificQuirks")
+ testOptions.needsSiteSpecificQuirks = parseBooleanTestHeaderValue(value);
+ if (key == "ignoresViewportScaleLimits")
+ testOptions.ignoresViewportScaleLimits = parseBooleanTestHeaderValue(value);
+ if (key == "useCharacterSelectionGranularity")
+ testOptions.useCharacterSelectionGranularity = parseBooleanTestHeaderValue(value);
+ if (key == "enableIntersectionObserver")
+ testOptions.enableIntersectionObserver = parseBooleanTestHeaderValue(value);
+ if (key == "enableModernMediaControls")
+ testOptions.enableModernMediaControls = parseBooleanTestHeaderValue(value);
+ if (key == "enablePointerLock")
+ testOptions.enablePointerLock = parseBooleanTestHeaderValue(value);
+ pairStart = pairEnd + 1;
+ }
+}
+
+TestOptions TestController::testOptionsForTest(const TestCommand& command) const
+{
+ TestOptions options(command.pathOrURL);
+
+ options.useRemoteLayerTree = m_shouldUseRemoteLayerTree;
+ options.shouldShowWebView = m_shouldShowWebView;
+
+ updatePlatformSpecificTestOptionsForTest(options, command.pathOrURL);
+ updateTestOptionsFromTestHeader(options, command.pathOrURL, command.absolutePath);
+
+ return options;
+}
+
+void TestController::updateWebViewSizeForTest(const TestInvocation& test)
+{
+ unsigned width = viewWidth;
+ unsigned height = viewHeight;
+ if (test.options().isSVGTest) {
+ width = w3cSVGViewWidth;
+ height = w3cSVGViewHeight;
+ }
+
+ mainWebView()->resizeTo(width, height);
+}
+
+void TestController::updateWindowScaleForTest(PlatformWebView* view, const TestInvocation& test)
+{
+ view->changeWindowScaleIfNeeded(test.options().deviceScaleFactor);
+}
+
+void TestController::configureViewForTest(const TestInvocation& test)
+{
+ ensureViewSupportsOptionsForTest(test);
+ updateWebViewSizeForTest(test);
+ updateWindowScaleForTest(mainWebView(), test);
+
+ platformConfigureViewForTest(test);
+}
class CommandTokenizer {
public:
@@ -696,7 +1101,11 @@ TestCommand parseInputLine(const std::string& inputLine)
result.shouldDumpPixels = true;
if (tokenizer.hasNext())
result.expectedPixelHash = tokenizer.next();
- } else
+ } else if (arg == std::string("--dump-jsconsolelog-in-stderr"))
+ result.dumpJSConsoleLogInStdErr = true;
+ else if (arg == std::string("--absolutePath"))
+ result.absolutePath = tokenizer.next();
+ else
die(inputLine);
}
return result;
@@ -704,18 +1113,26 @@ TestCommand parseInputLine(const std::string& inputLine)
bool TestController::runTest(const char* inputLine)
{
+ WKTextCheckerSetTestingMode(true);
TestCommand command = parseInputLine(std::string(inputLine));
m_state = RunningTest;
+
+ TestOptions options = testOptionsForTest(command);
+
+ WKRetainPtr<WKURLRef> wkURL(AdoptWK, createTestURL(command.pathOrURL.c_str()));
+ m_currentInvocation = std::make_unique<TestInvocation>(wkURL.get(), options);
- m_currentInvocation = adoptPtr(new TestInvocation(command.pathOrURL));
if (command.shouldDumpPixels || m_shouldDumpPixelsForAllTests)
m_currentInvocation->setIsPixelTest(command.expectedPixelHash);
if (command.timeout > 0)
m_currentInvocation->setCustomTimeout(command.timeout);
+ m_currentInvocation->setDumpJSConsoleLogInStdErr(command.dumpJSConsoleLogInStdErr);
+
+ platformWillRunTest(*m_currentInvocation);
m_currentInvocation->invoke();
- m_currentInvocation.clear();
+ m_currentInvocation = nullptr;
return true;
}
@@ -738,11 +1155,6 @@ void TestController::runTestingServerLoop()
void TestController::run()
{
- if (!resetStateToConsistentValues()) {
- TestInvocation::dumpWebProcessUnresponsiveness("<unknown> - TestController::run - Failed to reset state to consistent values\n");
- return;
- }
-
if (m_usingServerMode)
runTestingServerLoop();
else {
@@ -753,26 +1165,10 @@ void TestController::run()
}
}
-void TestController::runUntil(bool& done, TimeoutDuration timeoutDuration)
+void TestController::runUntil(bool& done, double timeout)
{
- double timeout = m_noTimeout;
- if (!m_forceNoTimeout) {
- switch (timeoutDuration) {
- case ShortTimeout:
- timeout = m_shortTimeout;
- break;
- case LongTimeout:
- timeout = m_longTimeout;
- break;
- case CustomTimeout:
- timeout = m_timeout;
- break;
- case NoTimeout:
- default:
- timeout = m_noTimeout;
- break;
- }
- }
+ if (m_forceNoTimeout)
+ timeout = noTimeout;
platformRunUntil(done, timeout);
}
@@ -789,6 +1185,33 @@ void TestController::didReceiveSynchronousMessageFromInjectedBundle(WKContextRef
*returnData = static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody).leakRef();
}
+WKTypeRef TestController::getInjectedBundleInitializationUserData(WKContextRef, const void* clientInfo)
+{
+ return static_cast<TestController*>(const_cast<void*>(clientInfo))->getInjectedBundleInitializationUserData().leakRef();
+}
+
+// WKPageInjectedBundleClient
+
+void TestController::didReceivePageMessageFromInjectedBundle(WKPageRef page, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveMessageFromInjectedBundle(messageName, messageBody);
+}
+
+void TestController::didReceiveSynchronousPageMessageFromInjectedBundle(WKPageRef page, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void* clientInfo)
+{
+ *returnData = static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody).leakRef();
+}
+
+void TestController::networkProcessDidCrash(WKContextRef context, const void *clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->networkProcessDidCrash();
+}
+
+void TestController::databaseProcessDidCrash(WKContextRef context, const void *clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->databaseProcessDidCrash();
+}
+
void TestController::didReceiveKeyDownMessageFromInjectedBundle(WKDictionaryRef messageBodyDictionary, bool synchronous)
{
WKRetainPtr<WKStringRef> keyKey = adoptWK(WKStringCreateWithUTF8CString("Key"));
@@ -800,18 +1223,15 @@ void TestController::didReceiveKeyDownMessageFromInjectedBundle(WKDictionaryRef
WKRetainPtr<WKStringRef> locationKey = adoptWK(WKStringCreateWithUTF8CString("Location"));
unsigned location = static_cast<unsigned>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, locationKey.get()))));
- if (synchronous)
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
-
m_eventSenderProxy->keyDown(key, modifiers, location);
-
- if (synchronous)
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
}
void TestController::didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
{
if (WKStringIsEqualToUTF8CString(messageName, "EventSender")) {
+ if (m_state != RunningTest)
+ return;
+
ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
@@ -826,7 +1246,6 @@ void TestController::didReceiveMessageFromInjectedBundle(WKStringRef messageName
WKEventModifiers modifiers = static_cast<WKEventModifiers>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, modifiersKey.get()))));
// Forward to WebProcess
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
if (WKStringIsEqualToUTF8CString(subMessageName, "MouseDown"))
m_eventSenderProxy->mouseDown(button, modifiers);
else
@@ -841,6 +1260,53 @@ void TestController::didReceiveMessageFromInjectedBundle(WKStringRef messageName
return;
}
+ if (WKStringIsEqualToUTF8CString(subMessageName, "MouseScrollBy")) {
+ WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
+ double x = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, xKey.get())));
+
+ WKRetainPtr<WKStringRef> yKey = adoptWK(WKStringCreateWithUTF8CString("Y"));
+ double y = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, yKey.get())));
+
+ // Forward to WebProcess
+ m_eventSenderProxy->mouseScrollBy(x, y);
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(subMessageName, "MouseScrollByWithWheelAndMomentumPhases")) {
+ WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
+ double x = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, xKey.get())));
+
+ WKRetainPtr<WKStringRef> yKey = adoptWK(WKStringCreateWithUTF8CString("Y"));
+ double y = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, yKey.get())));
+
+ WKRetainPtr<WKStringRef> phaseKey = adoptWK(WKStringCreateWithUTF8CString("Phase"));
+ int phase = static_cast<int>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, phaseKey.get()))));
+ WKRetainPtr<WKStringRef> momentumKey = adoptWK(WKStringCreateWithUTF8CString("Momentum"));
+ int momentum = static_cast<int>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, momentumKey.get()))));
+
+ // Forward to WebProcess
+ m_eventSenderProxy->mouseScrollByWithWheelAndMomentumPhases(x, y, phase, momentum);
+
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(subMessageName, "SwipeGestureWithWheelAndMomentumPhases")) {
+ WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
+ double x = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, xKey.get())));
+
+ WKRetainPtr<WKStringRef> yKey = adoptWK(WKStringCreateWithUTF8CString("Y"));
+ double y = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, yKey.get())));
+
+ WKRetainPtr<WKStringRef> phaseKey = adoptWK(WKStringCreateWithUTF8CString("Phase"));
+ int phase = static_cast<int>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, phaseKey.get()))));
+ WKRetainPtr<WKStringRef> momentumKey = adoptWK(WKStringCreateWithUTF8CString("Momentum"));
+ int momentum = static_cast<int>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, momentumKey.get()))));
+
+ m_eventSenderProxy->swipeGestureWithWheelAndMomentumPhases(x, y, phase, momentum);
+
+ return;
+ }
+
ASSERT_NOT_REACHED();
}
@@ -853,6 +1319,9 @@ void TestController::didReceiveMessageFromInjectedBundle(WKStringRef messageName
WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
{
if (WKStringIsEqualToUTF8CString(messageName, "EventSender")) {
+ if (m_state != RunningTest)
+ return nullptr;
+
ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
@@ -873,12 +1342,10 @@ WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedB
WKEventModifiers modifiers = static_cast<WKEventModifiers>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, modifiersKey.get()))));
// Forward to WebProcess
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
if (WKStringIsEqualToUTF8CString(subMessageName, "MouseDown"))
m_eventSenderProxy->mouseDown(button, modifiers);
else
m_eventSenderProxy->mouseUp(button, modifiers);
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
return 0;
}
@@ -890,25 +1357,39 @@ WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedB
double y = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, yKey.get())));
// Forward to WebProcess
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
m_eventSenderProxy->mouseMoveTo(x, y);
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
return 0;
}
- if (WKStringIsEqualToUTF8CString(subMessageName, "MouseScrollBy")) {
- WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
- double x = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, xKey.get())));
+#if PLATFORM(MAC)
+ if (WKStringIsEqualToUTF8CString(subMessageName, "MouseForceClick")) {
+ m_eventSenderProxy->mouseForceClick();
+ return 0;
+ }
- WKRetainPtr<WKStringRef> yKey = adoptWK(WKStringCreateWithUTF8CString("Y"));
- double y = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, yKey.get())));
+ if (WKStringIsEqualToUTF8CString(subMessageName, "StartAndCancelMouseForceClick")) {
+ m_eventSenderProxy->startAndCancelMouseForceClick();
+ return 0;
+ }
- // Forward to WebProcess
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
- m_eventSenderProxy->mouseScrollBy(x, y);
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
+ if (WKStringIsEqualToUTF8CString(subMessageName, "MouseForceDown")) {
+ m_eventSenderProxy->mouseForceDown();
+ return 0;
+ }
+
+ if (WKStringIsEqualToUTF8CString(subMessageName, "MouseForceUp")) {
+ m_eventSenderProxy->mouseForceUp();
+ return 0;
+ }
+
+ if (WKStringIsEqualToUTF8CString(subMessageName, "MouseForceChanged")) {
+ WKRetainPtr<WKStringRef> forceKey = adoptWK(WKStringCreateWithUTF8CString("Force"));
+ double force = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, forceKey.get())));
+
+ m_eventSenderProxy->mouseForceChanged(force);
return 0;
}
+#endif // PLATFORM(MAC)
if (WKStringIsEqualToUTF8CString(subMessageName, "ContinuousMouseScrollBy")) {
WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
@@ -921,9 +1402,7 @@ WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedB
bool paged = static_cast<bool>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, pagedKey.get()))));
// Forward to WebProcess
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
m_eventSenderProxy->continuousMouseScrollBy(x, y, paged);
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
return 0;
}
@@ -984,30 +1463,22 @@ WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedB
}
if (WKStringIsEqualToUTF8CString(subMessageName, "TouchStart")) {
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
m_eventSenderProxy->touchStart();
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
return 0;
}
if (WKStringIsEqualToUTF8CString(subMessageName, "TouchMove")) {
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
m_eventSenderProxy->touchMove();
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
return 0;
}
if (WKStringIsEqualToUTF8CString(subMessageName, "TouchEnd")) {
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
m_eventSenderProxy->touchEnd();
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
return 0;
}
if (WKStringIsEqualToUTF8CString(subMessageName, "TouchCancel")) {
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
m_eventSenderProxy->touchCancel();
- WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
return 0;
}
@@ -1035,21 +1506,47 @@ WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedB
return m_currentInvocation->didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody);
}
-// WKPageLoaderClient
+WKRetainPtr<WKTypeRef> TestController::getInjectedBundleInitializationUserData()
+{
+ return nullptr;
+}
-void TestController::didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef, const void* clientInfo)
+// WKContextClient
+
+void TestController::networkProcessDidCrash()
{
- static_cast<TestController*>(const_cast<void*>(clientInfo))->didCommitLoadForFrame(page, frame);
+ pid_t pid = WKContextGetNetworkProcessIdentifier(m_context.get());
+ fprintf(stderr, "#CRASHED - %s (pid %ld)\n", networkProcessName(), static_cast<long>(pid));
+ exit(1);
}
-void TestController::didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef, const void* clientInfo)
+void TestController::databaseProcessDidCrash()
{
- static_cast<TestController*>(const_cast<void*>(clientInfo))->didFinishLoadForFrame(page, frame);
+ pid_t pid = WKContextGetDatabaseProcessIdentifier(m_context.get());
+ fprintf(stderr, "#CRASHED - %s (pid %ld)\n", databaseProcessName(), static_cast<long>(pid));
+ exit(1);
}
-void TestController::didReceiveAuthenticationChallengeInFrame(WKPageRef page, WKFrameRef frame, WKAuthenticationChallengeRef authenticationChallenge, const void *clientInfo)
+// WKPageNavigationClient
+
+void TestController::didCommitNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef, const void* clientInfo)
{
- static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveAuthenticationChallengeInFrame(page, frame, authenticationChallenge);
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didCommitNavigation(page, navigation);
+}
+
+void TestController::didFinishNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didFinishNavigation(page, navigation);
+}
+
+bool TestController::canAuthenticateAgainstProtectionSpace(WKPageRef page, WKProtectionSpaceRef protectionSpace, const void* clientInfo)
+{
+ return static_cast<TestController*>(const_cast<void*>(clientInfo))->canAuthenticateAgainstProtectionSpace(page, protectionSpace);
+}
+
+void TestController::didReceiveAuthenticationChallenge(WKPageRef page, WKAuthenticationChallengeRef authenticationChallenge, const void *clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveAuthenticationChallenge(page, /*frame,*/ authenticationChallenge);
}
void TestController::processDidCrash(WKPageRef page, const void* clientInfo)
@@ -1057,52 +1554,114 @@ void TestController::processDidCrash(WKPageRef page, const void* clientInfo)
static_cast<TestController*>(const_cast<void*>(clientInfo))->processDidCrash();
}
-WKPluginLoadPolicy TestController::pluginLoadPolicy(WKPageRef page, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription, const void* clientInfo)
+void TestController::didBeginNavigationGesture(WKPageRef page, const void *clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didBeginNavigationGesture(page);
+}
+
+void TestController::willEndNavigationGesture(WKPageRef page, WKBackForwardListItemRef backForwardListItem, const void *clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->willEndNavigationGesture(page, backForwardListItem);
+}
+
+void TestController::didEndNavigationGesture(WKPageRef page, WKBackForwardListItemRef backForwardListItem, const void *clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didEndNavigationGesture(page, backForwardListItem);
+}
+
+void TestController::didRemoveNavigationGestureSnapshot(WKPageRef page, const void *clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didRemoveNavigationGestureSnapshot(page);
+}
+
+WKPluginLoadPolicy TestController::decidePolicyForPluginLoad(WKPageRef page, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription, const void* clientInfo)
{
- return static_cast<TestController*>(const_cast<void*>(clientInfo))->pluginLoadPolicy(page, currentPluginLoadPolicy, pluginInformation, unavailabilityDescription);
+ return static_cast<TestController*>(const_cast<void*>(clientInfo))->decidePolicyForPluginLoad(page, currentPluginLoadPolicy, pluginInformation, unavailabilityDescription);
}
-WKPluginLoadPolicy TestController::pluginLoadPolicy(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription)
+WKPluginLoadPolicy TestController::decidePolicyForPluginLoad(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription)
{
if (m_shouldBlockAllPlugins)
return kWKPluginLoadPolicyBlocked;
+
+#if PLATFORM(MAC)
+ WKStringRef bundleIdentifier = (WKStringRef)WKDictionaryGetItemForKey(pluginInformation, WKPluginInformationBundleIdentifierKey());
+ if (!bundleIdentifier)
+ return currentPluginLoadPolicy;
+
+ if (WKStringIsEqualToUTF8CString(bundleIdentifier, "com.apple.QuickTime Plugin.plugin"))
+ return currentPluginLoadPolicy;
+
+ if (WKStringIsEqualToUTF8CString(bundleIdentifier, "com.apple.testnetscapeplugin"))
+ return currentPluginLoadPolicy;
+
+ RELEASE_ASSERT_NOT_REACHED(); // Please don't use any other plug-ins in tests, as they will not be installed on all machines.
+#else
return currentPluginLoadPolicy;
+#endif
}
-void TestController::didCommitLoadForFrame(WKPageRef page, WKFrameRef frame)
+void TestController::didCommitNavigation(WKPageRef page, WKNavigationRef navigation)
{
- if (!WKFrameIsMainFrame(frame))
- return;
-
mainWebView()->focus();
}
-void TestController::didFinishLoadForFrame(WKPageRef page, WKFrameRef frame)
+bool TestController::canAuthenticateAgainstProtectionSpace(WKPageRef page, WKProtectionSpaceRef protectionSpace)
{
- if (m_state != Resetting)
- return;
+ if (m_shouldLogCanAuthenticateAgainstProtectionSpace)
+ m_currentInvocation->outputText("canAuthenticateAgainstProtectionSpace\n");
+ WKProtectionSpaceAuthenticationScheme authenticationScheme = WKProtectionSpaceGetAuthenticationScheme(protectionSpace);
+
+ if (authenticationScheme == kWKProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested) {
+ std::string host = toSTD(adoptWK(WKProtectionSpaceCopyHost(protectionSpace)).get());
+ return host == "localhost" || host == "127.0.0.1";
+ }
+
+ return authenticationScheme <= kWKProtectionSpaceAuthenticationSchemeHTTPDigest;
+}
- if (!WKFrameIsMainFrame(frame))
+void TestController::didFinishNavigation(WKPageRef page, WKNavigationRef navigation)
+{
+ if (m_state != Resetting)
return;
- WKRetainPtr<WKURLRef> wkURL(AdoptWK, WKFrameCopyURL(frame));
+ WKRetainPtr<WKURLRef> wkURL(AdoptWK, WKFrameCopyURL(WKPageGetMainFrame(page)));
if (!WKURLIsEqual(wkURL.get(), blankURL()))
return;
m_doneResetting = true;
- shared().notifyDone();
+ singleton().notifyDone();
}
-void TestController::didReceiveAuthenticationChallengeInFrame(WKPageRef page, WKFrameRef frame, WKAuthenticationChallengeRef authenticationChallenge)
+void TestController::didReceiveAuthenticationChallenge(WKPageRef page, WKAuthenticationChallengeRef authenticationChallenge)
{
- String message;
+ WKProtectionSpaceRef protectionSpace = WKAuthenticationChallengeGetProtectionSpace(authenticationChallenge);
+ WKAuthenticationDecisionListenerRef decisionListener = WKAuthenticationChallengeGetDecisionListener(authenticationChallenge);
+
+ if (WKProtectionSpaceGetAuthenticationScheme(protectionSpace) == kWKProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested) {
+ // Any non-empty credential signals to accept the server trust. Since the cross-platform API
+ // doesn't expose a way to create a credential from server trust, we use a password credential.
+
+ WKRetainPtr<WKCredentialRef> credential = adoptWK(WKCredentialCreate(toWK("accept server trust").get(), toWK("").get(), kWKCredentialPersistenceNone));
+ WKAuthenticationDecisionListenerUseCredential(decisionListener, credential.get());
+ return;
+ }
+
+ if (m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges) {
+ m_currentInvocation->outputText("Simulating reject protection space and continue for authentication challenge\n");
+ WKAuthenticationDecisionListenerRejectProtectionSpaceAndContinue(decisionListener);
+ return;
+ }
+
+ std::string host = toSTD(adoptWK(WKProtectionSpaceCopyHost(protectionSpace)).get());
+ int port = WKProtectionSpaceGetPort(protectionSpace);
+ String message = String::format("%s:%d - didReceiveAuthenticationChallenge - ", host.c_str(), port);
if (!m_handlesAuthenticationChallenges)
- message = "<unknown> - didReceiveAuthenticationChallenge - Simulating cancelled authentication sheet\n";
+ message.append("Simulating cancelled authentication sheet\n");
else
- message = String::format("<unknown> - didReceiveAuthenticationChallenge - Responding with %s:%s\n", m_authenticationUsername.utf8().data(), m_authenticationPassword.utf8().data());
+ message.append(String::format("Responding with %s:%s\n", m_authenticationUsername.utf8().data(), m_authenticationPassword.utf8().data()));
m_currentInvocation->outputText(message);
- WKAuthenticationDecisionListenerRef decisionListener = WKAuthenticationChallengeGetDecisionListener(authenticationChallenge);
if (!m_handlesAuthenticationChallenges) {
WKAuthenticationDecisionListenerUseCredential(decisionListener, 0);
return;
@@ -1113,17 +1672,103 @@ void TestController::didReceiveAuthenticationChallengeInFrame(WKPageRef page, WK
WKAuthenticationDecisionListenerUseCredential(decisionListener, credential.get());
}
+
+// WKContextDownloadClient
+
+void TestController::downloadDidStart(WKContextRef context, WKDownloadRef download, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidStart(context, download);
+}
+
+WKStringRef TestController::decideDestinationWithSuggestedFilename(WKContextRef context, WKDownloadRef download, WKStringRef filename, bool* allowOverwrite, const void* clientInfo)
+{
+ return static_cast<TestController*>(const_cast<void*>(clientInfo))->decideDestinationWithSuggestedFilename(context, download, filename, allowOverwrite);
+}
+
+void TestController::downloadDidFinish(WKContextRef context, WKDownloadRef download, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidFinish(context, download);
+}
+
+void TestController::downloadDidFail(WKContextRef context, WKDownloadRef download, WKErrorRef error, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidFail(context, download, error);
+}
+
+void TestController::downloadDidCancel(WKContextRef context, WKDownloadRef download, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidCancel(context, download);
+}
+
+void TestController::downloadDidStart(WKContextRef context, WKDownloadRef download)
+{
+ m_currentInvocation->outputText("Download started.\n");
+}
+
+WKStringRef TestController::decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef, WKStringRef filename, bool*& allowOverwrite)
+{
+ String suggestedFilename = toWTFString(filename);
+
+ StringBuilder builder;
+ builder.append("Downloading URL with suggested filename \"");
+ builder.append(suggestedFilename);
+ builder.append("\"\n");
+
+ m_currentInvocation->outputText(builder.toString());
+
+ const char* dumpRenderTreeTemp = libraryPathForTesting();
+ if (!dumpRenderTreeTemp)
+ return nullptr;
+
+ *allowOverwrite = true;
+ String temporaryFolder = String::fromUTF8(dumpRenderTreeTemp);
+ if (suggestedFilename.isEmpty())
+ suggestedFilename = "Unknown";
+
+ return toWK(temporaryFolder + "/" + suggestedFilename).leakRef();
+}
+
+void TestController::downloadDidFinish(WKContextRef, WKDownloadRef)
+{
+ m_currentInvocation->outputText("Download completed.\n");
+ m_currentInvocation->notifyDownloadDone();
+}
+
+void TestController::downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef error)
+{
+ String message = String::format("Download failed.\n");
+ m_currentInvocation->outputText(message);
+
+ WKRetainPtr<WKStringRef> errorDomain = adoptWK(WKErrorCopyDomain(error));
+ WKRetainPtr<WKStringRef> errorDescription = adoptWK(WKErrorCopyLocalizedDescription(error));
+ int errorCode = WKErrorGetErrorCode(error);
+
+ StringBuilder errorBuilder;
+ errorBuilder.append("Failed: ");
+ errorBuilder.append(toWTFString(errorDomain));
+ errorBuilder.append(", code=");
+ errorBuilder.appendNumber(errorCode);
+ errorBuilder.append(", description=");
+ errorBuilder.append(toWTFString(errorDescription));
+ errorBuilder.append("\n");
+
+ m_currentInvocation->outputText(errorBuilder.toString());
+ m_currentInvocation->notifyDownloadDone();
+}
+
+void TestController::downloadDidCancel(WKContextRef, WKDownloadRef)
+{
+ m_currentInvocation->outputText("Download cancelled.\n");
+ m_currentInvocation->notifyDownloadDone();
+}
+
void TestController::processDidCrash()
{
// This function can be called multiple times when crash logs are being saved on Windows, so
// ensure we only print the crashed message once.
if (!m_didPrintWebProcessCrashedMessage) {
-#if PLATFORM(MAC)
pid_t pid = WKPageGetProcessIdentifier(m_mainWebView->page());
- fprintf(stderr, "#CRASHED - WebProcess (pid %ld)\n", static_cast<long>(pid));
-#else
- fputs("#CRASHED - WebProcess\n", stderr);
-#endif
+ fprintf(stderr, "#CRASHED - %s (pid %ld)\n", webProcessName(), static_cast<long>(pid));
fflush(stderr);
m_didPrintWebProcessCrashedMessage = true;
}
@@ -1132,9 +1777,29 @@ void TestController::processDidCrash()
exit(1);
}
+void TestController::didBeginNavigationGesture(WKPageRef)
+{
+ m_currentInvocation->didBeginSwipe();
+}
+
+void TestController::willEndNavigationGesture(WKPageRef, WKBackForwardListItemRef)
+{
+ m_currentInvocation->willEndSwipe();
+}
+
+void TestController::didEndNavigationGesture(WKPageRef, WKBackForwardListItemRef)
+{
+ m_currentInvocation->didEndSwipe();
+}
+
+void TestController::didRemoveNavigationGestureSnapshot(WKPageRef)
+{
+ m_currentInvocation->didRemoveSwipeSnapshot();
+}
+
void TestController::simulateWebNotificationClick(uint64_t notificationID)
{
- m_webNotificationProvider.simulateWebNotificationClick(notificationID);
+ m_webNotificationProvider.simulateWebNotificationClick(mainWebView()->page(), notificationID);
}
void TestController::setGeolocationPermission(bool enabled)
@@ -1160,16 +1825,223 @@ void TestController::handleGeolocationPermissionRequest(WKGeolocationPermissionR
decidePolicyForGeolocationPermissionRequestIfPossible();
}
-void TestController::setCustomPolicyDelegate(bool enabled, bool permissive)
+bool TestController::isGeolocationProviderActive() const
{
- m_policyDelegateEnabled = enabled;
- m_policyDelegatePermissive = permissive;
+ return m_geolocationProvider->isActive();
+}
+
+static String originUserVisibleName(WKSecurityOriginRef origin)
+{
+ if (!origin)
+ return emptyString();
+
+ std::string host = toSTD(adoptWK(WKSecurityOriginCopyHost(origin))).c_str();
+ std::string protocol = toSTD(adoptWK(WKSecurityOriginCopyProtocol(origin))).c_str();
+
+ if (!host.length() || !protocol.length())
+ return emptyString();
+
+ unsigned short port = WKSecurityOriginGetPort(origin);
+ if (port)
+ return String::format("%s://%s:%d", protocol.c_str(), host.c_str(), port);
+
+ return String::format("%s://%s", protocol.c_str(), host.c_str());
+}
+
+static String userMediaOriginHash(WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin)
+{
+ String userMediaDocumentOriginString = originUserVisibleName(userMediaDocumentOrigin);
+ String topLevelDocumentOriginString = originUserVisibleName(topLevelDocumentOrigin);
+
+ if (topLevelDocumentOriginString.isEmpty())
+ return userMediaDocumentOriginString;
+
+ return String::format("%s-%s", userMediaDocumentOriginString.utf8().data(), topLevelDocumentOriginString.utf8().data());
+}
+
+static String userMediaOriginHash(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString)
+{
+ auto userMediaDocumentOrigin = adoptWK(WKSecurityOriginCreateFromString(userMediaDocumentOriginString));
+ if (!WKStringGetLength(topLevelDocumentOriginString))
+ return userMediaOriginHash(userMediaDocumentOrigin.get(), nullptr);
+
+ auto topLevelDocumentOrigin = adoptWK(WKSecurityOriginCreateFromString(topLevelDocumentOriginString));
+ return userMediaOriginHash(userMediaDocumentOrigin.get(), topLevelDocumentOrigin.get());
+}
+
+void TestController::setUserMediaPermission(bool enabled)
+{
+ m_isUserMediaPermissionSet = true;
+ m_isUserMediaPermissionAllowed = enabled;
+ decidePolicyForUserMediaPermissionRequestIfPossible();
+}
+
+static String createCanonicalUUIDString()
+{
+ unsigned randomData[4];
+ cryptographicallyRandomValues(reinterpret_cast<unsigned char*>(randomData), sizeof(randomData));
+
+ // Format as Version 4 UUID.
+ StringBuilder builder;
+ builder.reserveCapacity(36);
+ appendUnsignedAsHexFixedSize(randomData[0], builder, 8, Lowercase);
+ builder.append('-');
+ appendUnsignedAsHexFixedSize(randomData[1] >> 16, builder, 4, Lowercase);
+ builder.appendLiteral("-4");
+ appendUnsignedAsHexFixedSize(randomData[1] & 0x00000fff, builder, 3, Lowercase);
+ builder.append('-');
+ appendUnsignedAsHexFixedSize((randomData[2] >> 30) | 0x8, builder, 1, Lowercase);
+ appendUnsignedAsHexFixedSize((randomData[2] >> 16) & 0x00000fff, builder, 3, Lowercase);
+ builder.append('-');
+ appendUnsignedAsHexFixedSize(randomData[2] & 0x0000ffff, builder, 4, Lowercase);
+ appendUnsignedAsHexFixedSize(randomData[3], builder, 8, Lowercase);
+ return builder.toString();
+}
+
+class OriginSettings : public RefCounted<OriginSettings> {
+public:
+ explicit OriginSettings()
+ {
+ }
+
+ bool persistentPermission() const { return m_persistentPermission; }
+ void setPersistentPermission(bool permission) { m_persistentPermission = permission; }
+
+ String persistentSalt() const { return m_persistentSalt; }
+ void setPersistentSalt(const String& salt) { m_persistentSalt = salt; }
+
+ HashMap<uint64_t, String>& ephemeralSalts() { return m_ephemeralSalts; }
+
+ void incrementRequestCount() { ++m_requestCount; }
+ void resetRequestCount() { m_requestCount = 0; }
+ unsigned requestCount() const { return m_requestCount; }
+
+private:
+ HashMap<uint64_t, String> m_ephemeralSalts;
+ String m_persistentSalt;
+ unsigned m_requestCount { 0 };
+ bool m_persistentPermission { false };
+};
+
+String TestController::saltForOrigin(WKFrameRef frame, String originHash)
+{
+ auto& settings = settingsForOrigin(originHash);
+ auto& ephemeralSalts = settings.ephemeralSalts();
+ auto frameInfo = adoptWK(WKFrameCreateFrameInfo(frame));
+ auto frameHandle = WKFrameInfoGetFrameHandleRef(frameInfo.get());
+ uint64_t frameIdentifier = WKFrameHandleGetFrameID(frameHandle);
+ String frameSalt = ephemeralSalts.get(frameIdentifier);
+
+ if (settings.persistentPermission()) {
+ if (frameSalt.length())
+ return frameSalt;
+
+ if (!settings.persistentSalt().length())
+ settings.setPersistentSalt(createCanonicalUUIDString());
+
+ return settings.persistentSalt();
+ }
+
+ if (!frameSalt.length()) {
+ frameSalt = createCanonicalUUIDString();
+ ephemeralSalts.add(frameIdentifier, frameSalt);
+ }
+
+ return frameSalt;
+}
+
+void TestController::setUserMediaPersistentPermissionForOrigin(bool permission, WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString)
+{
+ auto originHash = userMediaOriginHash(userMediaDocumentOriginString, topLevelDocumentOriginString);
+ auto& settings = settingsForOrigin(originHash);
+ settings.setPersistentPermission(permission);
+}
+
+void TestController::handleCheckOfUserMediaPermissionForOrigin(WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, const WKUserMediaPermissionCheckRef& checkRequest)
+{
+ auto originHash = userMediaOriginHash(userMediaDocumentOrigin, topLevelDocumentOrigin);
+ auto salt = saltForOrigin(frame, originHash);
+ WKRetainPtr<WKStringRef> saltString = adoptWK(WKStringCreateWithUTF8CString(salt.utf8().data()));
+
+ WKUserMediaPermissionCheckSetUserMediaAccessInfo(checkRequest, saltString.get(), settingsForOrigin(originHash).persistentPermission());
}
-void TestController::setVisibilityState(WKPageVisibilityState visibilityState, bool isInitialState)
+void TestController::handleUserMediaPermissionRequest(WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionRequestRef request)
{
- setHidden(visibilityState != kWKPageVisibilityStateVisible);
- WKPageSetVisibilityState(m_mainWebView->page(), visibilityState, isInitialState);
+ auto originHash = userMediaOriginHash(userMediaDocumentOrigin, topLevelDocumentOrigin);
+ m_userMediaPermissionRequests.append(std::make_pair(originHash, request));
+ decidePolicyForUserMediaPermissionRequestIfPossible();
+}
+
+OriginSettings& TestController::settingsForOrigin(const String& originHash)
+{
+ RefPtr<OriginSettings> settings = m_cachedUserMediaPermissions.get(originHash);
+ if (!settings) {
+ settings = adoptRef(*new OriginSettings());
+ m_cachedUserMediaPermissions.add(originHash, settings);
+ }
+
+ return *settings;
+}
+
+unsigned TestController::userMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString)
+{
+ auto originHash = userMediaOriginHash(userMediaDocumentOriginString, topLevelDocumentOriginString);
+ return settingsForOrigin(originHash).requestCount();
+}
+
+void TestController::resetUserMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString)
+{
+ auto originHash = userMediaOriginHash(userMediaDocumentOriginString, topLevelDocumentOriginString);
+ settingsForOrigin(originHash).resetRequestCount();
+}
+
+void TestController::decidePolicyForUserMediaPermissionRequestIfPossible()
+{
+ if (!m_isUserMediaPermissionSet)
+ return;
+
+ for (auto& pair : m_userMediaPermissionRequests) {
+ auto originHash = pair.first;
+ auto request = pair.second.get();
+
+ auto& settings = settingsForOrigin(originHash);
+ settings.incrementRequestCount();
+
+ if (!m_isUserMediaPermissionAllowed && !settings.persistentPermission()) {
+ WKUserMediaPermissionRequestDeny(request, kWKPermissionDenied);
+ continue;
+ }
+
+ WKRetainPtr<WKArrayRef> audioDeviceUIDs = adoptWK(WKUserMediaPermissionRequestAudioDeviceUIDs(request));
+ WKRetainPtr<WKArrayRef> videoDeviceUIDs = adoptWK(WKUserMediaPermissionRequestVideoDeviceUIDs(request));
+
+ if (!WKArrayGetSize(videoDeviceUIDs.get()) && !WKArrayGetSize(audioDeviceUIDs.get())) {
+ WKUserMediaPermissionRequestDeny(request, kWKNoConstraints);
+ continue;
+ }
+
+ WKRetainPtr<WKStringRef> videoDeviceUID;
+ if (WKArrayGetSize(videoDeviceUIDs.get()))
+ videoDeviceUID = reinterpret_cast<WKStringRef>(WKArrayGetItemAtIndex(videoDeviceUIDs.get(), 0));
+ else
+ videoDeviceUID = adoptWK(WKStringCreateWithUTF8CString(""));
+
+ WKRetainPtr<WKStringRef> audioDeviceUID;
+ if (WKArrayGetSize(audioDeviceUIDs.get()))
+ audioDeviceUID = reinterpret_cast<WKStringRef>(WKArrayGetItemAtIndex(audioDeviceUIDs.get(), 0));
+ else
+ audioDeviceUID = adoptWK(WKStringCreateWithUTF8CString(""));
+
+ WKUserMediaPermissionRequestAllow(request, audioDeviceUID.get(), videoDeviceUID.get());
+ }
+ m_userMediaPermissionRequests.clear();
+}
+
+void TestController::setCustomPolicyDelegate(bool enabled, bool permissive)
+{
+ m_policyDelegateEnabled = enabled;
+ m_policyDelegatePermissive = permissive;
}
void TestController::decidePolicyForGeolocationPermissionRequestIfPossible()
@@ -1189,7 +2061,7 @@ void TestController::decidePolicyForGeolocationPermissionRequestIfPossible()
void TestController::decidePolicyForNotificationPermissionRequest(WKPageRef page, WKSecurityOriginRef origin, WKNotificationPermissionRequestRef request, const void*)
{
- TestController::shared().decidePolicyForNotificationPermissionRequest(page, origin, request);
+ TestController::singleton().decidePolicyForNotificationPermissionRequest(page, origin, request);
}
void TestController::decidePolicyForNotificationPermissionRequest(WKPageRef, WKSecurityOriginRef, WKNotificationPermissionRequestRef request)
@@ -1202,37 +2074,219 @@ void TestController::unavailablePluginButtonClicked(WKPageRef, WKPluginUnavailab
printf("MISSING PLUGIN BUTTON PRESSED\n");
}
-void TestController::decidePolicyForNavigationAction(WKPageRef, WKFrameRef, WKFrameNavigationType, WKEventModifiers, WKEventMouseButton, WKFrameRef, WKURLRequestRef, WKFramePolicyListenerRef listener, WKTypeRef, const void* clientInfo)
+void TestController::decidePolicyForNavigationAction(WKPageRef, WKNavigationActionRef navigationAction, WKFramePolicyListenerRef listener, WKTypeRef, const void* clientInfo)
{
static_cast<TestController*>(const_cast<void*>(clientInfo))->decidePolicyForNavigationAction(listener);
}
void TestController::decidePolicyForNavigationAction(WKFramePolicyListenerRef listener)
{
- if (m_policyDelegateEnabled && !m_policyDelegatePermissive) {
- WKFramePolicyListenerIgnore(listener);
- return;
- }
+ WKRetainPtr<WKFramePolicyListenerRef> retainedListener { listener };
+ const bool shouldIgnore { m_policyDelegateEnabled && !m_policyDelegatePermissive };
+ auto decisionFunction = [shouldIgnore, retainedListener]() {
+ if (shouldIgnore)
+ WKFramePolicyListenerIgnore(retainedListener.get());
+ else
+ WKFramePolicyListenerUse(retainedListener.get());
+ };
- WKFramePolicyListenerUse(listener);
+ if (m_shouldDecideNavigationPolicyAfterDelay)
+ RunLoop::main().dispatch(WTFMove(decisionFunction));
+ else
+ decisionFunction();
}
-void TestController::decidePolicyForResponse(WKPageRef, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef, bool canShowMIMEType, WKFramePolicyListenerRef listener, WKTypeRef, const void* clientInfo)
+void TestController::decidePolicyForNavigationResponse(WKPageRef, WKNavigationResponseRef navigationResponse, WKFramePolicyListenerRef listener, WKTypeRef, const void* clientInfo)
{
- static_cast<TestController*>(const_cast<void*>(clientInfo))->decidePolicyForResponse(frame, response, listener);
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->decidePolicyForNavigationResponse(navigationResponse, listener);
}
-void TestController::decidePolicyForResponse(WKFrameRef frame, WKURLResponseRef response, WKFramePolicyListenerRef listener)
+void TestController::decidePolicyForNavigationResponse(WKNavigationResponseRef navigationResponse, WKFramePolicyListenerRef listener)
{
// Even though Response was already checked by WKBundlePagePolicyClient, the check did not include plugins
// so we have to re-check again.
- WKRetainPtr<WKStringRef> wkMIMEType(AdoptWK, WKURLResponseCopyMIMEType(response));
- if (WKFrameCanShowMIMEType(frame, wkMIMEType.get())) {
+ if (WKNavigationResponseCanShowMIMEType(navigationResponse)) {
WKFramePolicyListenerUse(listener);
return;
}
- WKFramePolicyListenerIgnore(listener);
+ if (m_shouldDownloadUndisplayableMIMETypes)
+ WKFramePolicyListenerDownload(listener);
+ else
+ WKFramePolicyListenerIgnore(listener);
+}
+
+void TestController::didNavigateWithNavigationData(WKContextRef, WKPageRef, WKNavigationDataRef navigationData, WKFrameRef frame, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didNavigateWithNavigationData(navigationData, frame);
}
+void TestController::didNavigateWithNavigationData(WKNavigationDataRef navigationData, WKFrameRef)
+{
+ if (m_state != RunningTest)
+ return;
+
+ if (!m_shouldLogHistoryClientCallbacks)
+ return;
+
+ // URL
+ WKRetainPtr<WKURLRef> urlWK = adoptWK(WKNavigationDataCopyURL(navigationData));
+ WKRetainPtr<WKStringRef> urlStringWK = adoptWK(WKURLCopyString(urlWK.get()));
+ // Title
+ WKRetainPtr<WKStringRef> titleWK = adoptWK(WKNavigationDataCopyTitle(navigationData));
+ // HTTP method
+ WKRetainPtr<WKURLRequestRef> requestWK = adoptWK(WKNavigationDataCopyOriginalRequest(navigationData));
+ WKRetainPtr<WKStringRef> methodWK = adoptWK(WKURLRequestCopyHTTPMethod(requestWK.get()));
+
+ // FIXME: Determine whether the navigation was successful / a client redirect rather than hard-coding the message here.
+ m_currentInvocation->outputText(String::format("WebView navigated to url \"%s\" with title \"%s\" with HTTP equivalent method \"%s\". The navigation was successful and was not a client redirect.\n",
+ toSTD(urlStringWK).c_str(), toSTD(titleWK).c_str(), toSTD(methodWK).c_str()));
+}
+
+void TestController::didPerformClientRedirect(WKContextRef, WKPageRef, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didPerformClientRedirect(sourceURL, destinationURL, frame);
+}
+
+void TestController::didPerformClientRedirect(WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef)
+{
+ if (m_state != RunningTest)
+ return;
+
+ if (!m_shouldLogHistoryClientCallbacks)
+ return;
+
+ WKRetainPtr<WKStringRef> sourceStringWK = adoptWK(WKURLCopyString(sourceURL));
+ WKRetainPtr<WKStringRef> destinationStringWK = adoptWK(WKURLCopyString(destinationURL));
+
+ m_currentInvocation->outputText(String::format("WebView performed a client redirect from \"%s\" to \"%s\".\n", toSTD(sourceStringWK).c_str(), toSTD(destinationStringWK).c_str()));
+}
+
+void TestController::didPerformServerRedirect(WKContextRef, WKPageRef, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didPerformServerRedirect(sourceURL, destinationURL, frame);
+}
+
+void TestController::didPerformServerRedirect(WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef)
+{
+ if (m_state != RunningTest)
+ return;
+
+ if (!m_shouldLogHistoryClientCallbacks)
+ return;
+
+ WKRetainPtr<WKStringRef> sourceStringWK = adoptWK(WKURLCopyString(sourceURL));
+ WKRetainPtr<WKStringRef> destinationStringWK = adoptWK(WKURLCopyString(destinationURL));
+
+ m_currentInvocation->outputText(String::format("WebView performed a server redirect from \"%s\" to \"%s\".\n", toSTD(sourceStringWK).c_str(), toSTD(destinationStringWK).c_str()));
+}
+
+void TestController::didUpdateHistoryTitle(WKContextRef, WKPageRef, WKStringRef title, WKURLRef URL, WKFrameRef frame, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didUpdateHistoryTitle(title, URL, frame);
+}
+
+void TestController::didUpdateHistoryTitle(WKStringRef title, WKURLRef URL, WKFrameRef)
+{
+ if (m_state != RunningTest)
+ return;
+
+ if (!m_shouldLogHistoryClientCallbacks)
+ return;
+
+ WKRetainPtr<WKStringRef> urlStringWK(AdoptWK, WKURLCopyString(URL));
+ m_currentInvocation->outputText(String::format("WebView updated the title for history URL \"%s\" to \"%s\".\n", toSTD(urlStringWK).c_str(), toSTD(title).c_str()));
+}
+
+void TestController::setNavigationGesturesEnabled(bool value)
+{
+ m_mainWebView->setNavigationGesturesEnabled(value);
+}
+
+void TestController::setIgnoresViewportScaleLimits(bool ignoresViewportScaleLimits)
+{
+ WKPageSetIgnoresViewportScaleLimits(m_mainWebView->page(), ignoresViewportScaleLimits);
+}
+
+void TestController::setStatisticsPrevalentResource(WKStringRef hostName, bool value)
+{
+ WKResourceLoadStatisticsManagerSetPrevalentResource(hostName, value);
+}
+
+bool TestController::isStatisticsPrevalentResource(WKStringRef hostName)
+{
+ return WKResourceLoadStatisticsManagerIsPrevalentResource(hostName);
+}
+
+void TestController::setStatisticsHasHadUserInteraction(WKStringRef hostName, bool value)
+{
+ WKResourceLoadStatisticsManagerSetHasHadUserInteraction(hostName, value);
+}
+
+bool TestController::isStatisticsHasHadUserInteraction(WKStringRef hostName)
+{
+ return WKResourceLoadStatisticsManagerIsHasHadUserInteraction(hostName);
+}
+
+void TestController::setStatisticsTimeToLiveUserInteraction(double seconds)
+{
+ WKResourceLoadStatisticsManagerSetTimeToLiveUserInteraction(seconds);
+}
+
+void TestController::statisticsFireDataModificationHandler()
+{
+ WKResourceLoadStatisticsManagerFireDataModificationHandler();
+}
+
+void TestController::setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool value)
+{
+ WKResourceLoadStatisticsManagerSetNotifyPagesWhenDataRecordsWereScanned(value);
+}
+
+void TestController::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool value)
+{
+ WKResourceLoadStatisticsManagerSetShouldClassifyResourcesBeforeDataRecordsRemoval(value);
+}
+
+void TestController::setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double seconds)
+{
+ WKResourceLoadStatisticsManagerSetMinimumTimeBetweeenDataRecordsRemoval(seconds);
+}
+void TestController::statisticsResetToConsistentState()
+{
+ WKResourceLoadStatisticsManagerResetToConsistentState();
+}
+
+#if !PLATFORM(COCOA)
+void TestController::platformWillRunTest(const TestInvocation&)
+{
+}
+
+void TestController::platformCreateWebView(WKPageConfigurationRef configuration, const TestOptions& options)
+{
+ m_mainWebView = std::make_unique<PlatformWebView>(configuration, options);
+}
+
+PlatformWebView* TestController::platformCreateOtherPage(PlatformWebView* parentView, WKPageConfigurationRef configuration, const TestOptions& options)
+{
+ return new PlatformWebView(configuration, options);
+}
+
+WKContextRef TestController::platformAdjustContext(WKContextRef context, WKContextConfigurationRef contextConfiguration)
+{
+ return context;
+}
+
+void TestController::platformResetStateToConsistentValues()
+{
+
+}
+
+unsigned TestController::imageCountInGeneralPasteboard() const
+{
+ return 0;
+}
+
+#endif
+
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/TestController.h b/Tools/WebKitTestRunner/TestController.h
index 10031a176..cc753c297 100644
--- a/Tools/WebKitTestRunner/TestController.h
+++ b/Tools/WebKitTestRunner/TestController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2015-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,22 +29,28 @@
#include "GeolocationProviderMock.h"
#include "WebNotificationProvider.h"
#include "WorkQueueManager.h"
-#include <WebKit2/WKRetainPtr.h>
+#include <WebKit/WKRetainPtr.h>
#include <string>
#include <vector>
-#include <wtf/OwnPtr.h>
+#include <wtf/HashMap.h>
#include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
+
+OBJC_CLASS WKWebViewConfiguration;
namespace WTR {
class TestInvocation;
+class OriginSettings;
class PlatformWebView;
class EventSenderProxy;
+struct TestCommand;
+struct TestOptions;
// FIXME: Rename this TestRunner?
class TestController {
public:
- static TestController& shared();
+ static TestController& singleton();
static const unsigned viewWidth;
static const unsigned viewHeight;
@@ -52,29 +58,32 @@ public:
static const unsigned w3cSVGViewWidth;
static const unsigned w3cSVGViewHeight;
+ static const double defaultShortTimeout;
+ static const double noTimeout;
+
TestController(int argc, const char* argv[]);
~TestController();
bool verbose() const { return m_verbose; }
- WKStringRef injectedBundlePath() { return m_injectedBundlePath.get(); }
- WKStringRef testPluginDirectory() { return m_testPluginDirectory.get(); }
+ WKStringRef injectedBundlePath() const { return m_injectedBundlePath.get(); }
+ WKStringRef testPluginDirectory() const { return m_testPluginDirectory.get(); }
PlatformWebView* mainWebView() { return m_mainWebView.get(); }
WKContextRef context() { return m_context.get(); }
EventSenderProxy* eventSenderProxy() { return m_eventSenderProxy.get(); }
- void ensureViewSupportsOptions(WKDictionaryRef options);
bool shouldUseRemoteLayerTree() const { return m_shouldUseRemoteLayerTree; }
// Runs the run loop until `done` is true or the timeout elapses.
- enum TimeoutDuration { ShortTimeout, LongTimeout, NoTimeout, CustomTimeout };
bool useWaitToDumpWatchdogTimer() { return m_useWaitToDumpWatchdogTimer; }
- void runUntil(bool& done, TimeoutDuration);
+ void runUntil(bool& done, double timeoutSeconds);
void notifyDone();
- int getCustomTimeout();
+ bool shouldShowWebView() const { return m_shouldShowWebView; }
+ bool usingServerMode() const { return m_usingServerMode; }
+ void configureViewForTest(const TestInvocation&);
bool beforeUnloadReturnValue() const { return m_beforeUnloadReturnValue; }
void setBeforeUnloadReturnValue(bool value) { m_beforeUnloadReturnValue = value; }
@@ -86,27 +95,75 @@ public:
void setMockGeolocationPosition(double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed);
void setMockGeolocationPositionUnavailableError(WKStringRef errorMessage);
void handleGeolocationPermissionRequest(WKGeolocationPermissionRequestRef);
+ bool isGeolocationProviderActive() const;
+
+ // MediaStream.
+ String saltForOrigin(WKFrameRef, String);
+ void getUserMediaInfoForOrigin(WKFrameRef, WKStringRef originKey, bool&, WKRetainPtr<WKStringRef>&);
+ WKStringRef getUserMediaSaltForOrigin(WKFrameRef, WKStringRef originKey);
+ void setUserMediaPermission(bool);
+ void setUserMediaPersistentPermissionForOrigin(bool, WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString);
+ void handleUserMediaPermissionRequest(WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, WKUserMediaPermissionRequestRef);
+ void handleCheckOfUserMediaPermissionForOrigin(WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, const WKUserMediaPermissionCheckRef&);
+ OriginSettings& settingsForOrigin(const String&);
+ unsigned userMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString);
+ void resetUserMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString);
// Policy delegate.
void setCustomPolicyDelegate(bool enabled, bool permissive);
// Page Visibility.
- void setVisibilityState(WKPageVisibilityState, bool isInitialState);
+ void setHidden(bool);
+
+ unsigned imageCountInGeneralPasteboard() const;
+
+ bool resetStateToConsistentValues(const TestOptions&);
+ void resetPreferencesToConsistentValues(const TestOptions&);
- bool resetStateToConsistentValues();
- void resetPreferencesToConsistentValues();
+ void terminateWebContentProcess();
+ void reattachPageToWebProcess();
+
+ static const char* webProcessName();
+ static const char* networkProcessName();
+ static const char* databaseProcessName();
WorkQueueManager& workQueueManager() { return m_workQueueManager; }
+ void setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(bool value) { m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges = value; }
void setHandlesAuthenticationChallenges(bool value) { m_handlesAuthenticationChallenges = value; }
void setAuthenticationUsername(String username) { m_authenticationUsername = username; }
void setAuthenticationPassword(String password) { m_authenticationPassword = password; }
void setBlockAllPlugins(bool shouldBlock) { m_shouldBlockAllPlugins = shouldBlock; }
+ void setShouldLogHistoryClientCallbacks(bool shouldLog) { m_shouldLogHistoryClientCallbacks = shouldLog; }
+ void setShouldLogCanAuthenticateAgainstProtectionSpace(bool shouldLog) { m_shouldLogCanAuthenticateAgainstProtectionSpace = shouldLog; }
+
+ bool isCurrentInvocation(TestInvocation* invocation) const { return invocation == m_currentInvocation.get(); }
+
+ void setShouldDecideNavigationPolicyAfterDelay(bool value) { m_shouldDecideNavigationPolicyAfterDelay = value; }
+
+ void setNavigationGesturesEnabled(bool value);
+ void setIgnoresViewportScaleLimits(bool);
+
+ void setShouldDownloadUndisplayableMIMETypes(bool value) { m_shouldDownloadUndisplayableMIMETypes = value; }
+
+ void setStatisticsPrevalentResource(WKStringRef hostName, bool value);
+ bool isStatisticsPrevalentResource(WKStringRef hostName);
+ void setStatisticsHasHadUserInteraction(WKStringRef hostName, bool value);
+ bool isStatisticsHasHadUserInteraction(WKStringRef hostName);
+ void setStatisticsTimeToLiveUserInteraction(double seconds);
+ void statisticsFireDataModificationHandler();
+ void setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool);
+ void setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool);
+ void setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double);
+ void statisticsResetToConsistentState();
+
private:
+ WKRetainPtr<WKPageConfigurationRef> generatePageConfiguration(WKContextConfigurationRef);
+ WKRetainPtr<WKContextConfigurationRef> generateContextConfiguration() const;
void initialize(int argc, const char* argv[]);
- void createWebViewWithOptions(WKDictionaryRef);
+ void createWebViewWithOptions(const TestOptions&);
void run();
void runTestingServerLoop();
@@ -114,34 +171,87 @@ private:
void platformInitialize();
void platformDestroy();
+ WKContextRef platformAdjustContext(WKContextRef, WKContextConfigurationRef);
void platformInitializeContext();
+ void platformCreateWebView(WKPageConfigurationRef, const TestOptions&);
+ static PlatformWebView* platformCreateOtherPage(PlatformWebView* parentView, WKPageConfigurationRef, const TestOptions&);
+ void platformResetPreferencesToConsistentValues();
+ void platformResetStateToConsistentValues();
+#if PLATFORM(COCOA)
+ void cocoaResetStateToConsistentValues();
+#endif
+ void platformConfigureViewForTest(const TestInvocation&);
+ void platformWillRunTest(const TestInvocation&);
void platformRunUntil(bool& done, double timeout);
void platformDidCommitLoadForFrame(WKPageRef, WKFrameRef);
+ WKPreferencesRef platformPreferences();
void initializeInjectedBundlePath();
void initializeTestPluginDirectory();
+ void ensureViewSupportsOptionsForTest(const TestInvocation&);
+ TestOptions testOptionsForTest(const TestCommand&) const;
+ void updatePlatformSpecificTestOptionsForTest(TestOptions&, const std::string& pathOrURL) const;
+
+ void updateWebViewSizeForTest(const TestInvocation&);
+ void updateWindowScaleForTest(PlatformWebView*, const TestInvocation&);
+
void decidePolicyForGeolocationPermissionRequestIfPossible();
+ void decidePolicyForUserMediaPermissionRequestIfPossible();
// WKContextInjectedBundleClient
static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*);
static void didReceiveSynchronousMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void*);
+ static WKTypeRef getInjectedBundleInitializationUserData(WKContextRef, const void *clientInfo);
+
+ // WKPageInjectedBundleClient
+ static void didReceivePageMessageFromInjectedBundle(WKPageRef, WKStringRef messageName, WKTypeRef messageBody, const void*);
+ static void didReceiveSynchronousPageMessageFromInjectedBundle(WKPageRef, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void*);
void didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody);
WKRetainPtr<WKTypeRef> didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody);
+ WKRetainPtr<WKTypeRef> getInjectedBundleInitializationUserData();
void didReceiveKeyDownMessageFromInjectedBundle(WKDictionaryRef messageBodyDictionary, bool synchronous);
- // WKPageLoaderClient
- static void didCommitLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void*);
- void didCommitLoadForFrame(WKPageRef, WKFrameRef);
+ // WKContextClient
+ static void networkProcessDidCrash(WKContextRef, const void*);
+ void networkProcessDidCrash();
+ static void databaseProcessDidCrash(WKContextRef, const void*);
+ void databaseProcessDidCrash();
- static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void*);
- void didFinishLoadForFrame(WKPageRef, WKFrameRef);
+ // WKPageNavigationClient
+ static void didCommitNavigation(WKPageRef, WKNavigationRef, WKTypeRef userData, const void*);
+ void didCommitNavigation(WKPageRef, WKNavigationRef);
+ static void didFinishNavigation(WKPageRef, WKNavigationRef, WKTypeRef userData, const void*);
+ void didFinishNavigation(WKPageRef, WKNavigationRef);
+
+
+ // WKContextDownloadClient
+ static void downloadDidStart(WKContextRef, WKDownloadRef, const void*);
+ void downloadDidStart(WKContextRef, WKDownloadRef);
+ static WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef, WKStringRef filename, bool* allowOverwrite, const void *clientInfo);
+ WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef, WKStringRef filename, bool*& allowOverwrite);
+ static void downloadDidFinish(WKContextRef, WKDownloadRef, const void*);
+ void downloadDidFinish(WKContextRef, WKDownloadRef);
+ static void downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef, const void*);
+ void downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef);
+ static void downloadDidCancel(WKContextRef, WKDownloadRef, const void*);
+ void downloadDidCancel(WKContextRef, WKDownloadRef);
+
static void processDidCrash(WKPageRef, const void* clientInfo);
void processDidCrash();
- static WKPluginLoadPolicy pluginLoadPolicy(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription, const void* clientInfo);
- WKPluginLoadPolicy pluginLoadPolicy(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription);
+ static void didBeginNavigationGesture(WKPageRef, const void*);
+ static void willEndNavigationGesture(WKPageRef, WKBackForwardListItemRef, const void*);
+ static void didEndNavigationGesture(WKPageRef, WKBackForwardListItemRef, const void*);
+ static void didRemoveNavigationGestureSnapshot(WKPageRef, const void*);
+ void didBeginNavigationGesture(WKPageRef);
+ void willEndNavigationGesture(WKPageRef, WKBackForwardListItemRef);
+ void didEndNavigationGesture(WKPageRef, WKBackForwardListItemRef);
+ void didRemoveNavigationGestureSnapshot(WKPageRef);
+
+ static WKPluginLoadPolicy decidePolicyForPluginLoad(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription, const void* clientInfo);
+ WKPluginLoadPolicy decidePolicyForPluginLoad(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription);
static void decidePolicyForNotificationPermissionRequest(WKPageRef, WKSecurityOriginRef, WKNotificationPermissionRequestRef, const void*);
@@ -149,40 +259,54 @@ private:
static void unavailablePluginButtonClicked(WKPageRef, WKPluginUnavailabilityReason, WKDictionaryRef, const void*);
- static void didReceiveAuthenticationChallengeInFrame(WKPageRef, WKFrameRef, WKAuthenticationChallengeRef, const void *clientInfo);
- void didReceiveAuthenticationChallengeInFrame(WKPageRef, WKFrameRef, WKAuthenticationChallengeRef);
+ static bool canAuthenticateAgainstProtectionSpace(WKPageRef, WKProtectionSpaceRef, const void*);
+ bool canAuthenticateAgainstProtectionSpace(WKPageRef, WKProtectionSpaceRef);
+
+ static void didReceiveAuthenticationChallenge(WKPageRef, WKAuthenticationChallengeRef, const void*);
+ void didReceiveAuthenticationChallenge(WKPageRef, WKAuthenticationChallengeRef);
- // WKPagePolicyClient
- static void decidePolicyForNavigationAction(WKPageRef, WKFrameRef, WKFrameNavigationType, WKEventModifiers, WKEventMouseButton, WKFrameRef, WKURLRequestRef, WKFramePolicyListenerRef, WKTypeRef, const void*);
+ static void decidePolicyForNavigationAction(WKPageRef, WKNavigationActionRef, WKFramePolicyListenerRef, WKTypeRef, const void*);
void decidePolicyForNavigationAction(WKFramePolicyListenerRef);
- static void decidePolicyForResponse(WKPageRef, WKFrameRef, WKURLResponseRef, WKURLRequestRef, bool canShowMIMEType, WKFramePolicyListenerRef, WKTypeRef, const void*);
- void decidePolicyForResponse(WKFrameRef, WKURLResponseRef, WKFramePolicyListenerRef);
+ static void decidePolicyForNavigationResponse(WKPageRef, WKNavigationResponseRef, WKFramePolicyListenerRef, WKTypeRef, const void*);
+ void decidePolicyForNavigationResponse(WKNavigationResponseRef, WKFramePolicyListenerRef);
+
+ // WKContextHistoryClient
+ static void didNavigateWithNavigationData(WKContextRef, WKPageRef, WKNavigationDataRef, WKFrameRef, const void*);
+ void didNavigateWithNavigationData(WKNavigationDataRef, WKFrameRef);
+
+ static void didPerformClientRedirect(WKContextRef, WKPageRef, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef, const void*);
+ void didPerformClientRedirect(WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef);
- static WKPageRef createOtherPage(WKPageRef oldPage, WKURLRequestRef, WKDictionaryRef, WKEventModifiers, WKEventMouseButton, const void*);
+ static void didPerformServerRedirect(WKContextRef, WKPageRef, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef, const void*);
+ void didPerformServerRedirect(WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef);
+
+ static void didUpdateHistoryTitle(WKContextRef, WKPageRef, WKStringRef title, WKURLRef, WKFrameRef, const void*);
+ void didUpdateHistoryTitle(WKStringRef title, WKURLRef, WKFrameRef);
+
+ static WKPageRef createOtherPage(WKPageRef, WKPageConfigurationRef, WKNavigationActionRef, WKWindowFeaturesRef, const void*);
static void runModal(WKPageRef, const void* clientInfo);
static void runModal(PlatformWebView*);
- void setHidden(bool);
-
static const char* libraryPathForTesting();
static const char* platformLibraryPathForTesting();
- OwnPtr<TestInvocation> m_currentInvocation;
+ std::unique_ptr<TestInvocation> m_currentInvocation;
- bool m_verbose;
- bool m_printSeparators;
- bool m_usingServerMode;
- bool m_gcBetweenTests;
- bool m_shouldDumpPixelsForAllTests;
+ bool m_verbose { false };
+ bool m_printSeparators { false };
+ bool m_usingServerMode { false };
+ bool m_gcBetweenTests { false };
+ bool m_shouldDumpPixelsForAllTests { false };
std::vector<std::string> m_paths;
+ std::vector<std::string> m_allowedHosts;
WKRetainPtr<WKStringRef> m_injectedBundlePath;
WKRetainPtr<WKStringRef> m_testPluginDirectory;
WebNotificationProvider m_webNotificationProvider;
- OwnPtr<PlatformWebView> m_mainWebView;
+ std::unique_ptr<PlatformWebView> m_mainWebView;
WKRetainPtr<WKContextRef> m_context;
WKRetainPtr<WKPageGroupRef> m_pageGroup;
@@ -191,45 +315,65 @@ private:
Resetting,
RunningTest
};
- State m_state;
- bool m_doneResetting;
+ State m_state { Initial };
+ bool m_doneResetting { false };
- double m_longTimeout;
- double m_shortTimeout;
- double m_noTimeout;
- bool m_useWaitToDumpWatchdogTimer;
- bool m_forceNoTimeout;
+ bool m_useWaitToDumpWatchdogTimer { true };
+ bool m_forceNoTimeout { false };
- int m_timeout;
-
- bool m_didPrintWebProcessCrashedMessage;
- bool m_shouldExitWhenWebProcessCrashes;
+ bool m_didPrintWebProcessCrashedMessage { false };
+ bool m_shouldExitWhenWebProcessCrashes { true };
- bool m_beforeUnloadReturnValue;
+ bool m_beforeUnloadReturnValue { true };
- OwnPtr<GeolocationProviderMock> m_geolocationProvider;
+ std::unique_ptr<GeolocationProviderMock> m_geolocationProvider;
Vector<WKRetainPtr<WKGeolocationPermissionRequestRef> > m_geolocationPermissionRequests;
- bool m_isGeolocationPermissionSet;
- bool m_isGeolocationPermissionAllowed;
+ bool m_isGeolocationPermissionSet { false };
+ bool m_isGeolocationPermissionAllowed { false };
+
+ HashMap<String, RefPtr<OriginSettings>> m_cachedUserMediaPermissions;
+
+ typedef Vector<std::pair<String, WKRetainPtr<WKUserMediaPermissionRequestRef>>> PermissionRequestList;
+ PermissionRequestList m_userMediaPermissionRequests;
+
+ bool m_isUserMediaPermissionSet { false };
+ bool m_isUserMediaPermissionAllowed { false };
- bool m_policyDelegateEnabled;
- bool m_policyDelegatePermissive;
+ bool m_policyDelegateEnabled { false };
+ bool m_policyDelegatePermissive { false };
+ bool m_shouldDownloadUndisplayableMIMETypes { false };
- bool m_handlesAuthenticationChallenges;
+ bool m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges { false };
+ bool m_handlesAuthenticationChallenges { false };
String m_authenticationUsername;
String m_authenticationPassword;
- bool m_shouldBlockAllPlugins;
+ bool m_shouldBlockAllPlugins { false };
- bool m_forceComplexText;
- bool m_shouldUseAcceleratedDrawing;
- bool m_shouldUseRemoteLayerTree;
+ bool m_forceComplexText { false };
+ bool m_shouldUseAcceleratedDrawing { false };
+ bool m_shouldUseRemoteLayerTree { false };
- OwnPtr<EventSenderProxy> m_eventSenderProxy;
+ bool m_shouldLogCanAuthenticateAgainstProtectionSpace { false };
+ bool m_shouldLogHistoryClientCallbacks { false };
+ bool m_shouldShowWebView { false };
+
+ bool m_shouldDecideNavigationPolicyAfterDelay { false };
+
+ std::unique_ptr<EventSenderProxy> m_eventSenderProxy;
WorkQueueManager m_workQueueManager;
};
+struct TestCommand {
+ std::string pathOrURL;
+ std::string absolutePath;
+ bool shouldDumpPixels { false };
+ std::string expectedPixelHash;
+ int timeout { 0 };
+ bool dumpJSConsoleLogInStdErr { false };
+};
+
} // namespace WTR
#endif // TestController_h
diff --git a/Tools/WebKitTestRunner/TestInvocation.cpp b/Tools/WebKitTestRunner/TestInvocation.cpp
index cac2ba8b8..b0a0442cc 100644
--- a/Tools/WebKitTestRunner/TestInvocation.cpp
+++ b/Tools/WebKitTestRunner/TestInvocation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
* Copyright (C) 2012 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,196 +30,144 @@
#include "PlatformWebView.h"
#include "StringFunctions.h"
#include "TestController.h"
+#include "UIScriptController.h"
+#include "WebCoreTestSupport.h"
+#include <WebKit/WKContextPrivate.h>
+#include <WebKit/WKCookieManager.h>
+#include <WebKit/WKData.h>
+#include <WebKit/WKDictionary.h>
+#include <WebKit/WKInspector.h>
+#include <WebKit/WKPagePrivate.h>
+#include <WebKit/WKRetainPtr.h>
+#include <WebKit/WKWebsiteDataStoreRef.h>
#include <climits>
#include <cstdio>
-#include <WebKit2/WKContextPrivate.h>
-#include <WebKit2/WKData.h>
-#include <WebKit2/WKDictionary.h>
-#include <WebKit2/WKInspector.h>
-#include <WebKit2/WKRetainPtr.h>
-#include <wtf/PassOwnPtr.h>
+#include <unistd.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/CString.h>
-#if PLATFORM(MAC)
-#if !PLATFORM(IOS)
+#if PLATFORM(MAC) && !PLATFORM(IOS)
#include <Carbon/Carbon.h>
#endif
-#include <WebKit2/WKPagePrivateMac.h>
-#endif
-#include <unistd.h> // For getcwd.
+#if PLATFORM(COCOA)
+#include <WebKit/WKPagePrivateMac.h>
+#endif
+using namespace JSC;
using namespace WebKit;
using namespace std;
namespace WTR {
-static WKURLRef createWKURL(const char* pathOrURL)
+TestInvocation::TestInvocation(WKURLRef url, const TestOptions& options)
+ : m_options(options)
+ , m_url(url)
{
- if (strstr(pathOrURL, "http://") || strstr(pathOrURL, "https://") || strstr(pathOrURL, "file://"))
- return WKURLCreateWithUTF8CString(pathOrURL);
+ WKRetainPtr<WKStringRef> urlString = adoptWK(WKURLCopyString(m_url.get()));
- // Creating from filesytem path.
- size_t length = strlen(pathOrURL);
- if (!length)
- return 0;
-
- const char separator = '/';
- bool isAbsolutePath = pathOrURL[0] == separator;
- const char* filePrefix = "file://";
- static const size_t prefixLength = strlen(filePrefix);
-
- std::unique_ptr<char[]> buffer;
- if (isAbsolutePath) {
- buffer = std::make_unique<char[]>(prefixLength + length + 1);
- strcpy(buffer.get(), filePrefix);
- strcpy(buffer.get() + prefixLength, pathOrURL);
- } else {
- buffer = std::make_unique<char[]>(prefixLength + PATH_MAX + length + 2); // 1 for the separator
- strcpy(buffer.get(), filePrefix);
- if (!getcwd(buffer.get() + prefixLength, PATH_MAX))
- return 0;
- size_t numCharacters = strlen(buffer.get());
- buffer[numCharacters] = separator;
- strcpy(buffer.get() + numCharacters + 1, pathOrURL);
- }
-
- return WKURLCreateWithUTF8CString(buffer.get());
-}
+ size_t stringLength = WKStringGetLength(urlString.get());
-TestInvocation::TestInvocation(const std::string& pathOrURL)
- : m_url(AdoptWK, createWKURL(pathOrURL.c_str()))
- , m_pathOrURL(pathOrURL)
- , m_dumpPixels(false)
- , m_timeout(0)
- , m_gotInitialResponse(false)
- , m_gotFinalMessage(false)
- , m_gotRepaint(false)
- , m_error(false)
- , m_webProcessIsUnresponsive(false)
-{
+ Vector<char> urlVector;
+ urlVector.resize(stringLength + 1);
+
+ WKStringGetUTF8CString(urlString.get(), urlVector.data(), stringLength + 1);
+
+ m_urlString = String(urlVector.data(), stringLength);
}
TestInvocation::~TestInvocation()
{
+ if (m_pendingUIScriptInvocationData)
+ m_pendingUIScriptInvocationData->testInvocation = nullptr;
}
-void TestInvocation::setIsPixelTest(const std::string& expectedPixelHash)
+WKURLRef TestInvocation::url() const
{
- m_dumpPixels = true;
- m_expectedPixelHash = expectedPixelHash;
+ return m_url.get();
}
-void TestInvocation::setCustomTimeout(int timeout)
+bool TestInvocation::urlContains(const char* searchString) const
{
- m_timeout = timeout;
+ return m_urlString.contains(searchString, false);
}
-static void sizeWebViewForCurrentTest(const char* pathOrURL)
+void TestInvocation::setIsPixelTest(const std::string& expectedPixelHash)
{
- bool isSVGW3CTest = strstr(pathOrURL, "svg/W3C-SVG-1.1") || strstr(pathOrURL, "svg\\W3C-SVG-1.1");
-
- if (isSVGW3CTest)
- TestController::shared().mainWebView()->resizeTo(TestController::w3cSVGViewWidth, TestController::w3cSVGViewHeight);
- else
- TestController::shared().mainWebView()->resizeTo(TestController::viewWidth, TestController::viewHeight);
+ m_dumpPixels = true;
+ m_expectedPixelHash = expectedPixelHash;
}
-static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
+double TestInvocation::shortTimeout() const
{
- return strstr(pathOrURL, "loading/");
-}
+ if (!m_timeout) {
+ // Running WKTR directly, without webkitpy.
+ return TestController::defaultShortTimeout;
+ }
-#if ENABLE(INSPECTOR) && !PLATFORM(IOS)
-static bool shouldOpenWebInspector(const char* pathOrURL)
-{
- return strstr(pathOrURL, "inspector/") || strstr(pathOrURL, "inspector\\");
+ // This is not exactly correct for the way short timeout is used - it should not depend on whether a test is "slow",
+ // but it currently does. There is no way to know what a normal test's timeout is, as webkitpy only passes timeouts
+ // for each test individually.
+ // But there shouldn't be any observable negative consequences from this.
+ return m_timeout / 1000. / 2;
}
-#endif
-#if PLATFORM(MAC)
-static bool shouldUseThreadedScrolling(const char* pathOrURL)
+bool TestInvocation::shouldLogFrameLoadDelegates() const
{
- return strstr(pathOrURL, "tiled-drawing/") || strstr(pathOrURL, "tiled-drawing\\");
+ return urlContains("loading/");
}
-#endif
-static void updateThreadedScrollingForCurrentTest(const char* pathOrURL)
+bool TestInvocation::shouldLogHistoryClientCallbacks() const
{
-#if PLATFORM(MAC)
- WKRetainPtr<WKMutableDictionaryRef> viewOptions = adoptWK(WKMutableDictionaryCreate());
- WKRetainPtr<WKStringRef> useThreadedScrollingKey = adoptWK(WKStringCreateWithUTF8CString("ThreadedScrolling"));
- WKRetainPtr<WKBooleanRef> useThreadedScrollingValue = adoptWK(WKBooleanCreate(shouldUseThreadedScrolling(pathOrURL)));
- WKDictionarySetItem(viewOptions.get(), useThreadedScrollingKey.get(), useThreadedScrollingValue.get());
-
- WKRetainPtr<WKStringRef> useRemoteLayerTreeKey = adoptWK(WKStringCreateWithUTF8CString("RemoteLayerTree"));
- WKRetainPtr<WKBooleanRef> useRemoteLayerTreeValue = adoptWK(WKBooleanCreate(TestController::shared().shouldUseRemoteLayerTree()));
- WKDictionarySetItem(viewOptions.get(), useRemoteLayerTreeKey.get(), useRemoteLayerTreeValue.get());
-
- TestController::shared().ensureViewSupportsOptions(viewOptions.get());
-#else
- UNUSED_PARAM(pathOrURL);
-#endif
+ return urlContains("globalhistory/");
}
-static bool shouldUseFixedLayout(const char* pathOrURL)
+void TestInvocation::invoke()
{
-#if ENABLE(CSS_DEVICE_ADAPTATION)
- if (strstr(pathOrURL, "device-adapt/") || strstr(pathOrURL, "device-adapt\\"))
- return true;
-#endif
+ TestController::singleton().configureViewForTest(*this);
-#if USE(TILED_BACKING_STORE) && PLATFORM(EFL)
- if (strstr(pathOrURL, "sticky/") || strstr(pathOrURL, "sticky\\"))
- return true;
-#endif
- return false;
+ WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), false);
- UNUSED_PARAM(pathOrURL);
-}
-
-static void updateLayoutType(const char* pathOrURL)
-{
- WKRetainPtr<WKMutableDictionaryRef> viewOptions = adoptWK(WKMutableDictionaryCreate());
- WKRetainPtr<WKStringRef> useFixedLayoutKey = adoptWK(WKStringCreateWithUTF8CString("UseFixedLayout"));
- WKRetainPtr<WKBooleanRef> useFixedLayoutValue = adoptWK(WKBooleanCreate(shouldUseFixedLayout(pathOrURL)));
- WKDictionarySetItem(viewOptions.get(), useFixedLayoutKey.get(), useFixedLayoutValue.get());
+ m_textOutput.clear();
- TestController::shared().ensureViewSupportsOptions(viewOptions.get());
-}
+ TestController::singleton().setShouldLogHistoryClientCallbacks(shouldLogHistoryClientCallbacks());
-void TestInvocation::invoke()
-{
- TestController::TimeoutDuration timeoutToUse = TestController::LongTimeout;
- sizeWebViewForCurrentTest(m_pathOrURL.c_str());
- updateLayoutType(m_pathOrURL.c_str());
- updateThreadedScrollingForCurrentTest(m_pathOrURL.c_str());
+ WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain);
- m_textOutput.clear();
+ // FIXME: We should clear out visited links here.
WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("BeginTest"));
WKRetainPtr<WKMutableDictionaryRef> beginTestMessageBody = adoptWK(WKMutableDictionaryCreate());
WKRetainPtr<WKStringRef> dumpFrameLoadDelegatesKey = adoptWK(WKStringCreateWithUTF8CString("DumpFrameLoadDelegates"));
- WKRetainPtr<WKBooleanRef> dumpFrameLoadDelegatesValue = adoptWK(WKBooleanCreate(shouldLogFrameLoadDelegates(m_pathOrURL.c_str())));
+ WKRetainPtr<WKBooleanRef> dumpFrameLoadDelegatesValue = adoptWK(WKBooleanCreate(shouldLogFrameLoadDelegates()));
WKDictionarySetItem(beginTestMessageBody.get(), dumpFrameLoadDelegatesKey.get(), dumpFrameLoadDelegatesValue.get());
+ WKRetainPtr<WKStringRef> useFlexibleViewportKey = adoptWK(WKStringCreateWithUTF8CString("UseFlexibleViewport"));
+ WKRetainPtr<WKBooleanRef> useFlexibleViewportValue = adoptWK(WKBooleanCreate(options().useFlexibleViewport));
+ WKDictionarySetItem(beginTestMessageBody.get(), useFlexibleViewportKey.get(), useFlexibleViewportValue.get());
+
WKRetainPtr<WKStringRef> dumpPixelsKey = adoptWK(WKStringCreateWithUTF8CString("DumpPixels"));
WKRetainPtr<WKBooleanRef> dumpPixelsValue = adoptWK(WKBooleanCreate(m_dumpPixels));
WKDictionarySetItem(beginTestMessageBody.get(), dumpPixelsKey.get(), dumpPixelsValue.get());
WKRetainPtr<WKStringRef> useWaitToDumpWatchdogTimerKey = adoptWK(WKStringCreateWithUTF8CString("UseWaitToDumpWatchdogTimer"));
- WKRetainPtr<WKBooleanRef> useWaitToDumpWatchdogTimerValue = adoptWK(WKBooleanCreate(TestController::shared().useWaitToDumpWatchdogTimer()));
+ WKRetainPtr<WKBooleanRef> useWaitToDumpWatchdogTimerValue = adoptWK(WKBooleanCreate(TestController::singleton().useWaitToDumpWatchdogTimer()));
WKDictionarySetItem(beginTestMessageBody.get(), useWaitToDumpWatchdogTimerKey.get(), useWaitToDumpWatchdogTimerValue.get());
WKRetainPtr<WKStringRef> timeoutKey = adoptWK(WKStringCreateWithUTF8CString("Timeout"));
WKRetainPtr<WKUInt64Ref> timeoutValue = adoptWK(WKUInt64Create(m_timeout));
WKDictionarySetItem(beginTestMessageBody.get(), timeoutKey.get(), timeoutValue.get());
- WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), beginTestMessageBody.get());
+ WKRetainPtr<WKStringRef> dumpJSConsoleLogInStdErrKey = adoptWK(WKStringCreateWithUTF8CString("DumpJSConsoleLogInStdErr"));
+ WKRetainPtr<WKBooleanRef> dumpJSConsoleLogInStdErrValue = adoptWK(WKBooleanCreate(m_dumpJSConsoleLogInStdErr));
+ WKDictionarySetItem(beginTestMessageBody.get(), dumpJSConsoleLogInStdErrKey.get(), dumpJSConsoleLogInStdErrValue.get());
- TestController::shared().runUntil(m_gotInitialResponse, TestController::ShortTimeout);
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), beginTestMessageBody.get());
+
+ bool shouldOpenExternalURLs = false;
+
+ TestController::singleton().runUntil(m_gotInitialResponse, shortTimeout());
if (!m_gotInitialResponse) {
m_errorMessage = "Timed out waiting for initial response from web process\n";
m_webProcessIsUnresponsive = true;
@@ -228,42 +176,29 @@ void TestInvocation::invoke()
if (m_error)
goto end;
-#if ENABLE(INSPECTOR) && !PLATFORM(IOS)
- if (shouldOpenWebInspector(m_pathOrURL.c_str()))
- WKInspectorShow(WKPageGetInspector(TestController::shared().mainWebView()->page()));
-#endif // ENABLE(INSPECTOR)
-
- WKPageLoadURL(TestController::shared().mainWebView()->page(), m_url.get());
-
- if (TestController::shared().useWaitToDumpWatchdogTimer()) {
- if (m_timeout > 0)
- timeoutToUse = TestController::CustomTimeout;
- } else
- timeoutToUse = TestController::NoTimeout;
- TestController::shared().runUntil(m_gotFinalMessage, timeoutToUse);
+ WKPageLoadURLWithShouldOpenExternalURLsPolicy(TestController::singleton().mainWebView()->page(), m_url.get(), shouldOpenExternalURLs);
- if (!m_gotFinalMessage) {
- m_errorMessage = "Timed out waiting for final message from web process\n";
- m_webProcessIsUnresponsive = true;
- goto end;
- }
+ TestController::singleton().runUntil(m_gotFinalMessage, TestController::noTimeout);
if (m_error)
goto end;
dumpResults();
end:
-#if ENABLE(INSPECTOR) && !PLATFORM(IOS)
+#if !PLATFORM(IOS)
if (m_gotInitialResponse)
- WKInspectorClose(WKPageGetInspector(TestController::shared().mainWebView()->page()));
-#endif // ENABLE(INSPECTOR)
+ WKInspectorClose(WKPageGetInspector(TestController::singleton().mainWebView()->page()));
+#endif // !PLATFORM(IOS)
if (m_webProcessIsUnresponsive)
dumpWebProcessUnresponsiveness();
- else if (!TestController::shared().resetStateToConsistentValues()) {
- m_errorMessage = "Timed out loading about:blank before the next test";
- dumpWebProcessUnresponsiveness();
- }
+ else if (TestController::singleton().resetStateToConsistentValues(m_options))
+ return;
+
+ // The process is unresponsive, so let's start a new one.
+ TestController::singleton().terminateWebContentProcess();
+ // Make sure that we have a process, as invoke() will need one to send bundle messages for the next test.
+ TestController::singleton().reattachPageToWebProcess();
}
void TestInvocation::dumpWebProcessUnresponsiveness()
@@ -273,17 +208,25 @@ void TestInvocation::dumpWebProcessUnresponsiveness()
void TestInvocation::dumpWebProcessUnresponsiveness(const char* errorMessage)
{
- const char* errorMessageToStderr = 0;
-#if PLATFORM(MAC)
- char buffer[64];
- pid_t pid = WKPageGetProcessIdentifier(TestController::shared().mainWebView()->page());
- sprintf(buffer, "#PROCESS UNRESPONSIVE - WebProcess (pid %ld)\n", static_cast<long>(pid));
- errorMessageToStderr = buffer;
+ fprintf(stderr, "%s", errorMessage);
+ char buffer[1024] = { };
+#if PLATFORM(COCOA)
+ pid_t pid = WKPageGetProcessIdentifier(TestController::singleton().mainWebView()->page());
+ snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s (pid %ld)\n", TestController::webProcessName(), static_cast<long>(pid));
#else
- errorMessageToStderr = "#PROCESS UNRESPONSIVE - WebProcess";
+ snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName());
#endif
- dump(errorMessage, errorMessageToStderr, true);
+ dump(errorMessage, buffer, true);
+
+ if (!TestController::singleton().usingServerMode())
+ return;
+
+ if (isatty(fileno(stdin)) || isatty(fileno(stderr)))
+ fputs("Grab an image of the stack, then hit enter...\n", stderr);
+
+ if (!fgets(buffer, sizeof(buffer), stdin) || strcmp(buffer, "#SAMPLE FINISHED\n"))
+ fprintf(stderr, "Failed receive expected sample response, got:\n\t\"%s\"\nContinuing...\n", buffer);
}
void TestInvocation::dump(const char* textToStdout, const char* textToStderr, bool seenError)
@@ -302,11 +245,17 @@ void TestInvocation::dump(const char* textToStdout, const char* textToStderr, bo
fflush(stderr);
}
-void TestInvocation::forceRepaintDoneCallback(WKErrorRef, void* context)
+void TestInvocation::forceRepaintDoneCallback(WKErrorRef error, void* context)
{
+ // The context may not be valid any more, e.g. if WebKit is invalidating callbacks at process exit.
+ if (error)
+ return;
+
TestInvocation* testInvocation = static_cast<TestInvocation*>(context);
+ RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(testInvocation));
+
testInvocation->m_gotRepaint = true;
- TestController::shared().notifyDone();
+ TestController::singleton().notifyDone();
}
void TestInvocation::dumpResults()
@@ -316,18 +265,22 @@ void TestInvocation::dumpResults()
else
dumpAudio(m_audioResult.get());
- if (m_dumpPixels && m_pixelResult) {
- if (PlatformWebView::windowSnapshotEnabled()) {
+ if (m_dumpPixels) {
+ if (m_pixelResult)
+ dumpPixelsAndCompareWithExpected(m_pixelResult.get(), m_repaintRects.get(), TestInvocation::SnapshotResultType::WebContents);
+ else if (m_pixelResultIsPending) {
m_gotRepaint = false;
- WKPageForceRepaint(TestController::shared().mainWebView()->page(), this, TestInvocation::forceRepaintDoneCallback);
- TestController::shared().runUntil(m_gotRepaint, TestController::ShortTimeout);
+ WKPageForceRepaint(TestController::singleton().mainWebView()->page(), this, TestInvocation::forceRepaintDoneCallback);
+ TestController::singleton().runUntil(m_gotRepaint, shortTimeout());
if (!m_gotRepaint) {
m_errorMessage = "Timed out waiting for pre-pixel dump repaint\n";
m_webProcessIsUnresponsive = true;
return;
}
+
+ WKRetainPtr<WKImageRef> windowSnapshot = TestController::singleton().mainWebView()->windowSnapshotImage();
+ dumpPixelsAndCompareWithExpected(windowSnapshot.get(), m_repaintRects.get(), TestInvocation::SnapshotResultType::WebView);
}
- dumpPixelsAndCompareWithExpected(m_pixelResult.get(), m_repaintRects.get());
}
fputs("#EOF\n", stdout);
@@ -374,7 +327,7 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
m_gotFinalMessage = true;
m_error = true;
m_errorMessage = "FAIL\n";
- TestController::shared().notifyDone();
+ TestController::singleton().notifyDone();
return;
}
@@ -383,7 +336,7 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
WKStringRef messageBodyString = static_cast<WKStringRef>(messageBody);
if (WKStringIsEqualToUTF8CString(messageBodyString, "BeginTest")) {
m_gotInitialResponse = true;
- TestController::shared().notifyDone();
+ TestController::singleton().notifyDone();
return;
}
@@ -394,9 +347,15 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
- WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
- m_pixelResult = static_cast<WKImageRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultKey.get()));
- ASSERT(!m_pixelResult || m_dumpPixels);
+ WKRetainPtr<WKStringRef> pixelResultIsPendingKey = adoptWK(WKStringCreateWithUTF8CString("PixelResultIsPending"));
+ WKBooleanRef pixelResultIsPending = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultIsPendingKey.get()));
+ m_pixelResultIsPending = WKBooleanGetValue(pixelResultIsPending);
+
+ if (!m_pixelResultIsPending) {
+ WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
+ m_pixelResult = static_cast<WKImageRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultKey.get()));
+ ASSERT(!m_pixelResult || m_dumpPixels);
+ }
WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects"));
m_repaintRects = static_cast<WKArrayRef>(WKDictionaryGetItemForKey(messageBodyDictionary, repaintRectsKey.get()));
@@ -405,7 +364,7 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
m_audioResult = static_cast<WKDataRef>(WKDictionaryGetItemForKey(messageBodyDictionary, audioResultKey.get()));
m_gotFinalMessage = true;
- TestController::shared().notifyDone();
+ TestController::singleton().notifyDone();
return;
}
@@ -416,55 +375,69 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
return;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "DumpToStdErr")) {
+ ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+ WKStringRef textOutput = static_cast<WKStringRef>(messageBody);
+ fprintf(stderr, "%s", toWTFString(textOutput).utf8().data());
+ return;
+ }
+
if (WKStringIsEqualToUTF8CString(messageName, "BeforeUnloadReturnValue")) {
ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
WKBooleanRef beforeUnloadReturnValue = static_cast<WKBooleanRef>(messageBody);
- TestController::shared().setBeforeUnloadReturnValue(WKBooleanGetValue(beforeUnloadReturnValue));
+ TestController::singleton().setBeforeUnloadReturnValue(WKBooleanGetValue(beforeUnloadReturnValue));
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "AddChromeInputField")) {
- TestController::shared().mainWebView()->addChromeInputField();
+ TestController::singleton().mainWebView()->addChromeInputField();
WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallAddChromeInputFieldCallback"));
- WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0);
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "RemoveChromeInputField")) {
- TestController::shared().mainWebView()->removeChromeInputField();
+ TestController::singleton().mainWebView()->removeChromeInputField();
WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallRemoveChromeInputFieldCallback"));
- WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0);
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "FocusWebView")) {
- TestController::shared().mainWebView()->makeWebViewFirstResponder();
+ TestController::singleton().mainWebView()->makeWebViewFirstResponder();
WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallFocusWebViewCallback"));
- WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0);
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "SetBackingScaleFactor")) {
ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
double backingScaleFactor = WKDoubleGetValue(static_cast<WKDoubleRef>(messageBody));
- WKPageSetCustomBackingScaleFactor(TestController::shared().mainWebView()->page(), backingScaleFactor);
+ WKPageSetCustomBackingScaleFactor(TestController::singleton().mainWebView()->page(), backingScaleFactor);
WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallSetBackingScaleFactorCallback"));
- WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0);
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "SimulateWebNotificationClick")) {
ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
uint64_t notificationID = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
- TestController::shared().simulateWebNotificationClick(notificationID);
+ TestController::singleton().simulateWebNotificationClick(notificationID);
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetAddsVisitedLinks")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
+ WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), WKBooleanGetValue(enabledWK));
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "SetGeolocationPermission")) {
ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
- TestController::shared().setGeolocationPermission(WKBooleanGetValue(enabledWK));
+ TestController::singleton().setGeolocationPermission(WKBooleanGetValue(enabledWK));
return;
}
@@ -516,14 +489,60 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
WKDoubleRef speedWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, speedKeyWK.get()));
double speed = WKDoubleGetValue(speedWK);
- TestController::shared().setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed);
+ TestController::singleton().setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed);
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "SetMockGeolocationPositionUnavailableError")) {
ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
WKStringRef errorMessage = static_cast<WKStringRef>(messageBody);
- TestController::shared().setMockGeolocationPositionUnavailableError(errorMessage);
+ TestController::singleton().setMockGeolocationPositionUnavailableError(errorMessage);
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPermission")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
+ TestController::singleton().setUserMediaPermission(WKBooleanGetValue(enabledWK));
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPersistentPermissionForOrigin")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+
+ WKRetainPtr<WKStringRef> permissionKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permission"));
+ WKBooleanRef permissionWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissionKeyWK.get()));
+ bool permission = WKBooleanGetValue(permissionWK);
+
+ WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin"));
+ WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
+
+ WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
+ WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
+
+ TestController::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK, parentOriginWK);
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermissionRequestCountForOrigin")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+
+ WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin"));
+ WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
+
+ WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
+ WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
+
+ TestController::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK, parentOriginWK);
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetCacheModel")) {
+ ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
+ uint64_t model = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
+ WKContextSetCacheModel(TestController::singleton().context(), model);
return;
}
@@ -539,30 +558,26 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
WKBooleanRef permissiveWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissiveKeyWK.get()));
bool permissive = WKBooleanGetValue(permissiveWK);
- TestController::shared().setCustomPolicyDelegate(enabled, permissive);
+ TestController::singleton().setCustomPolicyDelegate(enabled, permissive);
return;
}
- if (WKStringIsEqualToUTF8CString(messageName, "SetVisibilityState")) {
+ if (WKStringIsEqualToUTF8CString(messageName, "SetHidden")) {
ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
- WKRetainPtr<WKStringRef> visibilityStateKeyWK(AdoptWK, WKStringCreateWithUTF8CString("visibilityState"));
- WKUInt64Ref visibilityStateWK = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, visibilityStateKeyWK.get()));
- WKPageVisibilityState visibilityState = static_cast<WKPageVisibilityState>(WKUInt64GetValue(visibilityStateWK));
-
- WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("isInitialState"));
- WKBooleanRef isInitialWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isInitialKeyWK.get()));
- bool isInitialState = WKBooleanGetValue(isInitialWK);
+ WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("hidden"));
+ WKBooleanRef hiddenWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isInitialKeyWK.get()));
+ bool hidden = WKBooleanGetValue(hiddenWK);
- TestController::shared().setVisibilityState(visibilityState, isInitialState);
+ TestController::singleton().setHidden(hidden);
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "ProcessWorkQueue")) {
- if (TestController::shared().workQueueManager().processWorkQueue()) {
+ if (TestController::singleton().workQueueManager().processWorkQueue()) {
WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("WorkQueueProcessedCallback"));
- WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0);
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
}
return;
}
@@ -570,14 +585,14 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
if (WKStringIsEqualToUTF8CString(messageName, "QueueBackNavigation")) {
ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
- TestController::shared().workQueueManager().queueBackNavigation(stepCount);
+ TestController::singleton().workQueueManager().queueBackNavigation(stepCount);
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "QueueForwardNavigation")) {
ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
- TestController::shared().workQueueManager().queueForwardNavigation(stepCount);
+ TestController::singleton().workQueueManager().queueForwardNavigation(stepCount);
return;
}
@@ -591,7 +606,10 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
WKRetainPtr<WKStringRef> targetKey(AdoptWK, WKStringCreateWithUTF8CString("target"));
WKStringRef targetWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, targetKey.get()));
- TestController::shared().workQueueManager().queueLoad(toWTFString(urlWK), toWTFString(targetWK));
+ WKRetainPtr<WKStringRef> shouldOpenExternalURLsKey(AdoptWK, WKStringCreateWithUTF8CString("shouldOpenExternalURLs"));
+ WKBooleanRef shouldOpenExternalURLsValueWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(loadDataDictionary, shouldOpenExternalURLsKey.get()));
+
+ TestController::singleton().workQueueManager().queueLoad(toWTFString(urlWK), toWTFString(targetWK), WKBooleanGetValue(shouldOpenExternalURLsValueWK));
return;
}
@@ -608,54 +626,110 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
WKRetainPtr<WKStringRef> unreachableURLKey(AdoptWK, WKStringCreateWithUTF8CString("unreachableURL"));
WKStringRef unreachableURLWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, unreachableURLKey.get()));
- TestController::shared().workQueueManager().queueLoadHTMLString(toWTFString(contentWK), baseURLWK ? toWTFString(baseURLWK) : String(), unreachableURLWK ? toWTFString(unreachableURLWK) : String());
+ TestController::singleton().workQueueManager().queueLoadHTMLString(toWTFString(contentWK), baseURLWK ? toWTFString(baseURLWK) : String(), unreachableURLWK ? toWTFString(unreachableURLWK) : String());
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "QueueReload")) {
- TestController::shared().workQueueManager().queueReload();
+ TestController::singleton().workQueueManager().queueReload();
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadingScript")) {
ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
WKStringRef script = static_cast<WKStringRef>(messageBody);
- TestController::shared().workQueueManager().queueLoadingScript(toWTFString(script));
+ TestController::singleton().workQueueManager().queueLoadingScript(toWTFString(script));
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "QueueNonLoadingScript")) {
ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
WKStringRef script = static_cast<WKStringRef>(messageBody);
- TestController::shared().workQueueManager().queueNonLoadingScript(toWTFString(script));
+ TestController::singleton().workQueueManager().queueNonLoadingScript(toWTFString(script));
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
+ TestController::singleton().setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(WKBooleanGetValue(value));
return;
}
- if (WKStringIsEqualToUTF8CString(messageName, "SetHandlesAuthenticationChallenge")) {
+ if (WKStringIsEqualToUTF8CString(messageName, "SetHandlesAuthenticationChallenges")) {
ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
- TestController::shared().setHandlesAuthenticationChallenges(WKBooleanGetValue(value));
+ TestController::singleton().setHandlesAuthenticationChallenges(WKBooleanGetValue(value));
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogCanAuthenticateAgainstProtectionSpace")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
+ TestController::singleton().setShouldLogCanAuthenticateAgainstProtectionSpace(WKBooleanGetValue(value));
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationUsername")) {
ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
WKStringRef username = static_cast<WKStringRef>(messageBody);
- TestController::shared().setAuthenticationUsername(toWTFString(username));
+ TestController::singleton().setAuthenticationUsername(toWTFString(username));
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationPassword")) {
ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
WKStringRef password = static_cast<WKStringRef>(messageBody);
- TestController::shared().setAuthenticationPassword(toWTFString(password));
+ TestController::singleton().setAuthenticationPassword(toWTFString(password));
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "SetBlockAllPlugins")) {
ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
WKBooleanRef shouldBlock = static_cast<WKBooleanRef>(messageBody);
- TestController::shared().setBlockAllPlugins(WKBooleanGetValue(shouldBlock));
+ TestController::singleton().setBlockAllPlugins(WKBooleanGetValue(shouldBlock));
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDecideNavigationPolicyAfterDelay")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
+ TestController::singleton().setShouldDecideNavigationPolicyAfterDelay(WKBooleanGetValue(value));
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetNavigationGesturesEnabled")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
+ TestController::singleton().setNavigationGesturesEnabled(WKBooleanGetValue(value));
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetIgnoresViewportScaleLimits")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
+ TestController::singleton().setIgnoresViewportScaleLimits(WKBooleanGetValue(value));
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDownloadUndisplayableMIMETypes")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
+ TestController::singleton().setShouldDownloadUndisplayableMIMETypes(WKBooleanGetValue(value));
+ return;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "RunUIProcessScript")) {
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+ WKRetainPtr<WKStringRef> scriptKey(AdoptWK, WKStringCreateWithUTF8CString("Script"));
+ WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID"));
+
+ UIScriptInvocationData* invocationData = new UIScriptInvocationData();
+ invocationData->testInvocation = this;
+ invocationData->callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
+ invocationData->scriptString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get()));
+ m_pendingUIScriptInvocationData = invocationData;
+ WKPageCallAfterNextPresentationUpdate(TestController::singleton().mainWebView()->page(), invocationData, runUISideScriptAfterUpdateCallback);
return;
}
@@ -667,12 +741,32 @@ WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedB
if (WKStringIsEqualToUTF8CString(messageName, "SetWindowIsKey")) {
ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
WKBooleanRef isKeyValue = static_cast<WKBooleanRef>(messageBody);
- TestController::shared().mainWebView()->setWindowIsKey(WKBooleanGetValue(isKeyValue));
- return 0;
+ TestController::singleton().mainWebView()->setWindowIsKey(WKBooleanGetValue(isKeyValue));
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetViewSize")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+ WKRetainPtr<WKStringRef> widthKey(AdoptWK, WKStringCreateWithUTF8CString("width"));
+ WKRetainPtr<WKStringRef> heightKey(AdoptWK, WKStringCreateWithUTF8CString("height"));
+
+ WKDoubleRef widthWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, widthKey.get()));
+ WKDoubleRef heightWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, heightKey.get()));
+
+ TestController::singleton().mainWebView()->resizeTo(WKDoubleGetValue(widthWK), WKDoubleGetValue(heightWK));
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "IsGeolocationClientActive")) {
+ bool isActive = TestController::singleton().isGeolocationProviderActive();
+ WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isActive));
+ return result;
}
if (WKStringIsEqualToUTF8CString(messageName, "IsWorkQueueEmpty")) {
- bool isEmpty = TestController::shared().workQueueManager().isWorkQueueEmpty();
+ bool isEmpty = TestController::singleton().workQueueManager().isWorkQueueEmpty();
WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isEmpty));
return result;
}
@@ -685,8 +779,234 @@ WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedB
#endif
return result;
}
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetAlwaysAcceptCookies")) {
+ WKBooleanRef accept = static_cast<WKBooleanRef>(messageBody);
+ WKHTTPCookieAcceptPolicy policy = WKBooleanGetValue(accept) ? kWKHTTPCookieAcceptPolicyAlways : kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
+ // FIXME: This updates the policy in WebProcess and in NetworkProcess asynchronously, which might break some tests' expectations.
+ WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), policy);
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "ImageCountInGeneralPasteboard")) {
+ unsigned count = TestController::singleton().imageCountInGeneralPasteboard();
+ WKRetainPtr<WKUInt64Ref> result(AdoptWK, WKUInt64Create(count));
+ return result;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "DeleteAllIndexedDatabases")) {
+ WKWebsiteDataStoreRemoveAllIndexedDatabases(WKContextGetWebsiteDataStore(TestController::singleton().context()));
+ return nullptr;
+ }
+
+#if PLATFORM(MAC)
+ if (WKStringIsEqualToUTF8CString(messageName, "ConnectMockGamepad")) {
+ ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
+
+ uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
+ WebCoreTestSupport::connectMockGamepad(index);
+
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "DisconnectMockGamepad")) {
+ ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
+
+ uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
+ WebCoreTestSupport::disconnectMockGamepad(index);
+
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadDetails")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+ WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex"));
+ WKRetainPtr<WKStringRef> gamepadIDKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadID"));
+ WKRetainPtr<WKStringRef> axisCountKey(AdoptWK, WKStringCreateWithUTF8CString("AxisCount"));
+ WKRetainPtr<WKStringRef> buttonCountKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonCount"));
+
+ WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
+ WKStringRef gamepadID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIDKey.get()));
+ WKUInt64Ref axisCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisCountKey.get()));
+ WKUInt64Ref buttonCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonCountKey.get()));
+
+ WebCoreTestSupport::setMockGamepadDetails(WKUInt64GetValue(gamepadIndex), toWTFString(gamepadID), WKUInt64GetValue(axisCount), WKUInt64GetValue(buttonCount));
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadAxisValue")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+ WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex"));
+ WKRetainPtr<WKStringRef> axisIndexKey(AdoptWK, WKStringCreateWithUTF8CString("AxisIndex"));
+ WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
+
+ WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
+ WKUInt64Ref axisIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisIndexKey.get()));
+ WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
+
+ WebCoreTestSupport::setMockGamepadAxisValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(axisIndex), WKDoubleGetValue(value));
+
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadButtonValue")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+ WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex"));
+ WKRetainPtr<WKStringRef> buttonIndexKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonIndex"));
+ WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
+
+ WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
+ WKUInt64Ref buttonIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonIndexKey.get()));
+ WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
+
+ WebCoreTestSupport::setMockGamepadButtonValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(buttonIndex), WKDoubleGetValue(value));
+
+ return nullptr;
+ }
+#endif // PLATFORM(MAC)
+
+ if (WKStringIsEqualToUTF8CString(messageName, "UserMediaPermissionRequestCountForOrigin")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+
+ WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin"));
+ WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
+
+ WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
+ WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
+
+ unsigned count = TestController::singleton().userMediaPermissionRequestCountForOrigin(originWK, parentOriginWK);
+ WKRetainPtr<WKUInt64Ref> result(AdoptWK, WKUInt64Create(count));
+ return result;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsPrevalentResource")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+ WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
+ WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
+
+ WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
+ WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
+
+ TestController::singleton().setStatisticsPrevalentResource(hostName, WKBooleanGetValue(value));
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsPrevalentResource")) {
+ ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+
+ WKStringRef hostName = static_cast<WKStringRef>(messageBody);
+ bool isPrevalent = TestController::singleton().isStatisticsPrevalentResource(hostName);
+ WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isPrevalent));
+ return result;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsHasHadUserInteraction")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+ WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
+ WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
+
+ WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
+ WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
+
+ TestController::singleton().setStatisticsHasHadUserInteraction(hostName, WKBooleanGetValue(value));
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasHadUserInteraction")) {
+ ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+
+ WKStringRef hostName = static_cast<WKStringRef>(messageBody);
+ bool hasHadUserInteraction = TestController::singleton().isStatisticsHasHadUserInteraction(hostName);
+ WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(hasHadUserInteraction));
+ return result;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTimeToLiveUserInteraction")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
+ WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
+ TestController::singleton().setStatisticsTimeToLiveUserInteraction(WKDoubleGetValue(seconds));
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "StatisticsFireDataModificationHandler")) {
+ TestController::singleton().statisticsFireDataModificationHandler();
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "StatisticsNotifyPagesWhenDataRecordsWereScanned")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
+ TestController::singleton().setStatisticsNotifyPagesWhenDataRecordsWereScanned(WKBooleanGetValue(value));
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval")) {
+ ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+ WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
+ TestController::singleton().setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(WKBooleanGetValue(value));
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsMinimumTimeBetweeenDataRecordsRemoval")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
+ WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
+ TestController::singleton().setStatisticsMinimumTimeBetweeenDataRecordsRemoval(WKDoubleGetValue(seconds));
+ return nullptr;
+ }
+
+ if (WKStringIsEqualToUTF8CString(messageName, "StatisticsResetToConsistentState")) {
+ TestController::singleton().statisticsResetToConsistentState();
+ return nullptr;
+ }
+
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
+}
+
+void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef, void* context)
+{
+ UIScriptInvocationData* data = static_cast<UIScriptInvocationData*>(context);
+ if (TestInvocation* invocation = data->testInvocation) {
+ RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(invocation));
+ invocation->runUISideScript(data->scriptString.get(), data->callbackID);
+ }
+ delete data;
+}
+
+void TestInvocation::runUISideScript(WKStringRef script, unsigned scriptCallbackID)
+{
+ m_pendingUIScriptInvocationData = nullptr;
+
+ if (!m_UIScriptContext)
+ m_UIScriptContext = std::make_unique<UIScriptContext>(*this);
+
+ m_UIScriptContext->runUIScript(toWTFString(script), scriptCallbackID);
+}
+
+void TestInvocation::uiScriptDidComplete(const String& result, unsigned scriptCallbackID)
+{
+ WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallUISideScriptCallback"));
+
+ WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
+ WKRetainPtr<WKStringRef> resultKey(AdoptWK, WKStringCreateWithUTF8CString("Result"));
+ WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID"));
+ WKRetainPtr<WKUInt64Ref> callbackIDValue = adoptWK(WKUInt64Create(scriptCallbackID));
+
+ WKDictionarySetItem(messageBody.get(), resultKey.get(), toWK(result).get());
+ WKDictionarySetItem(messageBody.get(), callbackIDKey.get(), callbackIDValue.get());
+
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get());
}
void TestInvocation::outputText(const WTF::String& text)
@@ -694,4 +1014,34 @@ void TestInvocation::outputText(const WTF::String& text)
m_textOutput.append(text);
}
+void TestInvocation::didBeginSwipe()
+{
+ WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidBeginSwipeCallback"));
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
+}
+
+void TestInvocation::willEndSwipe()
+{
+ WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallWillEndSwipeCallback"));
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
+}
+
+void TestInvocation::didEndSwipe()
+{
+ WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidEndSwipeCallback"));
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
+}
+
+void TestInvocation::didRemoveSwipeSnapshot()
+{
+ WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveSwipeSnapshotCallback"));
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
+}
+
+void TestInvocation::notifyDownloadDone()
+{
+ WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("NotifyDownloadDone"));
+ WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
+}
+
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/TestInvocation.h b/Tools/WebKitTestRunner/TestInvocation.h
index a32678135..df5885c7e 100644
--- a/Tools/WebKitTestRunner/TestInvocation.h
+++ b/Tools/WebKitTestRunner/TestInvocation.h
@@ -26,23 +26,35 @@
#ifndef TestInvocation_h
#define TestInvocation_h
+#include "JSWrappable.h"
+#include "TestOptions.h"
+#include "UIScriptContext.h"
+#include <WebKit/WKRetainPtr.h>
#include <string>
-#include <WebKit2/WKRetainPtr.h>
#include <wtf/Noncopyable.h>
-#include <wtf/OwnPtr.h>
#include <wtf/text/StringBuilder.h>
namespace WTR {
-class TestInvocation {
+class TestInvocation : public UIScriptContextDelegate {
WTF_MAKE_NONCOPYABLE(TestInvocation);
public:
- explicit TestInvocation(const std::string& pathOrURL);
+ explicit TestInvocation(WKURLRef, const TestOptions&);
~TestInvocation();
+ WKURLRef url() const;
+ bool urlContains(const char*) const;
+
+ const TestOptions& options() const { return m_options; }
+
void setIsPixelTest(const std::string& expectedPixelHash);
- void setCustomTimeout(int duration);
+ // Milliseconds
+ void setCustomTimeout(int duration) { m_timeout = duration; }
+ void setDumpJSConsoleLogInStdErr(bool value) { m_dumpJSConsoleLogInStdErr = value; }
+
+ // Seconds
+ double shortTimeout() const;
void invoke();
void didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody);
@@ -51,36 +63,66 @@ public:
void dumpWebProcessUnresponsiveness();
static void dumpWebProcessUnresponsiveness(const char* errorMessage);
void outputText(const WTF::String&);
+
+ void didBeginSwipe();
+ void willEndSwipe();
+ void didEndSwipe();
+ void didRemoveSwipeSnapshot();
+
+ void notifyDownloadDone();
+
private:
void dumpResults();
static void dump(const char* textToStdout, const char* textToStderr = 0, bool seenError = false);
- void dumpPixelsAndCompareWithExpected(WKImageRef, WKArrayRef repaintRects);
+ enum class SnapshotResultType { WebView, WebContents };
+ void dumpPixelsAndCompareWithExpected(WKImageRef, WKArrayRef repaintRects, SnapshotResultType);
void dumpAudio(WKDataRef);
bool compareActualHashToExpectedAndDumpResults(const char[33]);
static void forceRepaintDoneCallback(WKErrorRef, void* context);
+
+ struct UIScriptInvocationData {
+ unsigned callbackID;
+ WebKit::WKRetainPtr<WKStringRef> scriptString;
+ TestInvocation* testInvocation;
+ };
+ static void runUISideScriptAfterUpdateCallback(WKErrorRef, void* context);
- WKRetainPtr<WKURLRef> m_url;
- std::string m_pathOrURL;
+ bool shouldLogFrameLoadDelegates() const;
+ bool shouldLogHistoryClientCallbacks() const;
+
+ void runUISideScript(WKStringRef, unsigned callbackID);
+ // UIScriptContextDelegate
+ void uiScriptDidComplete(const String& result, unsigned callbackID) override;
+
+ const TestOptions m_options;
- bool m_dumpPixels;
+ WKRetainPtr<WKURLRef> m_url;
+ WTF::String m_urlString;
+
std::string m_expectedPixelHash;
- int m_timeout;
+ int m_timeout { 0 };
+ bool m_dumpJSConsoleLogInStdErr { false };
// Invocation state
- bool m_gotInitialResponse;
- bool m_gotFinalMessage;
- bool m_gotRepaint;
- bool m_error;
+ bool m_gotInitialResponse { false };
+ bool m_gotFinalMessage { false };
+ bool m_gotRepaint { false };
+ bool m_error { false };
+
+ bool m_dumpPixels { false };
+ bool m_pixelResultIsPending { false };
+ bool m_webProcessIsUnresponsive { false };
StringBuilder m_textOutput;
WKRetainPtr<WKDataRef> m_audioResult;
WKRetainPtr<WKImageRef> m_pixelResult;
WKRetainPtr<WKArrayRef> m_repaintRects;
std::string m_errorMessage;
- bool m_webProcessIsUnresponsive;
-
+
+ std::unique_ptr<UIScriptContext> m_UIScriptContext;
+ UIScriptInvocationData* m_pendingUIScriptInvocationData { nullptr };
};
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrapper.cpp b/Tools/WebKitTestRunner/TestOptions.cpp
index e3cf58c2c..d6e8ab238 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrapper.cpp
+++ b/Tools/WebKitTestRunner/TestOptions.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,57 +24,53 @@
*/
#include "config.h"
-#include "JSWrapper.h"
+#include "TestOptions.h"
-#include <JavaScriptCore/JSContextRefPrivate.h>
+#include <string>
+#include <wtf/text/WTFString.h>
namespace WTR {
-JSValueRef JSWrapper::wrap(JSContextRef context, JSWrappable* object)
+static bool pathContains(const std::string& pathOrURL, const char* substring)
{
- ASSERT_ARG(context, context);
-
- if (!object)
- return JSValueMakeNull(context);
-
- JSClassRef objectClass = object->wrapperClass();
- ASSERT(objectClass);
- JSObjectRef wrapperObject = JSObjectMake(context, objectClass, object);
- ASSERT(wrapperObject);
+ String path(pathOrURL.c_str());
+ return path.contains(substring); // Case-insensitive.
+}
- return wrapperObject;
+static bool shouldMakeViewportFlexible(const std::string& pathOrURL)
+{
+ return pathContains(pathOrURL, "viewport/") && !pathContains(pathOrURL, "visual-viewport/");
}
-JSWrappable* JSWrapper::unwrap(JSContextRef context, JSValueRef value)
+static bool shouldUseFixedLayout(const std::string& pathOrURL)
{
- ASSERT_ARG(context, context);
- ASSERT_ARG(value, value);
- if (!context || !value)
- return 0;
- return static_cast<JSWrappable*>(JSObjectGetPrivate(JSValueToObject(context, value, 0)));
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ if (pathContains(pathOrURL, "device-adapt/") || pathContains(pathOrURL, "device-adapt\\"))
+ return true;
+#endif
+ return false;
}
-static JSWrappable* unwrapObject(JSObjectRef object)
+static bool isSVGTestPath(const std::string& pathOrURL)
{
- JSWrappable* wrappable = static_cast<JSWrappable*>(JSObjectGetPrivate(object));
- ASSERT(wrappable);
- return wrappable;
+ return pathContains(pathOrURL, "svg/W3C-SVG-1.1") || pathContains(pathOrURL, "svg\\W3C-SVG-1.1");
}
-void JSWrapper::initialize(JSContextRef ctx, JSObjectRef object)
+static float deviceScaleFactorForTest(const std::string& pathOrURL)
{
- JSWrappable* wrappable = unwrapObject(object);
- if (!wrappable)
- return;
- wrappable->ref();
+ if (pathContains(pathOrURL, "/hidpi-3x-"))
+ return 3;
+ if (pathContains(pathOrURL, "/hidpi-"))
+ return 2;
+ return 1;
}
-void JSWrapper::finalize(JSObjectRef object)
+TestOptions::TestOptions(const std::string& pathOrURL)
+ : useFlexibleViewport(shouldMakeViewportFlexible(pathOrURL))
+ , useFixedLayout(shouldUseFixedLayout(pathOrURL))
+ , isSVGTest(isSVGTestPath(pathOrURL))
+ , deviceScaleFactor(deviceScaleFactorForTest(pathOrURL))
{
- JSWrappable* wrappable = unwrapObject(object);
- if (!wrappable)
- return;
- wrappable->deref();
}
-} // namespace WTR
+}
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrapper.h b/Tools/WebKitTestRunner/TestOptions.h
index d885801b9..9c665192c 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/Bindings/JSWrapper.h
+++ b/Tools/WebKitTestRunner/TestOptions.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,35 +23,36 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef JSWrapper_h
-#define JSWrapper_h
+#ifndef TestOptions_h
+#define TestOptions_h
-#include "JSWrappable.h"
-#include <JavaScriptCore/JSRetainPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
namespace WTR {
-// FIXME: If necessary, we can do wrapper caching here.
-class JSWrapper {
-public:
- static JSValueRef wrap(JSContextRef context, JSWrappable* object);
- static JSWrappable* unwrap(JSContextRef context, JSValueRef value);
-
- static void initialize(JSContextRef, JSObjectRef);
- static void finalize(JSObjectRef);
+struct TestOptions {
+ bool useThreadedScrolling { false };
+ bool useRemoteLayerTree { false };
+ bool shouldShowWebView { false };
+ bool useFlexibleViewport { false };
+ bool useFixedLayout { false };
+ bool isSVGTest { false };
+ bool useDataDetection { false };
+ bool useMockScrollbars { true };
+ bool needsSiteSpecificQuirks { false };
+ bool ignoresViewportScaleLimits { false };
+ bool useCharacterSelectionGranularity { false };
+ bool enableIntersectionObserver { false };
+ bool enableModernMediaControls { true };
+ bool enablePointerLock { false };
+
+ float deviceScaleFactor { 1 };
+ Vector<String> overrideLanguages;
+
+ TestOptions(const std::string& pathOrURL);
};
-inline JSValueRef toJS(JSContextRef context, JSWrappable* impl)
-{
- return JSWrapper::wrap(context, impl);
-}
-
-inline void setProperty(JSContextRef context, JSObjectRef object, const char* propertyName, JSWrappable* value, JSPropertyAttributes attributes, JSValueRef* exception)
-{
- JSRetainPtr<JSStringRef> propertyNameString(Adopt, JSStringCreateWithUTF8CString(propertyName));
- JSObjectSetProperty(context, object, propertyNameString.get(), JSWrapper::wrap(context, value), attributes, exception);
}
-} // namespace WTR
-
-#endif // JSWrapper_h
+#endif // TestOptions_h
diff --git a/Tools/WebKitTestRunner/WebKitTestRunnerPrefix.h b/Tools/WebKitTestRunner/WebKitTestRunnerPrefix.h
index dc958c10e..5f989fc54 100644
--- a/Tools/WebKitTestRunner/WebKitTestRunnerPrefix.h
+++ b/Tools/WebKitTestRunner/WebKitTestRunnerPrefix.h
@@ -27,13 +27,8 @@
#import <Foundation/Foundation.h>
#endif
-#if defined(BUILDING_GTK__)
-#include "autotoolsconfig.h"
-#endif /* defined (BUILDING_GTK__) */
-
+#include <WebKit/WebKit2_C.h>
#include <wtf/Platform.h>
-#include <WebKit2/WebKit2_C.h>
-
/* When C++ exceptions are disabled, the C++ library defines |try| and |catch|
* to allow C++ code that expects exceptions to build. These definitions
diff --git a/Tools/WebKitTestRunner/WebNotificationProvider.cpp b/Tools/WebKitTestRunner/WebNotificationProvider.cpp
index 55064249f..b009b36a3 100644
--- a/Tools/WebKitTestRunner/WebNotificationProvider.cpp
+++ b/Tools/WebKitTestRunner/WebNotificationProvider.cpp
@@ -26,10 +26,11 @@
#include "config.h"
#include "WebNotificationProvider.h"
-#include <WebKit2/WKMutableArray.h>
-#include <WebKit2/WKNotification.h>
-#include <WebKit2/WKNumber.h>
-#include <WebKit2/WKSecurityOrigin.h>
+#include <WebKit/WKMutableArray.h>
+#include <WebKit/WKNotification.h>
+#include <WebKit/WKNotificationManager.h>
+#include <WebKit/WKNumber.h>
+#include <WebKit/WKSecurityOriginRef.h>
#include <wtf/Assertions.h>
namespace WTR {
@@ -65,13 +66,14 @@ WebNotificationProvider::WebNotificationProvider()
WebNotificationProvider::~WebNotificationProvider()
{
- WKNotificationManagerSetProvider(m_notificationManager.get(), 0);
+ for (auto& manager : m_ownedNotifications)
+ WKNotificationManagerSetProvider(manager.key.get(), nullptr);
}
WKNotificationProviderV0 WebNotificationProvider::provider()
{
WKNotificationProviderV0 notificationProvider = {
- { kWKNotificationProviderCurrentVersion, this },
+ { 0, this },
WTR::showWebNotification,
WTR::closeWebNotification,
0, // didDestroyNotification
@@ -83,44 +85,73 @@ WKNotificationProviderV0 WebNotificationProvider::provider()
return notificationProvider;
}
-void WebNotificationProvider::showWebNotification(WKPageRef, WKNotificationRef notification)
+void WebNotificationProvider::showWebNotification(WKPageRef page, WKNotificationRef notification)
{
- if (!m_notificationManager)
- return;
-
+ auto context = WKPageGetContext(page);
+ auto notificationManager = WKContextGetNotificationManager(context);
uint64_t id = WKNotificationGetID(notification);
- ASSERT(!m_shownNotifications.contains(id));
- m_shownNotifications.add(id);
- WKNotificationManagerProviderDidShowNotification(m_notificationManager.get(), WKNotificationGetID(notification));
+ ASSERT(m_ownedNotifications.contains(notificationManager));
+ auto addResult = m_ownedNotifications.find(notificationManager)->value.add(id);
+ ASSERT_UNUSED(addResult, addResult.isNewEntry);
+ auto addResult2 = m_owningManager.set(id, notificationManager);
+ ASSERT_UNUSED(addResult2, addResult2.isNewEntry);
+ auto addResult3 = m_localToGlobalNotificationIDMap.add(std::make_pair(page, WKNotificationManagerGetLocalIDForTesting(notificationManager, notification)), id);
+ ASSERT_UNUSED(addResult3, addResult3.isNewEntry);
+
+ WKNotificationManagerProviderDidShowNotification(notificationManager, id);
}
-void WebNotificationProvider::closeWebNotification(WKNotificationRef notification)
+static void removeGlobalIDFromIDMap(HashMap<std::pair<WKPageRef, uint64_t>, uint64_t>& map, uint64_t id)
{
- if (!m_notificationManager)
- return;
+ for (auto iter = map.begin(); iter != map.end(); ++iter) {
+ if (iter->value == id) {
+ map.remove(iter);
+ return;
+ }
+ }
+ ASSERT_NOT_REACHED();
+}
+void WebNotificationProvider::closeWebNotification(WKNotificationRef notification)
+{
uint64_t id = WKNotificationGetID(notification);
+ ASSERT(m_owningManager.contains(id));
+ auto notificationManager = m_owningManager.get(id);
+
+ ASSERT(m_ownedNotifications.contains(notificationManager));
+ bool success = m_ownedNotifications.find(notificationManager)->value.remove(id);
+ ASSERT_UNUSED(success, success);
+ m_owningManager.remove(id);
+
+ removeGlobalIDFromIDMap(m_localToGlobalNotificationIDMap, id);
+
WKRetainPtr<WKUInt64Ref> wkID = WKUInt64Create(id);
WKRetainPtr<WKMutableArrayRef> array(AdoptWK, WKMutableArrayCreate());
WKArrayAppendItem(array.get(), wkID.get());
- m_shownNotifications.remove(id);
- WKNotificationManagerProviderDidCloseNotifications(m_notificationManager.get(), array.get());
+ WKNotificationManagerProviderDidCloseNotifications(notificationManager, array.get());
}
void WebNotificationProvider::addNotificationManager(WKNotificationManagerRef manager)
{
- // We assume there is only one for testing.
- ASSERT(!m_notificationManager);
- m_notificationManager = manager;
+ m_ownedNotifications.add(manager, HashSet<uint64_t>());
}
void WebNotificationProvider::removeNotificationManager(WKNotificationManagerRef manager)
{
- // We assume there is only one for testing.
- ASSERT(m_notificationManager);
- ASSERT(m_notificationManager.get() == manager);
- m_notificationManager = 0;
+ auto iterator = m_ownedNotifications.find(manager);
+ ASSERT(iterator != m_ownedNotifications.end());
+ auto toRemove = iterator->value;
+ WKRetainPtr<WKNotificationManagerRef> guard(manager);
+ m_ownedNotifications.remove(iterator);
+ WKRetainPtr<WKMutableArrayRef> array = adoptWK(WKMutableArrayCreate());
+ for (uint64_t notificationID : toRemove) {
+ bool success = m_owningManager.remove(notificationID);
+ ASSERT_UNUSED(success, success);
+ removeGlobalIDFromIDMap(m_localToGlobalNotificationIDMap, notificationID);
+ WKArrayAppendItem(array.get(), adoptWK(WKUInt64Create(notificationID)).get());
+ }
+ WKNotificationManagerProviderDidCloseNotifications(manager, array.get());
}
WKDictionaryRef WebNotificationProvider::notificationPermissions()
@@ -129,31 +160,28 @@ WKDictionaryRef WebNotificationProvider::notificationPermissions()
return WKMutableDictionaryCreate();
}
-void WebNotificationProvider::simulateWebNotificationClick(uint64_t notificationID)
+void WebNotificationProvider::simulateWebNotificationClick(WKPageRef page, uint64_t notificationID)
{
- if (!m_notificationManager)
- return;
-
- ASSERT(m_shownNotifications.contains(notificationID));
- WKNotificationManagerProviderDidClickNotification(m_notificationManager.get(), notificationID);
+ ASSERT(m_localToGlobalNotificationIDMap.contains(std::make_pair(page, notificationID)));
+ auto globalID = m_localToGlobalNotificationIDMap.get(std::make_pair(page, notificationID));
+ ASSERT(m_owningManager.contains(globalID));
+ WKNotificationManagerProviderDidClickNotification(m_owningManager.get(globalID), globalID);
}
void WebNotificationProvider::reset()
{
- if (!m_notificationManager) {
- m_shownNotifications.clear();
- return;
+ for (auto& notificationPair : m_ownedNotifications) {
+ if (notificationPair.value.isEmpty())
+ continue;
+ WKRetainPtr<WKMutableArrayRef> array = adoptWK(WKMutableArrayCreate());
+ for (uint64_t notificationID : notificationPair.value)
+ WKArrayAppendItem(array.get(), adoptWK(WKUInt64Create(notificationID)).get());
+
+ notificationPair.value.clear();
+ WKNotificationManagerProviderDidCloseNotifications(notificationPair.key.get(), array.get());
}
-
- WKRetainPtr<WKMutableArrayRef> array(AdoptWK, WKMutableArrayCreate());
- HashSet<uint64_t>::const_iterator itEnd = m_shownNotifications.end();
- for (HashSet<uint64_t>::const_iterator it = m_shownNotifications.begin(); it != itEnd; ++it) {
- WKRetainPtr<WKUInt64Ref> wkID = WKUInt64Create(*it);
- WKArrayAppendItem(array.get(), wkID.get());
- }
-
- m_shownNotifications.clear();
- WKNotificationManagerProviderDidCloseNotifications(m_notificationManager.get(), array.get());
+ m_owningManager.clear();
+ m_localToGlobalNotificationIDMap.clear();
}
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/WebNotificationProvider.h b/Tools/WebKitTestRunner/WebNotificationProvider.h
index fba2870fc..ccf8b1bce 100644
--- a/Tools/WebKitTestRunner/WebNotificationProvider.h
+++ b/Tools/WebKitTestRunner/WebNotificationProvider.h
@@ -26,9 +26,10 @@
#ifndef WebNotificationProvider_h
#define WebNotificationProvider_h
-#include <WebKit2/WKNotificationManager.h>
-#include <WebKit2/WKNotificationProvider.h>
-#include <WebKit2/WKRetainPtr.h>
+#include <WebKit/WKNotificationManager.h>
+#include <WebKit/WKNotificationProvider.h>
+#include <WebKit/WKRetainPtr.h>
+#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
namespace WTR {
@@ -45,12 +46,15 @@ public:
void removeNotificationManager(WKNotificationManagerRef);
WKDictionaryRef notificationPermissions();
- void simulateWebNotificationClick(uint64_t notificationID);
+ void simulateWebNotificationClick(WKPageRef, uint64_t notificationID);
void reset();
private:
- WKRetainPtr<WKNotificationManagerRef> m_notificationManager;
- HashSet<uint64_t> m_shownNotifications;
+ // Inverses of each other.
+ HashMap<WKRetainPtr<WKNotificationManagerRef>, HashSet<uint64_t>> m_ownedNotifications;
+ HashMap<uint64_t, WKNotificationManagerRef> m_owningManager;
+
+ HashMap<std::pair<WKPageRef, uint64_t>, uint64_t> m_localToGlobalNotificationIDMap;
};
}
diff --git a/Tools/WebKitTestRunner/WorkQueueManager.cpp b/Tools/WebKitTestRunner/WorkQueueManager.cpp
index e74fa3464..63f491b47 100644
--- a/Tools/WebKitTestRunner/WorkQueueManager.cpp
+++ b/Tools/WebKitTestRunner/WorkQueueManager.cpp
@@ -28,17 +28,17 @@
#include "PlatformWebView.h"
#include "TestController.h"
-#include <WebKit2/WKPage.h>
-#include <WebKit2/WKRetainPtr.h>
+#include <WebKit/WKPage.h>
+#include <WebKit/WKPagePrivate.h>
+#include <WebKit/WKRetainPtr.h>
#include <stdio.h>
-#include <wtf/PassOwnPtr.h>
#include <wtf/text/CString.h>
namespace WTR {
static inline WKPageRef mainPage()
{
- return TestController::shared().mainWebView()->page();
+ return TestController::singleton().mainWebView()->page();
}
static inline bool goToItemAtIndex(int index)
@@ -119,20 +119,21 @@ bool WorkQueueManager::processWorkQueue()
{
m_processing = false;
while (!m_processing && !m_workQueue.isEmpty()) {
- OwnPtr<WorkQueueItem> item(m_workQueue.takeFirst());
+ std::unique_ptr<WorkQueueItem> item(m_workQueue.takeFirst());
m_processing = (item->invoke() == WorkQueueItem::Loading);
}
return !m_processing;
}
-void WorkQueueManager::queueLoad(const String& url, const String& target)
+void WorkQueueManager::queueLoad(const String& url, const String& target, bool shouldOpenExternalURLs)
{
class LoadItem : public WorkQueueItem {
public:
- LoadItem(const String& url, const String& target)
+ LoadItem(const String& url, const String& target, bool shouldOpenExternalURLs)
: m_url(AdoptWK, WKURLCreateWithUTF8CString(url.utf8().data()))
, m_target(target)
+ , m_shouldOpenExternalURLs(shouldOpenExternalURLs)
{
}
@@ -143,15 +144,16 @@ void WorkQueueManager::queueLoad(const String& url, const String& target)
fprintf(stderr, "queueLoad for a specific target is not implemented.\n");
return WorkQueueItem::NonLoading;
}
- WKPageLoadURL(mainPage(), m_url.get());
+ WKPageLoadURLWithShouldOpenExternalURLsPolicy(mainPage(), m_url.get(), m_shouldOpenExternalURLs);
return WorkQueueItem::Loading;
}
WKRetainPtr<WKURLRef> m_url;
String m_target;
+ bool m_shouldOpenExternalURLs;
};
- enqueue(new LoadItem(url, target));
+ enqueue(new LoadItem(url, target, shouldOpenExternalURLs));
}
void WorkQueueManager::queueLoadHTMLString(const String& content, const String& baseURL, const String& unreachableURL)
@@ -222,7 +224,7 @@ void WorkQueueManager::enqueue(WorkQueueItem* item)
return;
}
- m_workQueue.append(adoptPtr(item));
+ m_workQueue.append(std::unique_ptr<WorkQueueItem>(item));
}
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/WorkQueueManager.h b/Tools/WebKitTestRunner/WorkQueueManager.h
index 21d5ebb88..273d51191 100644
--- a/Tools/WebKitTestRunner/WorkQueueManager.h
+++ b/Tools/WebKitTestRunner/WorkQueueManager.h
@@ -27,7 +27,6 @@
#define WorkQueueManager_h
#include <wtf/Deque.h>
-#include <wtf/OwnPtr.h>
#include <wtf/text/WTFString.h>
namespace WTR {
@@ -42,7 +41,7 @@ public:
void clearWorkQueue();
bool processWorkQueue(); // Returns 'true' if queue is processed (no new loading is started), returns 'false' otherwise.
- void queueLoad(const String& url, const String& target);
+ void queueLoad(const String& url, const String& target, bool shouldOpenExternalURLs);
void queueLoadHTMLString(const String& content, const String& baseURL, const String& unreachableURL);
void queueBackNavigation(unsigned howFarBackward);
void queueForwardNavigation(unsigned howFarForward);
@@ -51,7 +50,7 @@ public:
void queueNonLoadingScript(const String& script);
private:
- typedef Deque<OwnPtr<class WorkQueueItem> > WorkQueue;
+ typedef Deque<std::unique_ptr<class WorkQueueItem>> WorkQueue;
void enqueue(WorkQueueItem*); // Adopts pointer.
diff --git a/Tools/WebKitTestRunner/cairo/TestInvocationCairo.cpp b/Tools/WebKitTestRunner/cairo/TestInvocationCairo.cpp
index 828e65b1b..376f31986 100644
--- a/Tools/WebKitTestRunner/cairo/TestInvocationCairo.cpp
+++ b/Tools/WebKitTestRunner/cairo/TestInvocationCairo.cpp
@@ -32,7 +32,7 @@
#include "PixelDumpSupport.h"
#include "PlatformWebView.h"
#include "TestController.h"
-#include <WebKit2/WKImageCairo.h>
+#include <WebKit/WKImageCairo.h>
#include <cairo/cairo.h>
#include <cstdio>
#include <wtf/Assertions.h>
@@ -106,14 +106,9 @@ static void paintRepaintRectOverlay(cairo_surface_t* surface, WKArrayRef repaint
cairo_destroy(context);
}
-void TestInvocation::dumpPixelsAndCompareWithExpected(WKImageRef wkImage, WKArrayRef repaintRects)
+void TestInvocation::dumpPixelsAndCompareWithExpected(WKImageRef image, WKArrayRef repaintRects, SnapshotResultType)
{
-#if USE(ACCELERATED_COMPOSITING) && PLATFORM(EFL)
- UNUSED_PARAM(wkImage);
- cairo_surface_t* surface = WKImageCreateCairoSurface(TestController::shared().mainWebView()->windowSnapshotImage().get());
-#else
- cairo_surface_t* surface = WKImageCreateCairoSurface(wkImage);
-#endif
+ cairo_surface_t* surface = WKImageCreateCairoSurface(image);
if (repaintRects)
paintRepaintRectOverlay(surface, repaintRects);
diff --git a/Tools/WebKitTestRunner/config.h b/Tools/WebKitTestRunner/config.h
new file mode 100644
index 000000000..4042b715b
--- /dev/null
+++ b/Tools/WebKitTestRunner/config.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebKitTestRunner_config_h
+#define WebKitTestRunner_config_h
+
+#if defined (BUILDING_WITH_CMAKE)
+#include "cmakeconfig.h"
+#endif
+
+#include <WebCore/PlatformExportMacros.h>
+#include <WebKit/WebKit2_C.h>
+#include <wtf/Platform.h>
+#include <wtf/ExportMacros.h>
+#include <runtime/JSExportMacros.h>
+
+#endif
diff --git a/Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp b/Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp
index d25320125..e93caf5aa 100644
--- a/Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp
+++ b/Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp
@@ -14,7 +14,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -39,7 +39,7 @@
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/WTFString.h>
namespace WTR {
@@ -122,6 +122,8 @@ static guint webkitModifiersToGDKModifiers(WKEventModifiers wkModifiers)
modifiers |= GDK_MOD1_MASK;
if (wkModifiers & kWKEventModifiersMetaKey)
modifiers |= GDK_META_MASK;
+ if (wkModifiers & kWKEventModifiersCapsLockKey)
+ modifiers |= GDK_LOCK_MASK;
return modifiers;
}
@@ -162,8 +164,9 @@ void EventSenderProxy::updateClickCountForButton(int button)
m_clickButton = button;
}
-static void dispatchEvent(GdkEvent* event)
+void EventSenderProxy::dispatchEvent(GdkEvent* event)
{
+ ASSERT(m_testController->mainWebView());
gtk_main_do_event(event);
gdk_event_free(event);
}
@@ -217,6 +220,18 @@ int getGDKKeySymForKeyRef(WKStringRef keyRef, unsigned location, guint* modifier
return GDK_KEY_VoidSymbol;
}
+ if (WKStringIsEqualToUTF8CString(keyRef, "leftControl"))
+ return GDK_KEY_Control_L;
+ if (WKStringIsEqualToUTF8CString(keyRef, "rightControl"))
+ return GDK_KEY_Control_R;
+ if (WKStringIsEqualToUTF8CString(keyRef, "leftShift"))
+ return GDK_KEY_Shift_L;
+ if (WKStringIsEqualToUTF8CString(keyRef, "rightShift"))
+ return GDK_KEY_Shift_R;
+ if (WKStringIsEqualToUTF8CString(keyRef, "leftAlt"))
+ return GDK_KEY_Alt_L;
+ if (WKStringIsEqualToUTF8CString(keyRef, "rightAlt"))
+ return GDK_KEY_Alt_R;
if (WKStringIsEqualToUTF8CString(keyRef, "leftArrow"))
return GDK_KEY_Left;
if (WKStringIsEqualToUTF8CString(keyRef, "rightArrow"))
@@ -277,6 +292,8 @@ int getGDKKeySymForKeyRef(WKStringRef keyRef, unsigned location, guint* modifier
return GDK_KEY_Tab;
if (charCode == '\x8')
return GDK_KEY_BackSpace;
+ if (charCode == 0x001B)
+ return GDK_KEY_Escape;
if (WTF::isASCIIUpper(charCode))
*modifiers |= GDK_SHIFT_MASK;
@@ -416,7 +433,10 @@ void EventSenderProxy::mouseScrollBy(int horizontal, int vertical)
void EventSenderProxy::continuousMouseScrollBy(int horizontal, int vertical, bool paged)
{
// Gtk+ does not support paged scroll events.
- g_return_if_fail(!paged);
+ if (paged) {
+ WTFLogAlways("EventSenderProxy::continuousMouseScrollBy not implemented for paged scroll events");
+ return;
+ }
GdkEvent* event = gdk_event_new(GDK_SCROLL);
event->scroll.x = m_position.x;
@@ -433,6 +453,18 @@ void EventSenderProxy::continuousMouseScrollBy(int horizontal, int vertical, boo
sendOrQueueEvent(event);
}
+void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int x, int y, int /*phase*/, int /*momentum*/)
+{
+ // Gtk+ does not have the concept of wheel gesture phases or momentum. Just relay to
+ // the mouse wheel handler.
+ mouseScrollBy(x, y);
+}
+
+void EventSenderProxy::swipeGestureWithWheelAndMomentumPhases(int, int, int, int)
+{
+ notImplemented();
+}
+
void EventSenderProxy::leapForward(int milliseconds)
{
if (m_eventQueue.isEmpty())
@@ -466,6 +498,7 @@ GUniquePtr<GdkEvent> EventSenderProxy::createTouchEvent(GdkEventType eventType,
return touchEvent;
}
+#if ENABLE(TOUCH_EVENTS)
void EventSenderProxy::addTouchPoint(int x, int y)
{
// Touch ID is array index plus one, so 0 is skipped.
@@ -556,6 +589,6 @@ void EventSenderProxy::setTouchModifier(WKEventModifiers modifier, bool enable)
m_updatedTouchEvents.add(GPOINTER_TO_INT(event->touch.sequence));
}
}
-
+#endif // ENABLE(TOUCH_EVENTS)
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp b/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp
index fd6f8466b..eb0a08d74 100644
--- a/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp
+++ b/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp
@@ -28,13 +28,17 @@
#include "config.h"
#include "PlatformWebView.h"
-#include <WebKit2/WKViewPrivate.h>
+#include <WebKit/WKImageCairo.h>
+#include <WebKit/WKPageConfigurationRef.h>
+#include <WebKit/WKView.h>
+#include <WebKit/WKViewPrivate.h>
#include <gtk/gtk.h>
+#include <wtf/Assertions.h>
namespace WTR {
-PlatformWebView::PlatformWebView(WKContextRef context, WKPageGroupRef pageGroup, WKPageRef /* relatedPage */, WKDictionaryRef options)
- : m_view(WKViewCreate(context, pageGroup))
+PlatformWebView::PlatformWebView(WKPageConfigurationRef configuration, const TestOptions& options)
+ : m_view(WKViewCreate(configuration))
, m_window(gtk_window_new(GTK_WINDOW_POPUP))
, m_windowIsKey(true)
, m_options(options)
@@ -42,7 +46,7 @@ PlatformWebView::PlatformWebView(WKContextRef context, WKPageGroupRef pageGroup,
gtk_container_add(GTK_CONTAINER(m_window), GTK_WIDGET(m_view));
GtkAllocation size = { 0, 0, 800, 600 };
- gtk_widget_size_allocate(m_window, &size);
+ gtk_widget_size_allocate(GTK_WIDGET(m_view), &size);
gtk_window_resize(GTK_WINDOW(m_window), 800, 600);
gtk_widget_show_all(m_window);
@@ -55,14 +59,17 @@ PlatformWebView::~PlatformWebView()
gtk_widget_destroy(m_window);
}
-void PlatformWebView::resizeTo(unsigned width, unsigned height)
+void PlatformWebView::setWindowIsKey(bool isKey)
{
- GtkAllocation size = { 0, 0, static_cast<int>(width), static_cast<int>(height) };
- gtk_widget_size_allocate(m_window, &size);
- gtk_window_resize(GTK_WINDOW(m_window), width, height);
+ m_windowIsKey = isKey;
+}
- while (gtk_events_pending())
- gtk_main_iteration();
+void PlatformWebView::resizeTo(unsigned width, unsigned height, WebViewSizingMode sizingMode)
+{
+ WKRect frame = windowFrame();
+ frame.size.width = width;
+ frame.size.height = height;
+ setWindowFrame(frame, sizingMode);
}
WKPageRef PlatformWebView::page()
@@ -79,14 +86,8 @@ void PlatformWebView::focus()
WKRect PlatformWebView::windowFrame()
{
GtkAllocation geometry;
-#ifdef GTK_API_VERSION_2
- gint depth;
- gdk_window_get_geometry(gtk_widget_get_window(GTK_WIDGET(m_window)),
- &geometry.x, &geometry.y, &geometry.width, &geometry.height, &depth);
-#else
gdk_window_get_geometry(gtk_widget_get_window(GTK_WIDGET(m_window)),
&geometry.x, &geometry.y, &geometry.width, &geometry.height);
-#endif
WKRect frame;
frame.origin.x = geometry.x;
@@ -96,10 +97,15 @@ WKRect PlatformWebView::windowFrame()
return frame;
}
-void PlatformWebView::setWindowFrame(WKRect frame)
+void PlatformWebView::setWindowFrame(WKRect frame, WebViewSizingMode)
{
- gtk_window_move(GTK_WINDOW(m_window), frame.origin.x, frame.origin.y);
- resizeTo(frame.size.width, frame.size.height);
+ gdk_window_move_resize(gtk_widget_get_window(GTK_WIDGET(m_window)),
+ frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
+ GtkAllocation size = { 0, 0, static_cast<int>(frame.size.width), static_cast<int>(frame.size.height) };
+ gtk_widget_size_allocate(GTK_WIDGET(m_view), &size);
+
+ while (gtk_events_pending())
+ gtk_main_iteration();
}
void PlatformWebView::addChromeInputField()
@@ -110,20 +116,65 @@ void PlatformWebView::removeChromeInputField()
{
}
+void PlatformWebView::addToWindow()
+{
+}
+
+void PlatformWebView::removeFromWindow()
+{
+}
+
void PlatformWebView::makeWebViewFirstResponder()
{
}
+void PlatformWebView::changeWindowScaleIfNeeded(float)
+{
+}
+
WKRetainPtr<WKImageRef> PlatformWebView::windowSnapshotImage()
{
- // FIXME: implement to capture pixels in the UI process,
- // which may be necessary to capture things like 3D transforms.
- return 0;
+ int width = gtk_widget_get_allocated_width(GTK_WIDGET(m_view));
+ int height = gtk_widget_get_allocated_height(GTK_WIDGET(m_view));
+
+ while (gtk_events_pending())
+ gtk_main_iteration();
+
+ cairo_surface_t* imageSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+
+ cairo_t* context = cairo_create(imageSurface);
+ gtk_widget_draw(GTK_WIDGET(m_view), context);
+ cairo_destroy(context);
+
+ WKRetainPtr<WKImageRef> wkImage = adoptWK(WKImageCreateFromCairoSurface(imageSurface, 0 /* options */));
+
+ cairo_surface_destroy(imageSurface);
+ return wkImage;
}
void PlatformWebView::didInitializeClients()
{
}
+bool PlatformWebView::viewSupportsOptions(const TestOptions&) const
+{
+ return true;
+}
+
+void PlatformWebView::dismissAllPopupMenus()
+{
+ // gtk_menu_popdown doesn't modify the GList of attached menus, so it should
+ // be safe to walk this list while calling it.
+ GList* attachedMenusList = gtk_menu_get_for_attach_widget(GTK_WIDGET(m_view));
+ g_list_foreach(attachedMenusList, [] (void* data, void*) {
+ ASSERT(data);
+ gtk_menu_popdown(GTK_MENU(data));
+ }, nullptr);
+}
+
+void PlatformWebView::setNavigationGesturesEnabled(bool)
+{
+}
+
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/gtk/TestControllerGtk.cpp b/Tools/WebKitTestRunner/gtk/TestControllerGtk.cpp
index d8fb9f728..62d031a87 100644
--- a/Tools/WebKitTestRunner/gtk/TestControllerGtk.cpp
+++ b/Tools/WebKitTestRunner/gtk/TestControllerGtk.cpp
@@ -27,52 +27,68 @@
#include "config.h"
#include "TestController.h"
+#include "PlatformWebView.h"
#include <gtk/gtk.h>
#include <wtf/Platform.h>
-#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/RunLoop.h>
+#include <wtf/glib/GRefPtr.h>
+#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/WTFString.h>
namespace WTR {
-static guint gTimeoutSourceId = 0;
-
-static void cancelTimeout()
+static GSource* timeoutSource()
{
- if (!gTimeoutSourceId)
- return;
- g_source_remove(gTimeoutSourceId);
- gTimeoutSourceId = 0;
+ static GRefPtr<GSource> source = nullptr;
+ if (!source) {
+ source = adoptGRef(g_timeout_source_new(0));
+ g_source_set_ready_time(source.get(), -1);
+ g_source_set_name(source.get(), "[WTR] Test timeout source");
+ g_source_set_callback(source.get(), [](gpointer userData) -> gboolean {
+ g_source_set_ready_time(static_cast<GSource*>(userData), -1);
+ fprintf(stderr, "FAIL: TestControllerRunLoop timed out.\n");
+ RunLoop::main().stop();
+ return G_SOURCE_REMOVE;
+ }, source.get(), nullptr);
+ g_source_attach(source.get(), nullptr);
+ }
+ return source.get();
}
void TestController::notifyDone()
{
- gtk_main_quit();
- cancelTimeout();
+ g_source_set_ready_time(timeoutSource(), -1);
+ RunLoop::main().stop();
}
void TestController::platformInitialize()
{
}
-void TestController::platformDestroy()
+WKPreferencesRef TestController::platformPreferences()
{
+ return WKPageGroupGetPreferences(m_pageGroup.get());
}
-static gboolean timeoutCallback(gpointer)
+void TestController::platformDestroy()
{
- fprintf(stderr, "FAIL: TestControllerRunLoop timed out.\n");
- gtk_main_quit();
- return FALSE;
}
void TestController::platformRunUntil(bool&, double timeout)
{
- cancelTimeout();
- if (timeout != m_noTimeout) {
- gTimeoutSourceId = g_timeout_add(timeout * 1000, timeoutCallback, 0);
- g_source_set_name_by_id(gTimeoutSourceId, "[WebKit] timeoutCallback");
- }
- gtk_main();
+ if (timeout > 0) {
+ // FIXME: This conversion is now repeated in several places, it should be moved to a common place in WTF and used everywhere.
+ auto timeoutDuration = std::chrono::duration<double>(timeout);
+ auto safeDuration = std::chrono::microseconds::max();
+ if (timeoutDuration < safeDuration)
+ safeDuration = std::chrono::duration_cast<std::chrono::microseconds>(timeoutDuration);
+ gint64 currentTime = g_get_monotonic_time();
+ gint64 targetTime = currentTime + std::min<gint64>(G_MAXINT64 - currentTime, safeDuration.count());
+ ASSERT(targetTime >= currentTime);
+ g_source_set_ready_time(timeoutSource(), targetTime);
+ } else
+ g_source_set_ready_time(timeoutSource(), -1);
+ RunLoop::main().run();
}
static char* getEnvironmentVariableAsUTF8String(const char* variableName)
@@ -102,9 +118,14 @@ void TestController::platformInitializeContext()
{
}
-void TestController::setHidden(bool)
+void TestController::setHidden(bool hidden)
{
- // FIXME: Need to implement this to test visibilityState.
+ if (!m_mainWebView)
+ return;
+ if (hidden)
+ gtk_widget_unmap(GTK_WIDGET(m_mainWebView->platformView()));
+ else
+ gtk_widget_map(GTK_WIDGET(m_mainWebView->platformView()));
}
void TestController::runModal(PlatformWebView*)
@@ -117,4 +138,20 @@ const char* TestController::platformLibraryPathForTesting()
return 0;
}
+void TestController::platformConfigureViewForTest(const TestInvocation&)
+{
+ WKPageSetApplicationNameForUserAgent(mainWebView()->page(), WKStringCreateWithUTF8CString("WebKitTestRunnerGTK"));
+}
+
+void TestController::platformResetPreferencesToConsistentValues()
+{
+ if (!m_mainWebView)
+ return;
+ m_mainWebView->dismissAllPopupMenus();
+}
+
+void TestController::updatePlatformSpecificTestOptionsForTest(TestOptions&, const std::string&) const
+{
+}
+
} // namespace WTR
diff --git a/Tools/WebKitTestRunner/gtk/fonts/AHEM____.TTF b/Tools/WebKitTestRunner/gtk/fonts/AHEM____.TTF
new file mode 100644
index 000000000..ac81cb031
--- /dev/null
+++ b/Tools/WebKitTestRunner/gtk/fonts/AHEM____.TTF
Binary files differ
diff --git a/Tools/WebKitTestRunner/gtk/fonts/FontWithNoValidEncoding.fon b/Tools/WebKitTestRunner/gtk/fonts/FontWithNoValidEncoding.fon
new file mode 100644
index 000000000..8fff7d9c1
--- /dev/null
+++ b/Tools/WebKitTestRunner/gtk/fonts/FontWithNoValidEncoding.fon
Binary files differ
diff --git a/Tools/WebKitTestRunner/gtk/fonts/fonts.conf b/Tools/WebKitTestRunner/gtk/fonts/fonts.conf
new file mode 100644
index 000000000..2387e9581
--- /dev/null
+++ b/Tools/WebKitTestRunner/gtk/fonts/fonts.conf
@@ -0,0 +1,435 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+
+ <!-- Due to patent (http://freetype.sourceforge.net/patents.html)
+ issues hinting gives different results depending on the
+ freetype version of the linux distribution, avoiding hinting
+ gives more consistent results. When all the distributions
+ release freetype the 2.4, which enables by default the
+ hinting method that was patented, we could undo this change
+ and try the hinting again. -->
+ <match target="font">
+ <edit name="hinting" mode="assign">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <!-- This system may have turned off selection of bitmap fonts, but
+ we must turn it on again, because we want to be able to test that
+ bitmap fonts with no valid encodings are *never* selected regardless
+ of the Fontconfig settings. So force Fontconfig to select our cruddy
+ bitmap font -->
+ <selectfont>
+ <acceptfont>
+ <pattern>
+ <patelt name="family">
+ <string>FontWithNoValidEncoding</string>
+ </patelt>
+ </pattern>
+ </acceptfont>
+ </selectfont>
+
+ <!-- The sans-serif font should be Liberation Serif -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>serif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Times</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Times New Roman</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ </match>
+
+ <!-- Until we find good fonts to use for cursive and fantasy
+ just use our serif font. -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>cursive</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>fantasy</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ </match>
+
+ <!-- The sans-serif font should be Liberation Sans -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans serif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ </match>
+ <!-- We need to ensure that layout tests that use "Helvetica" don't
+ fall back to the default serif font -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Helvetica</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Arial</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Lucida Grande</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ </match>
+
+ <!-- The Monospace font should be Liberation Mono -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>monospace</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>mono</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+ <!-- We need to ensure that layout tests that use "Courier", "Courier New",
+ and "Monaco" (all monospace fonts) don't fall back to the default
+ serif font -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Courier</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Courier New</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Monaco</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+
+ <!-- The following hinting specializations are adapted from those in the
+ Chromium test_shell. We try to duplicate their incredibly thorough
+ testing here -->
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>NonAntiAliasedSans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ <edit name="antialias" mode="assign">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>SlightHintedSerif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ <edit name="hinting" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <edit name="hintstyle" mode="assign">
+ <const>hintslight</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>NonHintedSans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ <!-- These deliberately contradict each other. The 'hinting' preference
+ should take priority -->
+ <edit name="hintstyle" mode="assign">
+ <const>hintfull</const>
+ </edit>
+ <edit name="hinting" mode="assign">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>AutohintedSerif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ <edit name="hinting" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <edit name="autohint" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <edit name="hintstyle" mode="assign">
+ <const>hintmedium</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>HintedSerif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ <edit name="hinting" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <edit name="autohint" mode="assign">
+ <bool>false</bool>
+ </edit>
+ <edit name="hintstyle" mode="assign">
+ <const>hintmedium</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>FullAndAutoHintedSerif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ <edit name="hinting" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <edit name="autohint" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <edit name="hintstyle" mode="assign">
+ <const>hintfull</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>SubpixelEnabledSans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ <edit name="rgba" mode="assign">
+ <const>rgb</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>SubpixelDisabledSans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ <edit name="rgba" mode="assign">
+ <const>none</const>
+ </edit>
+ </match>
+
+ <!-- We need to enable simulated bold to for DejaVu Serif to ensure that we interpret
+ this property correctly in: platform/gtk/fonts/fontconfig-synthetic-bold.html -->
+ <match target="font">
+ <test qual="any" name="family">
+ <string>DejaVu Serif</string>
+ </test>
+ <test name="weight" compare="less_eq">
+ <const>medium</const>
+ </test>
+ <test target="pattern" name="weight" compare="more">
+ <const>medium</const>
+ </test>
+ <edit name="embolden" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <edit name="weight" mode="assign">
+ <const>bold</const>
+ </edit>
+ </match>
+
+ <!-- We need to enable simulated oblique to for DejaVu Serif to ensure that we interpret
+ this property correctly in: platform/gtk/fonts/fontconfig-synthetic-oblique.html -->
+ <match target="font">
+ <test qual="any" name="family">
+ <string>DejaVu Serif</string>
+ </test>
+ <test name="slant">
+ <const>roman</const>
+ </test>
+ <test target="pattern" name="slant" compare="not_eq">
+ <const>roman</const>
+ </test>
+ <edit name="matrix" mode="assign">
+ <times>
+ <name>matrix</name>
+ <matrix><double>1</double><double>0.2</double>
+ <double>0</double><double>1</double>
+ </matrix>
+ </times>
+ </edit>
+ <edit name="slant" mode="assign">
+ <const>oblique</const>
+ </edit>
+ <edit name="embeddedbitmap" mode="assign">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <!-- These fonts should be treated as identical by CSS font fallback. -->
+ <alias binding="same">
+ <family>FamilyStrongAliasedToFreeMono</family>
+ <accept>
+ <family>FreeMono</family>
+ </accept>
+ </alias>
+
+ <!-- These fonts should NOT be treated as identical by CSS font fallback. -->
+ <alias>
+ <family>FamilyWeakAliasedToFreeMono</family>
+ <accept>
+ <family>FreeMono</family>
+ </accept>
+ </alias>
+
+ <!-- If this font doesn't have a family name we are falling back. The fallback
+ font will certainly be one of the DejaVu fonts that we have in our
+ collection since they have a wide range of characters. Fontconfig might
+ choose DejaVu Sans or DejaVu Serif depending on the system, so we force
+ the use of DejaVu Sans in these situations to maintain consistency. -->
+ <match target="pattern">
+ <test qual="all" name="family" compare="eq">
+ <string></string>
+ </test>
+ <edit name="family" mode="append_last">
+ <string>DejaVu Sans</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>
+ </config>
+</fontconfig>
diff --git a/Tools/WebKitTestRunner/gtk/main.cpp b/Tools/WebKitTestRunner/gtk/main.cpp
index d53c6248a..7947ce55c 100644
--- a/Tools/WebKitTestRunner/gtk/main.cpp
+++ b/Tools/WebKitTestRunner/gtk/main.cpp
@@ -26,12 +26,21 @@
#include "config.h"
#include "TestController.h"
+#include <WebKit/WKTextCheckerGtk.h>
#include <gtk/gtk.h>
+#include <wtf/glib/GRefPtr.h>
int main(int argc, char** argv)
{
gtk_init(&argc, &argv);
+
+ GRefPtr<GPtrArray> languages = adoptGRef(g_ptr_array_new());
+ g_ptr_array_add(languages.get(), const_cast<gpointer>(static_cast<const void*>("en_US")));
+ g_ptr_array_add(languages.get(), nullptr);
+ WKTextCheckerSetSpellCheckingLanguages(reinterpret_cast<const char* const*>(languages->pdata));
+
// Prefer the not installed web and plugin processes.
WTR::TestController controller(argc, const_cast<const char**>(argv));
+
return 0;
}