Title: [258873] trunk
Revision
258873
Author
[email protected]
Date
2020-03-23 14:00:01 -0700 (Mon, 23 Mar 2020)

Log Message

Support inserting text or dictation alternative by simulating keyboard input
https://bugs.webkit.org/show_bug.cgi?id=209380
<rdar://problem/59445102>

Reviewed by Darin Adler.

Source/WebKit:

As a workaround for sites the implement their own editing system (e.g. facebook.com)
add a new insertion option that makes the insertion having a passing resemblance
of a person typing. The resemblance is achieved by dispatching DOM events with type
"keydown", "keyup", and "change".

* Shared/Cocoa/InsertTextOptions.cpp:
(IPC::ArgumentCoder<WebKit::InsertTextOptions>::encode):
(IPC::ArgumentCoder<WebKit::InsertTextOptions>::decode):
Encode and decode the new option.

* Shared/Cocoa/InsertTextOptions.h: Default the new option, shouldSimulateKeyboardInput,
to false to keep our current behavior.
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _shouldSimulateKeyboardInputOnTextInsertion]): Added. Returns NO when
building without USE(TEXT_INTERACTION_ADDITIONS) to keep the current behavior.

(-[WKContentView insertText:]):
(-[WKContentView insertText:alternatives:style:]):
Set the shouldSimulateKeyboardInput option.

* WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
(WebKit::WebPage::insertDictatedTextAsync):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::insertTextAsync):
If shouldSimulateKeyboardInput is false then do what we do now. Otherwise, dispatch a DOM event
of type "keydown" and perform the insertion. Then dispatch DOM events of type "keyup" and "change".

Tools:

Add tests to ensure that DOM events are dispatched on insertion when shouldSimulateKeyboardInput
is enabled.

I also added a convenience assertion function, EXPECT_NS_EQUAL, that can
compare NSObjects so long as they implement -isEqual and -description. I
make use of this to compare the actual array of fired DOM events types to
an expected array.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm:
(TestWebKitAPI::shouldSimulateKeyboardInputOnTextInsertionOverride):
(TestWebKitAPI::TEST):
* TestWebKitAPI/cocoa/TestCocoa.h:
(TestWebKitAPI::Util::assertNSObjectsAreEqual): Added.
(EXPECT_NS_EQUAL): Added.
* TestWebKitAPI/ios/insert-text.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (258872 => 258873)


--- trunk/Source/WebKit/ChangeLog	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Source/WebKit/ChangeLog	2020-03-23 21:00:01 UTC (rev 258873)
@@ -1,3 +1,38 @@
+2020-03-23  Daniel Bates  <[email protected]>
+
+        Support inserting text or dictation alternative by simulating keyboard input
+        https://bugs.webkit.org/show_bug.cgi?id=209380
+        <rdar://problem/59445102>
+
+        Reviewed by Darin Adler.
+
+        As a workaround for sites the implement their own editing system (e.g. facebook.com)
+        add a new insertion option that makes the insertion having a passing resemblance
+        of a person typing. The resemblance is achieved by dispatching DOM events with type
+        "keydown", "keyup", and "change".
+
+        * Shared/Cocoa/InsertTextOptions.cpp:
+        (IPC::ArgumentCoder<WebKit::InsertTextOptions>::encode):
+        (IPC::ArgumentCoder<WebKit::InsertTextOptions>::decode):
+        Encode and decode the new option.
+
+        * Shared/Cocoa/InsertTextOptions.h: Default the new option, shouldSimulateKeyboardInput,
+        to false to keep our current behavior.
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _shouldSimulateKeyboardInputOnTextInsertion]): Added. Returns NO when
+        building without USE(TEXT_INTERACTION_ADDITIONS) to keep the current behavior.
+
+        (-[WKContentView insertText:]):
+        (-[WKContentView insertText:alternatives:style:]):
+        Set the shouldSimulateKeyboardInput option.
+
+        * WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
+        (WebKit::WebPage::insertDictatedTextAsync):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::insertTextAsync):
+        If shouldSimulateKeyboardInput is false then do what we do now. Otherwise, dispatch a DOM event
+        of type "keydown" and perform the insertion. Then dispatch DOM events of type "keyup" and "change". 
+
 2020-03-23  Darin Adler  <[email protected]>
 
         Change TextIterator::rangeLength to not require a live range

Modified: trunk/Source/WebKit/Shared/Cocoa/InsertTextOptions.cpp (258872 => 258873)


--- trunk/Source/WebKit/Shared/Cocoa/InsertTextOptions.cpp	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Source/WebKit/Shared/Cocoa/InsertTextOptions.cpp	2020-03-23 21:00:01 UTC (rev 258873)
@@ -33,6 +33,7 @@
     encoder << options.registerUndoGroup;
     encoder << options.suppressSelectionUpdate;
     encoder << options.processingUserGesture;
+    encoder << options.shouldSimulateKeyboardInput;
     encoder << options.editingRangeIsRelativeTo;
 }
 
@@ -45,6 +46,8 @@
         return WTF::nullopt;
     if (!decoder.decode(options.processingUserGesture))
         return WTF::nullopt;
+    if (!decoder.decode(options.shouldSimulateKeyboardInput))
+        return WTF::nullopt;
     if (!decoder.decode(options.editingRangeIsRelativeTo))
         return WTF::nullopt;
     return options;

Modified: trunk/Source/WebKit/Shared/Cocoa/InsertTextOptions.h (258872 => 258873)


--- trunk/Source/WebKit/Shared/Cocoa/InsertTextOptions.h	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Source/WebKit/Shared/Cocoa/InsertTextOptions.h	2020-03-23 21:00:01 UTC (rev 258873)
@@ -34,6 +34,7 @@
     bool registerUndoGroup { false };
     bool suppressSelectionUpdate { false };
     bool processingUserGesture { false };
+    bool shouldSimulateKeyboardInput { false };
     EditingRangeIsRelativeTo editingRangeIsRelativeTo { EditingRangeIsRelativeTo::EditableRoot };
 };
 

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (258872 => 258873)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2020-03-23 21:00:01 UTC (rev 258873)
@@ -4710,6 +4710,15 @@
     _page->executeEditCommand("deleteBackward"_s);
 }
 
+- (BOOL)_shouldSimulateKeyboardInputOnTextInsertion
+{
+#if USE(TEXT_INTERACTION_ADDITIONS)
+    return [self _shouldSimulateKeyboardInputOnTextInsertionInternal];
+#else
+    return NO;
+#endif
+}
+
 // Inserts the given string, replacing any selected or marked text.
 - (void)insertText:(NSString *)aStringValue
 {
@@ -4717,7 +4726,7 @@
 
     WebKit::InsertTextOptions options;
     options.processingUserGesture = [keyboard respondsToSelector:@selector(isCallingInputDelegate)] && keyboard.isCallingInputDelegate;
-
+    options.shouldSimulateKeyboardInput = [self _shouldSimulateKeyboardInputOnTextInsertion];
     _page->insertTextAsync(aStringValue, WebKit::EditingRange(), WTFMove(options));
 }
 
@@ -4731,7 +4740,10 @@
         BOOL isLowConfidence = style == UITextAlternativeStyleLowConfidence;
         auto textAlternatives = adoptNS([[NSTextAlternatives alloc] initWithPrimaryString:aStringValue alternativeStrings:alternatives isLowConfidence:isLowConfidence]);
         WebCore::TextAlternativeWithRange textAlternativeWithRange { textAlternatives.get(), NSMakeRange(0, aStringValue.length) };
-        _page->insertDictatedTextAsync(aStringValue, { }, { textAlternativeWithRange }, { });
+
+        WebKit::InsertTextOptions options;
+        options.shouldSimulateKeyboardInput = [self _shouldSimulateKeyboardInputOnTextInsertion];
+        _page->insertDictatedTextAsync(aStringValue, { }, { textAlternativeWithRange }, WTFMove(options));
     }
 }
 

Modified: trunk/Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm (258872 => 258873)


--- trunk/Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm	2020-03-23 21:00:01 UTC (rev 258873)
@@ -38,6 +38,7 @@
 #import <WebCore/DictionaryLookup.h>
 #import <WebCore/Editor.h>
 #import <WebCore/EventHandler.h>
+#import <WebCore/EventNames.h>
 #import <WebCore/FocusController.h>
 #import <WebCore/FrameView.h>
 #import <WebCore/HTMLConverter.h>
@@ -197,8 +198,17 @@
     if (options.registerUndoGroup)
         send(Messages::WebPageProxy::RegisterInsertionUndoGrouping { });
 
+    RefPtr<Element> focusedElement = frame.document() ? frame.document()->focusedElement() : nullptr;
+    if (focusedElement && options.shouldSimulateKeyboardInput)
+        focusedElement->dispatchEvent(Event::create(eventNames().keydownEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes));
+
     ASSERT(!frame.editor().hasComposition());
     frame.editor().insertDictatedText(text, dictationAlternativeLocations, nullptr /* triggeringEvent */);
+
+    if (focusedElement && options.shouldSimulateKeyboardInput) {
+        focusedElement->dispatchEvent(Event::create(eventNames().keyupEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes));
+        focusedElement->dispatchEvent(Event::create(eventNames().changeEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes));
+    }
 }
 
 void WebPage::accessibilityTransferRemoteToken(RetainPtr<NSData> remoteToken)

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (258872 => 258873)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-03-23 21:00:01 UTC (rev 258873)
@@ -5343,7 +5343,11 @@
     
     if (options.registerUndoGroup)
         send(Messages::WebPageProxy::RegisterInsertionUndoGrouping());
-    
+
+    RefPtr<Element> focusedElement = frame.document() ? frame.document()->focusedElement() : nullptr;
+    if (focusedElement && options.shouldSimulateKeyboardInput)
+        focusedElement->dispatchEvent(Event::create(eventNames().keydownEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes));
+
     if (!frame.editor().hasComposition()) {
         // An insertText: might be handled by other responders in the chain if we don't handle it.
         // One example is space bar that results in scrolling down the page.
@@ -5350,6 +5354,11 @@
         frame.editor().insertText(text, nullptr, replacesText ? TextEventInputAutocompletion : TextEventInputKeyboard);
     } else
         frame.editor().confirmComposition(text);
+
+    if (focusedElement && options.shouldSimulateKeyboardInput) {
+        focusedElement->dispatchEvent(Event::create(eventNames().keyupEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes));
+        focusedElement->dispatchEvent(Event::create(eventNames().changeEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes));
+    }
 }
 
 void WebPage::hasMarkedText(CompletionHandler<void(bool)>&& completionHandler)

Modified: trunk/Tools/ChangeLog (258872 => 258873)


--- trunk/Tools/ChangeLog	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Tools/ChangeLog	2020-03-23 21:00:01 UTC (rev 258873)
@@ -1,3 +1,28 @@
+2020-03-23  Daniel Bates  <[email protected]>
+
+        Support inserting text or dictation alternative by simulating keyboard input
+        https://bugs.webkit.org/show_bug.cgi?id=209380
+        <rdar://problem/59445102>
+
+        Reviewed by Darin Adler.
+
+        Add tests to ensure that DOM events are dispatched on insertion when shouldSimulateKeyboardInput
+        is enabled.
+
+        I also added a convenience assertion function, EXPECT_NS_EQUAL, that can
+        compare NSObjects so long as they implement -isEqual and -description. I
+        make use of this to compare the actual array of fired DOM events types to
+        an expected array.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm:
+        (TestWebKitAPI::shouldSimulateKeyboardInputOnTextInsertionOverride):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/cocoa/TestCocoa.h:
+        (TestWebKitAPI::Util::assertNSObjectsAreEqual): Added.
+        (EXPECT_NS_EQUAL): Added.
+        * TestWebKitAPI/ios/insert-text.html: Added.
+
 2020-03-23  Kate Cheney  <[email protected]>
 
         Add checks for app-bound navigations when evaluating user style sheets

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (258872 => 258873)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-03-23 21:00:01 UTC (rev 258873)
@@ -984,6 +984,7 @@
 		CE3524FA1B1443890028A7C5 /* input-focus-blur.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CE3524F51B142BBB0028A7C5 /* input-focus-blur.html */; };
 		CE449E1121AE0F7200E7ADA1 /* WKWebViewFindString.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE449E1021AE0F7200E7ADA1 /* WKWebViewFindString.mm */; };
 		CE4D5DE71F6743BA0072CFC6 /* StringWithDirection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE4D5DE51F6743BA0072CFC6 /* StringWithDirection.cpp */; };
+		CE6D0EE32426B932002AD901 /* insert-text.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CE6D0EE22426B8ED002AD901 /* insert-text.html */; };
 		CE6E81A020A6935F00E2C80F /* SetTimeoutFunction.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE6E819F20A6935F00E2C80F /* SetTimeoutFunction.mm */; };
 		CE6E81A420A933D500E2C80F /* set-timeout-function.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CE6E81A320A933B800E2C80F /* set-timeout-function.html */; };
 		CE78705F2107AB980053AC67 /* MoveOnlyLifecycleLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE78705D2107AB8C0053AC67 /* MoveOnlyLifecycleLogger.cpp */; };
@@ -1374,6 +1375,7 @@
 				5110FCF61E01CD83006F8D0B /* IndexUpgrade.sqlite3 in Copy Resources */,
 				2EFF06CD1D8A429A0004BB30 /* input-field-in-scrollable-document.html in Copy Resources */,
 				CE3524FA1B1443890028A7C5 /* input-focus-blur.html in Copy Resources */,
+				CE6D0EE32426B932002AD901 /* insert-text.html in Copy Resources */,
 				57F56A5C1C7F8CC100F31D7E /* IsNavigationActionTrusted.html in Copy Resources */,
 				C9B4AD2C1ECA6F7F00F5FEA0 /* js-autoplay-audio.html in Copy Resources */,
 				C99B675D1E39722000FC6C80 /* js-play-with-controls.html in Copy Resources */,
@@ -2578,6 +2580,7 @@
 		CE50D8C81C8665CE0072EA5A /* OptionSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OptionSet.cpp; sourceTree = "<group>"; };
 		CE640CA52370A4F300C5CAA4 /* TestCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TestCocoa.h; path = cocoa/TestCocoa.h; sourceTree = "<group>"; };
 		CE640CA62370A4F300C5CAA4 /* TestCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = TestCocoa.mm; path = cocoa/TestCocoa.mm; sourceTree = "<group>"; };
+		CE6D0EE22426B8ED002AD901 /* insert-text.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = "insert-text.html"; path = "ios/insert-text.html"; sourceTree = SOURCE_ROOT; };
 		CE6E819F20A6935F00E2C80F /* SetTimeoutFunction.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SetTimeoutFunction.mm; sourceTree = "<group>"; };
 		CE6E81A320A933B800E2C80F /* set-timeout-function.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = "set-timeout-function.html"; path = "ios/set-timeout-function.html"; sourceTree = SOURCE_ROOT; };
 		CE78705C2107AB8C0053AC67 /* MoveOnlyLifecycleLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoveOnlyLifecycleLogger.h; sourceTree = "<group>"; };
@@ -3671,6 +3674,7 @@
 			isa = PBXGroup;
 			children = (
 				0F16BED72304A1D100B4A167 /* composited.html */,
+				CE6D0EE22426B8ED002AD901 /* insert-text.html */,
 				0F340777230382540060A1A0 /* overflow-scroll.html */,
 				A1C4FB721BACD1B7003742D0 /* pages.pages */,
 				CE6E81A320A933B800E2C80F /* set-timeout-function.html */,

Modified: trunk/Tools/TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm (258872 => 258873)


--- trunk/Tools/TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm	2020-03-23 21:00:01 UTC (rev 258873)
@@ -30,6 +30,7 @@
 #import "IPadUserInterfaceSwizzler.h"
 #import "InstanceMethodSwizzler.h"
 #import "PlatformUtilities.h"
+#import "TestCocoa.h"
 #import "TestInputDelegate.h"
 #import "TestWKWebView.h"
 #import "UIKitSPI.h"
@@ -37,6 +38,10 @@
 #import <WebKitLegacy/WebEvent.h>
 #import <cmath>
 
+@interface WKContentView ()
+- (BOOL)_shouldSimulateKeyboardInputOnTextInsertion;
+@end
+
 @interface InputAssistantItemTestingWebView : TestWKWebView
 + (UIBarButtonItemGroup *)leadingItemsForWebView:(WKWebView *)webView;
 + (UIBarButtonItemGroup *)trailingItemsForWebView:(WKWebView *)webView;
@@ -647,6 +652,47 @@
     EXPECT_TRUE(UIKeyboardImpl.sharedInstance._shouldSuppressSoftwareKeyboard);
 }
 
+static BOOL shouldSimulateKeyboardInputOnTextInsertionOverride(id, SEL)
+{
+    return YES;
+}
+
+TEST(KeyboardInputTests, InsertTextSimulatingKeyboardInput)
+{
+    InstanceMethodSwizzler overrideShouldSimulateKeyboardInputOnTextInsertion { NSClassFromString(@"WKContentView"), @selector(_shouldSimulateKeyboardInputOnTextInsertion), reinterpret_cast<IMP>(shouldSimulateKeyboardInputOnTextInsertionOverride) };
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
+    [inputDelegate setFocusStartsInputSessionPolicyHandler:[&](WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
+    [webView _setInputDelegate:inputDelegate.get()];
+
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"insert-text" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+    [webView synchronouslyLoadRequest:[NSURLRequest requestWithURL:testURL.get()]];
+    [webView evaluateJavaScriptAndWaitForInputSessionToChange:@"document.body.focus()"];
+    [[webView textInputContentView] insertText:@"hello"];
+    EXPECT_NS_EQUAL((@[@"keydown", @"beforeinput", @"input", @"keyup", @"change"]), [webView objectByEvaluatingJavaScript:@"firedEvents"]);
+}
+
+#if USE(DICTATION_ALTERNATIVES)
+
+TEST(KeyboardInputTests, InsertDictationAlternativesSimulatingKeyboardInput)
+{
+    InstanceMethodSwizzler overrideShouldSimulateKeyboardInputOnTextInsertion { NSClassFromString(@"WKContentView"), @selector(_shouldSimulateKeyboardInputOnTextInsertion), reinterpret_cast<IMP>(shouldSimulateKeyboardInputOnTextInsertionOverride) };
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
+    [inputDelegate setFocusStartsInputSessionPolicyHandler:[&](WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
+    [webView _setInputDelegate:inputDelegate.get()];
+
+    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"insert-text" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+    [webView synchronouslyLoadRequest:[NSURLRequest requestWithURL:testURL.get()]];
+    [webView evaluateJavaScriptAndWaitForInputSessionToChange:@"document.body.focus()"];
+    [[webView textInputContentView] insertText:@"hello" alternatives:@[ @"helo" ] style:UITextAlternativeStyleNone];
+    EXPECT_NS_EQUAL((@[@"keydown", @"beforeinput", @"input", @"keyup", @"change"]), [webView objectByEvaluatingJavaScript:@"firedEvents"]);
+}
+
+#endif
+
 } // namespace TestWebKitAPI
 
 #endif // PLATFORM(IOS_FAMILY)

Modified: trunk/Tools/TestWebKitAPI/cocoa/TestCocoa.h (258872 => 258873)


--- trunk/Tools/TestWebKitAPI/cocoa/TestCocoa.h	2020-03-23 20:53:15 UTC (rev 258872)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestCocoa.h	2020-03-23 21:00:01 UTC (rev 258873)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2019-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,8 +25,26 @@
 
 #pragma once
 
+#import "PlatformUtilities.h"
 #import "Test.h"
 
+namespace TestWebKitAPI {
+namespace Util {
+
+template<typename T, typename U>
+static inline ::testing::AssertionResult assertNSObjectsAreEqual(const char* expectedExpression, const char* actualExpression, T *expected, U *actual)
+{
+    if ((!expected && !actual) || [expected isEqual:actual])
+        return ::testing::AssertionSuccess();
+    return ::testing::internal::EqFailure(expectedExpression, actualExpression, toSTD([expected description]), toSTD([actual description]), false /* ignoring_case */);
+}
+
+} // namespace Util
+} // namespace TestWebKitAPI
+
+#define EXPECT_NS_EQUAL(expected, actual) \
+    EXPECT_PRED_FORMAT2(TestWebKitAPI::Util::assertNSObjectsAreEqual, expected, actual)
+
 #if USE(CG)
 
 std::ostream& operator<<(std::ostream&, const CGRect&);

Added: trunk/Tools/TestWebKitAPI/ios/insert-text.html (0 => 258873)


--- trunk/Tools/TestWebKitAPI/ios/insert-text.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/ios/insert-text.html	2020-03-23 21:00:01 UTC (rev 258873)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+let firedEvents = [];
+
+function logEvent(event)
+{
+    firedEvents.push(event.type);
+}
+
+function setupTest()
+{
+    document.body.addEventListener("keydown", logEvent, false);
+    document.body.addEventListener("beforeinput", logEvent, false);
+    document.body.addEventListener("input", logEvent, false);
+    document.body.addEventListener("keyup", logEvent, false);
+    document.body.addEventListener("change", logEvent, false);
+}
+</script>
+</head>
+<body _onload_="setupTest()" contenteditable="true">
+</body>
+</html>
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to