[GTK] WTR: Native HTML form validation popover is not supported
https://bugs.webkit.org/show_bug.cgi?id=167579

Reviewed by Carlos Garcia Campos.

This change enables form-validation-related tests. To this end, two APIs called
overridePreference and contentsOfUserInterfaceItem are added to UIScriptController.

Source/WebKit:

WebKitWebViewBase implements contentsOfUserInterfaceItem for UIScriptController
necessary for webkit tests. It returns a font size and an actual message of a validation
bubble in the dictionary format. For overridePreference, we directly call WKPreference API
in WKView.cpp

No new tests since this change is the enabler of existing tests.

* UIProcess/API/C/gtk/WKView.cpp:
(WKViewContentsOfUserInterfaceItem):
* UIProcess/API/C/gtk/WKViewPrivate.h:
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseContentsOfUserInterfaceItem):
* UIProcess/API/gtk/WebKitWebViewBasePrivate.h:

Tools:

UIScriptController.overridePreference configures the minimum font size of the validation bubbles
and UIScriptController.contentsOfUserInterfaceItem returns an actual bubble message along with its font size
in a json object.

* WebKitTestRunner/TestController.h: Make paltformPreferences public.
* WebKitTestRunner/gtk/UIScriptControllerGtk.cpp:
(WTR::UIScriptControllerGtk::overridePreference):
(WTR::toJSONObject):
(WTR::UIScriptControllerGtk::contentsOfUserInterfaceItem const):
* WebKitTestRunner/gtk/UIScriptControllerGtk.h:

LayoutTests:

We configure the minimum font size of the validation bubbles via UIScriptController.overridePreference
and retrieve a message and its font size through UIScriptController.contentsOfUserInterfaceItem.

* platform/gtk/TestExpectations: Enable form validation related tests we can perform with
  native bubble widgets but skip ones related to HTML-based form validation as Cocoa-based ports do.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@288666 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 8e8497f..0a91f6f 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2022-01-26  ChangSeok Oh  <changseok@webkit.org>
+
+        [GTK] WTR: Native HTML form validation popover is not supported
+        https://bugs.webkit.org/show_bug.cgi?id=167579
+
+        Reviewed by Carlos Garcia Campos.
+
+        This change enables form-validation-related tests. To this end, two APIs called
+        overridePreference and contentsOfUserInterfaceItem are added to UIScriptController.
+
+        We configure the minimum font size of the validation bubbles via UIScriptController.overridePreference
+        and retrieve a message and its font size through UIScriptController.contentsOfUserInterfaceItem.
+
+        * platform/gtk/TestExpectations: Enable form validation related tests we can perform with
+          native bubble widgets but skip ones related to HTML-based form validation as Cocoa-based ports do.
+
 2022-01-26  Ryan Haddad  <ryanhaddad@apple.com>
 
         REGRESSION (01/14/22?): [macOS Release WK2] imported/w3c/web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html and createImageBitmap-flipY.html are flaky failures
diff --git a/LayoutTests/platform/gtk/TestExpectations b/LayoutTests/platform/gtk/TestExpectations
index 28a126c..a16c6fc 100644
--- a/LayoutTests/platform/gtk/TestExpectations
+++ b/LayoutTests/platform/gtk/TestExpectations
@@ -644,23 +644,16 @@
 webkit.org/b/153833 fast/events/before-input-prevent-insert-replacement.html [ Skip ]
 webkit.org/b/153833 fast/events/input-event-insert-replacement.html [ Skip ]
 
-# Skip tests expecting native HTML form validation popover
-webkit.org/b/167579 fast/forms/scroll-into-view-and-show-validation-message.html [ Skip ]
-webkit.org/b/167579 fast/forms/navigation-dismisses-validation-bubbles.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-bubble-disappears-when-input-detached.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-bubble-disappears-when-input-moved.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-bubble-disappears-when-input-no-longer-visible.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-custom-message.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-message-detached-iframe.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-message-detached-iframe2.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-messages.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-bubble-escape-key-dismiss.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-message-minimum-font-size.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-message-on-checkbox.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-message-on-listbox.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-message-on-menulist.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-message-on-radio.html [ Skip ]
-webkit.org/b/167579 fast/forms/validation-message-clone.html [ Skip ]
+# These tests test the Shadow DOM based HTML form validation UI but GTK WK2 is using native dialogs instead.
+fast/forms/validation-message-on-listbox.html [ Skip ]
+fast/forms/validation-message-on-menulist.html [ Skip ]
+fast/forms/validation-message-on-radio.html [ Skip ]
+fast/forms/validation-message-on-checkbox.html [ Skip ]
+fast/forms/validation-message-on-range.html [ Skip ]
+fast/forms/validation-message-clone.html [ Skip ]
+fast/forms/validation-message-in-relative-body.html [ Skip ]
+fast/forms/validation-message-appearance.html [ Skip ]
+fast/forms/validation-message-on-textarea.html [ Skip ]
 
 webkit.org/b/137096 svg/W3C-SVG-1.1/text-altglyph-01-b.svg [ Failure ]
 webkit.org/b/137096 svg/custom/altglyph.svg [ Failure ]
@@ -927,8 +920,6 @@
 
 webkit.org/b/188406 [ Debug ] imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/dir.html [ Crash ]
 
-webkit.org/b/191882 fast/forms/validation-message-in-relative-body.html [ Failure Pass ]
-
 webkit.org/b/196799 imported/blink/fast/css/first-letter-crash-document-disposal.html [ Crash ]
 
 webkit.org/b/120839 animations/cross-fade-background-image.html [ ImageOnlyFailure Crash ]
@@ -1069,8 +1060,6 @@
 
 webkit.org/b/170484 swipe/main-frame-pinning-requirement.html [ Timeout ]
 
-webkit.org/b/202232 fast/forms/validation-message-appearance.html [ Failure ]
-
 webkit.org/b/208809 imported/w3c/web-platform-tests/css/WOFF2/blocks-extraneous-data-001.xht [ ImageOnlyFailure ]
 webkit.org/b/208809 imported/w3c/web-platform-tests/css/WOFF2/blocks-extraneous-data-002.xht [ ImageOnlyFailure ]
 webkit.org/b/208809 imported/w3c/web-platform-tests/css/WOFF2/blocks-extraneous-data-003.xht [ ImageOnlyFailure ]
@@ -1743,8 +1732,6 @@
 webkit.org/b/191688 compositing/overflow/clip-descendents.html [ Failure ]
 webkit.org/b/191688 compositing/repaint/absolute-painted-into-composited-ancestor.html [ Failure ]
 
-webkit.org/b/191882 fast/forms/validation-message-on-range.html [ Failure ]
-webkit.org/b/191882 fast/forms/validation-message-on-textarea.html [ Failure ]
 webkit.org/b/191882 fast/forms/auto-fill-button/input-credit-card-auto-fill-button.html [ Failure ]
 
 webkit.org/b/191885 fast/inline/simple-inline-inflow-positioned.html [ Failure ]
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index f9fefa0..bdbed52 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,27 @@
+2022-01-26  ChangSeok Oh  <changseok@webkit.org>
+
+        [GTK] WTR: Native HTML form validation popover is not supported
+        https://bugs.webkit.org/show_bug.cgi?id=167579
+
+        Reviewed by Carlos Garcia Campos.
+
+        This change enables form-validation-related tests. To this end, two APIs called
+        overridePreference and contentsOfUserInterfaceItem are added to UIScriptController.
+
+        WebKitWebViewBase implements contentsOfUserInterfaceItem for UIScriptController
+        necessary for webkit tests. It returns a font size and an actual message of a validation
+        bubble in the dictionary format. For overridePreference, we directly call WKPreference API
+        in WKView.cpp
+
+        No new tests since this change is the enabler of existing tests.
+
+        * UIProcess/API/C/gtk/WKView.cpp:
+        (WKViewContentsOfUserInterfaceItem):
+        * UIProcess/API/C/gtk/WKViewPrivate.h:
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseContentsOfUserInterfaceItem):
+        * UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
+
 2022-01-26  Per Arne Vollan  <pvollan@apple.com>
 
         [WP] Avoid calling IOSurfaceAlignProperty
diff --git a/Source/WebKit/UIProcess/API/C/gtk/WKView.cpp b/Source/WebKit/UIProcess/API/C/gtk/WKView.cpp
index 501c164..444e3e8 100644
--- a/Source/WebKit/UIProcess/API/C/gtk/WKView.cpp
+++ b/Source/WebKit/UIProcess/API/C/gtk/WKView.cpp
@@ -63,3 +63,8 @@
 {
     return webkitWebViewBaseCompleteBackSwipeForTesting(toImpl(viewRef));
 }
+
+GVariant* WKViewContentsOfUserInterfaceItem(WKViewRef viewRef, const char* userInterfaceItem)
+{
+    return webkitWebViewBaseContentsOfUserInterfaceItem(toImpl(viewRef), userInterfaceItem);
+}
diff --git a/Source/WebKit/UIProcess/API/C/gtk/WKViewPrivate.h b/Source/WebKit/UIProcess/API/C/gtk/WKViewPrivate.h
index aafd657..e2d46a3 100644
--- a/Source/WebKit/UIProcess/API/C/gtk/WKViewPrivate.h
+++ b/Source/WebKit/UIProcess/API/C/gtk/WKViewPrivate.h
@@ -40,6 +40,8 @@
 
 WK_EXPORT bool WKViewCompleteBackSwipeForTesting(WKViewRef viewRef);
 
+WK_EXPORT GVariant* WKViewContentsOfUserInterfaceItem(WKViewRef viewRef, const char* userInterfaceItem);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
index 573d7fe..935d3ab 100644
--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -1637,6 +1637,28 @@
     return FALSE;
 }
 
+GVariant* webkitWebViewBaseContentsOfUserInterfaceItem(WebKitWebViewBase* webViewBase, const char* userInterfaceItem)
+{
+    if (g_strcmp0(userInterfaceItem, "validationBubble"))
+        return nullptr;
+
+    WebPageProxy* page = webViewBase->priv->pageProxy.get();
+    auto* validationBubble = page->validationBubble();
+    String message = validationBubble ? validationBubble->message() : emptyString();
+    double fontSize = validationBubble ? validationBubble->fontSize() : 0;
+
+    GVariantBuilder subBuilder;
+    g_variant_builder_init(&subBuilder, G_VARIANT_TYPE_VARDICT);
+    g_variant_builder_add(&subBuilder, "{sv}", "message", g_variant_new_string(message.utf8().data()));
+    g_variant_builder_add(&subBuilder, "{sv}", "fontSize", g_variant_new_double(fontSize));
+
+    GVariantBuilder builder;
+    g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
+    g_variant_builder_add(&builder, "{sv}", userInterfaceItem, g_variant_builder_end(&subBuilder));
+
+    return g_variant_builder_end(&builder);
+}
+
 static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint /* x */, gint /* y */, gboolean keyboardMode, GtkTooltip* tooltip)
 {
     WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
index 9a1b30d..0da15d3 100644
--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
@@ -95,6 +95,8 @@
 bool webkitWebViewBaseBeginBackSwipeForTesting(WebKitWebViewBase*);
 bool webkitWebViewBaseCompleteBackSwipeForTesting(WebKitWebViewBase*);
 
+GVariant* webkitWebViewBaseContentsOfUserInterfaceItem(WebKitWebViewBase*, const char* userInterfaceItem);
+
 void webkitWebViewBaseDidStartProvisionalLoadForMainFrame(WebKitWebViewBase*);
 void webkitWebViewBaseDidFirstVisuallyNonEmptyLayoutForMainFrame(WebKitWebViewBase*);
 void webkitWebViewBaseDidFinishNavigation(WebKitWebViewBase*, API::Navigation*);
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 44f2d9d..a35b268 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,24 @@
+2022-01-26  ChangSeok Oh  <changseok@webkit.org>
+
+        [GTK] WTR: Native HTML form validation popover is not supported
+        https://bugs.webkit.org/show_bug.cgi?id=167579
+
+        Reviewed by Carlos Garcia Campos.
+
+        This change enables form-validation-related tests. To this end, two APIs called
+        overridePreference and contentsOfUserInterfaceItem are added to UIScriptController.
+
+        UIScriptController.overridePreference configures the minimum font size of the validation bubbles
+        and UIScriptController.contentsOfUserInterfaceItem returns an actual bubble message along with its font size
+        in a json object.
+
+        * WebKitTestRunner/TestController.h: Make paltformPreferences public.
+        * WebKitTestRunner/gtk/UIScriptControllerGtk.cpp:
+        (WTR::UIScriptControllerGtk::overridePreference):
+        (WTR::toJSONObject):
+        (WTR::UIScriptControllerGtk::contentsOfUserInterfaceItem const):
+        * WebKitTestRunner/gtk/UIScriptControllerGtk.h:
+
 2022-01-26  Jonathan Bedard  <jbedard@apple.com>
 
         [EWS] Ignore hooks from closed PRs
diff --git a/Tools/WebKitTestRunner/TestController.h b/Tools/WebKitTestRunner/TestController.h
index 6010d84..69a0786 100644
--- a/Tools/WebKitTestRunner/TestController.h
+++ b/Tools/WebKitTestRunner/TestController.h
@@ -370,6 +370,8 @@
     void setIsMediaKeySystemPermissionGranted(bool);
     WKRetainPtr<WKStringRef> takeViewPortSnapshot();
 
+    WKPreferencesRef platformPreferences();
+
 private:
     WKRetainPtr<WKPageConfigurationRef> generatePageConfiguration(const TestOptions&);
     WKRetainPtr<WKContextConfigurationRef> generateContextConfiguration(const TestOptions&) const;
@@ -407,7 +409,6 @@
     void platformRunUntil(bool& done, WTF::Seconds timeout);
     void platformDidCommitLoadForFrame(WKPageRef, WKFrameRef);
     WKContextRef platformContext();
-    WKPreferencesRef platformPreferences();
     void initializeInjectedBundlePath();
     void initializeTestPluginDirectory();
 
diff --git a/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.cpp b/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.cpp
index 28e8a7b..9aacc7a 100644
--- a/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.cpp
+++ b/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.cpp
@@ -28,12 +28,15 @@
 
 #include "EventSenderProxy.h"
 #include "PlatformWebView.h"
+#include "StringFunctions.h"
 #include "TestController.h"
 #include "UIScriptContext.h"
+#include <JavaScriptCore/JavaScript.h>
 #include <JavaScriptCore/OpaqueJSString.h>
 #include <WebKit/WKTextCheckerGLib.h>
 #include <WebKit/WKViewPrivate.h>
 #include <gtk/gtk.h>
+#include <wtf/JSONValues.h>
 #include <wtf/RunLoop.h>
 
 namespace WTR {
@@ -162,4 +165,42 @@
     });
 }
 
+void UIScriptControllerGtk::overridePreference(JSStringRef preference, JSStringRef value)
+{
+    if (toWTFString(preference) != "WebKitMinimumFontSize")
+        return;
+
+    auto preferences = TestController::singleton().platformPreferences();
+    WKPreferencesSetMinimumFontSize(preferences, static_cast<uint32_t>(toWTFString(value).toDouble()));
+}
+
+static Ref<JSON::Object> toJSONObject(GVariant* variant)
+{
+    Ref<JSON::Object> jsonObject = JSON::Object::create();
+
+    const char* key;
+    GVariant* value;
+    GVariantIter iter;
+    g_variant_iter_init(&iter, variant);
+    while (g_variant_iter_loop(&iter, "{&sv}", &key, &value)) {
+        const GVariantType* type = g_variant_get_type(value);
+        if (type && g_variant_type_equal(type, G_VARIANT_TYPE_VARDICT))
+            jsonObject->setObject(key, toJSONObject(value));
+        else if (type && g_variant_type_equal(type, G_VARIANT_TYPE_STRING))
+            jsonObject->setString(key, g_variant_get_string(value, nullptr));
+        else if (type && g_variant_type_equal(type, G_VARIANT_TYPE_DOUBLE))
+            jsonObject->setDouble(key, g_variant_get_double(value));
+    }
+    return jsonObject;
+}
+
+JSObjectRef UIScriptControllerGtk::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
+{
+    auto* webView = TestController::singleton().mainWebView()->platformView();
+    GRefPtr<GVariant> contentDictionary = adoptGRef(WKViewContentsOfUserInterfaceItem(webView, toWTFString(interfaceItem).utf8().data()));
+    auto jsonObject = toJSONObject(contentDictionary.get());
+
+    return JSValueToObject(m_context->jsContext(), contentDictionary ? JSValueMakeFromJSONString(m_context->jsContext(), createJSString(jsonObject->toJSONString().utf8().data()).get()) : JSValueMakeUndefined(m_context->jsContext()), nullptr);
+}
+
 } // namespace WTR
diff --git a/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h b/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h
index ecaf0a8..0fa1dc5 100644
--- a/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h
+++ b/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h
@@ -52,6 +52,10 @@
     void simulateAccessibilitySettingsChangeNotification(JSValueRef) override;
     void removeViewFromWindow(JSValueRef) override;
     void addViewToWindow(JSValueRef) override;
+
+private:
+    void overridePreference(JSStringRef, JSStringRef) override;
+    JSObjectRef contentsOfUserInterfaceItem(JSStringRef) const override;
 };
 
 } // namespace WTR