[WPE][GTK] Add webkit_frame_get_id() API
https://bugs.webkit.org/show_bug.cgi?id=197270

Reviewed by Carlos Garcia Campos.

Source/WebKit:

It's as simple as can be: just an API to return the ID of a frame.

* UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
* WebProcess/InjectedBundle/API/glib/WebKitFrame.cpp:
(webkit_frame_get_id):
* WebProcess/InjectedBundle/API/gtk/WebKitFrame.h:
* WebProcess/InjectedBundle/API/wpe/WebKitFrame.h:
* WebProcess/InjectedBundle/API/wpe/docs/wpe-webextensions-1.0-sections.txt:

Tools:

This was hard, but I added a test to verify that two different WebKitFrames of the same
WebKitWebPage return two different frame IDs.

* TestWebKitAPI/Tests/WebKitGLib/FrameTest.cpp:
(WebKitFrameTest::willSubmitFormCallback):
(WebKitFrameTest::testSubframe):
(registerTests):
* TestWebKitAPI/Tests/WebKitGLib/TestFrame.cpp:
(testWebKitFrameSubframe):
(beforeAll):
* TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp:
(willSubmitFormCallback):
* TestWebKitAPI/Tests/WebKitGLib/resources/form-in-frame.html: Added.
* TestWebKitAPI/Tests/WebKitGLib/resources/webkitglib-tests.gresource.xml:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245176 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 1b60328..22958a5 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,5 +1,21 @@
 2019-05-10  Michael Catanzaro  <mcatanzaro@igalia.com>
 
+        [WPE][GTK] Add webkit_frame_get_id() API
+        https://bugs.webkit.org/show_bug.cgi?id=197270
+
+        Reviewed by Carlos Garcia Campos.
+
+        It's as simple as can be: just an API to return the ID of a frame.
+
+        * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
+        * WebProcess/InjectedBundle/API/glib/WebKitFrame.cpp:
+        (webkit_frame_get_id):
+        * WebProcess/InjectedBundle/API/gtk/WebKitFrame.h:
+        * WebProcess/InjectedBundle/API/wpe/WebKitFrame.h:
+        * WebProcess/InjectedBundle/API/wpe/docs/wpe-webextensions-1.0-sections.txt:
+
+2019-05-10  Michael Catanzaro  <mcatanzaro@igalia.com>
+
         [WPE][GTK] Add WebKitWebPage::did-associate-form-controls-for-frame and deprecate original did-associate-form-controls
         https://bugs.webkit.org/show_bug.cgi?id=197271
 
diff --git a/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt b/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt
index 23eeaa6..df585a2 100644
--- a/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt
+++ b/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt
@@ -1599,6 +1599,7 @@
 <SECTION>
 <FILE>WebKitFrame</FILE>
 WebKitFrame
+webkit_frame_get_id
 webkit_frame_is_main_frame
 webkit_frame_get_uri
 webkit_frame_get_javascript_global_context
diff --git a/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitFrame.cpp b/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitFrame.cpp
index 21a3f63..da679db 100644
--- a/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitFrame.cpp
+++ b/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitFrame.cpp
@@ -59,6 +59,25 @@
 }
 
 /**
+ * webkit_frame_get_id:
+ * @frame: a #WebKitFrame
+ *
+ * Gets the process-unique identifier of this #WebKitFrame. No other
+ * frame in the same web process will have the same ID; however, frames
+ * in other web processes may.
+ *
+ * Returns: the identifier of @frame
+ *
+ * Since: 2.26
+ */
+guint64 webkit_frame_get_id(WebKitFrame* frame)
+{
+    g_return_val_if_fail(WEBKIT_IS_FRAME(frame), 0);
+
+    return frame->priv->webFrame->frameID();
+}
+
+/**
  * webkit_frame_is_main_frame:
  * @frame: a #WebKitFrame
  *
diff --git a/Source/WebKit/WebProcess/InjectedBundle/API/gtk/WebKitFrame.h b/Source/WebKit/WebProcess/InjectedBundle/API/gtk/WebKitFrame.h
index a310060..42f161b 100644
--- a/Source/WebKit/WebProcess/InjectedBundle/API/gtk/WebKitFrame.h
+++ b/Source/WebKit/WebProcess/InjectedBundle/API/gtk/WebKitFrame.h
@@ -57,6 +57,9 @@
 WEBKIT_API GType
 webkit_frame_get_type                                    (void);
 
+WEBKIT_API guint64
+webkit_frame_get_id                                      (WebKitFrame       *frame);
+
 WEBKIT_API gboolean
 webkit_frame_is_main_frame                               (WebKitFrame       *frame);
 
diff --git a/Source/WebKit/WebProcess/InjectedBundle/API/wpe/WebKitFrame.h b/Source/WebKit/WebProcess/InjectedBundle/API/wpe/WebKitFrame.h
index a3c6394..6a79c03 100644
--- a/Source/WebKit/WebProcess/InjectedBundle/API/wpe/WebKitFrame.h
+++ b/Source/WebKit/WebProcess/InjectedBundle/API/wpe/WebKitFrame.h
@@ -56,6 +56,9 @@
 WEBKIT_API GType
 webkit_frame_get_type                                    (void);
 
+WEBKIT_API guint64
+webkit_frame_get_id                                      (WebKitFrame       *frame);
+
 WEBKIT_API gboolean
 webkit_frame_is_main_frame                               (WebKitFrame       *frame);
 
diff --git a/Source/WebKit/WebProcess/InjectedBundle/API/wpe/docs/wpe-webextensions-1.0-sections.txt b/Source/WebKit/WebProcess/InjectedBundle/API/wpe/docs/wpe-webextensions-1.0-sections.txt
index a1d6844..e448296 100644
--- a/Source/WebKit/WebProcess/InjectedBundle/API/wpe/docs/wpe-webextensions-1.0-sections.txt
+++ b/Source/WebKit/WebProcess/InjectedBundle/API/wpe/docs/wpe-webextensions-1.0-sections.txt
@@ -76,6 +76,7 @@
 <SECTION>
 <FILE>WebKitFrame</FILE>
 WebKitFrame
+webkit_frame_get_id
 webkit_frame_is_main_frame
 webkit_frame_get_uri
 webkit_frame_get_js_context
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 3694911..cef2eaa 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,5 +1,27 @@
 2019-05-10  Michael Catanzaro  <mcatanzaro@igalia.com>
 
+        [WPE][GTK] Add webkit_frame_get_id() API
+        https://bugs.webkit.org/show_bug.cgi?id=197270
+
+        Reviewed by Carlos Garcia Campos.
+
+        This was hard, but I added a test to verify that two different WebKitFrames of the same
+        WebKitWebPage return two different frame IDs.
+
+        * TestWebKitAPI/Tests/WebKitGLib/FrameTest.cpp:
+        (WebKitFrameTest::willSubmitFormCallback):
+        (WebKitFrameTest::testSubframe):
+        (registerTests):
+        * TestWebKitAPI/Tests/WebKitGLib/TestFrame.cpp:
+        (testWebKitFrameSubframe):
+        (beforeAll):
+        * TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp:
+        (willSubmitFormCallback):
+        * TestWebKitAPI/Tests/WebKitGLib/resources/form-in-frame.html: Added.
+        * TestWebKitAPI/Tests/WebKitGLib/resources/webkitglib-tests.gresource.xml:
+
+2019-05-10  Michael Catanzaro  <mcatanzaro@igalia.com>
+
         [WPE][GTK] Add WebKitWebPage::did-associate-form-controls-for-frame and deprecate original did-associate-form-controls
         https://bugs.webkit.org/show_bug.cgi?id=197271
 
diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/FrameTest.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/FrameTest.cpp
index 2e67c0a..980215b7 100644
--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/FrameTest.cpp
+++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/FrameTest.cpp
@@ -131,6 +131,49 @@
         return true;
     }
 
+    static void willSubmitFormCallback(WebKitWebPage* page, WebKitDOMElement*, WebKitFormSubmissionStep, WebKitFrame* sourceFrame, WebKitFrame*, GPtrArray*, GPtrArray*, gpointer userData)
+    {
+        // The form is submitted from a subframe. It should have a different ID than the main frame.
+        WebKitFrame* mainFrame = webkit_web_page_get_main_frame(page);
+        g_assert_cmpuint(webkit_frame_get_id(mainFrame), !=, webkit_frame_get_id(sourceFrame));
+
+        auto* test = static_cast<WebKitFrameTest*>(userData);
+        g_main_loop_quit(test->m_mainLoop.get());
+    }
+
+    bool testSubframe(WebKitWebPage* page)
+    {
+        WebKitFrame* mainFrame = webkit_web_page_get_main_frame(page);
+        g_assert_true(WEBKIT_IS_FRAME(mainFrame));
+
+        GRefPtr<JSCContext> jsContext = adoptGRef(webkit_frame_get_js_context(mainFrame));
+        g_assert_true(JSC_IS_CONTEXT(jsContext.get()));
+        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(jsContext.get()));
+
+        GRefPtr<JSCValue> jsParentDocument = adoptGRef(jsc_context_get_value(jsContext.get(), "document"));
+        g_assert_true(JSC_IS_VALUE(jsParentDocument.get()));
+        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(jsParentDocument.get()));
+
+        GRefPtr<JSCValue> subframe = adoptGRef(jsc_value_object_invoke_method(jsParentDocument.get(), "getElementById", G_TYPE_STRING, "frame", G_TYPE_NONE));
+        g_assert_true(JSC_IS_VALUE(subframe.get()));
+        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(subframe.get()));
+
+        GRefPtr<JSCValue> contentWindow = adoptGRef(jsc_value_object_get_property(subframe.get(), "contentWindow"));
+        g_assert_true(JSC_IS_VALUE(contentWindow.get()));
+        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(contentWindow.get()));
+
+        GRefPtr<JSCValue> undefined = adoptGRef(jsc_value_object_invoke_method(contentWindow.get(), "postMessage", G_TYPE_STRING, "submit the form!", G_TYPE_STRING, "*", G_TYPE_NONE));
+        g_assert_true(JSC_IS_VALUE(undefined.get()));
+        g_assert_true(jsc_value_is_undefined(undefined.get()));
+
+        g_signal_connect(page, "will-submit-form", reinterpret_cast<GCallback>(willSubmitFormCallback), this);
+
+        m_mainLoop = adoptGRef(g_main_loop_new(nullptr, FALSE));
+        g_main_loop_run(m_mainLoop.get());
+
+        return true;
+    }
+
     bool runTest(const char* testName, WebKitWebPage* page) override
     {
         if (!strcmp(testName, "main-frame"))
@@ -141,10 +184,14 @@
             return testJavaScriptContext(page);
         if (!strcmp(testName, "javascript-values"))
             return testJavaScriptValues(page);
+        if (!strcmp(testName, "subframe"))
+            return testSubframe(page);
 
         g_assert_not_reached();
         return false;
     }
+
+    GRefPtr<GMainLoop> m_mainLoop;
 };
 
 static void __attribute__((constructor)) registerTests()
@@ -153,4 +200,5 @@
     REGISTER_TEST(WebKitFrameTest, "WebKitFrame/uri");
     REGISTER_TEST(WebKitFrameTest, "WebKitFrame/javascript-context");
     REGISTER_TEST(WebKitFrameTest, "WebKitFrame/javascript-values");
+    REGISTER_TEST(WebKitFrameTest, "WebKitFrame/subframe");
 }
diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestFrame.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestFrame.cpp
index f6d297f..65dcd92 100644
--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/TestFrame.cpp
+++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/TestFrame.cpp
@@ -42,12 +42,19 @@
     g_assert_true(test->runWebProcessTest("WebKitFrame", "javascript-values", testHTML));
 }
 
+static void testWebKitFrameSubframe(WebViewTest* test, gconstpointer)
+{
+    static const char* testHTML = "<html><body><iframe src='resource:///org/webkit/glib/tests/form-in-frame.html' id='frame'></iframe></body></html>";
+    g_assert_true(test->runWebProcessTest("WebKitFrame", "subframe", testHTML));
+}
+
 void beforeAll()
 {
     WebViewTest::add("WebKitFrame", "main-frame", testWebKitFrameMainFrame);
     WebViewTest::add("WebKitFrame", "uri", testWebKitFrameURI);
     WebViewTest::add("WebKitFrame", "javascript-context", testWebKitFrameJavaScriptContext);
     WebViewTest::add("WebKitFrame", "javascript-values", testWebKitFrameJavaScriptValues);
+    WebViewTest::add("WebKitFrame", "subframe", testWebKitFrameSubframe);
 }
 
 void afterAll()
diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp b/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp
index 1a56584..6bdad47 100644
--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp
+++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp
@@ -386,7 +386,7 @@
     g_assert_true(WEBKIT_DOM_IS_HTML_FORM_ELEMENT(formElement));
     G_GNUC_END_IGNORE_DEPRECATIONS;
 #endif
-    GRefPtr<JSCValue> jsFormElement = adoptGRef(webkit_frame_get_js_value_for_dom_object(webkit_web_page_get_main_frame(webPage), WEBKIT_DOM_OBJECT(formElement)));
+    GRefPtr<JSCValue> jsFormElement = adoptGRef(webkit_frame_get_js_value_for_dom_object(sourceFrame, WEBKIT_DOM_OBJECT(formElement)));
     g_assert_true(JSC_IS_VALUE(jsFormElement.get()));
     g_assert_true(jsc_value_is_object(jsFormElement.get()));
     g_assert_true(jsc_value_object_is_instance_of(jsFormElement.get(), "HTMLFormElement"));
diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/resources/form-in-frame.html b/Tools/TestWebKitAPI/Tests/WebKitGLib/resources/form-in-frame.html
new file mode 100644
index 0000000..0ec7d16
--- /dev/null
+++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/resources/form-in-frame.html
@@ -0,0 +1,8 @@
+<form id='form'>
+</form>
+<script>
+    window.addEventListener('message', event => {
+        if (event.data === 'submit the form!')
+            document.getElementById('form').submit();
+    }, false);
+</script>
diff --git a/Tools/TestWebKitAPI/Tests/WebKitGLib/resources/webkitglib-tests.gresource.xml b/Tools/TestWebKitAPI/Tests/WebKitGLib/resources/webkitglib-tests.gresource.xml
index ee571d7..ae642a7 100644
--- a/Tools/TestWebKitAPI/Tests/WebKitGLib/resources/webkitglib-tests.gresource.xml
+++ b/Tools/TestWebKitAPI/Tests/WebKitGLib/resources/webkitglib-tests.gresource.xml
@@ -2,6 +2,7 @@
 <gresources>
   <gresource prefix="/org/webkit/glib/tests/">
     <file alias="boring.html">Tools/TestWebKitAPI/Tests/WebKitGLib/resources/boring.html</file>
+    <file alias="form-in-frame.html">Tools/TestWebKitAPI/Tests/WebKitGLib/resources/form-in-frame.html</file>
     <file alias="link-title.js">Tools/TestWebKitAPI/Tests/WebKitGLib/resources/link-title.js</file>
   </gresource>
 </gresources>