Commit Graph

138 Commits

Author SHA1 Message Date
Sam Weinig 9cc977ee4d Allow testing of the final UIView tree on iOS platforms
https://bugs.webkit.org/show_bug.cgi?id=229016

Reviewed by Tim Horton.

Source/WebKit:

Test: remote-layer-tree/ios/uiview-tree-basic.html

* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(allowListedClassToString):
(dumpUIView):
(-[WKWebView _uiViewTreeAsText]):
Add partner SPI called _uiViewTreeAsText that dumps the WKWebView's
UIView tree as constructed via remote layer creation. It currently
dumps some basic properties of each view and uses an allow list of
class names so changes to implementation details in frameworks below
us, like UIKit, don't cause tests to fail.

Tools:

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::uiViewTreeAsText const):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::uiViewTreeAsText const):
Pipe new _uiViewTreeAsText SPI through to UIScriptController, matching the pattern
established by scrollingTreeAsText.

LayoutTests:

* remote-layer-tree: Added.
* remote-layer-tree/ios: Added.
* remote-layer-tree/ios/uiview-tree-basic-expected.txt: Added.
* remote-layer-tree/ios/uiview-tree-basic.html: Added.
Add basic test case excercising UIView tree dumping to ensure
it is working properly.

* resources/ui-helper.js:
(window.UIHelper.getUIViewTree):
Add helper to use get the UIView tree as text.

* TestExpectations:
* platform/ios/TestExpectations:
Ensure these tests are only run on iOS.


Canonical link: https://commits.webkit.org/240481@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280980 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-08-12 20:16:51 +00:00
Wenson Hsieh b2d7d3d04a caret-color does not work on first click in ios
https://bugs.webkit.org/show_bug.cgi?id=228859
rdar://81674787

Reviewed by Tim Horton.

Source/WebKit:

Addresses a couple of issues that cause the `caret-color` CSS property to not be applied when focusing editable
content on iOS. See below for more details.

Test: editing/caret/ios/caret-color-after-refocusing-input.html

* Platform/spi/ios/UIKitSPI.h:
* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView _serializedSelectionCaretBackgroundColorForTesting]):

Add support for a new test-only helper method. See Tools/ChangeLog for more information.

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(WebKit::WKSelectionDrawingInfo::WKSelectionDrawingInfo):
(WebKit::operator==):
(WebKit::operator<<):

Make a minor adjustment to ensure that changes to `caretColor` in `EditorState` are propagated to UIKit's
selection views. To achieve this, we add `caretColor` to `WKSelectionDrawingInfo`, and force the text selection
view to update the caret background color when the caret color changes (alongside other selection UI geometry
changes, which are applied underneath the call to `-selectionChanged`).

(-[WKContentView _updateChangedSelection:]):
(-[WKContentView textInteractionAssistant]):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getPlatformEditorState const):

Address an existing FIXME which (mostly) fixes this bug. Currently, the caret color is only computed when
`WebPage::m_focusedElement` is set. However, when resigning first responder, we clear out `WebPage`'s
`m_focusedElement`) right before updating the DOM selection, which creates a brief window during which we
compute an `EditorState` with a `caretColor` of transparent black.

To avoid this inconsistency, we instead compute the caret color from the selection container; this has the
additional benefit of allowing the caret color to change when changing selection within a single editable host
with multiple caret colors (instead of always just using the focused element's caret color).

Note that while this adjustment to `WebPage::getPlatformEditorState` is sufficient to ensure that the value of
`-[WKContentView insertionPointColor]` (which is based on `EditorState`) is always up-to-date, this doesn't
guarantee that the actual color of UIKit's caret view reflects the updated `-insertionPointColor`, which results
in situations where the caret color appears out-of-date after hiding the keyboard and refocusing an input field.
To fix this, we need the other adjustment in WKContentView (see above).

Tools:

Make it possible to test this bug by adding a UIScriptController hook to request the background color of the
current selection view's caret view, as serialized CSS text. See LayoutTests/ChangeLog for more details.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::selectionCaretBackgroundColor const):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::selectionCaretBackgroundColor const):

LayoutTests:

Add a new layout test that exercises the issue, as reported in Bugzilla (the call to `-resignFirstResponder`
simulates backgrounding Safari). To achieve this, we also introduce a script controller testing helper to grab
the native background color of the `UITextSelectionView`'s caret view; see Tools/ChangeLog for more details.

* editing/caret/ios/caret-color-after-refocusing-input-expected.txt: Added.
* editing/caret/ios/caret-color-after-refocusing-input.html: Added.
* resources/ui-helper.js:
(window.UIHelper.selectionCaretBackgroundColor):


Canonical link: https://commits.webkit.org/240352@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280767 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-08-09 01:21:41 +00:00
Wenson Hsieh 1a180891ec [iOS] Unified field is unselected after focusing URL bar if text was selected in a fixed position container
https://bugs.webkit.org/show_bug.cgi?id=228269
rdar://80556392

Reviewed by Tim Horton.

Source/WebKit:

In Safari on iOS 15, if the selection (either ranged or caret) is inside a fixed position container when the
user taps on the unified field, we'll immediately clear the text selection inside the unified field upon
bringing up the keyboard. This happens because the tab pill in iOS 15 is lowered as the URL bar is focused,
which causes the web view to scroll slightly. This, in turn, induces a brief unstable scrolling tree state,
which then causes us to temporarily hide and show selection views while scrolling in unstable state (see
r209931) by calling `-deactivateSelection` and then `-activateSelection` on the text interaction assistant.
Calling `-[UIWKTextInteractionAssistant activateSelection]` then causes UIKit to dispatch a
UITextSelectionViewActivatedNotification; In the unified field, which is a UITextField subclass, UIKit code then
listens for this notification and responds to it by clearing the selection if the newly activated selection's
host view (WKContentView) is different than itself, thereby causing the bug.

To fix this, we simply make two (minor) adjustments to the logic for temporarily hiding and showing the
selection while performing an unstable scroll. See below for more details.

Test: editing/selection/ios/scrolling-with-fixed-selection-does-not-unselect-native-text-field.html

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView shouldHideSelectionWhenScrolling]):

Only hide and (later) restore the selection in non-editable text if the selection is ranged. This is because
caret selections in non-editable content are not user-visible anyways, so there's no need to temporarily
suppress the selection.

(-[WKContentView _updateChangedSelection:]):

Only attempt to show the selection views again if doing so doesn't cause us to steal first responder status away
from the existing first responder; otherwise, we'll wait until we `-becomeFirstResponder` to `-activateSelection`.

(-[WKContentView selectionInteractionAssistant]): Deleted.

Tools:

We already have some very basic support for installing and removing native text fields in the view hierarchy,
through `TestRunner::(add|remove)ChromeInputField()`. In order to support the new layout test, we additionally
implement the ability to:

- Set text inside the native chrome input field that was installed using `addChromeInputField()`.
- Select all text inside the chrome input field.
- Query the chrome input field for the currently selected text.

We only support iOS for the time being, with stubs on other platforms, since the new test that uses this
functionality is iOS-specific; if needed in the future for a similar test on other platforms, we can implement
the stubbed testing hooks on TestRunner and PlatformWebView as well.

* DumpRenderTree/TestRunner.h:
* DumpRenderTree/mac/TestRunnerMac.mm:
(TestRunner::setTextInChromeInputField):
(TestRunner::selectChromeInputField):
(TestRunner::getSelectedTextInChromeInputField):
* DumpRenderTree/win/TestRunnerWin.cpp:
(TestRunner::setTextInChromeInputField):
(TestRunner::selectChromeInputField):
(TestRunner::getSelectedTextInChromeInputField):
* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::didReceiveMessageToPage):
(WTR::InjectedBundle::postSetTextInChromeInputField):
(WTR::InjectedBundle::postSelectChromeInputField):
(WTR::InjectedBundle::postGetSelectedTextInChromeInputField):
* WebKitTestRunner/InjectedBundle/InjectedBundle.h:
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setTextInChromeInputField):
(WTR::TestRunner::selectChromeInputField):
(WTR::TestRunner::getSelectedTextInChromeInputField):
(WTR::TestRunner::callSetTextInChromeInputFieldCallback):
(WTR::TestRunner::callSelectChromeInputFieldCallback):
(WTR::TestRunner::callGetSelectedTextInChromeInputFieldCallback):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/PlatformWebView.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
* WebKitTestRunner/gtk/PlatformWebViewGtk.cpp:
(WTR::PlatformWebView::setTextInChromeInputField):
(WTR::PlatformWebView::selectChromeInputField):
(WTR::PlatformWebView::getSelectedTextInChromeInputField):
* WebKitTestRunner/ios/PlatformWebViewIOS.mm:
(WTR::chromeInputField):

Additionally do some light refactoring by pulling out logic for grabbing the chrome input field (i.e. a view
with a tag of 1 under the window) out into a separate helper method. Use this helper in a few places below.

(WTR::PlatformWebView::addChromeInputField):
(WTR::PlatformWebView::setTextInChromeInputField):
(WTR::PlatformWebView::selectChromeInputField):
(WTR::PlatformWebView::getSelectedTextInChromeInputField):
(WTR::PlatformWebView::removeChromeInputField):
* WebKitTestRunner/mac/PlatformWebViewMac.mm:
(WTR::PlatformWebView::setTextInChromeInputField):
(WTR::PlatformWebView::selectChromeInputField):
(WTR::PlatformWebView::getSelectedTextInChromeInputField):
* WebKitTestRunner/win/PlatformWebViewWin.cpp:
(WTR::PlatformWebView::setTextInChromeInputField):
(WTR::PlatformWebView::selectChromeInputField):
(WTR::PlatformWebView::getSelectedTextInChromeInputField):
* WebKitTestRunner/wpe/PlatformWebViewWPE.cpp:
(WTR::PlatformWebView::setTextInChromeInputField):
(WTR::PlatformWebView::selectChromeInputField):
(WTR::PlatformWebView::getSelectedTextInChromeInputField):

LayoutTests:

Add a new layout test that installs, focuses, and selects text inside a native UITextField (simulating Safari's
URL field) while the DOM selection is inside a fixed position container, and then scrolls the web view a bit to
temporarily induce an unstable scrolling tree state. After this, we verify that the text selection inside the
native text field has not been cleared.

See Tools/ changes for more details.

* editing/selection/ios/scrolling-with-fixed-selection-does-not-unselect-native-text-field-expected.txt: Added.
* editing/selection/ios/scrolling-with-fixed-selection-does-not-unselect-native-text-field.html: Added.
* resources/ui-helper.js:
(window.UIHelper.addChromeInputField):
(window.UIHelper.removeChromeInputField):
(window.UIHelper.setTextInChromeInputField):
(window.UIHelper.selectChromeInputField):
(window.UIHelper.getSelectedTextInChromeInputField):
(window.UIHelper):


Canonical link: https://commits.webkit.org/239946@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280288 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-07-25 19:40:36 +00:00
Aditya Keerthi 2d3da68b54 [iPadOS] Do not present custom input peripherals when switching back to a tab with a focused element
https://bugs.webkit.org/show_bug.cgi?id=225541
<rdar://problem/77537795>

Reviewed by Wenson Hsieh.

Source/WebKit:

With the introduction of desktop-class browing on iPad, form control
elements began to retain focus even after their input peripheral
(popover, menu, etc.) was dismissed. This behavior matches macOS - when
a <select> element is clicked, a menu is presented, and when a option
is selected, the menu is dismissed but the element retains focus.

Consequently, when a <select> menu is dismissed by choosing an option on
an iPad with a hardware keyboard, the element retains focus. Now, when
switching tabs and coming back to the tab with the focused <select>, an
activity state update is triggered. Upon recognizing that there is a
focused element, an ElementDidFocus message is sent to the UIProcess.

In [WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:],
the focus is given permission to present the input peripheral (menu)
when the hardware keyboard is attached. This is necessary when necessary
when focusing a text input, because the UCB needs to be displayed and
text selection needs to be set up. However, the behavior is undesirable
for elements that present a popover or a menu (select, color inputs, and
date inputs), since the user is unexpectedly shown an input peripheral.
Even worse, the user's scroll position will be changed to ensure the
focused element is visible.

To fix the undesirable behavior, and get closer to the macOS behavior,
custom input peripherals should not be displayed when switching back
to a tab with a focused element.

Test: fast/forms/ios/focus-select-and-switch-tabs.html

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]):

Only show the input peripheral if it is not a keyboard view.

Tools:

Updated a UIScriptController hook that simulates attaching a hardware
keyboard to also swizzle [UIKeyboard isInHardwareKeyboardMode].

* WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::platformInitialize):
(WTR::TestController::platformResetStateToConsistentValues):

Moved the default swizzling behavior into this method so that it remains
consistent across tests.

Unfortunately, the default swizzling behavior contrasts with the default
value of GSEventSetHardwareKeyboardAttached. However, this is an existing
inconsistency, and should be looked at more carefully in a separate
investigation.

* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::returnYes):
(WTR::returnNo):
(WTR::UIScriptControllerIOS::setHardwareKeyboardAttached):

LayoutTests:

Added a test which simulates a tab switch by removing and re-adding the
webview to the window.

* fast/forms/ios/focus-select-and-switch-tabs-expected.txt: Added.
* fast/forms/ios/focus-select-and-switch-tabs.html: Added.
* resources/ui-helper.js:
(window.UIHelper.becomeFirstResponder):
(window.UIHelper.removeViewFromWindow):
(window.UIHelper.addViewToWindow):


Canonical link: https://commits.webkit.org/237532@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277265 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-10 16:26:17 +00:00
Wenson Hsieh b5bed29c7b REGRESSION (r271660): Tap highlight no longer shows when tapping clickable elements without touch event listeners
https://bugs.webkit.org/show_bug.cgi?id=224385
<rdar://problem/76462370>

Reviewed by Tim Horton.

Source/WebKit:

In r271660, I added a call to `-finishInteraction` when resetting the synthetic tap gesture to fix a bug where
it was possible for the tap highlight to remain indefinitely when tapping on a clickable element with a touchend
event listener. This was because the touch end deferring gesture defers `-_singleTapDidReset:` until after
`-_didGetTapHighlightForRequest:…nodeHasBuiltInClickHandling:`, where we receive the tap highlight information.

```
2021-04-09 13:05:27.141097-0700 -[WKContentView(WKInteraction) _singleTapIdentified:]
2021-04-09 13:05:27.148678-0700 -[WKContentView(WKInteraction) _didGetTapHighlightForRequest:…nodeHasBuiltInClickHandling:]
2021-04-09 13:05:27.162525-0700 -[WKContentView(WKInteraction) _singleTapRecognized:]
2021-04-09 13:05:27.162675-0700   ↳ -[WKContentView(WKInteraction) _showTapHighlight]
2021-04-09 13:05:27.163250-0700 -[WKContentView(WKInteraction) _singleTapDidReset:]
2021-04-09 13:05:51.849481-0700   ↳ -[WKContentView(WKInteraction) _finishInteraction]
```

However, in the case where there is no touchend event listener and when fast-click is active, we reset the tap
gesture before receiving the tap highlight information:

```
2021-04-09 13:05:51.836638-0700 -[WKContentView(WKInteraction) _singleTapIdentified:]
2021-04-09 13:05:51.846152-0700 -[WKContentView(WKInteraction) _singleTapRecognized:]
2021-04-09 13:05:51.847196-0700 -[WKContentView(WKInteraction) _singleTapDidReset:]
2021-04-09 13:05:51.848563-0700 -[WKContentView(WKInteraction) _didGetTapHighlightForRequest:…nodeHasBuiltInClickHandling:]
2021-04-09 13:05:51.848851-0700   ↳ -[WKContentView(WKInteraction) _showTapHighlight]
2021-04-09 13:05:51.849481-0700   ↳ -[WKContentView(WKInteraction) _finishInteraction]

```

Critically, this means that calling `-_finishInteraction` in `-_singleTapDidReset:` prematurely flagged the
tap highlight request as complete (by setting `_isTapHighlightIDValid` to `NO`) in the case where we aren't
deferring gestures, which caused us to avoid showing the tap highlight at all when we eventually receive the tap
highlight information.

To fix this, only fade out the tap highlight view in `-_singleTapDidReset:` if the tap highlight request has
already finished (i.e. `_isTapHighlightIDValid` has been set to `NO`). Additionally, split logic for fading out
the highlight view into a separate method, and add a `BOOL` flag to make the fading idempotent.

Test: fast/events/touch/ios/tap-highlight-during-synthetic-click.html

* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView _tapHighlightViewRect]):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView tapHighlightViewRect]):

Also add a testing-only method to report the frame of the tap highlight view. Note that this only attempts to
return the current `frame` of the tap highlight view instead of converting the frame to the coordinate system of
the content view (as other similar testing hooks do), since the tap highlight view only exists in the view
hierarchy for a brief duration.

(-[WKContentView _finishInteraction]):
(-[WKContentView _fadeTapHighlightViewIfNeeded]):
(-[WKContentView _singleTapDidReset:]):

Tools:

Add plumbing to expose the frame of the tap highlight view via `UIScriptController`.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::tapHighlightViewRect const):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::tapHighlightViewRect const):

LayoutTests:

Add a new layout test that exercises 3 scenarios, using the new testing SPI:

1.  Tapping on a `button` that prevents the "touchend" event (and therefore prevents clicking) should cause
    the tap highlight to not show up.
2.  Tapping on a `button` that has a "touchend" event listener and does not prevent default should cause the tap
    highlight to show up.
3.  Tapping on a `button` with no event listeners should cause the tap highlight to show up.

* fast/events/touch/ios/tap-highlight-during-synthetic-click-expected.txt: Added.
* fast/events/touch/ios/tap-highlight-during-synthetic-click.html: Added.
* resources/ui-helper.js:
(window.UIHelper.tapHighlightViewRect):

Canonical link: https://commits.webkit.org/236362@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275791 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-10 03:01:13 +00:00
Wenson Hsieh 0d24367fed REGRESSION (r274610): Unable to drag images when image extraction is enabled
https://bugs.webkit.org/show_bug.cgi?id=224211
<rdar://problem/76229563>

Reviewed by Tim Horton.

Source/WebKit:

r274610 introduced a new deferring gesture recognizer intended to prevent several text interaction gestures from
recognizing during pending image extraction. However, this also causes dragging on iOS to fail, since the
gesture used to initiate dragging is excluded by the new deferring gesture recognizer. To fix this, allow the
new deferring gesture to recognize simultaneously alongside all gestures with the exception of only the gestures
it is intended to defer (i.e. text interaction gestures).

Test: fast/events/ios/dragstart-on-image-by-long-pressing.html

* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView _isAnimatingDragCancel]):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[UIGestureRecognizer _wk_isTapAndAHalf]):

Add a WebKit category method that returns whether or not a gesture recognizer is a tap-and-a-half gesture.

(-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):

Allow the image extraction deferring gesture to recognize alongside all other gestures, with the exception of
the text interaction gestures determined by `-shouldDeferGestureDueToImageExtraction:`. This limits the impact
of this new deferring gesture, such that it only affects the text interaction gestures it is intended to defer.

(-[WKContentView shouldDeferGestureDueToImageExtraction:]):

Add a helper method to determine whether or not a gesture recognizer should be deferred, due to pending image
extraction. We pull this logic behind a helper method because it's now consulted from two call sites.

(-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]):
(-[WKContentView dragInteraction:item:willAnimateCancelWithAnimator:]):
(-[WKContentView isAnimatingDragCancel]):

Add a testing hook to return whether or not the drag cancel animation is running. See Tools/ChangeLog and the
new layout test for more detail.

(tapAndAHalfRecognizerClass): Deleted.

Tools:

Add support for some new testing infrastructure; see below for more details.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::isAnimatingDragCancel const):

Add a new testing hook to return whether or not the web view's drag interaction is currently animating a drag
cancel (i.e., the drag preview is animating back to its original frame).

* WebKitTestRunner/TestOptions.cpp:
(WTR::TestOptions::defaults):
(WTR::TestOptions::keyTypeMapping):
* WebKitTestRunner/TestOptions.h:
(WTR::TestOptions::dragInteractionPolicy const):

Add a test option that allows tests to override the drag interaction policy to "always-allow",
"always-disallow", and the default value. This option allows us to force drag and drop to be enabled when
testing on iPhone simulator.

* WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::dragInteractionPolicy):
(WTR::TestController::platformResetStateToConsistentValues):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::isAnimatingDragCancel const):

LayoutTests:

Add a new layout test that initiates dragging on an image using a synthesized event stream, and verifies that
"dragstart" and "dragend" events are dispatched on the image.

* fast/events/ios/dragstart-on-image-by-long-pressing-expected.txt: Added.
* fast/events/ios/dragstart-on-image-by-long-pressing.html: Added.
* resources/ui-helper.js:
(window.UIHelper.isAnimatingDragCancel):

Add a `UIHelper` method that returns whether or not the dragging animation is being cancelled. The new test uses
this hook to wait for the drag cancel animation to end before proceeding to the next test.


Canonical link: https://commits.webkit.org/236202@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275546 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-06 20:39:10 +00:00
Aditya Keerthi 7686cbd037 [iOS] Refactor WKFileUploadPanel to use UniformTypeIdentifiers
https://bugs.webkit.org/show_bug.cgi?id=223000
<rdar://problem/75237774>

Reviewed by Tim Horton.

Source/WebKit:

Uniform type identifier APIs in MobileCoreServices were deprecated in
iOS 14. Instead, use the new APIs in the UniformTypeIdentifiers
framework.

This patch also cleans up instances of code duplication when comparing
uniform type idenfifiers and increases the test coverage for
WKFileUploadPanel.

Test: fast/forms/ios/file-upload-panel-accept.html

* Configurations/WebKit.xcconfig:

Link UniformTypeIdentifiers.framework on watchOS and tvOS.

* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:

Expose _filePickerAcceptedTypeIdentifiers to enable testing of accepted
file types.

* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView _filePickerAcceptedTypeIdentifiers]):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView filePickerAcceptedTypeIdentifiers]):
* UIProcess/ios/forms/WKFileUploadPanel.h:
* UIProcess/ios/forms/WKFileUploadPanel.mm:
(setContainsUTIThatConformsTo):

Modified this helper method to take in an NSSet rather than an NSArray
to avoid unnecessary conversion. Replaced MobileCoreServices API usage
with UniformTypeIdentifiers API.

(-[WKFileUploadPanel presentWithParameters:resultListener:]):

Determine the accepted UTIs and image picker configuration once before
presentation and store them in member variables to reduce code
duplication.

(-[WKFileUploadPanel currentAvailableActionTitles]):
(-[WKFileUploadPanel acceptedTypeIdentifiers]):

Expose the accepted type identifers as a sorted array for testing.

(-[WKFileUploadPanel _mediaTypesForPickerSourceType:]):
(-[WKFileUploadPanel _cameraButtonLabel]):
(-[WKFileUploadPanel contextMenuInteraction:configurationForMenuAtLocation:]):
(-[WKFileUploadPanel showFilePickerMenu]):
(-[WKFileUploadPanel showDocumentPickerMenu]):
(-[WKFileUploadPanel _uploadItemFromMediaInfo:successBlock:failureBlock:]):

Tools:

Added UIScriptController hooks to retrieve the type identifiers for
a presented file upload panel.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::filePickerAcceptedTypeIdentifiers):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::filePickerAcceptedTypeIdentifiers):

LayoutTests:

Added a test to verify that the value of the accept attribute for file
inputs is mapped to the correct set of type identifiers.

* fast/forms/ios/file-upload-panel-accept-expected.txt: Added.
* fast/forms/ios/file-upload-panel-accept.html: Added.
* resources/ui-helper.js:
(window.UIHelper.dismissFilePicker):
(window.UIHelper.filePickerAcceptedTypeIdentifiers):


Canonical link: https://commits.webkit.org/235425@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@274581 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-17 20:10:46 +00:00
Devin Rousso b2f1871547 [macOS] change for the language/subtitle tracks button to use an `NSMenu` instead of web content
https://bugs.webkit.org/show_bug.cgi?id=223239
<rdar://problem/75462340>

Reviewed by Eric Carlson.

Source/WebCore:

Tests: media/modern-media-controls/tracks-support/auto-text-track.html
       media/modern-media-controls/tracks-support/captions-offset-with-controls-bar.html
       media/modern-media-controls/tracks-support/click-track-in-contextmenu.html
       media/modern-media-controls/tracks-support/hidden-tracks.html
       media/modern-media-controls/tracks-support/no-tracks.html
       media/modern-media-controls/tracks-support/off-text-track.html
       media/modern-media-controls/tracks-support/show-contextmenu-then-double-click-on-tracks-button.html
       media/modern-media-controls/tracks-support/text-track-selected-via-media-api.html

* Modules/mediacontrols/MediaControlsHost.h:
* Modules/mediacontrols/MediaControlsHost.cpp:
(WebCore::MediaControlsContextMenuProvider::create): Added.
(WebCore::MediaControlsContextMenuProvider::MediaControlsContextMenuProvider): Added.
(WebCore::MediaControlsContextMenuProvider::~MediaControlsContextMenuProvider): Added.
(WebCore::MediaControlsContextMenuProvider::populateContextMenu): Added.
(WebCore::MediaControlsContextMenuProvider::contextMenuItemSelected): Added.
(WebCore::MediaControlsContextMenuProvider::contextMenuCleared): Added.
(WebCore::MediaControlsContextMenuProvider::contextMenuContextType): Added.
(WebCore::MediaControlsContextMenuEventListener::create): Added.
(WebCore::MediaControlsContextMenuEventListener::operator== const): Added.
(WebCore::MediaControlsContextMenuEventListener::handleEvent): Added.
(WebCore::MediaControlsContextMenuEventListener::MediaControlsContextMenuEventListener): Added.
(WebCore::MediaControlsHost::showMediaControlsContextMenu):
Create platform-agnostic helper functions and types for creating submenus and menu items so
that this logic added for iOS can also be used for macOS.

* page/ContextMenuContext.h:
(WebCore::ContextMenuContext::type const): Added.
* page/ContextMenuContext.cpp:
(WebCore::ContextMenuContext::ContextMenuContext):
Move `WebKit::ContextMenuContextData::Type` to `WebCore::ContextmenuContext::Type` so that
it can be used in WebCore as well.

* page/ContextMenuProvider.h:
(WebCore::ContextMenuProvider::contextMenuContextType): Added.
* page/ContextMenuController.h:
* page/ContextMenuController.cpp:
(WebCore::ContextMenuController::handleContextMenuEvent):
(WebCore::ContextMenuController::showContextMenu):
(WebCore::ContextMenuController::maybeCreateContextMenu):
Allow the `ContextMenuProvider` to further customize the `ContextMenu` that's created, such
as allowing the hit test to include UA shadow roots and controlling "Inspect Element".

* platform/ContextMenuItem.h:
* platform/ContextMenuItem.cpp:
(WebCore::ContextMenuItem::ContextMenuItem):
(WebCore::ContextMenuItem::setIndentationLevel): Added.
(WebCore::ContextMenuItem::indentationLevel const): Added.
Provide a way to eventually set the `-[NSMenuItem setIndentationLevel:]`.

* Modules/modern-media-controls/controls/tracks-panel.js: Removed.
* Modules/modern-media-controls/controls/tracks-panel.css: Removed.
* Modules/modern-media-controls/controls/background-click-delegate-notifier.js:
(BackgroundClickDelegateNotifier.prototype.handleEvent):
* Modules/modern-media-controls/controls/macos-fullscreen-media-controls.css:
(.media-controls.mac.fullscreen):
* Modules/modern-media-controls/controls/media-controls.js:
(MediaControls.prototype.showTracksPanel): Deleted.
(MediaControls.prototype.hideTracksPanel): Deleted.
* Modules/modern-media-controls/controls/media-controls.css:
(.media-controls.shows-tracks-panel > .controls-bar > *, .media-controls.shows-tracks-panel > button): Deleted.
* Modules/modern-media-controls/media/tracks-support.js:
(TracksSupport.prototype.buttonWasPressed):
(TracksSupport.prototype.syncControl):
(TracksSupport.prototype._sortedTrackList):
(TracksSupport): Deleted.
(TracksSupport.prototype.tracksPanelNumberOfSections): Deleted.
(TracksSupport.prototype.tracksPanelTitleForSection): Deleted.
(TracksSupport.prototype.tracksPanelNumberOfTracksInSection): Deleted.
(TracksSupport.prototype.tracksPanelTitleForTrackInSection): Deleted.
(TracksSupport.prototype.tracksPanelIsTrackInSectionSelected): Deleted.
(TracksSupport.prototype.tracksPanelSelectionDidChange): Deleted.
* Modules/modern-media-controls/js-files:
Remove everything related to `TracksPanel` now that macOS also uses a contextmenu.

* Modules/modern-media-controls/controls/inline-media-controls.js:
(InlineMediaControls.prototype.layout):
(InlineMediaControls.prototype._rightContainerButtons):
(InlineMediaControls.prototype._droppableButtons):
* Modules/modern-media-controls/controls/macos-fullscreen-media-controls.js:
(MacOSFullscreenMediaControls):
The `OverflowButton` should be the last right container button to be dropped.

* Modules/modern-media-controls/media/media-controller.js:
(MediaController.prototype.showMediaControlsContextMenu):
Provide a way for callers to provide additional options.

* page/MediaControlsContextMenuItem.h:
(WebCore::MediaControlsContextMenuItem::encode const):
(WebCore::MediaControlsContextMenuItem::decode):
Drive-by: Rename `isChecked` to `checked` to match `ContextMenuItem`.

* Modules/modern-media-controls/controls/tracks-button.js:
(TracksButton.prototype.get contextMenuOptions):
Drive-by: Rename object keys for clarity.

* page/ChromeClient.h:
Be more explicit with compiler flags.

* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::mediaControlsScript):

* Modules/modern-media-controls/images/macOS/Overflow.svg:
Rework this "..." icon to be ">>" to match similar icons elsewhere on macOS.

* WebCore.xcodeproj/project.pbxproj:

Source/WebKit:

* Shared/ContextMenuContextData.h:
* Shared/ContextMenuContextData.cpp:
(WebKit::ContextMenuContextData::ContextMenuContextData):
Move `WebKit::ContextMenuContextData::Type` to `WebCore::ContextmenuContext::Type` so that
it can be used in WebCore as well.

* Shared/WebContextMenuItemData.h:
* Shared/WebContextMenuItemData.cpp:
(WebKit::WebContextMenuItemData::WebContextMenuItemData):
(WebKit::WebContextMenuItemData::core const):
(WebKit::WebContextMenuItemData::encode const):
(WebKit::WebContextMenuItemData::decode):
(WebKit::WebContextMenuItemData::indentationLevel const): Added.
Provide a way to eventually set the `-[NSMenuItem setIndentationLevel:]`.

* UIProcess/WebContextMenuProxy.h:
* UIProcess/mac/WebContextMenuProxyMac.h:
* UIProcess/mac/WebContextMenuProxyMac.mm:
(-[WKMenuDelegate initWithMenuProxy:]): Added.
(-[WKMenuDelegate menuWillOpen:]): Added.
(-[WKMenuDelegate menuDidClose:]): Added.
(WebKit::WebContextMenuProxyMac::getContextMenuItem):
(WebKit::WebContextMenuProxyMac::useContextMenuItems):
(WebKit::WebContextMenuProxyMac::platformMenu const): Added.
(WebKit::contentsOfContextMenuItem): Added.
(WebKit::WebContextMenuProxyMac::platformData const): Added.
Add support for `-[NSMenuItem setIndentationLevel:]`.

* UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
* UIProcess/API/Cocoa/WKWebViewTesting.mm:
(-[WKWebView _contentsOfUserInterfaceItem:]):
(-[WKWebView _didShowContextMenu]): Added.
(-[WKWebView _didDismissContextMenu]): Added.
* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView _didShowContextMenu]): Deleted.
(-[WKWebView _didDismissContextMenu]): Deleted.
Move these methods so they can be used on macOS too.

* UIProcess/PageClient.h:
(WebKit::PageClient::didShowContextMenu): Added.
(WebKit::PageClient::didDismissContextMenu): Added.
* UIProcess/mac/PageClientImplMac.h:
* UIProcess/mac/PageClientImplMac.mm:
(WebKit::PageClientImpl::didShowContextMenu): Added.
(WebKit::PageClientImpl::didDismissContextMenu): Added.
Add support for `didShowContextMenu`/`didDismissContextMenu` for tests.

* UIProcess/API/mac/WKWebViewTestingMac.mm:
(-[WKWebView _activeMenu]):
* UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::contentsOfUserInterfaceItem): Added.
* UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::platformActiveContextMenu const): Added.
Add support for `contentsOfUserInterfaceItem` for tests.

* UIProcess/WebPageProxy.messages.in:
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.cpp:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
* UIProcess/ios/WKActionSheetAssistant.h:
* UIProcess/ios/WKActionSheetAssistant.mm:
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.cpp:
Be more explicit with compiler flags.

Source/WTF:

* wtf/PlatformEnableCocoa.h:
Turn on `ENABLE_MEDIA_CONTROLS_CONTEXT_MENUS` for macOS.

Tools:

* WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
* WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView _didShowContextMenu]):
(-[TestRunnerWKWebView _didDismissContextMenu]):
(-[TestRunnerWKWebView resetInteractionCallbacks]):
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.h:
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm:
(WTR::UIScriptControllerCocoa::setDidShowContextMenuCallback): Added.
(WTR::UIScriptControllerCocoa::setDidDismissContextMenuCallback): Added.
(WTR::UIScriptControllerCocoa::isShowingContextMenu const): Added.
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::setDidShowContextMenuCallback): Deleted.
(WTR::UIScriptControllerIOS::setDidDismissContextMenuCallback): Deleted.
(WTR::UIScriptControllerIOS::isShowingContextMenu const): Deleted.
Move these methods so they can be used on macOS too.

LayoutTests:

* media/modern-media-controls/tracks-support/auto-text-track.html: Added.
* media/modern-media-controls/tracks-support/auto-text-track-expected.txt: Added.
* media/modern-media-controls/tracks-support/click-track-in-contextmenu.html: Added.
* media/modern-media-controls/tracks-support/click-track-in-contextmenu-expected.txt: Added.
* media/modern-media-controls/tracks-support/hidden-tracks.html: Added.
* media/modern-media-controls/tracks-support/hidden-tracks-expected.txt: Added.
* media/modern-media-controls/tracks-support/off-text-track.html: Added.
* media/modern-media-controls/tracks-support/off-text-track-expected.txt: Added.
* media/modern-media-controls/tracks-support/show-contextmenu-then-double-click-on-tracks-button.html: Added.
* media/modern-media-controls/tracks-support/show-contextmenu-then-double-click-on-tracks-button-expected.txt: Added.
* media/modern-media-controls/tracks-support/text-track-selected-via-media-api.html: Added.
* media/modern-media-controls/tracks-support/text-track-selected-via-media-api-expected.txt: Added.
* media/modern-media-controls/tracks-support/ios/tracks-support-auto-text-track.html: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-auto-text-track-expected.txt: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-click-track-in-contextmenu.html: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-click-track-in-contextmenu-expected.txt: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-hidden-tracks.html: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-hidden-tracks-expected.txt: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-off-text-track.html: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-off-text-track-expected.txt: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-show-contextmenu-then-double-click-on-tracks-button.html: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-show-contextmenu-then-double-click-on-tracks-button-expected.txt: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-text-track-selected-via-media-api.html: Removed.
* media/modern-media-controls/tracks-support/ios/tracks-support-text-track-selected-via-media-api-expected.txt: Removed.
Move the iOS tracks support tests out of an iOS folder since macOS now also uses a contextmenu.

* media/modern-media-controls/resources/media-controls-loader.js:
* media/modern-media-controls/resources/media-controls-utils.js:
(showTracksPanel): Deleted.
* media/modern-media-controls/media-controller/media-controller-click-on-video-background-to-dismiss-tracks-panel-should-not-toggle-playback.html: Removed.
* media/modern-media-controls/media-controller/media-controller-click-on-video-background-to-dismiss-tracks-panel-should-not-toggle-playback-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-controls-bar-remains-visible-after-clicking-over-it.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-controls-bar-remains-visible-after-clicking-over-it-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-hide.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-hide-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-hide-click-outside.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-hide-click-outside-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-hide-esc-key.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-hide-esc-key-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-population.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-population-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-position-and-size.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-position-and-size-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-prevent-controls-bar-from-fading.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-prevent-controls-bar-from-fading-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-prevent-default-on-keydown.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-prevent-default-on-keydown-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-right-x.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-right-x-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-select-track-with-keyboard.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-select-track-with-keyboard-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-select-track-with-mouse.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-select-track-with-mouse-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-up-click-outside-media-does-not-dimiss-media-controls-when-media-is-paused.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-up-click-outside-media-does-not-dimiss-media-controls-when-media-is-paused-expected.txt: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-up-click-over-media-does-not-dimiss-media-controls-when-media-is-playing.html: Removed.
* media/modern-media-controls/tracks-panel/tracks-panel-up-click-over-media-does-not-dimiss-media-controls-when-media-is-playing-expected.txt: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-auto-text-track.html: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-auto-text-track-expected.txt: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-click-track-in-panel.html: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-click-track-in-panel-expected.txt: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-hidden-tracks.html: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-hidden-tracks-expected.txt: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-off-text-track.html: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-off-text-track-expected.txt: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-show-and-populate-panel.html: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-show-and-populate-panel-expected.txt: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-show-panel-after-dragging-controls.html: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-show-panel-after-dragging-controls-expected.txt: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-show-panel-fullscreen.html: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-show-panel-fullscreen-expected.txt: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-show-panel-then-double-click-on-tracks-button.html: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-show-panel-then-double-click-on-tracks-button-expected.txt: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-text-track-selected-via-media-api.html: Removed.
* media/modern-media-controls/tracks-support/mac/tracks-support-text-track-selected-via-media-api-expected.txt: Removed.
Remove everything related to `TracksPanel` now that macOS also uses a contextmenu.

* media/modern-media-controls/tracks-support/captions-offset-with-controls-bar.html: Renamed from LayoutTests/media/modern-media-controls/tracks-support/tracks-support-captions-offset-with-controls-bar.html.
* media/modern-media-controls/tracks-support/captions-offset-with-controls-bar-expected.txt: Renamed from LayoutTests/media/modern-media-controls/tracks-support/tracks-support-captions-offset-with-controls-bar-expected.txt.
* media/modern-media-controls/tracks-support/no-tracks.html: Renamed from LayoutTests/media/modern-media-controls/tracks-support/tracks-support-no-tracks.html.
* media/modern-media-controls/tracks-support/no-tracks-expected.txt: Renamed from LayoutTests/media/modern-media-controls/tracks-support/tracks-support-no-tracks-expected.txt.
Renamed these tests to remove the redundant "tracks-support".

* media/modern-media-controls/tracks-support/tracks-support-audio-tracks.html: Removed.
* media/modern-media-controls/tracks-support/tracks-support-audio-tracks-expected.txt: Removed.
* media/modern-media-controls/tracks-support/tracks-support-text-tracks.html: Removed.
* media/modern-media-controls/tracks-support/tracks-support-text-tracks-expected.txt: Removed.
These tests are covered by the other added/renamed tests above.

* media/modern-media-controls/macos-fullscreen-media-controls/macos-fullscreen-media-controls-buttons-containers-styles.html:
* media/modern-media-controls/macos-fullscreen-media-controls/macos-fullscreen-media-controls-buttons-containers-styles-expected.txt:
* media/modern-media-controls/macos-fullscreen-media-controls/macos-fullscreen-media-controls-buttons-styles.html:
* media/modern-media-controls/macos-fullscreen-media-controls/macos-fullscreen-media-controls-buttons-styles-expected.txt:
* media/modern-media-controls/macos-fullscreen-media-controls/macos-fullscreen-media-controls-constructor.html:
* media/modern-media-controls/macos-fullscreen-media-controls/macos-fullscreen-media-controls-constructor-expected.txt:
* media/modern-media-controls/macos-fullscreen-media-controls/macos-fullscreen-media-controls-right-container-margin.html:
* media/modern-media-controls/macos-fullscreen-media-controls/macos-fullscreen-media-controls-right-container-margin-expected.txt:
* media/modern-media-controls/macos-inline-media-controls/macos-inline-media-controls-placard.html:
* media/modern-media-controls/macos-inline-media-controls/macos-inline-media-controls-volume-slider-visibility.html:
* media/modern-media-controls/macos-inline-media-controls/macos-inline-media-dropping-controls-expected.txt:
* media/modern-media-controls/macos-inline-media-controls/macos-inline-media-shows-start-button.html:
Update existing tests to accomodate the `OverflowButton`.

* resources/ui-helper.js:
(window.UIHelper.chooseMenuAction): Added.
(window.UIHelper.async chooseMenuAction): Deleted.
Use `UIScriptController.prototype.chooseMenuAction` instead of a combination of
`UIScriptController.prototype.rectForMenuAction` and `UIScriptController.prototype.activateAt`
since `UIScriptController::chooseMenuAction` basically does that anyways.

* TestExpectations:
* platform/ios/TestExpectations:
* platform/mac/TestExpectations:
* platform/mac-wk2/TestExpectations:


Canonical link: https://commits.webkit.org/235372@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@274521 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-16 21:57:18 +00:00
Martin Robinson cb2738daa1 [GTK][WPE] Implement support for CSS Scroll Snap
https://bugs.webkit.org/show_bug.cgi?id=203684

Patch by Martin Robinson <mrobinson@igalia.com> on 2021-02-18
Reviewed by Carlos Garcia Campos.

.:

Add initial support for css-scroll-snap on WebKitGTK+ and WebKitWPE. This
adds support for all types of scroll snapping that WebKit supports apart
from mouse wheel snapping. Support for that will be added in a followup
change.

* Source/cmake/OptionsGTK.cmake: Enable scroll snapping when experimental features
are enabled.
* Source/cmake/OptionsWPE.cmake: Ditto.

Source/WebCore:

No new tests. This change unskips all cross-platform scroll-snap tests
on both platforms.

* Headers.cmake: Add headers to header list.
* page/scrolling/ScrollSnapOffsetsInfo.cpp:
(WebCore::findFirstSnapStopOffsetBetweenOriginAndDestination): Fix a compilation
warning that now shows up on my system.
* platform/generic/ScrollAnimatorGeneric.cpp:
(WebCore::ScrollAnimatorGeneric::scroll): Pass the 'behavior' parameter to
the superclass call.
(WebCore::ScrollAnimatorGeneric::scrollToOffsetWithoutAnimation): Call into the super
class to update the position instead of using the special method in the subclass.
(WebCore::ScrollAnimatorGeneric::updatePosition): Also update the current snap index.
This is necessary so that changes to the scroll position also modify the currently
target snap index.

LayoutTests:

* css3/scroll-snap/scroll-padding-mainframe-paging.html: Since the GTK+ port has
animated scrolling, we need to modify this test to support a scroll operation
that does not happen immediately.
* platform/gtk/TestExpectations: Unskip scroll snap tests.
* platform/wpe/TestExpectations: Ditto.
* resources/ui-helper.js:
(window.UIHelper.waitForTargetScrollAnimationToSettle): Added a new helper that
uses rAF to detect when an animated scroll operation has finished. This is the
same strategy that the WPT tests use to detect this.

Canonical link: https://commits.webkit.org/234268@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@273070 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-18 08:49:40 +00:00
Aditya Keerthi babd3562c1 [iOS][FCR] Use UIColorPickerViewController for color inputs
https://bugs.webkit.org/show_bug.cgi?id=221572
<rdar://problem/72183130>

Reviewed by Sam Weinig.

Source/WebCore:

* html/HTMLInputElement.h:

Export function so it can be called from WebKit layer.

Source/WebKit:

UIColorPickerViewController was added in iOS 14, while WebKit still
uses a custom color picker. To stay consistent with the rest of the
platform, this patch drops the custom color picker and adopts
UIColorPickerViewController for <input type=color> on iOS.

Test: fast/forms/ios/choose-color-from-color-picker.html

* Platform/spi/ios/UIKitSPI.h:

Added SPI declarations for _UISheetPresentationController and
UIColorPickerViewController.

* Shared/FocusedElementInformation.cpp:
(WebKit::FocusedElementInformation::encode const):
(WebKit::FocusedElementInformation::decode):
* Shared/FocusedElementInformation.h:

Added colorValue member to avoid parsing the input's value
in the UIProcess.

* SourcesCocoa.txt:
* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView setSelectedColorForColorPicker:]):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _shouldShowAutomaticKeyboardUIIgnoringInputMode]):
(-[WKContentView _elementTypeRequiresAccessoryView:]):

The new color picker does not appear as a keyboard input view.

(-[WKContentView updateFocusedElementValueAsColor:]):
(-[WKContentView setSelectedColorForColorPicker:]):
* UIProcess/ios/forms/WKFormColorControl.h:
* UIProcess/ios/forms/WKFormColorControl.mm:
(-[WKColorPicker initWithView:]):
(-[WKColorPicker selectColor:]):

Note that the delegate method is not called when programmatically
setting the selected color.

(-[WKColorPicker focusedElementSuggestedColors]):

Suggested colors from a <datalist> element are displayed in the
favorites view.

(-[WKColorPicker updateColorPickerState]):
(-[WKColorPicker configurePresentation]):

On iPad, the color picker is displayed a popover. On iPhone, the picker
is displayed as a half-sheet, and can be dragged up into a fullscreen
view.

(-[WKColorPicker controlBeginEditing]):
(-[WKColorPicker controlEndEditing]):
(-[WKColorPicker presentationControllerDidDismiss:]):
(-[WKColorPicker colorPickerViewControllerDidSelectColor:]):
(-[WKColorPicker colorPickerViewControllerDidFinish:]):
(-[WKFormColorControl initWithView:]):
(-[WKFormColorControl selectColor:]):
* UIProcess/ios/forms/WKFormColorPicker.h: Removed.
* UIProcess/ios/forms/WKFormColorPicker.mm: Removed.
* UIProcess/ios/forms/WKFormSelectPicker.h:

Build fix.

* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getFocusedElementInformation):

Tools:

Added UIScriptController hooks to simulate selecting a color on the
new color picker.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::setSelectedColorForColorPicker):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::setSelectedColorForColorPicker):

LayoutTests:

Added a test which displays the new color picker and verifies that
selecting a color updates the corresponding input's value.

* fast/forms/color/color-input-activate-crash.html:

Replaced call to activateElementAndWaitForInputSession with
activateElement and ensurePresentationUpdate, since tapping on a
color input no longer presents a keyboard input view.

* fast/forms/ios/choose-color-from-color-picker-expected.txt: Added.
* fast/forms/ios/choose-color-from-color-picker.html: Added.
* resources/ui-helper.js:
(UIHelper.setSelectedColorForColorPicker):


Canonical link: https://commits.webkit.org/233861@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272597 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-09 19:25:04 +00:00
Wenson Hsieh bf602c3f32 REGRESSION (r271660): Unable to interact with page after long-pressing image on images.google.com
https://bugs.webkit.org/show_bug.cgi?id=221584
<rdar://problem/74073581>

Reviewed by Andy Estes.

Source/WebKit:

After long pressing on an image with an active touchend event listener, it's possible to sometimes get stuck in
a state where further interaction with the page is impossible, due to all gesture recognizers (except for the
touchend deferral gestures) remaining in either Failed or Ended state.

When presenting the context menu with a long press, the touch event gesture transitions to Failed state due to
the active touch being cancelled. Normally, this invokes `-_webTouchEventsRecognized:` with all touch points
being released, which allows us to "lift" the deferred gesture gate by failing any deferring gesture recognizers
that are still in Possible state (i.e. deferring native gestures).

However, it's possible for touch deferring gestures (in particular, the touchend deferrer) introduced in r271660
to end (i.e. call `-touchesEnded:withEvent:`) before the touch event gesture gets a chance to call
`-_webTouchEventsRecognized:`. In this scenario, the touch end deferral gesture remains in Possible state, and
prevents the touch event gesture from subsequently firing its action (`-_webTouchEventsRecognized:`), presumably
because UIKit is waiting for all other gestures in the same subgraph as the touch event gesture recognizer to
Fail.

This effectively results in a gesture "deadlock", since the web touch event gesture recognizer won't call
`-_webTouchEventsRecognized:` until the touch end deferring gesture has failed, and the touch end deferring
gesture won't fail until `-_webTouchEventsRecognized:` is called. To fix this, we restore a bit of logic that
was removed with r271193, such that we allow our deferring gesture recognizers to transition to Failed state
underneath `-touchesEnded:withEvent:`, as long it's [1] not actively deferring any native gestures, and [2] the
web touch event gesture has already failed, so we aren't expecting a subsequent call to
`-_webTouchEventsRecognized:` until the deferring gesture has failed.

Note that this check for the touch event gesture recognizer's state (condition [2] above) is necessary to
prevent the touchend deferring gesture from failing prematurely (i.e. right before we're about to dispatch
preventable `touchend` events).

Test: fast/events/touch/ios/tap-after-long-press-on-image.html

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _isTouchStartDeferringGesture:]):
(-[WKContentView _isTouchEndDeferringGesture:]):
(-[WKContentView deferringGestureRecognizer:didEndTouchesWithEvent:]):

Add a delegate hook when a deferring gesture's ends touches; use this hook in `WKContentView` to "lift" the
gesture gate if needed, in the case where the touch event gesture recognizer has already failed and we can't
expect `-_webTouchEventsRecognized:` to be called with all touch points released.

(-[WKContentView contextMenuInteraction:willEndForConfiguration:animator:]):

Add a missing call to `-[WKWebView _didDismissContextMenu]` here to make `UIHelper.waitForContextMenuToHide()`
actually work with image and link context menus in WebKitTestRunner.

* UIProcess/ios/WKDeferringGestureRecognizer.h:
* UIProcess/ios/WKDeferringGestureRecognizer.mm:
(-[WKDeferringGestureRecognizer touchesEnded:withEvent:]):

LayoutTests:

Add a new layout test that (sometimes) exercises the problem. Given the nature of the bug, it doesn't seem
possible to write a test that reproduces the bug 100% of the time. See WebKit ChangeLog for more details.

* fast/events/touch/ios/tap-after-long-press-on-image-expected.txt: Added.
* fast/events/touch/ios/tap-after-long-press-on-image.html: Added.
* resources/ui-helper.js:
(UIHelper.EventStreamBuilder.prototype.wait):

Add a helper to simply increment the time offset when building an event stream.


Canonical link: https://commits.webkit.org/233856@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272584 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-09 17:57:55 +00:00
Aditya Keerthi f5b52e69f1 [macOS] Selecting a date on datetime-local inputs unexpectedly adds second and millisecond fields
https://bugs.webkit.org/show_bug.cgi?id=221350
<rdar://problem/73943517>

Reviewed by Devin Rousso.

Source/WebCore:

Currently, when setting the value of a datetime-local input using the
picker, the length of the current value of the input is used to determine
whether or not to return a value with second/millisecond precision.

This is approach is incorrect, since the value could be empty, while the
step attribute can specify second/millisecond precision. To fix, ensure
the DateTimeChooserParameters knows whether the input has second and
millisecond fields. That information can then be used by the UIProcess
to return a correctly formatted value to the WebProcess.

Test: fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker.html

* html/BaseDateAndTimeInputType.cpp:
(WebCore::BaseDateAndTimeInputType::handleDOMActivateEvent):
(WebCore::BaseDateAndTimeInputType::didChangeValueFromControl):
(WebCore::BaseDateAndTimeInputType::setupDateTimeChooserParameters):

Moved this method from HTMLInputElement to the input type, since it is
specific to date/time input types, and to leverage the existing
shouldHaveSecondField and shouldHaveMillisecondField methods when
building the DateTimeChooserParameters.

* html/BaseDateAndTimeInputType.h:
* html/HTMLInputElement.cpp:
* html/HTMLInputElement.h:
* platform/DateTimeChooserParameters.h:

Added hasSecondField and hasMillisecondField members, so that the UIProcess
knows whether or not to return a string that contains seconds/milliseconds.

(WebCore::DateTimeChooserParameters::encode const):
(WebCore::DateTimeChooserParameters::decode):

Source/WebKit:

* UIProcess/mac/WebDateTimePickerMac.mm:
(-[WKDateTimePicker updatePicker:]):
(-[WKDateTimePicker dateFormatStringForType:]):

Do not use the length of the value to determine whether or seconds and
milliseconds should be present, since the value can be empty.

Instead, use the new information in DateTimeChooserParameters, matching
the visual appearance of the input.

Tools:

Added a method to UIScriptController to simulate selecting a date using
the presented date picker.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::chooseDateTimePickerValue):
* WebKitTestRunner/mac/UIScriptControllerMac.h:
* WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptControllerMac::chooseDateTimePickerValue):

LayoutTests:

Added a test to to verify that the presence of seconds and milliseconds
in the value of a datetime-local input after selecting a date using the
picker matches the configuration.

* fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker-expected.txt: Added.
* fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker.html: Added.
* resources/ui-helper.js:
(window.UIHelper.chooseDateTimePickerValue):


Canonical link: https://commits.webkit.org/233696@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272368 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-04 14:59:24 +00:00
Aditya Keerthi 27da6af7a7 [iOS][FCR] Add new picker for select elements
https://bugs.webkit.org/show_bug.cgi?id=221153
<rdar://problem/73770389>

Reviewed by Tim Horton.

Source/WebKit:

Tapping on a select element should display an context menu that allows
users to choose one of the specified options. Rather than presenting a
UIPickerView, tapping on select elements now create UIContextMenuInteractions,
similar to date and file inputs.

Test: fast/forms/ios/form-control-refresh/select/choose-select-option.html

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _shouldShowAutomaticKeyboardUIIgnoringInputMode]):

The new picker does not bring up the keyboard view on all devices.

(-[WKContentView _elementTypeRequiresAccessoryView:]):

Changed from a static method to an instance method, as the returned
value depends on a flag which is only accessible through the instance.

(-[WKContentView requiresAccessoryView]):
(-[WKContentView _formControlRefreshEnabled]):
(-[WKContentView _shouldShowKeyboardForElement:]):
(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]):
(-[WKContentView _removeContextMenuViewIfPossible]):

Do not remove the context menu if an select element is actively being
interacted with.

(-[WKContentView selectControl]):
* UIProcess/ios/forms/WKFormSelectControl.mm:
(-[WKFormSelectControl initWithView:]):
* UIProcess/ios/forms/WKFormSelectPicker.h:
* UIProcess/ios/forms/WKFormSelectPicker.mm:
(-[WKSelectPicker initWithView:]):
(-[WKSelectPicker controlView]):
(-[WKSelectPicker controlBeginEditing]):

Ensure the position information is up-to-date prior to presenting the
context menu.

(-[WKSelectPicker controlEndEditing]):
(-[WKSelectPicker dealloc]):
(-[WKSelectPicker didSelectOptionIndex:]):
(-[WKSelectPicker createMenu]):

Build the menu using UIActions and UIMenus. Since optgroup elements
cannot be nested, only the root UIMenu can contain UIMenus. Submenus
can only contain UIActions.

(-[WKSelectPicker actionForOptionItem:withIndex:]):
(-[WKSelectPicker contextMenuInteraction:previewForHighlightingMenuWithConfiguration:]):
(-[WKSelectPicker _contextMenuInteraction:styleForMenuWithConfiguration:]):
(-[WKSelectPicker contextMenuInteraction:configurationForMenuAtLocation:]):
(-[WKSelectPicker contextMenuInteraction:willDisplayMenuForConfiguration:animator:]):
(-[WKSelectPicker contextMenuInteraction:willEndForConfiguration:animator:]):
(-[WKSelectPicker removeContextMenuInteraction]):
(-[WKSelectPicker ensureContextMenuInteraction]):
(-[WKSelectPicker showSelectPicker]):
(-[WKSelectPicker selectRow:inComponent:extendingSelection:]):

Implement method for testing select pickers.

LayoutTests:

* fast/forms/ios/form-control-refresh/select/choose-select-option-expected.txt: Added.
* fast/forms/ios/form-control-refresh/select/choose-select-option.html: Added.
* resources/ui-helper.js:
(window.UIHelper.waitForContextMenuToShow):

Added a new UIHelper method to wait until a context menu is displayed.


Canonical link: https://commits.webkit.org/233662@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272334 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-03 20:27:31 +00:00
Simon Fraser 0ff9a3440e [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
https://bugs.webkit.org/show_bug.cgi?id=220886
<rdar://71177566>

Reviewed by Sam Weinig.
Source/WebCore:

theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
that alter the page height; this caused the post-layout updateScrollbars() called from
FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
to the allowed range.

If the page laid out while rubberbanding was happening, the current scroll position would
be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
triggering the jump to top in the UI process.

There's existing code to prevent this from happening if we know that rubberbanding is
happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
by having updateVisibleContentRects() push information about rubberbanding nodes onto
RemoteScrollingCoordinator.

We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
won't see any rubberbanding nodes anyway.

Test: fast/scrolling/ios/content-size-change-during-rubberband.html

* page/FrameView.cpp:
(WebCore::FrameView::isRubberBandInProgress const):
* page/FrameView.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::updateScrollbars):

Source/WebKit:

theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
that alter the page height; this caused the post-layout updateScrollbars() called from
FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
to the allowed range.

If the page laid out while rubberbanding was happening, the current scroll position would
be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
triggering the jump to top in the UI process.

There's existing code to prevent this from happening if we know that rubberbanding is
happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
by having updateVisibleContentRects() push information about rubberbanding nodes onto
RemoteScrollingCoordinator.

We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
won't see any rubberbanding nodes anyway.

* UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
* WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h:
* WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm:
(WebKit::RemoteScrollingCoordinator::addNodeWithActiveRubberBanding):
(WebKit::RemoteScrollingCoordinator::removeNodeWithActiveRubberBanding):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::updateVisibleContentRects):

Tools:

Add test infrastructure to allow UIScriptController::scrollToOffset() and
UIScriptController::immediateScrollToOffset() to take an options argument with
a 'unconstrained' property, which allows scrolling to unstable offset to simulate
rubberbanding.

* DumpRenderTree/ios/UIScriptControllerIOS.h:
* DumpRenderTree/ios/UIScriptControllerIOS.mm:
(WTR::contentOffsetBoundedIfNecessary):
(WTR::UIScriptControllerIOS::scrollToOffset):
(WTR::UIScriptControllerIOS::immediateScrollToOffset):
(WTR::contentOffsetBoundedInValidRange): Deleted.
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::scrollToOffset):
(WTR::UIScriptController::immediateScrollToOffset):
* TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
(WTR::toScrollToOptions):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::contentOffsetBoundedIfNecessary):
(WTR::UIScriptControllerIOS::scrollToOffset):
(WTR::UIScriptControllerIOS::immediateScrollToOffset):
(WTR::contentOffsetBoundedInValidRange): Deleted.

LayoutTests:

Add test infrastructure to allow UIScriptController::scrollToOffset() and
UIScriptController::immediateScrollToOffset() to take an options argument with
a 'unconstrained' property, which allows scrolling to unstable offset to simulate
rubberbanding.

* fast/scrolling/ios/content-size-change-during-rubberband-expected.txt: Added.
* fast/scrolling/ios/content-size-change-during-rubberband.html: Added.
* resources/ui-helper.js:
(window.UIHelper.scrollTo.return.new.Promise.):
(window.UIHelper.scrollTo.return.new.Promise):
(window.UIHelper.scrollTo):
(window.UIHelper.immediateScrollTo):
(window.UIHelper.immediateUnstableScrollTo):


Canonical link: https://commits.webkit.org/233292@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271786 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-25 00:47:32 +00:00
Aditya Keerthi 021c2bffbc [Contact Picker API] Add support for picker UI on iOS
https://bugs.webkit.org/show_bug.cgi?id=218189
<rdar://problem/69862277>

Reviewed by Devin Rousso.

Source/WebKit:

ContactsManager.select() should present a contact picker on platforms
which support one. This patch enables the end-to-end functionality on
iOS, presenting a contact picker upon a call to the API and returning
the selected contacts upon dismissal.

Tests: contact-picker/contacts-select-after-dismissing-picker.html
       contact-picker/contacts-select-while-presenting-picker.html
       contact-picker/contacts-select.html

* Platform/spi/Cocoa/ContactsUISPI.h: Added.
* SourcesCocoa.txt:
* UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
* UIProcess/API/Cocoa/WKWebViewTesting.mm:
(-[WKWebView _didPresentContactPicker]):
(-[WKWebView _didDismissContactPicker]):
(-[WKWebView _dismissContactPickerWithContacts:]):
* UIProcess/Cocoa/WKContactPicker.h: Added.
* UIProcess/Cocoa/WKContactPicker.mm: Added.

WKContactPicker is a WebKit wrapper around CNContactPickerViewController.

(-[WKCNContactPickerDelegate initWithContactPickerDelegate:]):

WKCNContactPickerDelegate is wrapper around CNContactPickerDelegate.
This is necessary as single/multiple selection in a
CNContactPickerViewController is determined by which delegate methods
are implemented. The two specializations of this class include the
methods necessary to present a single-select and multi-select picker
respectively.

(-[WKCNContactPickerDelegate contactPickerDidCancel:]):
(-[WKCNContactPickerSingleSelectDelegate contactPicker:didSelectContact:]):
(-[WKCNContactPickerMultiSelectDelegate contactPicker:didSelectContacts:]):
(-[WKContactPicker delegate]):
(-[WKContactPicker setDelegate:]):
(-[WKContactPicker initWithView:]):
(-[WKContactPicker presentWithRequestData:completionHandler:]):
(-[WKContactPicker contactPickerDidCancel:]):

This delegate method is called when the picker is dismissed by
tapping the done button or when the picker is dismissed by swiping
down.

(-[WKContactPicker contactPicker:didSelectContact:]):
(-[WKContactPicker contactPicker:didSelectContacts:]):
(-[WKContactPicker _contactPickerDidDismissWithContactInfo:]):
(-[WKContactPicker _contactInfoFromCNContact:]):
(-[WKContactPicker dismissWithContacts:]):
(-[WKContactPicker _contactsFromJSContacts:]):
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::showContactPicker):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _showContactPicker:completionHandler:]):
(-[WKContentView contactPickerDidPresent:]):
(-[WKContentView contactPickerDidDismiss:]):
(-[WKContentView _dismissContactPickerWithContacts:]):
* WebKit.xcodeproj/project.pbxproj:

Source/WTF:

* wtf/PlatformHave.h:

Added HAVE(CONTACTSUI) and HAVE(CNCONTACTPICKERVIEWCONTROLLER) macros.

Tools:

Added UIScriptController hooks to observe the presentation and
dismissal of a contact picker. Furthermore, the
dismissContactPickerWithContacts method was added to allow tests to
dismiss the presented contact picker with a set of selected contacts.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptContext.h:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::isShowingContactPicker const):
(WTR::UIScriptController::dismissContactPickerWithContacts):
* TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
(WTR::UIScriptController::setDidShowContactPickerCallback):
(WTR::UIScriptController::didShowContactPickerCallback const):
(WTR::UIScriptController::setDidHideContactPickerCallback):
(WTR::UIScriptController::didHideContactPickerCallback const):
* WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
* WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView resetInteractionCallbacks]):
(-[TestRunnerWKWebView _didPresentContactPicker]):
(-[TestRunnerWKWebView _didDismissContactPicker]):
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.h:
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm:
(WTR::UIScriptControllerCocoa::setDidShowContactPickerCallback):
(WTR::UIScriptControllerCocoa::setDidHideContactPickerCallback):
(WTR::UIScriptControllerCocoa::isShowingContactPicker const):
(WTR::UIScriptControllerCocoa::dismissContactPickerWithContacts):

LayoutTests:

Added tests to verify the presentation and dismissal of a contact
picker on iOS. The new tests are only run on iOS WK2, since that is the
only platform which currently supports the presentation of a contact
picker. Note that these tests will be enabled on macOS WK2 once support
is added in a forthcoming patch.

* TestExpectations:
* contact-picker/contacts-select-after-dismissing-picker-expected.txt: Added.
* contact-picker/contacts-select-after-dismissing-picker.html: Added.
* contact-picker/contacts-select-expected.txt: Added.
* contact-picker/contacts-select-while-presenting-picker-expected.txt: Added.
* contact-picker/contacts-select-while-presenting-picker.html: Added.
* contact-picker/contacts-select.html: Added.
* platform/ios-wk2/TestExpectations:
* resources/ui-helper.js:
(window.UIHelper.waitForContactPickerToShow):
(window.UIHelper.waitForContactPickerToHide):
(window.UIHelper.dismissContactPickerWithContacts):


Canonical link: https://commits.webkit.org/231232@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269394 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-11-04 22:36:46 +00:00
Tetsuharu Ohzeki 01cdf95ae6 Accessory bar next/previous buttons do not work on inputs in shadow roots
https://bugs.webkit.org/show_bug.cgi?id=203292

Patch by Tetsuharu Ohzeki <tetsuharu.ohzeki@gmail.com> on 2020-10-27
Reviewed by Ryosuke Niwa.

Source/WebCore:

Tests: fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree.html

* page/FocusController.cpp:
(WebCore::FocusController::nextFocusableElement):
(WebCore::FocusController::previousFocusableElement):

LayoutTests:

Introduced testcases only need to run with iOS family.

* fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree-expected.txt: Added.
* fast/shadow-dom/ios/accessory-bar-work-on-input-with-tabindex-in-shadow-tree.html: Added.
* TestExpectations:
* platform/ios/TestExpectations:
  Avoid to run introduced tests because we don't have to run them and
  tests are crashed on these platforms.
* resources/ui-helper.js:
(window.UIHelper.moveToNextByKeyboardAccessoryBar):
(window.UIHelper.moveToPrevByKeyboardAccessoryBar):
(window.UIHelper):

Canonical link: https://commits.webkit.org/230950@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269059 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-10-27 18:51:38 +00:00
Aditya Keerthi c3c20bd9f3 [iOS] Prevent presentation of input peripherals when focusing form controls with a validation message
https://bugs.webkit.org/show_bug.cgi?id=218004
<rdar://problem/70507678>

Reviewed by Wenson Hsieh.

Source/WebCore:

Added isFocusingWithValidationMessage() to HTMLFormControlElement so
that the state can be encoded in FocusedElementInformation and sent to
the UIProcess.

See WebKit Changelog for more information.

Test: fast/forms/ios/input-peripherals-with-validation-message.html

* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::isFocusingWithValidationMessage const):
(WebCore::HTMLFormControlElement::focusAndShowValidationMessage):
* html/HTMLFormControlElement.h:

Source/WebKit:

Interactive form validation can result in the presentation of a
validation message bubble near the first form control that has invalid
data. Prior to displaying the message, the invalid control is focused.
On iOS, this also has the effect of also presenting a virtual keyboard
or another custom input peripheral, such as a context menu for date
inputs.

Attempting to present both the validation message and custom input
peripheral can leave the view in an inconsistent state. For example,
<select> popovers have a strange flashing behavior when presented
alongside a validation message, and context menus can fail to present
entirely.

In order to address these issues, we should never attempt to present
both a validation message and an input peripheral. Instead, we can
prevent the presentation of input peripherals when the focused control
is presenting a validation message. This behavior matches macOS. Note
that we still present the keyboard for controls that have a keyboard
view, since the keyboard area does overlap the area where a validation
message is presented.

* Shared/FocusedElementInformation.cpp:
(WebKit::FocusedElementInformation::encode const):
(WebKit::FocusedElementInformation::decode):
* Shared/FocusedElementInformation.h:

Added isFocusingWithValidationMessage to the struct, so that the UIProcess
knows that the element gained focus due to the presentation of a
validation message.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]):

Prevent an input view from being shown if the control does not present
a keyboard and was focused with a validation message.

(-[WKContentView _elementDidBlur]):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getFocusedElementInformation):

LayoutTests:

Added a test which verifies that focusing on a date input as a result
of presenting a validation message, successfully presents the message,
and does not present a context menu. The test also ensures that controls
that present a keyboard, such as text inputs, present both the message
and the keyboard.

* fast/forms/ios/input-peripherals-with-validation-message-expected.txt: Added.
* fast/forms/ios/input-peripherals-with-validation-message.html: Added.
* resources/ui-helper.js:
(window.UIHelper.isShowingPopover):


Canonical link: https://commits.webkit.org/230794@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@268866 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-10-22 15:55:54 +00:00
Megan Gardner 032826b76f Stop gap patch fix for regression in r267329.
https://bugs.webkit.org/show_bug.cgi?id=218020
Source/WebCore:

<rdar://problem/69542459>

Reviewed by Darin Adler.

The refactoring in https://bugs.webkit.org/show_bug.cgi?id=216739 caused selections to
expand in both directions after a double-click and drag to expand on mac. This behavior
was not observed on iOS. This removes the error-prone calculation.
Note that this bug does not occur if only testing immediatly moving the drag point to the
end of the selection. Dragging across all the words as a real user would needs to be emulated.

Test: editing/selection/double-click-and-drag-over-anchor-to-select.html

* editing/VisibleSelection.cpp:
(WebCore::VisibleSelection::validate):

LayoutTests:

Reviewed by Darin Adler.

* editing/selection/double-click-and-drag-over-anchor-to-select-expected.txt: Added.
* editing/selection/double-click-and-drag-over-anchor-to-select.html: Added.
* resources/ui-helper.js:
(window.UIHelper.doubleClickAtMouseDown):
(window.UIHelper.mouseUp):
(window.UIHelper.dragMouseAcrossElement):
(window.UIHelper.doubleClickElementMouseDown):


Canonical link: https://commits.webkit.org/230775@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@268847 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-10-22 00:40:55 +00:00
Tim Horton 0aa9bc32fa iOS: <attachment>'s QuickLook thumbnails can appear squished
https://bugs.webkit.org/show_bug.cgi?id=216209
<rdar://problem/67817706>

Reviewed by Wenson Hsieh.

Source/WebCore:

Test: fast/attachment/attachment-thumbnail-preserves-aspect-ratio.html

* html/HTMLAttachmentElement.idl:
* testing/Internals.cpp:
(WebCore::Internals::attachmentThumbnailInfo):
* testing/Internals.h:
* testing/Internals.idl:
Expose the attachment thumbnail size via Internals.

* rendering/RenderThemeIOS.mm:
(WebCore::RenderAttachmentInfo::RenderAttachmentInfo):
Allow the thumbnail aspect ratio to vary, instead of assuming it is always square.

Source/WebKit:

* UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::convertPlatformImageToBitmap):
Propagate an image of the same aspect ratio that QuickLook provided,
instead of squishing it to square.

* UIProcess/QuickLookThumbnailLoader.mm:
(-[WKQLThumbnailLoadOperation start]):
Only request full thumbnails; we do not want the icon form, since <attachment>
already has one without QuickLook's help; if we can't get a full thumbnail,
we'll just leave it alone.

Tools:

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::insertAttachmentForFilePath):
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::currentTestURL const):
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.h:
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm:
(WTR::UIScriptControllerCocoa::insertAttachmentForFilePath):
Make it possible to insert an attachment wrapping a file on disk
via UIScriptController.

LayoutTests:

* fast/attachment/attachment-thumbnail-preserves-aspect-ratio-expected.txt: Added.
* fast/attachment/attachment-thumbnail-preserves-aspect-ratio.html: Added.
* fast/attachment/resources/400x200-circle.png: Added.
* platform/ios/fast/attachment/attachment-thumbnail-preserves-aspect-ratio-expected.txt: Added.
* resources/ui-helper.js:
(window.UIHelper.insertAttachmentForFilePath):
Add a test that dumps the thumbnail size for a 400x200 attachment.
We only run it on iOS, because on macOS, QuickLook always returns
an image of the size we ask for (400x400), padded with whitespace,
so the problem does not reproduce and the test doesn't work right there.
On iOS, the result used to be 400x400 and now is 400x200.

I tried and failed to make a more useful test (a ref test, actually
testing the presentation) because it's quite hard to match the
native <attachment> painting.


Canonical link: https://commits.webkit.org/229108@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@266743 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-09-08 19:47:05 +00:00
Aditya Keerthi c73d6e952d [macOS] Update date picker when the inner control is edited
https://bugs.webkit.org/show_bug.cgi?id=216004

Reviewed by Wenson Hsieh.

Source/WebCore:

The value of the attached date picker should match the value in the
inner control. In order to achieve this behavior, m_dateTimeChooser
is notified whenever didChangeValueFromControl is called.

Note that the attached date picker's value is not updated on a
programmatic edit (setting input.value), as a sudden change not
triggered by the user would result in a poor user experience.

Test: fast/forms/date/date-editable-components/date-picker-update-on-edit.html

* html/BaseChooserOnlyDateAndTimeInputType.cpp:
(WebCore::BaseChooserOnlyDateAndTimeInputType::didChangeValueFromControl):

Source/WebKit:

* UIProcess/mac/WebDateTimePickerMac.mm:
(WebKit::WebDateTimePickerMac::showDateTimePicker):

If showDateTimePicker is called while a picker is already being
displayed, call updatePicker: rather than showPicker:.

(-[WKDateTimePicker initWithParams:inView:]):

The NSDatePicker and NSDateFormatter should use a UTC timezone.
This is necessary as all double values passed into WKDateTimePicker
are UTC timestamps. This has no effect on the value returned to
the WebProcess on user selection, as a timezone-agnostic format
string is used.

(-[WKDateTimePicker updatePicker:]):

Set the date value of the owned NSDatePicker to the value in the
DateTimeChooserParameters.

Tools:

Added dateTimePickerValue testing hook in order to enable testing the
current value of the presented date picker. The returned value is a
UTC timestamp is milliseconds, matching the date input's valueAsNumber.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::dateTimePickerValue const):
* WebKitTestRunner/mac/UIScriptControllerMac.h:
* WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptControllerMac::dateTimePickerValue const):

LayoutTests:

Added a test to verify that the date picker is updated when the user edits the control.

* fast/forms/date/date-editable-components/date-picker-update-on-edit-expected.txt: Added.
* fast/forms/date/date-editable-components/date-picker-update-on-edit.html: Added.
* resources/ui-helper.js:
(window.UIHelper.dateTimePickerValue):


Canonical link: https://commits.webkit.org/228866@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@266461 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-09-02 15:35:57 +00:00
Tim Horton bd0ed21283 Remove unused editable image code
https://bugs.webkit.org/show_bug.cgi?id=215991

Reviewed by Simon Fraser.

Source/WebCore:

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* editing/EditAction.cpp:
(WebCore::undoRedoLabel):
* editing/EditAction.h:
* editing/Editor.cpp:
(WebCore::Editor::insertEditableImage): Deleted.
* editing/Editor.h:
* editing/EditorCommand.cpp:
(WebCore::createCommandMap):
(WebCore::executeInsertEditableImage): Deleted.
(WebCore::enabledInRichlyEditableTextWithEditableImagesEnabled): Deleted.
* editing/InsertEditableImageCommand.cpp: Removed.
* editing/InsertEditableImageCommand.h: Removed.
* en.lproj/Localizable.strings:
* html/HTMLAttributeNames.in:
* html/HTMLImageElement.cpp:
(WebCore::HTMLImageElement::parseAttribute):
(WebCore::HTMLImageElement::insertedIntoAncestor):
(WebCore::HTMLImageElement::removedFromAncestor):
(WebCore::HTMLImageElement::copyNonAttributePropertiesFromElement):
(WebCore::HTMLImageElement::supportsFocus const): Deleted.
(WebCore::HTMLImageElement::isFocusable const): Deleted.
(WebCore::HTMLImageElement::didFinishInsertingNode): Deleted.
(WebCore::HTMLImageElement::hasEditableImageAttribute const): Deleted.
(WebCore::HTMLImageElement::editableImageViewID const): Deleted.
(WebCore::HTMLImageElement::updateEditableImage): Deleted.
(WebCore::HTMLImageElement::defaultEventHandler): Deleted.
* html/HTMLImageElement.h:
* page/ChromeClient.h:
(WebCore::ChromeClient::associateEditableImageWithAttachment): Deleted.
(WebCore::ChromeClient::didCreateEditableImage): Deleted.
(WebCore::ChromeClient::didDestroyEditableImage): Deleted.
* page/EditableImageReference.cpp: Removed.
* page/EditableImageReference.h: Removed.
* page/Settings.yaml:
* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::nextEmbeddedViewID): Deleted.
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::setContentsToSolidColor):
(WebCore::GraphicsLayer::setContentsToEmbeddedView): Deleted.
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::createPlatformCALayerForEmbeddedView): Deleted.
(WebCore::GraphicsLayerCA::setContentsToEmbeddedView): Deleted.
* platform/graphics/ca/GraphicsLayerCA.h:
* platform/graphics/ca/PlatformCALayer.cpp:
(WebCore::operator<<):
* platform/graphics/ca/PlatformCALayer.h:
* platform/graphics/ca/cocoa/PlatformCALayerCocoa.h:
* platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
(WebCore::PlatformCALayerCocoa::PlatformCALayerCocoa):
(WebCore::PlatformCALayerCocoa::embeddedViewID const): Deleted.
* rendering/RenderImage.cpp:
(WebCore::RenderImage::isEditableImage const): Deleted.
(WebCore::RenderImage::requiresLayer const): Deleted.
* rendering/RenderImage.h:
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::shouldBeNormalFlowOnly const):
(WebCore::RenderLayer::calculateClipRects const):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateConfiguration):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingLayer const):
(WebCore::RenderLayerCompositor::requiresOwnBackingStore const):
(WebCore::RenderLayerCompositor::reasonsForCompositing const):
(WebCore::RenderLayerCompositor::requiresCompositingForEditableImage const): Deleted.
* rendering/RenderLayerCompositor.h:

Source/WebKit:

* DerivedSources.make:
* Platform/spi/ios/PencilKitSPI.h: Removed.
* Shared/FocusedElementInformation.cpp:
(WebKit::FocusedElementInformation::encode const):
(WebKit::FocusedElementInformation::decode):
* Shared/FocusedElementInformation.h:
* Shared/RemoteLayerTree/RemoteLayerBackingStore.mm:
(WebKit::RemoteLayerBackingStore::drawInContext):
* Shared/RemoteLayerTree/RemoteLayerTreeTransaction.h:
* Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::LayerCreationProperties::LayerCreationProperties):
(WebKit::RemoteLayerTreeTransaction::LayerCreationProperties::encode const):
(WebKit::RemoteLayerTreeTransaction::LayerCreationProperties::decode):
* Shared/WebPreferences.yaml:
* SourcesCocoa.txt:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _setupPageConfiguration:]):
* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration init]):
(-[WKWebViewConfiguration copyWithZone:]):
(-[WKWebViewConfiguration _setEditableImagesEnabled:]): Deleted.
(-[WKWebViewConfiguration _editableImagesEnabled]): Deleted.
* UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
* UIProcess/API/ios/WKWebViewIOS.h:
* UIProcess/API/ios/WKWebViewIOS.mm:
(-[WKWebView _setupScrollAndContentViews]):
(-[WKWebView _stylusTapGestureShouldCreateEditableImage]): Deleted.
* UIProcess/PageClient.h:
(WebKit::PageClient::createDrawingView): Deleted.
* UIProcess/RemoteLayerTree/RemoteLayerTreeHost.h:
* UIProcess/RemoteLayerTree/RemoteLayerTreeHost.mm:
(WebKit::RemoteLayerTreeHost::layerWillBeRemoved):
(WebKit::RemoteLayerTreeHost::clearLayers):
(WebKit::RemoteLayerTreeHost::makeNode):
* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm:
(WebKit::RemoteLayerTreeHost::makeNode):
(WebKit::RemoteLayerTreeHost::createEmbeddedView): Deleted.
* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h:
* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
(-[WKEmbeddedView initWithEmbeddedViewID:]): Deleted.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didAttachToRunningProcess):
(WebKit::WebPageProxy::resetState):
(WebKit::WebPageProxy::willUpdateAttachmentAttributes):
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::editableImageController): Deleted.
* UIProcess/ios/EditableImageController.h: Removed.
* UIProcess/ios/EditableImageController.messages.in: Removed.
* UIProcess/ios/EditableImageController.mm: Removed.
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::createDrawingView): Deleted.
* UIProcess/ios/PencilKitSoftLink.h: Removed.
* UIProcess/ios/PencilKitSoftLink.mm: Removed.
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView setUpInteraction]):
(-[WKContentView cleanUpInteraction]):
(-[WKContentView _removeDefaultGestureRecognizers]):
(-[WKContentView _addDefaultGestureRecognizers]):
(-[WKContentView gestureRecognizerShouldBegin:]):
(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]):
(-[WKContentView _elementDidBlur]):
(-[WKContentView _stylusSingleTapRecognized:]): Deleted.
(-[WKContentView _drawingCoordinator]): Deleted.
* UIProcess/ios/WKDrawingCoordinator.h: Removed.
* UIProcess/ios/WKDrawingCoordinator.mm: Removed.
* UIProcess/ios/WKDrawingView.h: Removed.
* UIProcess/ios/WKDrawingView.mm: Removed.
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::handleStylusSingleTapAtPoint): Deleted.
* UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm:
(WebKit::WebChromeClient::associateEditableImageWithAttachment): Deleted.
(WebKit::WebChromeClient::didCreateEditableImage): Deleted.
(WebKit::WebChromeClient::didDestroyEditableImage): Deleted.
* WebProcess/WebPage/RemoteLayerTree/GraphicsLayerCARemote.cpp:
(WebKit::GraphicsLayerCARemote::createPlatformCALayerForEmbeddedView): Deleted.
* WebProcess/WebPage/RemoteLayerTree/GraphicsLayerCARemote.h:
* WebProcess/WebPage/RemoteLayerTree/PlatformCALayerRemote.cpp:
(WebKit::PlatformCALayerRemote::createForEmbeddedView): Deleted.
(WebKit::PlatformCALayerRemote::embeddedViewID const): Deleted.
* WebProcess/WebPage/RemoteLayerTree/PlatformCALayerRemote.h:
* WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.mm:
(WebKit::RemoteLayerTreeContext::layerDidEnterContext):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::isAssistableElement):
(WebKit::WebPage::getFocusedElementInformation):
(WebKit::WebPage::handleStylusSingleTapAtPoint): Deleted.

Tools:

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::drawSquareInEditableImage): Deleted.
(WTR::UIScriptController::numberOfStrokesInEditableImage): Deleted.
* TestRunnerShared/spi/PencilKitTestSPI.h: Removed.
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
(webViewForTestingAttachments):
(TestWebKitAPI::forEachViewInHierarchy): Deleted.
(TestWebKitAPI::findEditableImageCanvas): Deleted.
(TestWebKitAPI::drawSquareInEditableImage): Deleted.
* TestWebKitAPI/ios/PencilKitTestSPI.h: Removed.
* WebKitTestRunner/TestController.cpp:
(WTR::updateTestOptionsFromTestHeader):
* WebKitTestRunner/TestOptions.h:
(WTR::TestOptions::hasSameInitializationOptions const):
* WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
* WebKitTestRunner/cocoa/TestControllerCocoa.mm:
(WTR::TestController::platformCreateWebView):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::findEditableImageCanvas const): Deleted.
(WTR::UIScriptControllerIOS::drawSquareInEditableImage): Deleted.
(WTR::UIScriptControllerIOS::numberOfStrokesInEditableImage): Deleted.

LayoutTests:

* editing/images/basic-editable-image-expected.txt: Removed.
* editing/images/basic-editable-image-from-execCommand-expected.txt: Removed.
* editing/images/basic-editable-image-from-execCommand.html: Removed.
* editing/images/basic-editable-image-with-gesture-expected.txt: Removed.
* editing/images/basic-editable-image-with-gesture.html: Removed.
* editing/images/basic-editable-image.html: Removed.
* editing/images/editable-image-creates-attachment-expected.txt: Removed.
* editing/images/editable-image-creates-attachment.html: Removed.
* editing/images/paste-editable-image-expected.txt: Removed.
* editing/images/paste-editable-image.html: Removed.
* editing/images/redo-insert-editable-image-maintains-strokes-expected.txt: Removed.
* editing/images/redo-insert-editable-image-maintains-strokes.html: Removed.
* editing/images/reparent-editable-image-maintains-strokes-expected.txt: Removed.
* editing/images/reparent-editable-image-maintains-strokes.html: Removed.
* editing/images/undo-insert-editable-image-expected.txt: Removed.
* editing/images/undo-insert-editable-image.html: Removed.
* resources/ui-helper.js:
(window.UIHelper.drawSquareInEditableImage): Deleted.
(window.UIHelper.numberOfStrokesInEditableImage): Deleted.


Canonical link: https://commits.webkit.org/228778@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@266342 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-08-31 03:26:23 +00:00
Aditya Keerthi f306f45ea9 [macOS] Show picker for date and datetime-local input types
https://bugs.webkit.org/show_bug.cgi?id=214946

Reviewed by Darin Adler and Wenson Hsieh.

Source/WebCore:

Date and datetime-local input types require a calendar picker to be presented when activated.
Consequently, BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent was modified to
create a DateTimeChooser and display a calendar upon activation. This object is destroyed
when the element is blurred, hiding the calendar.

There is currently no picker UI for month, week, and time input types. As a result,
handleDOMActivateEvent is a no-op on those input types.

Wrote an encoder and decoder for DateTimeChooserParameters, so that the picker can be
created with the correct values.

Tests: fast/forms/date/date-show-hide-picker.html
       fast/forms/datetimelocal/datetimelocal-show-hide-picker.html

* WebCore.xcodeproj/project.pbxproj:
* html/BaseChooserOnlyDateAndTimeInputType.cpp:
(WebCore::BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent):
(WebCore::BaseChooserOnlyDateAndTimeInputType::elementDidBlur):
(WebCore::BaseChooserOnlyDateAndTimeInputType::isPresentingAttachedView const):
(WebCore::BaseChooserOnlyDateAndTimeInputType::didChooseValue):
* html/BaseChooserOnlyDateAndTimeInputType.h:
* html/HTMLInputElement.cpp:
* html/MonthInputType.cpp:
(WebCore::MonthInputType::handleDOMActivateEvent):
* html/MonthInputType.h:
* html/TimeInputType.cpp:
(WebCore::TimeInputType::handleDOMActivateEvent):
* html/TimeInputType.h:
* html/WeekInputType.cpp:
(WebCore::WeekInputType::handleDOMActivateEvent):
* html/WeekInputType.h:
* loader/EmptyClients.cpp:
(WebCore::EmptyChromeClient::createDateTimeChooser):
* loader/EmptyClients.h:
* page/Chrome.cpp:
(WebCore::Chrome::createDateTimeChooser):
* page/Chrome.h:
* page/ChromeClient.h:
* platform/DateTimeChooser.h:
* platform/DateTimeChooserClient.h:
* platform/DateTimeChooserParameters.h: Added.
(WebCore::DateTimeChooserParameters::encode const):
(WebCore::DateTimeChooserParameters::decode):

Source/WebKit:

Created WKDateTimePicker as a wrapper around NSDatePicker. The picker is
displayed in its own NSWindow, ensuring the view is always above the page.
WebPageProxy and WKDateTimePicker communicate through WebDateTimePickerMac,
in order for the picker to be initialized with the correct initial, minimum,
and maximum date, and so that the chosen date can be sent back to the
WebProcess.

Added IPC messages to enable communication between the UIProcess and the
WebProcess necessary for showing and hiding the picker.

* Sources.txt:
* SourcesCocoa.txt:
* UIProcess/PageClient.h:
* UIProcess/WebDateTimePicker.cpp: Added.
(WebKit::WebDateTimePicker::WebDateTimePicker):
(WebKit::WebDateTimePicker::~WebDateTimePicker):
(WebKit::WebDateTimePicker::endPicker):
* UIProcess/WebDateTimePicker.h: Added.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::showDateTimePicker):
(WebKit::WebPageProxy::endDateTimePicker):
(WebKit::WebPageProxy::didChooseDate):
(WebKit::WebPageProxy::didEndDateTimePicker):
(WebKit::WebPageProxy::closeOverlayedViews):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::createDateTimePicker):
* UIProcess/mac/PageClientImplMac.h:
* UIProcess/mac/PageClientImplMac.mm:
(WebKit::PageClientImpl::createDateTimePicker):
* UIProcess/mac/WebDateTimePickerMac.h: Added.
* UIProcess/mac/WebDateTimePickerMac.mm: Added.
(WebKit::WebDateTimePickerMac::create):
(WebKit::WebDateTimePickerMac::~WebDateTimePickerMac):
(WebKit::WebDateTimePickerMac::WebDateTimePickerMac):
(WebKit::WebDateTimePickerMac::endPicker):
(WebKit::WebDateTimePickerMac::showDateTimePicker):
(WebKit::WebDateTimePickerMac::didChooseDate):
(-[WKDateTimePickerWindow initWithContentRect:styleMask:backing:defer:]):
(-[WKDateTimePickerWindow canBecomeKeyWindow]):
(-[WKDateTimePickerWindow hasKeyAppearance]):
(-[WKDateTimePickerWindow shadowOptions]):
(-[WKDateTimePicker initWithParams:inView:]):
(-[WKDateTimePicker showPicker:]):
(-[WKDateTimePicker invalidate]):
(-[WKDateTimePicker didChooseDate:]):
(-[WKDateTimePicker dateFormatStringForType:]):
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::createDateTimeChooser):
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebCoreSupport/WebDateTimeChooser.cpp: Added.
(WebKit::WebDateTimeChooser::WebDateTimeChooser):
(WebKit::WebDateTimeChooser::didChooseDate):
(WebKit::WebDateTimeChooser::didEndChooser):
(WebKit::WebDateTimeChooser::endChooser):
(WebKit::WebDateTimeChooser::showChooser):
* WebProcess/WebCoreSupport/WebDateTimeChooser.h: Added.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::setActiveDateTimeChooser):
(WebKit::WebPage::didChooseDate):
(WebKit::WebPage::didEndDateTimePicker):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Source/WebKitLegacy/mac:

* WebCoreSupport/WebChromeClient.h:
* WebCoreSupport/WebChromeClient.mm:
(WebChromeClient::createDateTimeChooser):

Tools:

Added isShowingDateTimePicker testing hook in order to enable testing of the visibility of
the picker.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::isShowingDateTimePicker const):
* WebKitTestRunner/mac/UIScriptControllerMac.h:
* WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptControllerMac::isShowingDateTimePicker const):

LayoutTests:

Added tests to verify that the picker is correctly shown and hidden for date and
datetime-local input types.

* fast/forms/date/date-show-hide-picker-expected.txt: Added.
* fast/forms/date/date-show-hide-picker.html: Added.
* fast/forms/datetimelocal/datetimelocal-show-hide-picker-expected.txt: Added.
* fast/forms/datetimelocal/datetimelocal-show-hide-picker.html: Added.
* platform/ios/TestExpectations:
* resources/ui-helper.js:
(window.UIHelper.isShowingDateTimePicker):


Canonical link: https://commits.webkit.org/228540@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@266063 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-08-24 16:25:10 +00:00
Wenson Hsieh b0e0e950d1 Programmatic selection of text in a text field causes the highlight overlay to spill out
https://bugs.webkit.org/show_bug.cgi?id=215647
<rdar://problem/67404979>

Reviewed by Darin Adler.

Source/WebCore:

See WebKit ChangeLog for more detail.

* html/HTMLTextFormControlElement.h: Export a helper function.

Source/WebKit:

UIKit consults the SPI method `-_selectionClipRect` on WKContentView to determine the maximum bounds in which it
is allowed to show text selection UI (i.e. the text caret view, selection highlight views, and selection
grabbers). Normally, when contentEditable elements and editable text form controls are focused, we plumb the
bounds of the focused element to the UI process via `focusedElementRect` in editor state's post layout data.
However, in this case, the selection is inside a readonly text field that is *not* focused; this causes us to
return `CGRectNull` from `-_selectionClipRect`, which means that UIKit selection UI is not clipped at all and
instead overflows the bounds of the input element.

To fix this, rearrange some logic in `WebPage::getPlatformEditorState` in `WebPageIOS.mm` such that we compute
and send the selection clipping rect if the selection is inside a text form control, even if it is not the
focused element. In doing this, we also rename some confusingly-named members in `EditorState::PostLayoutData`
(see below for more detail).

Test: editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html

* Platform/spi/ios/UIKitSPI.h:

Add a declaration for `-_selectionClipRect`.

* Shared/EditorState.cpp:
(WebKit::EditorState::PostLayoutData::encode const):
(WebKit::EditorState::PostLayoutData::decode):
(WebKit::operator<<):
* Shared/EditorState.h:

Split the existing rect member `focusedElementRect` into two: `selectionClipRect` on iOS, and
`selectionBoundingRect` on macOS. Previously, `focusedElementRect` was set to the focused element's bounding
rect on iOS (as expected), but on macOS, we set to the bounds of the ranged or caret selection; we proceed to
use this rect to mean the bounds of the selection anyways in macOS-specific code, so it makes more sense to just
move this into the macOS-specific section.

Additionally, after the below change in WebPageIOS, `focusedElementRect` is no longer specific to the focused
element, so rename it instead to `selectionClipRect` instead. In `WKContentViewInteraction.mm`, this rect is
effectively only used in two ways: as the selection clip rect for UIKit, and to determine if the selection would
be completely clipped anyways (in which case we suppress UIKit text interactions), so `selectionClipRect` is a
name that is suitable for both purposes.

* UIProcess/API/mac/WKWebViewTestingMac.mm:
(-[WKWebView _candidateRect]):
* UIProcess/Cocoa/WebViewImpl.mm:

Rename `focusedElementRect` to `selectionBoundingRect` on macOS.

(WebKit::WebViewImpl::handleRequestedCandidates):
* UIProcess/ios/WKContentViewInteraction.mm:

Rename `focusedElementRect` to `selectionClipRect` on iOS.

(WebKit::WKSelectionDrawingInfo::WKSelectionDrawingInfo):
(-[WKContentView _selectionClipRect]):

Change this to not require a focused element when returning the selection clip rect, and instead return the
editor state's selection clip rect as long as it is not empty.

(-[WKContentView _updateSelectionAssistantSuppressionState]):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getPlatformEditorState const):

Refactor this code to compute and send selectionClipRect as long as the selection is inside a form control or
editing host (not just when there is a focused element). Also leave a drive-by FIXME about using the focused
element (instead of the selection container node) when computing the caret color.

* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::getPlatformEditorState const):

Tools:

* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::clipSelectionViewRectToContentView):

Add a helper function to clip UIKit selection UI rects (for carets, selection grabbers, and ranged selection
highlights) to the content view's (WKContentView's) bounds, as well as the selection clip rect if it is nonnull.

(WTR::UIScriptControllerIOS::selectionStartGrabberViewRect const):
(WTR::UIScriptControllerIOS::selectionEndGrabberViewRect const):
(WTR::UIScriptControllerIOS::selectionCaretViewRect const):
(WTR::UIScriptControllerIOS::selectionRangeViewRects const):

LayoutTests:

* editing/selection/ios/select-all-in-readonly-input-does-not-overflow-expected.txt: Added.
* editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html: Added.

Add a new layout test to verify that the width of the selection view does not exceed the width of the readonly
input containing the selected text.

* resources/ui-helper.js:
(window.UIHelper.async waitForSelectionToAppear):

Adjust this UIHelper function to additionally resolve to the selection rects, so that it won't be necessary for
callers to ask for the selection view rects separately after waiting for selection views to appear.


Canonical link: https://commits.webkit.org/228528@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@266051 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-08-24 01:51:56 +00:00
Wenson Hsieh 2a8421421e [macOS] It should be possible to override spellchecking results in WebKitTestRunner
https://bugs.webkit.org/show_bug.cgi?id=215290

Reviewed by Devin Rousso.

Tools:

Refactor `setSpellCheckerResults` so that it is on `UIScriptController` instead of `TestRunner`, such that it
can be triggered asynchronously from a layout test. This allows the testing hook to work in WebKit2, where the
swizzled spell checker is in the UI process.

* DumpRenderTree/TestRunner.cpp:
(TestRunner::staticFunctions):
(setSpellCheckerResultsCallback): Deleted.
* DumpRenderTree/TestRunner.h:
* DumpRenderTree/ios/UIScriptControllerIOS.h:

Add a method implementation stub for iOS.

* DumpRenderTree/mac/TestRunnerMac.mm:
(TestRunner::setSpellCheckerResults): Deleted.
* DumpRenderTree/mac/UIScriptControllerMac.h:
* DumpRenderTree/mac/UIScriptControllerMac.mm:
(WTR::UIScriptControllerMac::setSpellCheckerResults):
* DumpRenderTree/win/TestRunnerWin.cpp:
(TestRunner::setSpellCheckerLoggingEnabled):
(TestRunner::setSpellCheckerResults): Deleted.
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::setSpellCheckerResults):
* TestRunnerShared/cocoa/LayoutTestSpellChecker.h:
* TestRunnerShared/cocoa/LayoutTestSpellChecker.mm:
(-[LayoutTestSpellChecker setResultsFromJSValue:inContext:]):
(-[LayoutTestSpellChecker setResultsFromJSObject:inContext:]): Deleted.
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/mac/TestControllerMac.mm:
(WTR::TestController::platformResetStateToConsistentValues):

Make sure that we uninstall the swizzled `LayoutTestSpellChecker` between tests.

* WebKitTestRunner/mac/UIScriptControllerMac.h:
* WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptControllerMac::setSpellCheckerResults):

LayoutTests:

* editing/spelling/markers-expected.txt:
* editing/spelling/markers.html:

Rewrite this layout test to use async-await, instead of asynchronously calling the recursive `done` function.
Additionally, adopt `UIHelper.setSpellCheckerResults`.

* editing/spelling/text-replacement-after-typing-to-word.html:

Adopt `UIHelper.setSpellCheckerResults`. This allows us to enable the test on macOS WebKit2, since the only
thing that prevented it from working before was the ability to `setSpellCheckerResults` in WebKit2.

* platform/mac-wk2/TestExpectations:
* resources/ui-helper.js:

Add a `UIHelper` method to override the system spell checker with given results.

(window.UIHelper.async setSpellCheckerResults):


Canonical link: https://commits.webkit.org/228074@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265396 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-08-07 23:05:36 +00:00
Simon Fraser bf6b30fcc3 Update event regions only once per frame
https://bugs.webkit.org/show_bug.cgi?id=215132
<rdar://problem/66533779>

Reviewed by Darin Adler.

Source/WebCore:

Event regions (for touch-action, editable areas etc) were updated as part of
compositing updates, but we only need their output once per rendering update, so
move their computation out of RenderLayerCompositor::updateBackingAndHierarchy()
and into a new RenderLayer tree walk that is called from Page::doAfterUpdateRendering().

RenderLayerBacking stores a dirty bit to track when regions need to be updated.

Reduces the amount of time spent in rendering updates when scrolling on facebook.com
on iPad, which has lots of discontiguous touch-action regions.

* dom/Document.cpp:
(WebCore::Document::updateEventRegions):
* dom/Document.h:
* page/Frame.cpp:
(WebCore::Frame::layerTreeAsText const):
* page/Page.cpp:
(WebCore::Page::doAfterUpdateRendering):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::calculateClipRects const):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::maintainsEventRegion const):
(WebCore::RenderLayerBacking::updateEventRegion):
* rendering/RenderLayerBacking.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateEventRegions):
(WebCore::RenderLayerCompositor::updateBackingAndHierarchy):
* rendering/RenderLayerCompositor.h:

LayoutTests:

Tests that dispatch mouseWheel events in a way that tests event regions need to wait
now for a rendering update. `await UIHelper.animationFrame()` is not enough, because
the function resumes inside a microtask at the end of the requestAnimationFrame callback,
which is before we've completed the rest of the rendering update, and thus before
the event regions have been updated.

In addition, `await UIHelper.animationFrame()` followed by eventSender calls to issue
wheel events actually trigger Page::updateRendering() re-entrancy, via the
WKBundlePageForceRepaint() in EventSendingController::mouseScrollByWithWheelAndMomentumPhases().

To fix this, add and use UIHelper.renderingUpdate(), which waits for a rAF and uses a setTimeout()
to get past the end of the current rendering update.

* fast/scrolling/mac/absolute-in-overflow-scroll-dynamic-expected.html:
* fast/scrolling/mac/absolute-in-overflow-scroll-dynamic.html:
* fast/scrolling/mac/absolute-in-overflow-scroll.html:
* fast/scrolling/mac/async-scroll-overflow-hidden-on-one-axis.html:
* fast/scrolling/mac/async-scroll-overflow-rtl-zoomed.html:
* fast/scrolling/mac/async-scroll-overflow-top-inset.html:
* fast/scrolling/mac/async-scroll-overflow.html:
* fast/scrolling/mac/clip-path-hit-test.html:
* fast/scrolling/mac/move-node-in-overflow-scroll.html:
* fast/scrolling/mac/overflow-scrolled-document.html:
* fast/scrolling/mac/overflow-zoomed-document.html:
* fast/scrolling/mac/overlapped-overflow-scroll.html:
* resources/ui-helper.js:
(window.UIHelper.async renderingUpdate):

Canonical link: https://commits.webkit.org/227970@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265289 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-08-05 16:36:43 +00:00
Wenson Hsieh 07a78ceef2 REGRESSION (r264170): fast/events/touch/ios/long-press-on-image.html times out
https://bugs.webkit.org/show_bug.cgi?id=215075
<rdar://problem/66294637>

Reviewed by Megan Gardner.

Tools:

This test started timing out after r264170, due to the `if (self.showingContextMenu)` early return added inside
`-[TestRunnerWKWebView _didShowContextMenu]`. If this test is run after another test that attempts to show a
context menu but does not dismiss it, we will begin the test in a state where `showingContextMenu` is already
set to `YES`, which means that `didShowContextMenuCallback` will never be invoked.

To address this, force any context menu interactions on `WKContentView` to dismiss between tests. See below for
more details.

* WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
* WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView immediatelyDismissContextMenuIfNeeded]):

When resetting state between tests, forcibly dismiss any context menus that were shown while running the
previous test and reset `showingContextMenu` back to `NO`.

(-[TestRunnerWKWebView contentView]):

Drive-by refactoring: add a readonly helper property to grab the WKWebView's content view for testing purposes,
and use this property instead of directly calling `-valueForKeyPath:` in a few places (see below).

* WebKitTestRunner/ios/PlatformWebViewIOS.mm:
(WTR::PlatformWebView::windowSnapshotImage):
* WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::notifyDone):
(WTR::TestController::platformResetStateToConsistentValues):
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::platformContentView const):
(WTR::UIScriptControllerIOS::calendarType const):

LayoutTests:

Drive-by fix: this helper function had intended to use the `didDismissContextMenuCallback` property to register
callbacks for context menu dismissal, but instead, it sets a new property (`didHideContextMenuCallback`) on
`UIScriptController` that doesn't actually have any effect. The purpose of doing this is to make it safe to
invoke `waitForInputSessionToDismiss()` in the middle of the context menu dismissal animation when dismissing
date pickers on iOS. While it seems that none of our existing tests currently depend on this behavior in order
to pass, it still seems important to fix to avoid timing out when using this helper method in the future.

* resources/ui-helper.js:
(window.UIHelper.waitForInputSessionToDismiss.return.new.Promise.):
(window.UIHelper.waitForInputSessionToDismiss.return.new.Promise):
(window.UIHelper.waitForInputSessionToDismiss):


Canonical link: https://commits.webkit.org/227897@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265211 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-08-03 20:29:17 +00:00
Chris Dumez 2ca4d3d4f3 [ iOS wk2 ] imported/w3c/web-platform-tests/web-share/share-without-user-gesture.https.html is a constant timeout
https://bugs.webkit.org/show_bug.cgi?id=214694
<rdar://problem/66001110>

Reviewed by Tim Horton.

Tools:

The test was failing because there was a share sheet still being presented from a previous Web Share test.
TestController::platformResetStateToConsistentValues() would wait for that share sheet to get dismiss and
would eventually give up and report the test as timing out. The issue is that WebKit layout test were
relying on a UIScriptController function to dismiss the share sheet but Web Platform Tests did not.
To address the issue, we now always promptly dismiss the share sheet in WebKitTestRunner, without the need
for a UIScriptController function call. The Share Sheet now gets dismissed promptly in both WebKit tests
and WPT tests.

For robustness, I also added code in WebKitTestRunner to dismiss any remaining presented view controller
after waiting, to avoid failing on the next test in such cases.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::setShareSheetCompletesImmediatelyWithResolution): Deleted.
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.h:
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm:
(WTR::UIScriptControllerCocoa::setShareSheetCompletesImmediatelyWithResolution): Deleted.
Delete UIScriptController.setShareSheetCompletesImmediatelyWithResolution() utility function for tests now
that it is the default in WebKit TestRunner.

* WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::platformResetStateToConsistentValues):
- Call _setShareSheetCompletesImmediatelyWithResolutionForTesting:YES on the test WKWebView instead of relying
  on individual tests to do that.
- For robustness, if there is still a presented view controller after waiting, we now dismiss it ourselves
  instead of failing. This otherwise leads to next test to be reported as failing (or timing out) because there
  is a presented view controller that remains from the previous test. Note that this is not needed to fix the
  layout test in question since we now properly dismiss the share UI in WPT tests but I still think it is a good
  thing to do for robustness and avoid test flakiness.

LayoutTests:

* fast/web-share/share-transient-activation-expired.html:
* fast/web-share/share-transient-activation.html:
* fast/web-share/share-with-files.html:
* fast/web-share/share-with-no-url.html:
* fast/web-share/share.html:
* platform/ios/TestExpectations:
* resources/ui-helper.js:
(window.UIHelper.setShareSheetCompletesImmediatelyWithResolution): Deleted.
Update existing layout test so stop calling UIHelper.setShareSheetCompletesImmediatelyWithResolution() now that it
is the default in WebKitTestRunner.

* platform/ios/TestExpectations:
Unskip test that is no longer timing out.


Canonical link: https://commits.webkit.org/227560@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@264834 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-07-24 16:44:55 +00:00
Wenson Hsieh 3e4731805f REGRESSION (r258871): Shift + click to extend selection loses currently selected text
https://bugs.webkit.org/show_bug.cgi?id=214617
<rdar://problem/64980223>

Reviewed by Megan Gardner.

Source/WebCore:

After the changes in r258871, shift clicking sometimes fails to preserve the existing selected text range on
macOS and iOS. The logic in `EventHandler::handleMousePressEventSingleClick` uses the `textDistance` helper
method to count the number of characters between the start of the current selection to the newly selected
extent, as well as the number of characters between the end of the current selection and the newly selected
extent position. It compares these two character counts, and attempts to choose the new selection extents in
such a way that maximizes the amount of selected text.

However, after r258871, `textDistance` uses `characterCount` instead of `TextIterator::rangeLength`. Unlike the
former, `rangeLength` is robust in the case where the start position comes after the end position (in document
order), since the process of creating a live `Range` object swaps the start and end if needed. This isn't the
case when using `SimpleRange`. Instead, when given a simple range where the start comes after the end,
`characterCount` will iterate text in the DOM, starting from the start position and ending at the end of the
document rather than the end position. The result is that `characterCount` actually counts the number of
characters between the start position and the end of the document, rather than the number of characters between
the two positions.

In the context of this bug, if the start of the current selection is "far away" (in terms of character count)
from the end of the document and the new extent position comes after end of the current selection, we will end
up choosing the end (instead of the start) as one of the new extents of the updated selection.

To fix this (as well as other similar issues that might've arisen when replacing uses of
`TextIterator::rangeLength` with `characterCount`), simply teach `characterCount` to flip the start and end
positions if the end position of the `SimpleRange` comes before the start.

Test: editing/selection/shift-click-includes-existing-selection.html

* editing/TextIterator.cpp:
(WebCore::characterCount):

LayoutTests:

Add a new layout test to verify that the bug does not occur.

* editing/mac/spelling/autocorrection-contraction-expected.txt:

Rebaseline an existing layout test, restoring the test expectations to what they were prior to r258871. It seems
that the more recently added expectations (while not seemingly incorrect) were dependent on `characterCount`
computing the number of characters from the start position to the end of the document, rather than the end.

* editing/selection/shift-click-includes-existing-selection-expected.txt: Added.
* editing/selection/shift-click-includes-existing-selection.html: Added.
* resources/ui-helper.js:
(window.UIHelper.activateAt.return.new.Promise):
(window.UIHelper.activateAt):
(window.UIHelper.activateElement):

Add an optional `modifiers` argument to the `activateAt` and `activateElement` helper methods, which can be used
to simulate key modifiers being held while synthesizing the "activation" (i.e. tap or click).


Canonical link: https://commits.webkit.org/227435@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@264690 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-07-22 02:47:29 +00:00
Megan Gardner 4d50718854 Selection is not always clearing when tapping.
https://bugs.webkit.org/show_bug.cgi?id=214326
Source/WebKit:

<rdar://problem/65069201>

Reviewed by Wenson Hsieh.

In r262280 we stopped the UIWKGestureOneFingerTap gesture from starting if the tap was not inside
the current selection. That caused the selection to not always be cleared, especially when tapping
on an element that could create an overlay in which the selection was supposed to be obscured. We
short circuited this gesture because it used to cause a sync IPC message to be sent to the web process,
but that code has subsequently changed, so allowing the gesture to start and clear the selection in all
cases is no longer a performance concern, so changing the behavior back to allowing the gesture to always
start, even if the touch is not inside the selection rect.

Test: editing/selection/ios/hide-selection-after-tap-on-prevent-default-element.html

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):

LayoutTests:

Reviewed by Wenson Hsieh.

* editing/selection/ios/hide-selection-after-tap-on-prevent-default-element-expected.txt: Added.
* editing/selection/ios/hide-selection-after-tap-on-prevent-default-element.html: Added.
* resources/ui-helper.js:
(window.UIHelper.tapElement):


Canonical link: https://commits.webkit.org/227229@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@264481 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-07-16 21:59:33 +00:00
Wenson Hsieh 9ae9239cf8 REGRESSION (r259840): Pressing Esc or ⌘+"." does not dismiss time picker on iOS
https://bugs.webkit.org/show_bug.cgi?id=214122
<rdar://problem/64940487>

Reviewed by Tim Horton.

Source/WebKit:

Prior to r259840, when presenting context menus for certain input types (i.e. "time" and "datetime-local") on
iOS, UIKit would tell the presented view controller's view (a `UIDatePicker` in this case) to become first
responder. As a result, `WKContentView` would resign first responder, which (by default) blurs the focused
element and dismisses the context menu. The result is thats time pickers would immediately dismiss upon
presentation.

To mitigate this, r259840 adopted the existing active focus retaining mechanism to temporarily decouple
WKContentView's first responder status from the currently focused form element. However, this also causes
`-endEditingAndUpdateFocusAppearanceWithReason:` to bail, due to `self.webView._retainingActiveFocusedState`
returning `YES`. This means that codepaths meant to immediately dismiss UI for the focused element (for example,
when pressing Escape on a hardware keyboard on iOS) will not be able to dismiss UI.

To fix this, push the flag that keeps track of whether we're relinquishing first responder to the focused
element down into `WKContentView`, and have `WKContentView` automatically stop relinquishing first responder to
the focused element in `-[WKContentView accessoryDone]`.

Fixes an existing test: fast/forms/ios/dismiss-picker-using-keyboard.html

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView accessoryDone]):

Stop relinquishing focus to the focused element, so that form elements that require first responder can be
dismissed when triggering `-accessoryDone` (e.g. when pressing the Esc key on a hardware keyboard).

(-[WKContentView startRelinquishingFirstResponderToFocusedElement]):
(-[WKContentView stopRelinquishingFirstResponderToFocusedElement]):

Renamed from `-preserveFocus` and `-releaseFocus`, respectively. Also, made these methods idempotent using a new
`BOOL` flag, `_isRelinquishingFirstResponderToFocusedElement`.

(-[WKContentView preserveFocus]): Deleted.
(-[WKContentView releaseFocus]): Deleted.
* UIProcess/ios/forms/WKDateTimeInputControl.mm:
(-[WKDateTimePicker controlBeginEditing]):
(-[WKDateTimePicker controlEndEditing]):

Use the renamed WKContentView methods, and also remove the `_preservingFocus` flag.

* UIProcess/ios/forms/WKFormPopover.mm:
(-[WKRotatingPopover presentPopoverAnimated:]):
(-[WKRotatingPopover dismissPopoverAnimated:]):

Use the renamed WKContentView methods.

LayoutTests:

* fast/forms/ios/dismiss-picker-using-keyboard.html:
* fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html:
* fast/forms/ios/time-picker-value-change-expected.txt:
* fast/forms/ios/time-picker-value-change.html:

Adjust a few layout tests to be compatible with date and time inputs.

* resources/ui-helper.js:
(window.UIHelper.waitForInputSessionToDismiss.return.new.Promise):
(window.UIHelper.waitForInputSessionToDismiss):


Canonical link: https://commits.webkit.org/226959@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@264187 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-07-09 19:46:09 +00:00
Wenson Hsieh 24d08afe83 [iOS] Occasional crash under -[UIView _setViewDelegate:] when presenting date and time pickers
https://bugs.webkit.org/show_bug.cgi?id=214120
<rdar://problem/65246918>

Reviewed by Darin Adler.

Source/WebKit:

This crash happens when attempting to present a date picker (`<input type=date>`) immediately after dismissing
it. We encounter an Objective-C exception thrown by UIKit, due to the `WKDateTimeContextMenuViewController`'s
view (the `UIDatePicker`) being presented while it is still owned by the preview view controller. We often avoid
this crash because the `WKDateTimeContextMenuViewController` is usually only owned by `WKDateTimePicker`, so
when we set `_viewController` to a new instance of `WKDateTimeContextMenuViewController`, the old view
controller is destroyed, and thus no longer owns the `UIDatePicker` view.

However, it's possible for anything (e.g. animation blocks in UIKit) to cause the old view controller to live
past the creation of the new view controller. If this happens, when we go and call `-setView:` on the new view
controller with the date picker view, the date picker view may still be the view of the old controller, and we
end up crashing.

To fix this, explicitly unload the old view controller's view before attempting to create the new view
controller.

Test: fast/forms/ios/show-and-dismiss-date-input.html

* UIProcess/ios/forms/WKDateTimeInputControl.mm:
(-[WKDateTimePicker contextMenuInteraction:configurationForMenuAtLocation:]):
(-[WKDateTimePicker contextMenuInteraction:willDisplayMenuForConfiguration:animator:]):
(-[WKDateTimePicker contextMenuInteraction:willEndForConfiguration:animator:]):

Make it possible to test date and time picker presentation and dismissal by calling into the private testing-
only subclassing hooks on `WKWebView` when we finish presenting and dismissing the date picker context menu.

(-[WKDateTimePicker removeContextMenuInteraction]):

Tools:

Implement additional support for testing date and time pickers presented using context menus on iOS 14.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::isShowingContextMenu const):
* WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
* WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView _didShowContextMenu]):
(-[TestRunnerWKWebView _didDismissContextMenu]):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::setDidDismissContextMenuCallback):

Call the completion callback with `CallbackTypeDidDismissContextMenu`, rather than
`CallbackTypeDidEndFormControlInteraction`.

(WTR::UIScriptControllerIOS::isShowingContextMenu const):

Add a new script controller to ask whether we're currently presenting a context menu. This is useful in the case
where we want to wait until we're no longer showing a context menu, since we'll either immediately invoke script
completion, or stash a completion callback on `didDismissContextMenuCallback` to invoke script completion after
the context menu is finished dismissing.

LayoutTests:

Add a new layout test to verify that presenting a date picker twice does not result in a crash.

* fast/forms/ios/show-and-dismiss-date-input-expected.txt: Added.
* fast/forms/ios/show-and-dismiss-date-input.html: Added.
* resources/ui-helper.js:
(window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.):

Teach this helper method to wait for context menus as well (for the case of date and time pickers on iOS).

(window.UIHelper.waitForInputSessionToDismiss.return.new.Promise.):
(window.UIHelper.waitForInputSessionToDismiss.return.new.Promise):
(window.UIHelper.waitForInputSessionToDismiss):

Likewise, teach this to wait for context menu dismissal.

(window.UIHelper.waitForContextMenuToHide.return.new.Promise):
(window.UIHelper.waitForContextMenuToHide):

Add a new helper to wait for context menus to hide.


Canonical link: https://commits.webkit.org/226942@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@264170 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-07-09 15:15:29 +00:00
Wenson Hsieh c0d612a81d [iPadOS] Unable to change focus between Google Docs windows by tapping
https://bugs.webkit.org/show_bug.cgi?id=213985
<rdar://problem/57083267>

Reviewed by Darin Adler.

Source/WebKit:

When putting two Google Docs windows side-by-side on iPad, it's currently not possible to change the window to
which keyboard input is routed. In native views (e.g. two side-by-side Notes windows), this is normally handled
by `UITextMultiTapRecognizer`, which is part of the `UITextSelectionInteraction`; tapping to place the text
selection calls into `-[UITextInteractionAssistant setFirstResponderIfNecessaryActivatingSelection:]`, which
updates the key window if needed. This doesn't apply to Google Docs because they instead use touch events to
drive their own "text interaction"-like behaviors instead of relying on system gesture recognizers, which we
suppress due to the fact that the selection is within a hidden contenteditable.

But even in non-hidden editable areas, the initial tap to focus an editable element still doesn't automatically
make the window key, since the editable text interaction gestures are still inactive when tapping to focus an
editable element. This means two taps are currently required to change the key window when focusing two Safari
windows side-by-side: the first tap to focus the element (via the synthetic click gesture), and the second tap
to trigger the editable text interaction tap gesture that is used to set the selection.

To fix both of these issues, make some minor adjustments to call `-makeKeyWindow` from WebKit when focusing
editable elements. See below for more details.

Test: editing/selection/ios/become-key-window-when-focusing-editable-area.html

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _webTouchEventsRecognized:]):

For the case in Google Docs where a hidden editable element is used and tapping in the page does not result in
the element being refocused, we additionally need to make sure that we make our window key anyways. Limit this
hack to tap gestures, and only when there is a hidden focused editable element to emulate platform behavior of
updating the key window based on the text tap gesture.

(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]):

Make the content view's window key when focusing an editable element.

(-[WKContentView hasHiddenContentEditable]):

Consider the selection to be inside a hidden editable area if the `WebKit::FocusedElementIsTooSmall` flag is set
as well. While this doesn't affect Google Docs, it does affect some other custom editors, such as Quip.

(-[WKContentView mouseGestureRecognizerChanged:]):

Additionally make the current window key when clicking in a hidden editable area with a trackpad on iOS.

Tools:

Add WebKitTestRunner support for being able to verify that a web view's window has become the key window.

* DumpRenderTree/CMakeLists.txt:
* DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
* DumpRenderTree/UIScriptController.cpp: Added.
(WTR::UIScriptController::setWindowIsKey):
(WTR::UIScriptController::windowIsKey const):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp: Renamed from Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp.

Rename `UIScriptController.cpp` (in TestRunnerShared) to `UIScriptControllerShared.cpp`, and introduce new
DumpRenderTree and WebKitTestRunner versions of `UIScriptController.cpp` to house DumpRenderTree and
WebKitTestRunner-specific UIScriptController method implementations.

For now, these are just `windowIsKey` and `setWindowIsKey` below, which plumb into their respective platform-
agnostic `PlatformWebView` methods in WebKitTestRunner.

* WebKitTestRunner/UIScriptController.cpp: Added.
(WTR::UIScriptController::windowIsKey const):
(WTR::UIScriptController::setWindowIsKey):
* WebKitTestRunner/CMakeLists.txt:
* WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
* WebKitTestRunner/ios/PlatformWebViewIOS.mm:
(-[WebKitTestRunnerWindow becomeKeyWindow]):
(-[WebKitTestRunnerWindow resignKeyWindow]):

Update these two methods to update `m_windowIsKey` when the test runner's `UIWindow` becomes the key window (or
stops being the key window). This is invoked when `-[UIWindow makeKeyWindow]` is called (e.g. from within WebKit
code when tapping on an editable element).

(WTR::PlatformWebView::setWindowIsKey):

Avoid infinitely looping when setting windowIsKey to `true`, due to `-becomeKeyWindow` calling back into
`setWindowIsKey`.

LayoutTests:

Add a new layout test to verify that tapping to focus a plain textarea causes the web view's window to become
the key window, as well as tapping to focus a hidden contenteditable area, over a touch handler that prevents
default.

* editing/selection/ios/become-key-window-when-focusing-editable-area-expected.txt: Added.
* editing/selection/ios/become-key-window-when-focusing-editable-area.html: Added.
* resources/ui-helper.js:
(window.UIHelper.setWindowIsKey):
(window.UIHelper.windowIsKey):


Canonical link: https://commits.webkit.org/226799@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@263979 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-07-06 19:45:54 +00:00
Wenson Hsieh a745d9ae75 [iOS 14] A couple of tests in editing/selection/ios fail after <rdar://problem/60978283>
https://bugs.webkit.org/show_bug.cgi?id=213746
More work towards <rdar://problem/64808138>

Reviewed by Devin Rousso.

The UIKit change in <rdar://problem/60978283> adjusts text interaction behaviors such that a long press gesture
while editing makes a new caret selection, rather than a new word-granularity selection. Tweak a couple of
layout tests in editing/selection/ios that currently assume that long presses while editing will select a word.

* editing/selection/ios/select-text-in-existing-selection-expected.txt:
* editing/selection/ios/select-text-in-existing-selection.html:

This test verifies that the selection can be changed by making a long press inside an existing selection.
However, it now fails after the changes in <rdar://problem/60978283> because it expects the selected text to be
"jumped", but instead, the selection ends up being a caret inside the word "jumped". Tweak this test to verify
that the selection anchors' common ancestor node is the text node with the text "jumped" instead, to handle both
possibilities (where a long press selects a word vs. sets a caret selection).

* editing/selection/ios/selection-extends-into-overflow-area.html:

This test verifies the position and size of a ranged selection made inside content that visibly overflows its
parent container. It now fails because it tries to long press the word to make a selection; instead, use a
double tap gesture to make the word selection.

* resources/ui-helper.js:
(window.UIHelper.doubleTapElement):

Add a new helper method that double taps in the middle of the given element.

(window.UIHelper.callFunctionAndWaitForEvent):

Adjust this helper method to wait for the given function to resolve, if the given function returns a Promise.


Canonical link: https://commits.webkit.org/226559@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@263708 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-06-29 23:58:59 +00:00
Wenson Hsieh e1ef937fcc Allow clipboard API access when pasting from a menu item or key binding
https://bugs.webkit.org/show_bug.cgi?id=211990
<rdar://problem/63308916>

Reviewed by Megan Gardner.

Source/WebCore:

Allow the contents of the clipboard to be programmatically requested by the page while pasting from trusted UI
(i.e. the paste menu item, or when WebKit API is called by the app to trigger the paste). This allows the
'reading' part of the async clipboard API (`read` and `readText`) to be used when the user pastes in an editable
element, without having to fall back to showing the DOM paste access menu.

Note that this change should not have an effect on the pasteboard security model, since it only grants the page
programmatic access to the contents of the pasteboard in the case where access to the pasteboard has already
been granted by the user. Additionally, even in the event that the web process is compromised, even if the web
process can be tricked into believing it has been granted pasteboard access, the changes in r259151 will prevent
it from being able to request pasteboard data, unless the user (or the application, on behalf of the user) has
explicitly pasted via trusted API calls that are inaccessible from the web process.

Test: editing/async-clipboard/clipboard-read-while-pasting.html

* editing/Editor.cpp:
(WebCore::Editor::paste):
(WebCore::Editor::pasteAsPlainText):
(WebCore::Editor::pasteAsQuotation):

If `FromMenuOrKeyBinding::Yes` is passed in, set the `m_pastingFromMenuOrKeyBinding` flag to true during the
scope of the paste command.

* editing/Editor.h:
(WebCore::Editor::isPastingFromMenuOrKeyBinding const):
* editing/EditorCommand.cpp:
(WebCore::executePaste):
(WebCore::executePasteAndMatchStyle):
(WebCore::executePasteAsPlainText):
(WebCore::executePasteAsQuotation):

Pass in `FromMenuOrKeyBinding::Yes` when triggering the paste from a menu item or key binding.

* page/Frame.cpp:
(WebCore::Frame::requestDOMPasteAccess):

When pasting from menu or key binding, grant the page DOM paste access without requiring the DOM paste access
UI to be shown and confirmed.

Tools:

Add a UIScriptController method to trigger a paste from the application process.

* DumpRenderTree/cocoa/UIScriptControllerCocoa.h:
* DumpRenderTree/cocoa/UIScriptControllerCocoa.mm:
(WTR::UIScriptControllerCocoa::paste):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::paste):
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.h:
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm:
(WTR::UIScriptControllerCocoa::paste):

LayoutTests:

Add a new layout test to verify that the contents of the clipboard can be read while performing a paste that was
not triggered from the DOM.

* editing/async-clipboard/clipboard-read-while-pasting-expected.txt: Added.
* editing/async-clipboard/clipboard-read-while-pasting.html: Added.
* platform/win/TestExpectations:
* resources/ui-helper.js:
(window.UIHelper.async copyText):
(window.UIHelper.async paste):


Canonical link: https://commits.webkit.org/224916@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261825 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-18 19:05:27 +00:00
Wenson Hsieh 1a389680a4 Single selection <select> with <optgroups> shows multiple selected options
https://bugs.webkit.org/show_bug.cgi?id=199485
<rdar://problem/52757531>

Reviewed by Megan Gardner.

Source/WebKit:

Fixes a long-standing bug in WKMultipleSelectPicker. Prior to this patch, we rely on the delegate method
`-pickerView:row:column:checked:` to be called twice whenever an item is selected: one time for the item that is
no longer checked, and another for the newly checked item. This method is responsible for updating the cached
`FocusedElementInformation` that determines the data model for the select menu, with the expectation that the
unchecked item would be updated to have `isSelected = false;`, and the new checked item would have `isSelected`
`= true;`.

However, `-pickerView:row:column:checked:` is only called for visible item cells. This means that if the user
checks an item, scrolls the select menu items down so that the checked item is offscreen, and then checks a
different item, we only get notified that the new item is checked, and as a result, fail to uncheck the previous
item.

To address this, tweak our logic for handling a single select so that when an item is checked, we additionally
update the previously checked item to not be selected. Also, fix what seems to be a bug in the logic for
updating `_singleSelectionIndex`, which is currently updated even when the item is unchecked. It seems to work
out at the moment, because `-pickerView:row:column:checked:` seems to be called with `checked := YES` after the
previous item was unchecked (assuming that it was visible).

Test: fast/forms/ios/no-stale-checked-items-in-select-picker.html

* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView selectFormAccessoryHasCheckedItemAtRow:]):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView selectFormAccessoryHasCheckedItemAtRow:]):

Add plumbing for a new testing hook.

* UIProcess/ios/forms/WKFormSelectControl.h:
* UIProcess/ios/forms/WKFormSelectControl.mm:
(-[WKFormSelectControl selectFormAccessoryHasCheckedItemAtRow:]):
* UIProcess/ios/forms/WKFormSelectPicker.mm:
(-[WKMultipleSelectPicker pickerView:viewForRow:forComponent:reusingView:]):
(-[WKMultipleSelectPicker pickerView:row:column:checked:]):
(-[WKMultipleSelectPicker selectRow:inComponent:extendingSelection:]):

Also, fix an existing bug in this testing helper method that crashed the test runner due to calling an
unimplemented selector. Instead of trying to invoke `-pickerView:didSelectRow:inComponent:`, we should be using
`-pickerView:row:column:checked:` instead for multiple select pickers (which, somewhat confusingly, are still
used for single select elements that have `optgroup`s.)

(-[WKMultipleSelectPicker selectFormAccessoryHasCheckedItemAtRow:]):

Tools:

Add a new helper method to check whether the currently presented form accessory is a select menu, and has a
checked menu item at the given row.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::selectFormAccessoryHasCheckedItemAtRow const):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::selectFormAccessoryHasCheckedItemAtRow const):

LayoutTests:

Add a layout test to verify that we don't leave behind a checked select item after scrolling it offscreen and
then checking a different item.

* fast/forms/ios/no-stale-checked-items-in-select-picker-expected.txt: Added.
* fast/forms/ios/no-stale-checked-items-in-select-picker.html: Added.
* platform/ipad/TestExpectations:
* resources/ui-helper.js:
(window.UIHelper.selectFormAccessoryPickerRow):
(window.UIHelper.selectFormAccessoryHasCheckedItemAtRow):


Canonical link: https://commits.webkit.org/224906@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261815 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-18 16:23:30 +00:00
Wenson Hsieh 5fe9841d46 [iOS] Unexpected capitalization of next word after repositioning caret
https://bugs.webkit.org/show_bug.cgi?id=211969
<rdar://problem/62605526>

Reviewed by Alex Christensen.

Source/WebKit:

The changes in r242551 refactored synchronous autocorrection context request logic such that it uses
`waitForAndDispatchImmediately` instead of `sendSync`, in order to make it interruptible by unbounded sync IPC
sent from the web process. If the UI process receives sync IPC, it will immediately cancel the autocorrection
context request (returning an empty context), before proceeding to handle the incoming sync IPC.

In a more recent version of iOS, other changes around spellchecking have caused the synchronous message
`WebPageProxy::checkTextOfParagraph` to be sent from the web process in such a way that it now frequently
coincides with the synchronous autocorrection context request being sent from the UI process. The result is that
we now frequently end up cancelling autocorrection requests early by responding with empty contexts. This
manifests in the keyboard sometimes losing information about its autocapitalization context and believing that
it is in an empty text field, which reverts to default autocorrection suggestions and autocapitalizes the
software keyboard.

To fix this, instead of using the `InterruptWaitingIfSyncMessageArrives` option when waiting for the IPC
response, add and use a new flag that allows us to process an incoming sync IPC message if we're waiting for
the sync message response. We use this new IPC flag when waiting synchronously for HandleAutocorrectionContext.

Test: editing/selection/ios/changing-selection-does-not-trigger-autocapitalization.html

* Platform/IPC/Connection.cpp:
(IPC::Connection::processIncomingMessage):

If the new IPC flag is set and the incoming message is synchronous, allow it to immediately dispatch the sync
message by enqueueing it and then waking up `m_waitForMessageCondition` so that it can process the message.

* Platform/IPC/Connection.h:
* Platform/spi/ios/UIKitSPI.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView requestAutocorrectionContextWithCompletionHandler:]):

Use `DispatchIncomingSyncMessagesWhileWaiting` instead of `InterruptWaitingIfSyncMessageArrives`.

Tools:

Add a new UIScriptController hook to query whether or not the software keyboard is in shifted state.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::keyboardIsAutomaticallyShifted const):
* TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:

Adjust a couple of API tests that copy and paste back-to-back, so that they wait for the copy to finish before
attempting to paste.

* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::keyboardIsAutomaticallyShifted const):

LayoutTests:

Add a new layout test to verify that the keyboard does not automatically shift (i.e. autocapitalize) when
changing selection quickly inside a text field.

* editing/selection/ios/changing-selection-does-not-trigger-autocapitalization-expected.txt: Added.
* editing/selection/ios/changing-selection-does-not-trigger-autocapitalization.html: Added.
* resources/ui-helper.js:
(window.UIHelper.keyboardIsAutomaticallyShifted):


Canonical link: https://commits.webkit.org/224903@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261812 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-18 15:23:09 +00:00
Simon Fraser 16928bfad0 Make it possible to test overlay scrollbar interactions
https://bugs.webkit.org/show_bug.cgi?id=211342

Reviewed by Daniel Bates.

Source/WebCore:

Add internals.horizontalScrollbarState() and internals.verticalScrollbarState() and hook them
up via ScrollableArea to ScrollAnimatorMac. They dump state based on the NSScrollerImp state.

Make internals.setUsesOverlayScrollbars(true) actually trigger real overlay scrollbars by notifying
the ScrollbarTheme about the scrollbar style change.

Tests: fast/scrolling/mac/scrollbars/overlay-scrollbar-hovered.html
       fast/scrolling/mac/scrollbars/overlay-scrollbar-reveal.html
       fast/scrolling/mac/scrollbars/overlay-scrollbar-state.html
       fast/scrolling/mac/scrollbars/scrollbar-state.html

* platform/ScrollAnimator.h:
(WebCore::ScrollAnimator::ScrollAnimator::horizontalScrollbarStateForTesting const):
(WebCore::ScrollAnimator::ScrollAnimator::verticalScrollbarStateForTesting const):
* platform/ScrollableArea.cpp:
(WebCore::ScrollableArea::horizontalScrollbarStateForTesting const):
(WebCore::ScrollableArea::verticalScrollbarStateForTesting const):
* platform/ScrollableArea.h:
* platform/mac/NSScrollerImpDetails.h:
* platform/mac/ScrollAnimatorMac.h:
* platform/mac/ScrollAnimatorMac.mm:
(WebCore::scrollbarState):
(WebCore::ScrollAnimatorMac::horizontalScrollbarStateForTesting const):
(WebCore::ScrollAnimatorMac::verticalScrollbarStateForTesting const):
* testing/Internals.cpp:
(WebCore:: const):
(WebCore::Internals::scrollbarOverlayStyle const):
(WebCore::Internals::scrollbarUsingDarkAppearance const):
(WebCore::Internals::horizontalScrollbarState const):
(WebCore::Internals::verticalScrollbarState const):
(WebCore::Internals::setUsesOverlayScrollbars):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

New tests, and some helper functions in UIHelper.

* fast/scrolling/mac/scrollbars/overlay-scrollbar-hovered-expected.txt: Added.
* fast/scrolling/mac/scrollbars/overlay-scrollbar-hovered.html: Added.
* fast/scrolling/mac/scrollbars/overlay-scrollbar-reveal-expected.txt: Added.
* fast/scrolling/mac/scrollbars/overlay-scrollbar-reveal.html: Added.
* fast/scrolling/mac/scrollbars/overlay-scrollbar-state-expected.txt: Added.
* fast/scrolling/mac/scrollbars/overlay-scrollbar-state.html: Added.
* fast/scrolling/mac/scrollbars/scrollbar-state-expected.txt: Added.
* fast/scrolling/mac/scrollbars/scrollbar-state.html: Added.
* resources/ui-helper.js:
(window.UIHelper.async mouseWheelMayBeginAt):
(window.UIHelper.async mouseWheelCancelAt):
(window.UIHelper.async waitForCondition):

Canonical link: https://commits.webkit.org/224231@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261056 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-03 03:49:16 +00:00
Simon Fraser b34f2abeac EventHandler::selectCursor() has broken resize over coordinate conversion code
https://bugs.webkit.org/show_bug.cgi?id=210778

Reviewed by Zalan Bujtas.

Source/WebCore:

EventHandler::selectCursor() appeared to make a local hit-test point from window
to content coordinates, which made no sense, but this happened to work because
RenderLayer::hitTestLayer() set the HitTestResult localPoint to a global point
if you hit the resizer.

Clean up this mess by having all resizer-related geometry queries be in local coordinates.

As a bonus, actually set the cursor to a resize cursor when over the resizer.

Test: fast/events/cursors/mouse-cursor-over-resizer.html

* page/EventHandler.cpp:
(WebCore::EventHandler::selectCursor):
(WebCore::EventHandler::handleMousePressEvent):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::resize):
(WebCore::RenderLayer::offsetFromResizeCorner const):
(WebCore::RenderLayer::isPointInResizeControl const):
(WebCore::RenderLayer::hitTestLayer):
(WebCore::RenderLayer::hitTestResizerInFragments const):
* rendering/RenderLayer.h:

LayoutTests:

* TestExpectations:
* fast/events/cursors/mouse-cursor-over-resizer-expected.txt: Added.
* fast/events/cursors/mouse-cursor-over-resizer.html: Added.
* fast/events/mouse-cursor-change.html:
* platform/mac-wk2/TestExpectations:
* resources/ui-helper.js:
(window.UIHelper.async moveMouseAndWaitForFrame):


Canonical link: https://commits.webkit.org/223837@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260615 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-24 01:08:44 +00:00
Antoine Quint f0f0280f98 [ Mojave wk1 Release ] animations/transition-and-animation-1.html is a flaky failure
https://bugs.webkit.org/show_bug.cgi?id=210051
<rdar://problem/61345177>

Reviewed by Simon Fraser.

The purpose of this test is to check that running an animation does not trigger a transition for the animated
property. The way this test was written is that it would use `setTimeout()` to set a timer at a time computed to
be 500ms after the completion of the animation. However, using a timer like this is flaky by design as the animation
could technically be still in flight if the system is under heavy load.

We rewrite this test to use an "animationend" event to determine the animation has really completed and then wait
another frame, using `requestAnimationFrame()` to check that the computed style is as expected.

* animations/transition-and-animation-1.html:
* resources/ui-helper.js:
(window.UIHelper.waitForEvent):

Canonical link: https://commits.webkit.org/223748@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260513 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-22 16:21:37 +00:00
Megan Gardner a6b2add32b Date and Time form controls not showing correct initial values on immediate second invocation.
https://bugs.webkit.org/show_bug.cgi?id=210613

Reviewed by Wenson Hsieh.

Source/WebKit:

Updating the webprocess with the newly picked time did not update the local store of that data in the
UI process, so when the control was activated a second time, and we skipped the round trip to the
webprocess to get the data we were certian we already had, we did not start the popover in the
correct state. We now update the webprocess and the local UI stored variable at the same time.

Test: fast/forms/ios/time-picker-value-change.html

* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView timePickerValueHour]):
(-[WKWebView timePickerValueMinute]):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView updateValueAsNumberForViewController:]):
(-[WKContentView updateValueForViewController:]):
(-[WKContentView setTimePickerValueToHour:minute:]):
(-[WKContentView timePickerValueHour]):
(-[WKContentView timePickerValueMinute]):
* UIProcess/ios/forms/WKFormInputControl.h:
* UIProcess/ios/forms/WKFormInputControl.mm:
(-[WKDateTimePicker hour]):
(-[WKDateTimePicker minute]):
(-[WKDateTimePicker _dateChangedSetAsNumber]):
(-[WKDateTimePicker _dateChangedSetAsString]):
(-[WKDateTimePicker setHour:minute:]):
(-[WKFormInputControl setTimePickerHour:minute:]):
(-[WKFormInputControl timePickerValueHour]):
(-[WKFormInputControl timePickerValueMinute]):
(-[WKDateTimePopover setHour:minute:]):
(-[WKDateTimePopover hour]):
(-[WKDateTimePopover minute]):

Tools:

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::timePickerValueHour const):
(WTR::UIScriptController::timePickerValueMinute const):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::timePickerValueHour const):
(WTR::UIScriptControllerIOS::timePickerValueMinute const):

LayoutTests:

* fast/forms/ios/time-picker-value-change-expected.txt: Added.
* fast/forms/ios/time-picker-value-change.html: Added.
* resources/ui-helper.js:
(window.UIHelper.timerPickerValues):


Canonical link: https://commits.webkit.org/223655@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260402 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-20 21:45:03 +00:00
Simon Fraser 888033aab1 [Async overflow scroll] Horizontal scrolls can trigger unwanted back swipes
https://bugs.webkit.org/show_bug.cgi?id=210095
<rdar://problem/61376245>

Reviewed by Tim Horton.

Source/WebCore:

With async overflow/frame scrolling, EventDispatcher::wheelEvent() can't immediately
determine whether the scrolling tree handled the scroll; we have to wait until the
event has been processed by the scrolling thread. To allow that, add a
ScrollingEventResult::SendToScrollingThread return value and a give tryToHandleWheelEvent()
a callback that's called when the scrolling thread is done with the event. EventDispatcher
uses that to send the "didReceiveEvent" with "handled" back to the UI process, which then
proceeds with history or reading list swipes.

Various fixes were necessary to correctly determine whether the event was handled.

ScrollingTreeFrameScrollingNodeMac::handleWheelEvent() didn't return an accurate ScrollingEventResult,
and ScrollController didn't return false in cases where rubber-banding was disabled (which broke navigation swipes
and reading list navigation).

Tests: scrollingcoordinator/mac/latching/main-frame-back-swipe.html
       scrollingcoordinator/mac/latching/simple-page-rubberbands.html

* page/scrolling/ScrollingCoordinatorTypes.h:
* page/scrolling/ScrollingThread.h:
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::handleWheelEvent):
(WebCore::ScrollingTree::mainFrameCanRubberBandInDirection):
* page/scrolling/ScrollingTree.h:
* page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::tryToHandleWheelEvent):
* page/scrolling/ThreadedScrollingTree.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::ScrollingTreeFrameScrollingNodeMac::handleWheelEvent):
* page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
(WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandInDirection const):
* platform/cocoa/ScrollController.h:
* platform/cocoa/ScrollController.mm:
(WebCore::ScrollController::handleWheelEvent):
(WebCore::ScrollController::wheelDeltaBiasingTowardsVertical):
(WebCore::ScrollController::directionFromEvent):
(WebCore::ScrollController::shouldRubberBandInHorizontalDirection const):
(WebCore::ScrollController::shouldRubberBandInDirection const):
(WebCore::ScrollController::shouldRubberBandInHorizontalDirection): Deleted.

Source/WebKit:

With async overflow/frame scrolling, EventDispatcher::wheelEvent() can't immediately
determine whether the scrolling tree handled the scroll; we have to wait until the
event has been processed by the scrolling thread. To allow that, add a
ScrollingEventResult::SendToScrollingThread return value and a give tryToHandleWheelEvent()
a callback that's called when the scrolling thread is done with the event. EventDispatcher
uses that to send the "didReceiveEvent" with "handled" back to the UI process, which then
proceeds with history or reading list swipes.

Various fixes were necessary to correctly determine whether the event was handled.

ScrollingTreeFrameScrollingNodeMac::handleWheelEvent() didn't return an accurate ScrollingEventResult,
and ScrollController didn't return false in cases where rubber-banding was disabled (which broke navigation swipes
and reading list navigation).

* UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::handleWheelEvent):
* UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::tryToHandleWheelEvent):
* UIProcess/RemoteLayerTree/RemoteScrollingTree.h:
* WebProcess/WebPage/EventDispatcher.cpp:
(WebKit::EventDispatcher::wheelEvent):
(WebKit::EventDispatcher::sendDidReceiveEvent):
* WebProcess/WebPage/EventDispatcher.h:

LayoutTests:

Tests that rubberbanding works on a simple page, and that edge swipes work on a simple page.

Edge swipes inside overflow:scroll are still broken by latching and will be fixed later.

* resources/ui-helper.js:
(window.UIHelper.async mouseWheelScrollAt):
* scrollingcoordinator/mac/latching/main-frame-back-swipe-expected.txt: Added.
* scrollingcoordinator/mac/latching/main-frame-back-swipe.html: Added.
* scrollingcoordinator/mac/latching/simple-page-rubberbands-expected.txt: Added.
* scrollingcoordinator/mac/latching/simple-page-rubberbands.html: Added.

Canonical link: https://commits.webkit.org/223165@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@259805 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-09 16:25:08 +00:00
Daniel Bates 7dcf0a23f9 Track editable elements on screen
https://bugs.webkit.org/show_bug.cgi?id=209888
<rdar://problem/61196886>

Reviewed by Simon Fraser.

Source/JavaScriptCore:

Add feature define to track editable elements on screen (enabled by default on iOS and iOS Simulator).

* Configurations/FeatureDefines.xcconfig:

Source/WebCore:

Amend EventRegion to store a region of all the hit test visible rects of editable elements
on the page. This data will be sent over to the UI process so that it can quickly determine
if a search rect would intersect any editable elements.

An element is considered editable if it has CSS -webkit-user-modify value that isn't read-only.
Note that the value of the HTML content attribute contenteditable is internally converted to
its -webkit-user-modify equivalent (e.g. contenteditable="true" <=> "-webkit-user-modify: read-write").

Tests: editing/editable-region/fixed-and-absolute-contenteditable-scrolled.html
       editing/editable-region/float-contenteditable.html
       editing/editable-region/hit-test-basic.html
       editing/editable-region/hit-test-fixed.html
       editing/editable-region/hit-test-overlap.html
       editing/editable-region/iframe.html
       editing/editable-region/input-basic.html
       editing/editable-region/out-hanging-child-of-contenteditable.html
       editing/editable-region/overflow-scroll-text-field-and-contenteditable.html
       editing/editable-region/relative-inside-fixed-contenteditable-scrolled.html
       editing/editable-region/relative-inside-transformed-contenteditable.html
       editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables.html

* Configurations/FeatureDefines.xcconfig: Add feature define to track editable elements on
screen (enabled by default on iOS and iOS Simulator).
* dom/Document.h:
(WebCore::Document::mayHaveEditableElements const):
(WebCore::Document::setMayHaveEditableElements):
Add some state to each document to track whether it may have an editable element or not. This
value represents a "maybe" because it is only set and never unset. It is set if the style resolver
saw an element with an editable style. This flag is used as a performance optimization to avoid
creating an event region if there are no editable elements on the page.

* page/Frame.cpp:
(WebCore::Frame::invalidateContentEventRegionsIfNeeded): Check if there are any editable elements.
If so, invalidate the event region.
* rendering/EventRegion.cpp:
(WebCore::EventRegion::operator== const): Update for editable region.
(WebCore::EventRegion::unite): If the specified style has a writable CSS user-modify value then
unite the region with the editable region.
(WebCore::EventRegion::translate): Update for editable region.
(WebCore::EventRegion::containsEditableElementsInRect const): Added. Check if the specified rect
intersects the editable region. If it does then that means there are one or more editable elements
whose bounds intersect that rect. Otherwise, there are none.
(WebCore::EventRegion::dump const): Update for editable region.
* rendering/EventRegion.h:
(WebCore::EventRegion::intersects const): Added.
(WebCore::EventRegion::rectsForEditableElements const): Return the rects in the editable region.
(WebCore::EventRegion::encode const): Encode the editable region.
(WebCore::EventRegion::decode): Decode the editable region.
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintObject): Traverse descendants if the page has any editable elements
so that we find all of them.
* rendering/RenderElement.cpp:
(WebCore::RenderElement::styleWillChange): Amend the event region invalidation criterion to look
for a change in writability. If there was a change (e.g. read-only to read-write) then invalidate
the event region to force a re-computation of it.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::invalidateEventRegion): If the document has editable elements then we need
to create an event region.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateEventRegion): Update the region if there are editable elements.
(WebCore::RenderLayerBacking::paintDebugOverlays): Paint the editable elements in the debug overlay.
For now, I piggybacked (like was done for touch-action regions) on the non-fast scrollable region
flag (not shown in the patch). I will look to add a dedicated debug overlay flag in a follow up patch.
* style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::resolveElement): Mark the document as having an editable element if
the style for the element being resolved is writable.

Source/WebCore/PAL:

Add feature define to track editable elements on screen (enabled by default on iOS and iOS Simulator).

* Configurations/FeatureDefines.xcconfig:

Source/WebKit:

Speed up -_requestTextInputContextsInRect when the rect does not intersect any editable
elements by over 4450 times on reddit.com! Another way of saying this is that it reduces
the time from an average of 303.252ms to 0.0680625ms in a Production build.

This speed up is accomplished by having the web process track the rects of the editable
elements on the page and send this information as a region data structure over to the UI
process as part of the EventRegion object. This region is used to determine if there
*may* be an editable element inside the rectangele. It never reports a false negative,
but it can report a false positive: a rectangle is over an editable element when it
actually isn't, (e.g. there is a non-composited element with a higher z-order than the
editable element that intersects the search rect).

* Configurations/FeatureDefines.xcconfig: Add feature define to track editable elements on
screen (enabled by default on iOS and iOS Simulator).
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _mayContainEditableElementsInRect:]): Added.
(-[WKWebView _requestTextInputContextsInRect:completionHandler:]): Checks if the search
rects hits an editable element in a RemoteLayerTree node's editable region. If it does
not hit any then we know there are no editable elements and return immediately. If it
does hit something then we still need to ask the web process to perform a hit test to
find the actual elements, respecting z-ordering (which is lost when these elements' rects
are united to form the editable region).
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h:
* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
(WebKit::collectDescendantViewsInRect): Added.
(WebKit::mayContainEditableElementsInRect): Added.

Source/WebKitLegacy/mac:

Add feature define to track editable elements on screen (enabled by default on iOS and iOS Simulator).

* Configurations/FeatureDefines.xcconfig:

Tools:

Add more unit tests for -_requestTextInputContextsInRect. Also add test infrastructure to
be able to verify that WebKit::mayContainEditableElementsInRect() works.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::mayContainEditableElementsInRect):
Expose an internal function to test WebKit::mayContainEditableElementsInRect().

* TestWebKitAPI/Configurations/FeatureDefines.xcconfig: Add feature define.
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm:
(webViewLoadHTMLStringAndWaitForAllFramesToPaint): Renamed; formerly webViewLoadHTMLStringAndWaitForDOMLoadEvent.
Also make it wait for the next presentation update after we paint.
(TEST):
(squareCenteredAtPoint): Added.
(webViewLoadHTMLStringAndWaitForDOMLoadEvent): Deleted; renamed webViewLoadHTMLStringAndWaitForAllFramesToPaint().
* TestWebKitAPI/Tests/WebKitCocoa/editable-region-composited-and-non-composited-overlap.html: Added.
* TestWebKitAPI/ios/editable-region-composited-and-non-composited-overlap.html: Added.
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::mayContainEditableElementsInRect): Added.

LayoutTests:

Add some tests. Some of these tests were derived from a torture test page written by Simon Fraser.

* TestExpectations: Skip directory editing/editable-region everywhere. I will unskip this in the iOS TestExpectations file.
* editing/editable-region/fixed-and-absolute-contenteditable-scrolled-expected.txt: Added.
* editing/editable-region/fixed-and-absolute-contenteditable-scrolled.html: Added.
* editing/editable-region/float-contenteditable-expected.txt: Added.
* editing/editable-region/float-contenteditable.html: Added.
* editing/editable-region/hit-test-basic-expected.txt: Added.
* editing/editable-region/hit-test-basic.html: Added.
* editing/editable-region/hit-test-fixed-expected.txt: Added.
* editing/editable-region/hit-test-fixed.html: Added.
* editing/editable-region/hit-test-overlap-expected.txt: Added.
* editing/editable-region/hit-test-overlap.html: Added.
* editing/editable-region/iframe-expected.txt: Added.
* editing/editable-region/iframe.html: Added.
* editing/editable-region/input-basic-expected.txt: Added.
* editing/editable-region/input-basic.html: Added.
* editing/editable-region/out-hanging-child-of-contenteditable-expected.txt: Added.
* editing/editable-region/out-hanging-child-of-contenteditable.html: Added.
* editing/editable-region/overflow-scroll-text-field-and-contenteditable-expected.txt: Added.
* editing/editable-region/overflow-scroll-text-field-and-contenteditable.html: Added.
* editing/editable-region/relative-inside-fixed-contenteditable-scrolled-expected.txt: Added.
* editing/editable-region/relative-inside-fixed-contenteditable-scrolled.html: Added.
* editing/editable-region/relative-inside-transformed-contenteditable-expected.txt: Added.
* editing/editable-region/relative-inside-transformed-contenteditable.html: Added.
* editing/editable-region/resources/hit-test-utilities.js: Added.
(async shouldHaveEditableElementsInRect):
(async shouldNotHaveEditableElementsInRect):
(shouldNotHaveEditableElementsInRectForElement):
* editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables-expected.txt: Added.
* editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables.html: Added.
* platform/ios/TestExpectations: Unskip editing/editable-region.
* resources/ui-helper.js:
(window.UIHelper.mayContainEditableElementsInRect): Added. Convenience function that turns around
and calls the UIScriptController function of the same name and returns a boolean instead of a string.

Canonical link: https://commits.webkit.org/223123@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@259762 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-08 22:41:44 +00:00
Wenson Hsieh 039adbce86 Preventing touch events should not prevent gestures installed above WKWebView from recognizing
https://bugs.webkit.org/show_bug.cgi?id=210080
<rdar://problem/61365814>

Reviewed by Tim Horton.

Source/WebKit:

Makes a small adjustment to native gesture deferral logic, so that gestures installed above WKWebView (in the
view hierarchy) are not prevented from recognizing by WKDeferringGestureRecognizer. This makes it possible for
WebKit clients to install custom gestures outside of WKWebView that cannot be prevented by web content, without
having to create a separate window and pass touches through to the WKWebView.

Test: fast/events/touch/ios/prevent-default-with-window-tap-gesture.html

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]):

Tools:

Add a UIScriptController helper method that allows a test to install a tap gesture recognizer on the UIWindow
containing the web view. This method additionally takes a JavaScript callback, which is invoked when the tap
gesture is recognized.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptContext.h:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::installTapGestureOnWindow):
* WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
* WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView resetInteractionCallbacks]):
(-[TestRunnerWKWebView didRecognizeTapOnWindow]):
(-[TestRunnerWKWebView windowTapRecognizedCallback]):
(-[TestRunnerWKWebView setWindowTapRecognizedCallback:]):
(-[TestRunnerWKWebView willMoveToWindow:]):
(-[TestRunnerWKWebView didMoveToWindow]):
(-[TestRunnerWKWebView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::installTapGestureOnWindow):

LayoutTests:

Add a new layout test to verify that calling preventDefault() on touchstart doesn't prevent gesture recognizers
installed above the WKWebView from recognizing. To do this, we use the new UIScriptController method to add a
gesture recognizer to the window containing the web view, and then simulate a tap over an element that prevents
the touchstart event.

* fast/events/touch/ios/prevent-default-with-window-tap-gesture-expected.txt: Added.
* fast/events/touch/ios/prevent-default-with-window-tap-gesture.html: Added.
* resources/ui-helper.js:
(window.UIHelper.async activateElementAfterInstallingTapGestureOnWindow.return.new.Promise.):
(window.UIHelper.async activateElementAfterInstallingTapGestureOnWindow.return.new.Promise):
(window.UIHelper.async activateElementAfterInstallingTapGestureOnWindow):
(window.UIHelper):


Canonical link: https://commits.webkit.org/223041@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@259669 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-07 21:00:49 +00:00
Simon Fraser 331e56cb53 Add some more scroll-latching tests
https://bugs.webkit.org/show_bug.cgi?id=209924

Reviewed by Zalan Bujtas.

Add three scroll latching tests.

iframe-latch-small-deltas.html tests that starting a second scroll where the dominant
direction can't be determined re-uses the previous latching. This test currently fails.

overflow-in-iframe-latching.html tests a wheel over a scrolled-to-top overflow inside
a not-scrolled-to-top iframe; the iframe should scroll. This test currently fails.

latching-and-wheel-events.html tests that wheel events always go to the innermost target,
even if not latched, and don't propagate across frame boundaries. This test passes
the event propagation part, but fails in a similar way to overflow-in-iframe-latching.html .

* fast/scrolling/latching/iframe-latch-small-deltas-expected.txt: Added.
* fast/scrolling/latching/iframe-latch-small-deltas.html: Added.
* fast/scrolling/latching/latching-and-wheel-events-expected.txt: Added.
* fast/scrolling/latching/latching-and-wheel-events.html: Added.
* fast/scrolling/latching/overflow-in-iframe-latching-expected.txt: Added.
* fast/scrolling/latching/overflow-in-iframe-latching.html: Added.
* platform/mac-wk1/fast/scrolling/latching/iframe-latch-small-deltas-expected.txt: Added.
* platform/mac-wk1/fast/scrolling/latching/latching-and-wheel-events-expected.txt: Added.
* platform/mac-wk1/fast/scrolling/latching/overflow-in-iframe-latching-expected.txt: Added.
* resources/ui-helper.js:
(window.UIHelper.async mouseWheelScrollAt):
(window.UIHelper.async waitForScrollCompletion):

Canonical link: https://commits.webkit.org/222843@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@259417 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-02 21:35:43 +00:00
Simon Fraser d786d4dc0c Hit-test CALayers on the scrolling thread for async frame/overflow scrolling
https://bugs.webkit.org/show_bug.cgi?id=208740
<rdar://problem/48028836>

Reviewed by Tim Horton.

Source/WebCore:

Implement hit-testing in the scrolling thread so we can determine which overflow/subframe
to scroll without hitting the main thread.

ScrollingTreeMac overrides scrollingNodeForPoint() and hit-tests through CALayers, starting at the
root content layer. Locking ensures that the CALayer tree doesn't change while we're hit-testing it.
We collect layers for the given point in back-to-front order much like the iOS code _web_findDescendantViewAtPoint
(too different to share though), and consult event regions on PlatformCALayerCocoa's to determine if the
point is inside the part of the layer that should receive events.

To handle the complex stacking/containing block cases, isScrolledBy() consults the scrolling tree.

For testing, fix it so that multiple calls to monitorWheelEvents() in a single test each start
with clean state.

Tests: fast/scrolling/mac/absolute-in-overflow-scroll.html
       fast/scrolling/mac/async-scroll-overflow.html
       fast/scrolling/mac/move-node-in-overflow-scroll.html
       fast/scrolling/mac/overlapped-overflow-scroll.html

* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::handleWheelEvent):
(WebCore::ScrollingTree::scrollingNodeForPoint):
* page/scrolling/ScrollingTree.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
* page/scrolling/mac/ScrollingTreeMac.h:
* page/scrolling/mac/ScrollingTreeMac.mm:
(collectDescendantLayersAtPoint):
(scrollingNodeIDForLayer):
(isScrolledBy):
(ScrollingTreeMac::scrollingNodeForPoint):
* testing/js/WebCoreTestSupport.cpp:
(WebCoreTestSupport::monitorWheelEvents): Make sure that each call to eventSender.monitorWheelEvents() clears previous state.

Source/WebKit:

Make sure that each call to eventSender.monitorWheelEvents() clears previous state.

* WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
(WKBundlePageStartMonitoringScrollOperations):

LayoutTests:

Add some UIHelper functions for mousewheel scrolling, and use them in new tests.
Fix some old malformed expectations.

* fast/scrolling/ios/hit-testing-iframe-001-expected.html: Was malformed.
* fast/scrolling/ios/hit-testing-iframe-002-expected.html:
* fast/scrolling/ios/hit-testing-iframe-003-expected.html:
* fast/scrolling/ios/hit-testing-iframe-004-expected.html:
* fast/scrolling/ios/hit-testing-iframe-005-expected.html:
* fast/scrolling/ios/hit-testing-iframe-006-expected.html:
* fast/scrolling/mac/absolute-in-overflow-scroll-expected.txt: Added.
* fast/scrolling/mac/absolute-in-overflow-scroll.html: Added.
* fast/scrolling/mac/async-scroll-overflow-expected.txt: Added.
* fast/scrolling/mac/async-scroll-overflow.html: Added.
* fast/scrolling/mac/move-node-in-overflow-scroll-expected.txt: Added.
* fast/scrolling/mac/move-node-in-overflow-scroll.html: Added.
* fast/scrolling/mac/overlapped-overflow-scroll-expected.txt: Added.
* fast/scrolling/mac/overlapped-overflow-scroll.html: Added.
* resources/ui-helper.js:
(window.UIHelper.async mouseWheelScrollAt):
(window.UIHelper.async animationFrame):

Canonical link: https://commits.webkit.org/221653@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@258044 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-03-07 01:45:55 +00:00
Wenson Hsieh ba053e1f05 fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html is failing in iOS 13.4 beta
https://bugs.webkit.org/show_bug.cgi?id=208096
<rdar://problem/59632008>

Reviewed by Alexey Proskuryakov.

Tools:

In the iOS 13.4 beta, the fix for <rdar://problem/56422337> changed -[UIDatePicker setCalendar:], such that
if the new calendar locale matches that of the current calendar's locale (and several other properties of the
new NSCalendar are also unchanged), then the UIDatePicker's calendar will also avoid changing.

In our layout tests, the mechanism we use to simulate the user changing their preferred calendar is no longer
compatible with the above change since the swizzled NSCalendar instance does not have a locale set, so it will
default to the same locale as the one used in the original NSCalendar. This means the call to -setCalendar: ends
up being a no-op, so the test fails to override the simulated Japanese calendar type with a Gregorian calendar
in the credit card expiry field.

To fix this, additionally specify a calendar locale identifier when generating the mock NSCalendar.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::setDefaultCalendarType):
* WebKitTestRunner/TestController.h:

Change m_overriddenCalendarIdentifier to m_overriddenCalendarAndLocaleIdentifiers, a pair of calendar
identifier and calendar locale identifier.

* WebKitTestRunner/cocoa/TestControllerCocoa.mm:
(WTR::swizzledCalendar):
(WTR::TestController::overriddenCalendarIdentifier const):
(WTR::TestController::overriddenCalendarLocaleIdentifier const):

Clean these up by returning the `NSString *` instead of making another `RetainPtr`.

(WTR::TestController::setDefaultCalendarType):

Plumb the new calendar's locale identifier through this method.

(WTR::TestController::cocoaResetStateToConsistentValues):
(WTR::TestController::getOverriddenCalendarIdentifier const): Deleted.
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.h:
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm:
(WTR::UIScriptControllerCocoa::setDefaultCalendarType):

LayoutTests:

Adjust the layout test to also set the mock calendar's locale.

* fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html:
* resources/ui-helper.js:
(window.UIHelper.setDefaultCalendarType):


Canonical link: https://commits.webkit.org/221054@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@257187 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-02-23 02:30:07 +00:00
Wenson Hsieh d18268564b fast/events/touch/ios/long-press-on-link.html consistently times out after r254699
https://bugs.webkit.org/show_bug.cgi?id=207095

Reviewed by Darin Adler.

After <https://trac.webkit.org/r254699>, tests that end without causing presented view controllers to dismiss
will always cause the subsequent test to time out. This happens all the time with the layout test
fast/events/touch/ios/long-press-on-link.html, which runs after fast/events/touch/ios/long-press-on-image.html;
both of these tests long press previewable elements to present a context menu, but don't attempt to dismiss
these previews.

Address this by tapping at the web view's origin after ending the long press gesture, which causes the preview
view controllers that were presented by the test to dismiss.

* fast/events/touch/ios/long-press-on-image-expected.txt:
* fast/events/touch/ios/long-press-on-image.html:
* fast/events/touch/ios/long-press-on-link-expected.txt:
* fast/events/touch/ios/long-press-on-link.html:

Modernize these layout tests by adopting helper methods for driving interaction (instead of directly using
testRunner.runUIScript). Also, use the testing helpers in `js-test.js`, and add descriptions to each test.

* resources/ui-helper.js:
(window.UIHelper.longPressAndGetContextMenuContentAt.return.new.Promise):
(window.UIHelper.longPressAndGetContextMenuContentAt):

Make this resolve the promise to a parsed JSON object instead of a JSON string. Currently, the result is a JSON
string that is parsed at each call site.


Canonical link: https://commits.webkit.org/220101@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@255545 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-02-02 00:56:13 +00:00
Wenson Hsieh f534e0cf75 Add a test to verify that the callout bar appears after selecting a word
https://bugs.webkit.org/show_bug.cgi?id=206488
<rdar://problem/58661768>

Reviewed by Darin Adler.

* editing/selection/ios/show-callout-bar-after-selecting-word-expected.txt: Added.
* editing/selection/ios/show-callout-bar-after-selecting-word.html: Added.

Add the new layout test.

* resources/ui-helper.js:
(window.UIHelper.rectForMenuAction):

Wrap this UI script in its own function scope, such that it can be used multiple times in the same layout test.


Canonical link: https://commits.webkit.org/219570@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@254833 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-01-20 20:24:54 +00:00
Wenson Hsieh 683f9e2892 [iOS] WKWebView touch event gesture recognition should not block the application process main thread when possible
https://bugs.webkit.org/show_bug.cgi?id=204664
<rdar://problem/38670692>

Reviewed by Tim Horton.

Source/WebKit:

Adds a mechanism that allows some sync touch events on iOS to be sent asynchronously. To do this, we use the
deferring gesture mechanism introduced in trac.webkit.org/r253005 to defer all gestures under WKContentView (and
WebKit-owned scroll views) when a touch starts, such that they will not recognize until we know that the page
has either prevented default or not (assuming that the touch was over an active listener). See below for more
details.

Tests: fast/events/touch/ios/prevent-default-on-touch-start-with-slow-event-listener.html
       fast/events/touch/ios/scroll-on-touch-start-with-slow-event-listener.html

* UIProcess/GenericCallback.h:
* UIProcess/PageClient.h:
* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
(-[WKChildScrollView gestureRecognizer:shouldRequireFailureOfGestureRecognizer:]):
(-[WKChildScrollView gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:]):

Implement gesture recognizer delegate hooks to add dynamic failure requirements between a child scroll view's
gestures and the new deferring gesture recognizers on WKContentView. This allows pan gestures over a scrollable
container to hold off on recognizing while the deferring gesture recognizer has not failed yet.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handlePreventableTouchEvent):
(WebKit::WebPageProxy::handleUnpreventableTouchEvent):

Rename handleTouchEventSynchronously and handleTouchEventAsynchronously to handlePreventableTouchEvent and
handleUnpreventableTouchEvent, respectively. Instead of always sending touchstart events that may prevent native
gestures synchronously, we may now go through the same `EventDispatcher::TouchEvent` codepath used when
dispatching touch events in passive tracking regions. However, in the case of preventable touchstarts, we
additionally store a completion callback that is invoked after the touch event has been handled by the page; we
then either un-defer or prevent native gestures here (depending on whether the page prevented default) by
calling PageClient::doneDeferringNativeGestures.

Non-touchstart events are still dispatched synchronously, to ensure that calling preventDefault() on touchmove
and touchend continue to prevent default gestures from recognizing.

(WebKit::WebPageProxy::boolCallback):
(WebKit::WebPageProxy::handleTouchEventSynchronously): Deleted.
(WebKit::WebPageProxy::handleTouchEventAsynchronously): Deleted.

See above.

* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::isHandlingPreventableTouchStart const):

This is used in WKContentView to determine whether deferring gestures need to remain active after the touch
ends. See below for more detail.

* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::doneDeferringNativeGestures):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[UIGestureRecognizer _wk_cancel]):
(-[WKContentView setupInteraction]):
(-[WKContentView cleanupInteraction]):
(-[WKContentView _removeDefaultGestureRecognizers]):
(-[WKContentView _addDefaultGestureRecognizers]):

Add and remove the new deferring gesture recognizers here.

(-[WKContentView _webTouchEventsRecognized:]):
(-[WKContentView _webTouchEvent:preventsNativeGestures:]):
(-[WKContentView _doneDeferringNativeGestures:]):
(-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
(-[WKContentView ensurePositionInformationIsUpToDate:]):

Drive-by fix: add a missing hasRunningProcess check that causes a flaky assertion under
`AuxiliaryProcessProxy::connection()` in layout tests.

(-[WKContentView gestureRecognizer:shouldRequireFailureOfGestureRecognizer:]):
(-[WKContentView gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:]):

Add dynamic failure requirements between WKContentView's gestures (including all text interaction, context menu,
and drag and drop gestures) and the new deferring gesture recognizers.

(-[WKContentView _didStartProvisionalLoadForMainFrame]):

Force the two-finger double tap gesture recognizer to reset when loading a new page. Without this, the layout
test fast/events/ios/click-event-while-editing-node.html will rarely fail when run after a test that dispatches
a two-finger tap, such as fast/events/ios/click-event-two-finger-single-tap-meta-key.html. This is because the
new deferring gestures will temporarily unite multi-finger tap gestures with one-finger double tap gestures in
the same subgraph when performing a tap gesture with more than one finger. This means that there's a 300 ms
delay before a normal single tap can be recognized again, which (without forcing the two-finger double tap to
reset) would cause a subsequent test that loads in under 300 ms and attempts to send a tap to fail.

(-[WKContentView deferringGestureRecognizer:shouldDeferGesturesAfterBeginningTouchesWithEvent:]):

Avoid deferring native gestures if the scroll view is decelerating; this matches behavior of the web touch event
gesture recognizer.

(-[WKContentView deferringGestureRecognizer:shouldDeferGesturesAfterEndingTouchesWithEvent:]):

Normally, after -touchesEnded:withEvent:, we stop deferring native gesture recognizers by failing the deferring
gestures. However, if we're still waiting for a response from the web process, then let
-_doneDeferringNativeGestures: handle this instead.

(-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]):
(-[WKContentView deferringGestureRecognizer:shouldDeferGesturesWithEvent:]): Deleted.

Renamed to -shouldDeferGesturesAfterBeginningTouchesWithEvent:.

* UIProcess/ios/WKDeferringGestureRecognizer.h:
* UIProcess/ios/WKDeferringGestureRecognizer.mm:
(-[WKDeferringGestureRecognizer touchesBegan:withEvent:]):
(-[WKDeferringGestureRecognizer touchesEnded:withEvent:]):

Override this and add a new delegate hook to determine whether we want the deferring gesture recognizer to
immediately fail when touches end. It's important to override this and transition to failure state in this case,
since not doing so could mean that the deferring gestures stay in Possible state forever; this may lead to the
gesture subgraph containing these deferring gestures being unable to reset, since it's waiting for the deferring
gesture to either fail or end.

* UIProcess/ios/WKScrollView.mm:
(-[WKScrollView gestureRecognizer:shouldRequireFailureOfGestureRecognizer:]):
(-[WKScrollView gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:]):

Defer more scroll view gestures.

* WebProcess/WebPage/EventDispatcher.cpp:
(WebKit::EventDispatcher::touchEvent):

Add an optional CallbackID parameter to this IPC message. If a callback ID is given, then we avoid coalescing
the touch event. To implement this, we additionally refactor the queued touch events map to contain lists of
<WebTouchEvent, Optional<CallbackID>> pairs; if a queued touch event has a corresponding CallbackID, then we
fire the callback corresponding to the ID, indicating whether the touch event was handled by the page.

* WebProcess/WebPage/EventDispatcher.h:
* WebProcess/WebPage/EventDispatcher.messages.in:
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::dispatchAsynchronousTouchEvents):

LayoutTests:

* fast/events/touch/ios/prevent-default-on-touch-start-with-slow-event-listener-expected.txt: Added.
* fast/events/touch/ios/prevent-default-on-touch-start-with-slow-event-listener.html: Added.
* fast/events/touch/ios/scroll-on-touch-start-with-slow-event-listener-expected.txt: Added.
* fast/events/touch/ios/scroll-on-touch-start-with-slow-event-listener.html: Added.

Add new layout tests to cover behaviors when panning over active touchstart handlers that spin for an extended
length of time (in this case, 400 milliseconds) in overflow scrolling containers. A touchstart handler that
prevents default should still block scrolling, and a touchstart handler that does not should still allow the
user to scroll.

* fast/events/touch/ios/show-modal-alert-during-touch-start.html:
* http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt:
* http/tests/security/anchor-download-block-crossorigin-expected.txt:

Rebaseline these tests by changing some line numbers.

* resources/ui-helper.js:
(window.UIHelper.sendEventStream.return.new.Promise):
(window.UIHelper.sendEventStream):

Add a new UIHelper method to send a JSON object as an event stream.

(UIHelper.EventStreamBuilder.prototype._reset):
(UIHelper.EventStreamBuilder.prototype.begin):
(UIHelper.EventStreamBuilder.prototype.move):
(UIHelper.EventStreamBuilder.prototype.end):
(UIHelper.EventStreamBuilder.prototype.takeResult):

Add a new helper class to make it easier to construct event streams, for the purposes of sending to
UIScriptController::sendEventStream.


Canonical link: https://commits.webkit.org/218214@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@253267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-12-08 03:57:23 +00:00
Megan Gardner 75dffc5cd2 Update dismiss-picker-using-keyboard.html test to work on iPad correctly
https://bugs.webkit.org/show_bug.cgi?id=204257
<rdar://problem/57239690>

Reviewed by Wenson Hsieh.

The iPad does not use the keyboard to show the options for these form controls,
and instead uses a popover. This expands the test infrastructure to allow for
either iPhone or iPad functionality.

* fast/forms/ios/dismiss-picker-using-keyboard.html:
* resources/ui-helper.js:
(window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.):
(window.UIHelper.waitForInputSessionToDismiss.return.new.Promise.):
(window.UIHelper.waitForInputSessionToDismiss.return.new.Promise):
(window.UIHelper.waitForInputSessionToDismiss):


Canonical link: https://commits.webkit.org/217606@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252608 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-11-19 01:05:14 +00:00