Changeset 226366 in webkit
- Timestamp:
- Jan 3, 2018 10:36:24 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r226354 r226366 1 2018-01-03 Michael Catanzaro <mcatanzaro@igalia.com> 2 3 [GTK] Add web process API to detect when form is submitted via JavaScript 4 https://bugs.webkit.org/show_bug.cgi?id=173915 5 6 Reviewed by Carlos Garcia Campos. 7 8 Epiphany relies on the DOM submit event to detect when a form has been submitted. However, 9 for historical reasons, the submit event is not emitted when a form is submitted by 10 JavaScript. It is therefore not currently possible for a web browser to reliably detect form 11 submission and not possible to implement a robust password storage feature. In order to 12 avoid this problem, this patch adds a new WebKitWebPage signal, will-submit-form, that 13 browsers can use in preference to a DOM event listener. 14 15 Unfortunately, this signal is not available for WPE because it depends on the DOM API. 16 17 There are two submission events, WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT and 18 WEBKIT_FORM_SUBMISSION_WILL_COMPLETE. WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT 19 occurs earlier than WEBKIT_FORM_SUBMISSION_WILL_COMPLETE and can be used to retrieve form 20 values before websites receive the DOM submit event. This is useful as some websites like 21 to delete form values right before a submit would normally happen in order to attempt to 22 defeat browser password managers. There are two tricks to note: JavaScript can cancel form 23 submission immediately after this event occurs (by returning false in an onsubmit handler), 24 and, for historical reasons, this event will not occur at all when form submission is 25 triggered by JavaScript. WEBKIT_FORM_SUBMISSION_WILL_COMPLETE occurs next, and is more 26 straightforward: it is always emitted when a form is about to be submitted, when it is too 27 late to cancel. 28 29 The recommended way to reliably retrieve password form values would be to watch for both 30 events, use the form value detected in WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT 31 if that event is emitted, and use the value detected later in 32 WEBKIT_FORM_SUBMISSION_WILL_COMPLETE otherwise. 33 34 Since one of the signal arguments is an enum, we now have to run glib-mkenums for the web 35 process API. And that has resulted in this patch also adding GType goo for 36 WebKitConsoleMessageLevel and WebKitConsoleMessageSource that was previously missing. Any 37 applications that for some unlikely reason want to use these enums in properties or signals 38 will be happy. 39 40 * PlatformGTK.cmake: 41 * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt: 42 * WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp: 43 (webkit_web_page_class_init): 44 * WebProcess/InjectedBundle/API/gtk/WebKitWebPage.h: 45 * WebProcess/InjectedBundle/API/gtk/WebKitWebProcessEnumTypes.cpp.template: Added. 46 * WebProcess/InjectedBundle/API/gtk/WebKitWebProcessEnumTypes.h.template: Added. 47 1 48 2018-01-03 Carlos Garcia Campos <cgarcia@igalia.com> 2 49 -
trunk/Source/WebKit/PlatformGTK.cmake
r226268 r226366 426 426 427 427 ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitEnumTypes.cpp 428 ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitWebProcessEnumTypes.cpp 428 429 ) 429 430 … … 500 501 501 502 set(WebKit2WebExtension_INSTALLED_HEADERS 503 ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitWebProcessEnumTypes.h 502 504 ${WEBKIT_DIR}/WebProcess/InjectedBundle/API/gtk/WebKitConsoleMessage.h 503 505 ${WEBKIT_DIR}/WebProcess/InjectedBundle/API/gtk/WebKitFrame.h … … 850 852 851 853 COMMAND glib-mkenums --template ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitEnumTypes.cpp.template ${WebKit2GTK_ENUM_GENERATION_HEADERS} | sed s/web_kit/webkit/ > ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitEnumTypes.cpp 852 VERBATIM) 854 VERBATIM 855 ) 856 857 set(WebKit2GTK_WEB_PROCESS_ENUM_GENERATION_HEADERS ${WebKit2WebExtension_INSTALLED_HEADERS}) 858 list(REMOVE_ITEM WebKit2GTK_WEB_PROCESS_ENUM_GENERATION_HEADERS ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitWebProcessEnumTypes.h) 859 add_custom_command( 860 OUTPUT ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitWebProcessEnumTypes.h 861 ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitWebProcessEnumTypes.cpp 862 DEPENDS ${WebKit2GTK_WEB_PROCESS_ENUM_GENERATION_HEADERS} 863 864 COMMAND glib-mkenums --template ${WEBKIT_DIR}/WebProcess/InjectedBundle/API/gtk/WebKitWebProcessEnumTypes.h.template ${WebKit2GTK_WEB_PROCESS_ENUM_GENERATION_HEADERS} | sed s/web_kit/webkit/ | sed s/WEBKIT_TYPE_KIT/WEBKIT_TYPE/ > ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitWebProcessEnumTypes.h 865 866 COMMAND glib-mkenums --template ${WEBKIT_DIR}/WebProcess/InjectedBundle/API/gtk/WebKitWebProcessEnumTypes.cpp.template ${WebKit2GTK_WEB_PROCESS_ENUM_GENERATION_HEADERS} | sed s/web_kit/webkit/ > ${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}/WebKitWebProcessEnumTypes.cpp 867 VERBATIM 868 ) 853 869 854 870 WEBKIT_BUILD_INSPECTOR_GRESOURCES(${DERIVED_SOURCES_WEBKIT2GTK_DIR}) … … 1053 1069 "${FORWARDING_HEADERS_DIR}" 1054 1070 "${FORWARDING_HEADERS_WEBKIT2GTK_DIR}" 1071 "${DERIVED_SOURCES_WEBKIT2GTK_API_DIR}" 1055 1072 ) 1056 1073 -
trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt
r226264 r226366 1439 1439 <FILE>WebKitWebPage</FILE> 1440 1440 WebKitWebPage 1441 WebKitFormSubmissionStep 1441 1442 webkit_web_page_get_dom_document 1442 1443 webkit_web_page_get_id … … 1453 1454 WEBKIT_IS_WEB_PAGE_CLASS 1454 1455 WEBKIT_WEB_PAGE_GET_CLASS 1456 WEBKIT_TYPE_FORM_SUBMISSION_STEP 1455 1457 1456 1458 <SUBSECTION Private> 1457 1459 WebKitWebPagePrivate 1458 1460 webkit_web_page_get_type 1461 webkit_form_submission_step_get_type 1459 1462 </SECTION> 1460 1463 … … 1554 1557 <SUBSECTION Standard> 1555 1558 WEBKIT_TYPE_CONSOLE_MESSAGE 1559 WEBKIT_TYPE_CONSOLE_MESSAGE_LEVEL 1560 WEBKIT_TYPE_CONSOLE_MESSAGE_SOURCE 1556 1561 1557 1562 <SUBSECTION Private> 1558 1563 webkit_console_message_get_type 1564 webkit_console_message_level_get_type 1565 webkit_console_message_source_get_type 1559 1566 </SECTION> 1560 1567 -
trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp
r223953 r226366 58 58 #include "WebKitDOMDocumentPrivate.h" 59 59 #include "WebKitDOMElementPrivate.h" 60 #include "WebKitDOMHTMLFormElementPrivate.h" 60 61 #include "WebKitWebHitTestResultPrivate.h" 62 #include "WebKitWebProcessEnumTypes.h" 61 63 #endif 62 64 … … 73 75 #if PLATFORM(GTK) 74 76 FORM_CONTROLS_ASSOCIATED, 77 WILL_SUBMIT_FORM, 75 78 #endif 76 79 … … 381 384 } 382 385 386 void willSubmitForm(WebPage*, HTMLFormElement* formElement, WebFrame* frame, WebFrame* sourceFrame, const Vector<std::pair<String, String>>& values, RefPtr<API::Object>&) override 387 { 388 fireFormSubmissionEvent(WEBKIT_FORM_SUBMISSION_WILL_COMPLETE, formElement, frame, sourceFrame, values); 389 } 390 391 void willSendSubmitEvent(WebPage*, HTMLFormElement* formElement, WebFrame* frame, WebFrame* sourceFrame, const Vector<std::pair<String, String>>& values) override 392 { 393 fireFormSubmissionEvent(WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT, formElement, frame, sourceFrame, values); 394 } 395 383 396 void didAssociateFormControls(WebPage*, const Vector<RefPtr<Element>>& elements) override 384 397 { … … 393 406 394 407 private: 408 void fireFormSubmissionEvent(WebKitFormSubmissionStep step, HTMLFormElement* formElement, WebFrame* frame, WebFrame* sourceFrame, const Vector<std::pair<String, String>>& values) 409 { 410 WebKitFrame* webkitTargetFrame = webkitFrameGetOrCreate(frame); 411 WebKitFrame* webkitSourceFrame = webkitFrameGetOrCreate(sourceFrame); 412 413 GRefPtr<GPtrArray> textFieldNames = adoptGRef(g_ptr_array_new_full(values.size(), g_free)); 414 GRefPtr<GPtrArray> textFieldValues = adoptGRef(g_ptr_array_new_full(values.size(), g_free)); 415 for (auto& pair : values) { 416 g_ptr_array_add(textFieldNames.get(), g_strdup(pair.first.utf8().data())); 417 g_ptr_array_add(textFieldValues.get(), g_strdup(pair.second.utf8().data())); 418 } 419 420 g_signal_emit(m_webPage, signals[WILL_SUBMIT_FORM], 0, WebKit::kit(formElement), step, webkitSourceFrame, webkitTargetFrame, textFieldNames.get(), textFieldValues.get()); 421 } 422 395 423 WebKitWebPage* m_webPage; 396 424 }; … … 559 587 g_cclosure_marshal_VOID__BOXED, 560 588 G_TYPE_NONE, 1, 589 G_TYPE_PTR_ARRAY); 590 591 /** 592 * WebKitWebPage::will-submit-form: 593 * @web_page: the #WebKitWebPage on which the signal is emitted 594 * @form: the #WebKitDOMHTMLFormElement to be submitted 595 * @step: a #WebKitFormSubmissionEventType indicating the current 596 * stage of form submission 597 * @source_frame: the #WebKitFrame containing the form to be 598 * submitted 599 * @target_frame: the #WebKitFrame containing the form's target, 600 * which may be the same as @source_frame if no target was specified 601 * @text_field_names: (element-type utf8) (transfer none): names of 602 * the form's text fields 603 * @text_field_values: (element-type utf8) (transfer none): values 604 * of the form's text fields 605 * 606 * This signal is emitted to indicate various points during form 607 * submission. @step indicates the current stage of form submission. 608 * 609 * If this signal is emitted with %WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT, 610 * then the DOM submit event is about to be emitted. JavaScript code 611 * may rely on the submit event to detect that the user has clicked 612 * on a submit button, and to possibly cancel the form submission 613 * before %WEBKIT_FORM_SUBMISSION_WILL_COMPLETE. However, beware 614 * that, for historical reasons, the submit event is not emitted at 615 * all if the form submission is triggered by JavaScript. For these 616 * reasons, %WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT may not 617 * be used to reliably detect whether a form will be submitted. 618 * Instead, use it to detect if a user has clicked on a form's 619 * submit button even if JavaScript later cancels the form 620 * submission, or to read the values of the form's fields even if 621 * JavaScript later clears certain fields before submitting. This 622 * may be needed, for example, to implement a robust browser 623 * password manager, as some misguided websites may use such 624 * techniques to attempt to thwart password managers. 625 * 626 * If this signal is emitted with %WEBKIT_FORM_SUBMISSION_WILL_COMPLETE, 627 * the form will imminently be submitted. It can no longer be 628 * cancelled. This event always occurs immediately before a form is 629 * submitted to its target, so use this event to reliably detect 630 * when a form is submitted. This event occurs after 631 * %WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT if that event is 632 * emitted. 633 * 634 * Since: 2.20 635 */ 636 signals[WILL_SUBMIT_FORM] = g_signal_new( 637 "will-submit-form", 638 G_TYPE_FROM_CLASS(klass), 639 G_SIGNAL_RUN_LAST, 640 0, 0, nullptr, 641 g_cclosure_marshal_generic, 642 G_TYPE_NONE, 6, 643 WEBKIT_DOM_TYPE_HTML_FORM_ELEMENT, 644 WEBKIT_TYPE_FORM_SUBMISSION_STEP, 645 WEBKIT_TYPE_FRAME, 646 WEBKIT_TYPE_FRAME, 647 G_TYPE_PTR_ARRAY, 561 648 G_TYPE_PTR_ARRAY); 562 649 #endif -
trunk/Source/WebKit/WebProcess/InjectedBundle/API/gtk/WebKitWebPage.h
r187024 r226366 47 47 typedef struct _WebKitWebEditor WebKitWebEditor; 48 48 49 /** 50 * WebKitFormSubmissionStep: 51 * @WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT: indicates the form's 52 * DOM submit event is about to be emitted. 53 * @WEBKIT_FORM_SUBMISSION_WILL_COMPLETE: indicates the form is about 54 * to be submitted. 55 * 56 * Used to indicate a particular stage in form submission. See 57 * #WebKitWebPage::will-submit-form. 58 * 59 * Since: 2.20 60 */ 61 typedef enum { 62 WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT, 63 WEBKIT_FORM_SUBMISSION_WILL_COMPLETE, 64 } WebKitFormSubmissionStep; 65 49 66 struct _WebKitWebPage { 50 67 GObject parent; -
trunk/Tools/ChangeLog
r226365 r226366 1 2018-01-03 Michael Catanzaro <mcatanzaro@igalia.com> 2 3 [GTK] Add web process API to detect when form is submitted via JavaScript 4 https://bugs.webkit.org/show_bug.cgi?id=173915 5 6 Reviewed by Carlos Garcia Campos. 7 8 Test it. 9 10 * TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp: 11 (FormSubmissionTest::FormSubmissionTest): 12 (FormSubmissionTest::~FormSubmissionTest): 13 (FormSubmissionTest::testFormSubmissionResult): 14 (FormSubmissionTest::willSendDOMEventCallback): 15 (FormSubmissionTest::willCompleteCallback): 16 (FormSubmissionTest::runJavaScriptAndWaitUntilFormSubmitted): 17 (testWebExtensionFormSubmissionSteps): 18 (beforeAll): 19 * TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp: 20 (DelayedSignal::DelayedSignal): 21 (emitFormSubmissionEvent): 22 (handleFormSubmissionCallback): 23 (willSubmitFormCallback): 24 (pageCreatedCallback): 25 1 26 2018-01-03 Michael Catanzaro <mcatanzaro@igalia.com> 2 27 -
trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp
r226326 r226366 31 31 #define FORM2_ID "form2-id" 32 32 33 #define FORM_SUBMISSION_TEST_ID "form-submission-test-id" 34 33 35 #if PLATFORM(GTK) 34 36 static void testWebExtensionGetTitle(WebViewTest* test, gconstpointer) … … 278 280 g_dbus_connection_signal_unsubscribe(connection, id); 279 281 } 282 283 class FormSubmissionTest : public WebViewTest { 284 public: 285 MAKE_GLIB_TEST_FIXTURE(FormSubmissionTest); 286 287 FormSubmissionTest() 288 { 289 GUniquePtr<char> extensionBusName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", s_webExtensionID)); 290 m_proxy = adoptGRef(bus->createProxy(extensionBusName.get(), 291 "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", m_mainLoop)); 292 GDBusConnection* connection = g_dbus_proxy_get_connection(m_proxy.get()); 293 294 m_willSendDOMEventCallbackID = g_dbus_connection_signal_subscribe(connection, 295 nullptr, 296 "org.webkit.gtk.WebExtensionTest", 297 "FormSubmissionWillSendDOMEvent", 298 "/org/webkit/gtk/WebExtensionTest", 299 nullptr, 300 G_DBUS_SIGNAL_FLAGS_NONE, 301 reinterpret_cast<GDBusSignalCallback>(willSendDOMEventCallback), 302 this, 303 nullptr); 304 g_assert(m_willSendDOMEventCallbackID); 305 306 m_willCompleteCallbackID = g_dbus_connection_signal_subscribe(connection, 307 nullptr, 308 "org.webkit.gtk.WebExtensionTest", 309 "FormSubmissionWillComplete", 310 "/org/webkit/gtk/WebExtensionTest", 311 nullptr, 312 G_DBUS_SIGNAL_FLAGS_NONE, 313 reinterpret_cast<GDBusSignalCallback>(willCompleteCallback), 314 this, 315 nullptr); 316 g_assert(m_willCompleteCallbackID); 317 } 318 319 ~FormSubmissionTest() 320 { 321 GDBusConnection* connection = g_dbus_proxy_get_connection(m_proxy.get()); 322 g_dbus_connection_signal_unsubscribe(connection, m_willSendDOMEventCallbackID); 323 g_dbus_connection_signal_unsubscribe(connection, m_willCompleteCallbackID); 324 } 325 326 static void testFormSubmissionResult(GVariant* result) 327 { 328 const char* formID; 329 const char* concatenatedTextFieldNames; 330 const char* concatenatedTextFieldValues; 331 gboolean targetFrameIsMainFrame; 332 gboolean sourceFrameIsMainFrame; 333 g_variant_get(result, "(&s&s&sbb)", &formID, &concatenatedTextFieldNames, &concatenatedTextFieldValues, &targetFrameIsMainFrame, &sourceFrameIsMainFrame); 334 335 g_assert_cmpstr(formID, ==, FORM_SUBMISSION_TEST_ID); 336 g_assert_cmpstr(concatenatedTextFieldNames, ==, "foo,bar,"); 337 g_assert_cmpstr(concatenatedTextFieldValues, ==, "first,second,"); 338 g_assert(!targetFrameIsMainFrame); 339 g_assert(sourceFrameIsMainFrame); 340 } 341 342 static void willSendDOMEventCallback(GDBusConnection*, const char*, const char*, const char*, const char*, GVariant* result, FormSubmissionTest* test) 343 { 344 test->m_willSendDOMEventCallbackExecuted = true; 345 testFormSubmissionResult(result); 346 } 347 348 static void willCompleteCallback(GDBusConnection*, const char*, const char*, const char*, const char*, GVariant* result, FormSubmissionTest* test) 349 { 350 test->m_willCompleteCallbackExecuted = true; 351 testFormSubmissionResult(result); 352 test->quitMainLoop(); 353 } 354 355 void runJavaScriptAndWaitUntilFormSubmitted(const char* js) 356 { 357 webkit_web_view_run_javascript(m_webView, js, nullptr, nullptr, nullptr); 358 g_main_loop_run(m_mainLoop); 359 } 360 361 GRefPtr<GDBusProxy> m_proxy; 362 guint m_willSendDOMEventCallbackID { 0 }; 363 guint m_willCompleteCallbackID { 0 }; 364 bool m_willSendDOMEventCallbackExecuted { false }; 365 bool m_willCompleteCallbackExecuted { false }; 366 }; 367 368 static void testWebExtensionFormSubmissionSteps(FormSubmissionTest* test, gconstpointer) 369 { 370 test->loadHtml("<form id=\"" FORM_SUBMISSION_TEST_ID "\" target=\"target_frame\">" 371 "<input type=\"text\" name=\"foo\" value=\"first\">" 372 "<input type=\"text\" name=\"bar\" value=\"second\">" 373 "<input type=\"submit\" id=\"submit_button\">" 374 "</form>" 375 "<iframe name=\"target_frame\"></iframe>", nullptr); 376 test->waitUntilLoadFinished(); 377 378 static const char* submitFormScript = 379 "var form = document.getElementById(\"" FORM_SUBMISSION_TEST_ID "\");" 380 "form.submit();"; 381 test->runJavaScriptAndWaitUntilFormSubmitted(submitFormScript); 382 // Submit must not be emitted when the form is submitted via JS. 383 // https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit 384 g_assert(!test->m_willSendDOMEventCallbackExecuted); 385 g_assert(test->m_willCompleteCallbackExecuted); 386 test->m_willCompleteCallbackExecuted = false; 387 388 static const char* manuallySubmitFormScript = 389 "var button = document.getElementById(\"submit_button\");" 390 "button.click();"; 391 test->runJavaScriptAndWaitUntilFormSubmitted(manuallySubmitFormScript); 392 g_assert(test->m_willSendDOMEventCallbackExecuted); 393 g_assert(test->m_willCompleteCallbackExecuted); 394 test->m_willSendDOMEventCallbackExecuted = false; 395 test->m_willCompleteCallbackExecuted = false; 396 397 test->loadHtml("<form id=\"" FORM_SUBMISSION_TEST_ID "\" target=\"target_frame\">" 398 "</form>" 399 "<iframe name=\"target_frame\"></iframe>", nullptr); 400 test->waitUntilLoadFinished(); 401 } 280 402 #endif // PLATFORM(GTK) 281 403 … … 297 419 WebViewTest::add("WebKitWebView", "install-missing-plugins-permission-request", testInstallMissingPluginsPermissionRequest); 298 420 WebViewTest::add("WebKitWebExtension", "form-controls-associated-signal", testWebExtensionFormControlsAssociated); 421 FormSubmissionTest::add("WebKitWebExtension", "form-submission-steps", testWebExtensionFormSubmissionSteps); 299 422 #endif 300 423 } -
trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp
r220403 r226366 62 62 " <arg type='s' name='formIds' direction='out'/>" 63 63 " </signal>" 64 " <signal name='FormSubmissionWillSendDOMEvent'>" 65 " <arg type='s' name='formID' direction='out'/>" 66 " <arg type='s' name='textFieldNames' direction='out'/>" 67 " <arg type='s' name='textFieldValues' direction='out'/>" 68 " <arg type='b' name='targetFrameIsMainFrame' direction='out'/>" 69 " <arg type='b' name='sourceFrameIsMainFrame' direction='out'/>" 70 " </signal>" 71 " <signal name='FormSubmissionWillComplete'>" 72 " <arg type='s' name='formID' direction='out'/>" 73 " <arg type='s' name='textFieldNames' direction='out'/>" 74 " <arg type='s' name='textFieldValues' direction='out'/>" 75 " <arg type='b' name='targetFrameIsMainFrame' direction='out'/>" 76 " <arg type='b' name='sourceFrameIsMainFrame' direction='out'/>" 77 " </signal>" 64 78 " <signal name='URIChanged'>" 65 79 " <arg type='s' name='uri' direction='out'/>" … … 72 86 DocumentLoadedSignal, 73 87 URIChangedSignal, 88 #if PLATFORM(GTK) 74 89 FormControlsAssociatedSignal, 90 FormSubmissionWillSendDOMEventSignal, 91 FormSubmissionWillCompleteSignal, 92 #endif 75 93 } DelayedSignalType; 76 94 77 95 struct DelayedSignal { 78 DelayedSignal(DelayedSignalType type)96 explicit DelayedSignal(DelayedSignalType type) 79 97 : type(type) 80 98 { … … 87 105 } 88 106 107 DelayedSignal(DelayedSignalType type, const char* str, const char* str2, const char* str3, gboolean b, gboolean b2) 108 : type(type) 109 , str(str) 110 , str2(str2) 111 , str3(str3) 112 , b(b) 113 , b2(b2) 114 { 115 } 116 89 117 DelayedSignalType type; 90 118 CString str; 119 CString str2; 120 CString str3; 121 gboolean b; 122 gboolean b2; 91 123 }; 92 124 … … 309 341 delayedSignalsQueue.append(DelayedSignal(FormControlsAssociatedSignal, formIds.get())); 310 342 } 343 344 static void emitFormSubmissionEvent(GDBusConnection* connection, const char* methodName, const char* formID, const char* names, const char* values, gboolean targetFrameIsMainFrame, gboolean sourceFrameIsMainFrame) 345 { 346 bool ok = g_dbus_connection_emit_signal( 347 connection, 348 nullptr, 349 "/org/webkit/gtk/WebExtensionTest", 350 "org.webkit.gtk.WebExtensionTest", 351 methodName, 352 g_variant_new("(sssbb)", formID, names, values, targetFrameIsMainFrame, sourceFrameIsMainFrame), 353 nullptr); 354 g_assert(ok); 355 } 356 357 static void handleFormSubmissionCallback(WebKitWebPage* webPage, DelayedSignalType delayedSignalType, const char* methodName, WebKitDOMHTMLFormElement* formElement, WebKitFrame* sourceFrame, WebKitFrame* targetFrame, GPtrArray* textFieldNames, GPtrArray* textFieldValues, WebKitWebExtension* extension) 358 { 359 GString* namesBuilder = g_string_new(nullptr); 360 for (guint i = 0; i < textFieldNames->len; ++i) { 361 auto* name = static_cast<char*>(g_ptr_array_index(textFieldNames, i)); 362 g_string_append(namesBuilder, name); 363 g_string_append_c(namesBuilder, ','); 364 } 365 GUniquePtr<char> names(g_string_free(namesBuilder, FALSE)); 366 367 GString* valuesBuilder = g_string_new(nullptr); 368 for (guint i = 0; i < textFieldValues->len; ++i) { 369 auto* value = static_cast<char*>(g_ptr_array_index(textFieldValues, i)); 370 g_string_append(valuesBuilder, value); 371 g_string_append_c(valuesBuilder, ','); 372 } 373 GUniquePtr<char> values(g_string_free(valuesBuilder, FALSE)); 374 375 gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection"); 376 if (data) 377 emitFormSubmissionEvent(G_DBUS_CONNECTION(data), methodName, webkit_dom_element_get_id(WEBKIT_DOM_ELEMENT(formElement)), names.get(), values.get(), webkit_frame_is_main_frame(targetFrame), webkit_frame_is_main_frame(sourceFrame)); 378 else 379 delayedSignalsQueue.append(DelayedSignal(delayedSignalType, webkit_dom_element_get_id(WEBKIT_DOM_ELEMENT(formElement)), names.get(), values.get(), webkit_frame_is_main_frame(targetFrame), webkit_frame_is_main_frame(sourceFrame))); 380 } 381 382 static void willSubmitFormCallback(WebKitWebPage* webPage, WebKitDOMHTMLFormElement* formElement, WebKitFormSubmissionStep step, WebKitFrame* sourceFrame, WebKitFrame* targetFrame, GPtrArray* textFieldNames, GPtrArray* textFieldValues, WebKitWebExtension* extension) 383 { 384 switch (step) { 385 case WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT: 386 handleFormSubmissionCallback(webPage, FormSubmissionWillSendDOMEventSignal, "FormSubmissionWillSendDOMEvent", formElement, sourceFrame, targetFrame, textFieldNames, textFieldValues, extension); 387 break; 388 case WEBKIT_FORM_SUBMISSION_WILL_COMPLETE: 389 handleFormSubmissionCallback(webPage, FormSubmissionWillCompleteSignal, "FormSubmissionWillComplete", formElement, sourceFrame, targetFrame, textFieldNames, textFieldValues, extension); 390 break; 391 default: 392 g_assert_not_reached(); 393 } 394 } 311 395 #endif 312 396 … … 320 404 g_signal_connect(webPage, "context-menu", G_CALLBACK(contextMenuCallback), nullptr); 321 405 g_signal_connect(webPage, "form-controls-associated", G_CALLBACK(formControlsAssociatedCallback), extension); 406 g_signal_connect(webPage, "will-submit-form", G_CALLBACK(willSubmitFormCallback), extension); 322 407 #endif 323 408 } … … 446 531 emitURIChanged(connection, delayedSignal.str.data()); 447 532 break; 533 #if PLATFORM(GTK) 448 534 case FormControlsAssociatedSignal: 449 #if PLATFORM(GTK)450 535 emitFormControlsAssociated(connection, delayedSignal.str.data()); 451 #elif PLATFORM(WPE) 536 break; 537 case FormSubmissionWillCompleteSignal: 538 emitFormSubmissionEvent(connection, "FormSubmissionWillComplete", delayedSignal.str.data(), delayedSignal.str2.data(), delayedSignal.str3.data(), delayedSignal.b, delayedSignal.b2); 539 break; 540 case FormSubmissionWillSendDOMEventSignal: 541 emitFormSubmissionEvent(connection, "FormSubmissionWillSendDOMEvent", delayedSignal.str.data(), delayedSignal.str2.data(), delayedSignal.str3.data(), delayedSignal.b, delayedSignal.b2); 542 break; 543 #endif 452 544 g_assert_not_reached(); 453 #endif454 break;455 545 } 456 546 }
Note: See TracChangeset
for help on using the changeset viewer.